I'm writing a recursive function in python that keeps giving me a division by zero error, why am I getting this?
I've tried several rearrangements of if statements to eliminate all operations when n==0 but somehow it still occurs. I've added a print(n) to the else portion to see when the error occurs and it prints fine all the way to n=2, but then when n=1 it seems I get the error. This is strange because when I do kleinfeldt(1) it works fine...
def kleinfeldt(n):
if n == 1:
return 1
else:
return ((1/(n^2)) + kleinfeldt(n-1))
If I type in kleinfeldt(3) for example, I should get a result of 1 + 1/4 + 1/9, but instead it just says that there's a division by zero error.
It seems that you confused the XOR operator (^) with power operator (**). The code works fine if change it:
def kleinfeldt(n):
if n == 1:
return 1
else:
return ((1/(n**2)) + kleinfeldt(n-1))
If you care about precise result you may want to read about fractions module.
Yes, indeed you will get an ZeroDivisionError: integer division or modulo by zero error because you are using an xor(^) operator in the below line of else condition :
return ((1/(n^2)) + kleinfeldt(n-1))
When it comes to the input 3, 2^2 will give you the 0 output so if you divide 1/(2^2) you will get an error.
To avoid this, you can use ** which will act as a power function or you can do like below :
import math
int(math.pow(2, 2))
Try the below modified codes :
def kleinfeldt(n):
if n == 1:
return 1
else:
return ((1/(n**2)) + kleinfeldt(n-1))
Or
import math
def kleinfeldt(n):
if n == 1:
return 1
else:
return ((1/(int(math.pow(n, 2)))) + kleinfeldt(n-1))
I hope it helps...
Related
In this kata you need to build a function to return either true/True or false/False if a string can be seen as the repetition of a simpler/shorter subpattern or not.
For example:
has_subpattern("a") == False #no repeated pattern
has_subpattern("aaaa") == True #created repeating "a"
has_subpattern("abcd") == False #no repeated pattern
has_subpattern("abababab") == True #created repeating "ab"
has_subpattern("ababababa") == False #cannot be entirely reproduced repeating a pattern
Strings will never be empty and can be composed of any character (just consider upper- and lowercase letters as different entities) and can be pretty long (keep an eye on performances!).
My solution is:
def has_subpattern(string):
string_size = len(string)
for i in range(1, string_size):
slice1 = string[:i]
appearence_count = string.count(slice1)
slice1_len = len(slice1)
if appearence_count > 0:
if appearence_count * slice1_len == string_size:
return True
return False
Obviously there are weak and too slow things like slice1 = string[:i] and string.count() in loop..
Is there better ways to solve an issue or ways to improve performance ?
Short regex approach:
import re
def has_subpattern_re(s):
return bool(re.search(r'^(\w+)\1+$', s))
It'll provide a close (to initial has_subpattern approach) performance on small strings:
import timeit
...
print(timeit.timeit('has_subpattern("abababab")', 'from __main__ import has_subpattern'))
0.7413144190068124
print(timeit.timeit('has_subpattern_re("abababab")', 'from __main__ import re, has_subpattern_re'))
0.856149295999785
But, a significant performance increase (in about 3-5 times faster) on long strings:
print(timeit.timeit('has_subpattern("ababababababababababababababababababababababababa")', 'from __main__ import has_subpattern'))
14.669428467008402
print(timeit.timeit('has_subpattern_re("ababababababababababababababababababababababababa")', 'from __main__ import re, has_subpattern_re'))
4.308312018998549
And one more test for a more longer string:
print(timeit.timeit('has_subpattern("ababababababababababababababababababababababababaababababababababababababababababababababababababab")', 'from __main__ import has_subpattern'))
35.998031173992786
print(timeit.timeit('has_subpattern_re("ababababababababababababababababababababababababaababababababababababababababababababababababababab")', 'from __main__ import re, has_subpattern_re'))
7.010367843002314
Within standard Python, the bottlenecks here will be count, which enjoys C speed implementation and the looping.
The looping itself may be hard to speed-up (althogh Cython may be of some help).
Hence, the most important optimization is to reduce the number of loopings.
One obvious way is to let range() do not exceed half the size of the input (+ 2: + 1 for rounding issues, + 1 for end extrema exclusion in range()):
Also, string is a standard Python module, so better not use it as a variable name.
def has_subpattern_loop(text):
for i in range(1, len(text) // 2 + 2):
subtext = text[:i]
num_subtext = text.count(subtext)
if num_subtext > 1 and num_subtext * len(subtext) == len(text):
return True
return False
A much more effective way of restricting the number of calls to count is to skip computation when i is not a multiple of the length of the input.
def has_subpattern_loop2(text):
for i in range(1, len(text) // 2 + 2):
if len(text) % i == 0:
subtext = text[:i]
num_subtext = text.count(subtext)
if num_subtext > 1 and num_subtext * len(subtext) == len(text):
return True
return False
Even better would be to generate only the divisors of the length of the input.
This could be done using sympy and the approach outlined here:
import sympy as sym
import functools
def get_divisors(n):
if n == 1:
yield 1
return
factors = list(sym.factor_.factorint(n).items())
nfactors = len(factors)
f = [0] * nfactors
while True:
yield functools.reduce(lambda x, y: x * y, [factors[x][0]**f[x] for x in range(nfactors)], 1)
i = 0
while True:
f[i] += 1
if f[i] <= factors[i][1]:
break
f[i] = 0
i += 1
if i >= nfactors:
return
def has_subpattern_divs(text):
for i in get_divisors(len(text)):
subtext = text[:i]
num_subtext = text.count(subtext)
if num_subtext > 1 and num_subtext * len(subtext) == len(text):
return True
return False
A completely different approach is the one proposed in #ВладДавидченко answer:
def has_subpattern_find(text):
return (text * 2).find(text, 1) != len(text)
or the more memory efficient (requires ~50% less additional memory compared to has_subpattern_find2()):
def has_subpattern_find2(text):
return (text + text[:len(text) // 2 + 2]).find(text, 1) > 0
and it is based on the idea that if there is a exactly self-repeating string, the string itself must be found in a circularly extended string:
Input: abab
Extension1: abababab
Found1: |-abab
Extension2: ababab
Found2: |-abab
Input: ababa
Extension1: ababaababa
Found1: |----ababa
Extension2: ababab
Found2: NOT FOUND!
The find-based method are the fastest, with has_subpattern_find() being fastest in the small input size regime, and has_subpattern_find2() gets generally faster in the intermediate and large input size regime (especially in the False case).
For shorter inputs, the direct looping approaches (especially has_subpattern_loop2()) are fastest, closely followed (but sometimes surpassed by has_subpattern_re()), but as soon as the input gets bigger (and especially for the False outcome), the has_subpattern_divs() method gets to be the fastest (aside of find-based ones) by far and large, as shown by the following benchmarks.
For the True outcome, has_subpattern_loop2() gets to be the fastest due to the very small number of loops required, which is independent of the input size.
The input is generated as a function of n using:
def gen_input(n, m=0):
g = string.ascii_lowercase
if not m:
m = n
offset = '!' if n % 2 else ''
return g[:n] * (m // min(n, len(g)) + 2) + offset
so that if n is even, the has_subpattern*() always return True and the opposite for odd n.
Note that, in general, the has_subpattern() function will depend not only on the raw size of the input but also on the length of the repeating string, if any. This is not explored in the benchmarks, except for the odd/even separation.
Even Inputs
Odd Inputs
(Full code available here).
(EDITED to include some more solutions as well as comparison with regex-based solution from #RomanPerekhrest)
(EDITED to include some more solutions based on the find from #ВладДавидченко)
Found another one solution, probably will be useful:
def has_subpattern(string):
return (string * 2).find(string, 1) != len(string)
a power of two is a number of the form 2n where n is an integer, i.e. the result of exponentiation with number two as the base and integer n as the exponent.
i want to test a power of two number.For example if i input 128 program input should be True because 128=2^7
so i wrote this code:
import math
def power_of_two(x):
if(x==0):
print ("False")
return False
else:
n = math.log2(x)
if n%1 > 0:
return False
else:
return True
but in this code if i try for example 4096 it works well but if i try larger numbers,for example 4722366482869645213702 it didn't work it output True(should be False)
how can i fix this problem??
def power_of_two(x):
return x > 0 and (x & (x-1)) == 0
Explanation.
Powers of 2 look like
10000000000000000000
After subtraction of 1 they look like
01111111111111111111
Bitwise and of these numbers is 0. For other positive numbers it's false.
A simple solution is to convert the number to its binary form, using bin then test if the first digit is a 1 and all others are 0.
def is_a_power_of_two(x):
if x == 1:
return True
b = bin(x)[2:]
return int(b[0]) == 1 and int(b[1:]) == 0
That's not very fast, but if performances are not an issue for you then it's just fine.
You can test that there are no false negatives using this:
for i in range(100):
assert is_a_power_of_two(2**i)
I am a beginner at learning python 3 and I am just writing basic programs. I wrote this simple program which would take a number in and divide it by numbers starting from 1 to the square root of the number and find the remainders and add it to a list and print it.
import math
def prime_checker(num):
n=1
list_of_remainder=[]
while n == math.floor(num**0.5):
var=int(num % n)
list_of_remainder.append(var)
n += 1
return list_of_remainder
var=prime_checker(10)
print(var)
Please tell me what I did wrong. I would like to point out here that I did try to research a bit and find error but I couldn't and only then have I posted this question.
The problem that I faced was that it printed out an empty list.
to start with, your while loop is not executed even once. The condition for your while loop is
while n == math.floor(num**0.5):
The argument num you are passing to the function prime_checker is equal to 10. In this case your condition test is:
while 1 == math.floor(10**0.5)
which is
while 1 == 3 which is obviously not true and as a result the loop is not executed even once.
import math
def prime_checker(num):
list_of_remainder = []
number=num;
n=1
x=math.floor(number**0.5)
while n <= x:
v=int(number % n)
list_of_remainder.append(v)
n += 1
return list_of_remainder
var=prime_checker(10)
print(var)
The goal is to generate catalan numbers ! my code works up to n = 30 (i tried the same algorithm in JAVA and it's totally correct,but, then something strange happens with python , it gives wrong numbers back after n=30. I'm totally sure that there is an issue about rounding or maybe formats, but can't figure it out by myself!
def catalan(n):
if n < 0:
return -1
else:
if n == 0:
return 1
else:
c_n = (4*n-2)/(n+1)*catalan(n-1)
return int(c_n)
By using /(n+1) you produce a floating point number, which by its nature has a limited precision. This precision is not accurate enough for the larger numbers that appear with n > 30.
So instead, use a formula that sticks with integer numbers: first multiply and only then perform the division, an integer division:
c_n = (4*n-2)*catalan(n-1)//(n+1)
The cast to int is then also unnecessary, and you can just do:
return c_n
Side note: you don't need else when you return in the if part of the statement. So you can write:
def catalan(n):
if n < 0:
return -1
if n == 0:
return 1
return (4*n-2)*catalan(n-1)//(n+1)
I was reading Jeff Knupp's blog and I came across this easy little script:
import math
def is_prime(n):
if n > 1:
if n == 2:
return True
if n % 2 == 0:
return False
for current in range(3, int(math.sqrt(n) + 1), 2):
if n % current == 0:
return False
return True
return False
print(is_prime(17))
(note: I added the import math at the beginning. You can see the original here:
http://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/)
This is all pretty straightforward and I get the majority of it, but I'm not sure what's going on with his use of the range function. I haven't ever used it this way or seen anyone else use it this way, but then I'm a beginner. What does it mean for the range function to have three parameters, and how does this accomplish testing for primeness?
Also (and apologies if this is a stupid question), but the very last 'return False' statement. That is there so that if a number is passed to the function that is less than one (and thus not able to be prime), the function won't even waste its time evaluating that number, right?
The third is the step. It iterates through every odd number less than or equal to the square root of the input (3, 5, 7, etc.).
import math #import math module
def is_prime(n): #define is_prime function and assign variable n to its argument (n = 17 in this example).
if n > 1: #check if n (its argument) is greater than one, if so, continue; else return False (this is the last return in the function).
if n == 2: #check if n equals 2, it so return True and exit.
return True
if n % 2 == 0: #check if the remainder of n divided by two equas 0, if so, return False (is not prime) and exit.
return False
for current in range(3, int(math.sqrt(n) + 1), 2): #use range function to generate a sequence starting with value 3 up to, but not including, the truncated value of the square root of n, plus 1. Once you have this secuence give me every other number ( 3, 5, 7, etc)
if n % current == 0: #Check every value from the above secuence and if the remainder of n divided by that value is 0, return False (it's not prime)
return False
return True #if not number in the secuence divided n with a zero remainder then n is prime, return True and exit.
return False
print(is_prime(17))