Getting Integer division and modulo by zero error - python-3.x

I'm getting Integer Division or Modulo by zero error.
def getProduct(n):
product = 1
while (n != 0):
product = product * (n % 10)
n = n // 10
return product
def printSubstrings(n):
s=int(math.log10(n))
d=(math.pow(10,s))
k=d
count = 0
while n>0:
while d>0:
ans=0
ans = getProduct(n//d)
if ans%4==0 or ans%2!=0:
count+=1
d=int(d/10)
n = int(n%k)
k = int(k//10)
d = k
print(count)
Simple Inputs are running well but On entering Large input data it gives ZERODIVISIONERROR
on large input
10
11903030 2093524 04935049 09024 12242910 109310 1000901 103412 102901 10290191
Error I get:
Traceback (most recent call last):
File "e:/CodeWork/Code Challenge/rough.py", line 271, in <module>
printSubstrings(num)
File "e:/CodeWork/Code Challenge/rough.py", line 261, in printSubstrings
n = int(n%k)
ZeroDivisionError: integer division or modulo by zero

You need to make sure k != 0 holds before you compute n % k.
Since the modulus operator % is implemented by finding the remainder upon division, you will get a division by zero error if you try to evaluate n % 0 for any integer n.

Related

Sum of Fibonacci sequence throws overflow error for large numbers

For smaller numbers, till r = 1472 the below code is working well and good.
Code:
import math
def fib(n):
s5 = math.sqrt(5)
phi = (1 + s5) / 2;
return int(round(pow(phi, n) / s5));
def calculateSum(l, r):
# Using our deduced result
sum = fib(r + 2) - fib(l + 1)
res = sum % 1000000007
return res
l = 5
r =1400
print(calculateSum(l,r))
But when the r goes beyond 1473 it throws the following error.
Traceback (most recent call last):
File "C:/Users/HP/PycharmProjects/spoj/FIBOSUM.py", line 20, in <module>
print(calculateSum(l,r))
File "C:/Users/HP/PycharmProjects/spoj/FIBOSUM.py", line 14, in calculateSum
sum = fib(r + 2) - fib(l + 1)
File "C:/Users/HP/PycharmProjects/spoj/FIBOSUM.py", line 9, in fib
return int(round(pow(phi, n) / s5));
OverflowError: (34, 'Result too large')
Process finished with exit code 1
And I referred and searched about this error and found a way to mitigate using this link Error 34, Result too large. These changes are reflected below
Code2:
import decimal
def fib(n):
s5 = decimal.Decimal(5).sqrt()
phi = (1 + s5) / 2;
return int(round(pow(phi, n) / s5));
def calculateSum(l, r):
# Using our deduced result
sum = fib(r + 2) - fib(l + 1)
res = sum % 1000000007
return res
l = 5
r =4500000
print(calculateSum(l,r))
These changes are works for the numbers approximately less than say r = 4550000 but a number larger than 5000000 throws the following error
Traceback (most recent call last):
File "C:/Users/HP/PycharmProjects/spoj/FIBOSUM.py", line 20, in <module>
print(calculateSum(l,r))
File "C:/Users/HP/PycharmProjects/spoj/FIBOSUM.py", line 14, in calculateSum
sum = fib(r + 2) - fib(l + 1)
File "C:/Users/HP/PycharmProjects/spoj/FIBOSUM.py", line 9, in fib
return int(round(pow(phi, n) / s5));
decimal.Overflow: [<class 'decimal.Overflow'>]
Could anybody help me to resolve this problem?

OverflowError: (34, 'Result too large') in round function

I need to use the round function in my code because at a point the floats became too big and python can't handle them, so i simply implemented it like this:
def h(x, theta):
return theta[0] + theta[1] * x
def err(theta, x, y):
error = []
i = 0
for e in x:
prevision = h(x[i], theta) - y[i] #part where i putted round function
prevision = round(prevision, 10)
print(prevision)
error.append(prevision)
i += 1
return error
def sqrErr(error):
sqrError = []
for e in error:
sqrError.append(e ** 2)
return sqrError
def errForX(error, x):
errorForX = []
i = 0
for e in error:
errorForX.append(error[i] * x[i])
i += 1
return errorForX
def Theta(theta, error, sqrError, errorForX, lr):
newThetaList = []
i = 0
for e in theta:
newTheta = 0
if i == 0: #theta_0
newTheta = e - lr * (1/2) * sum(error) * ((1/4) * sum(sqrError))
elif i == 1: #theta:1
newTheta = e - lr *(1/2) * sum(errorForX) * ((1/4) * sum(sqrError))
newThetaList.append(newTheta)
i += 1
return newThetaList
def Train():
nLoops = 1000000
y =[5, 11, 21]
x = [2, 5, 10]
theta = [0, 0]
lr = 0.00021
prediction = []
for loop in range(nLoops):
error = err(theta, x, y)
sqrError = sqrErr(error)
errorForX = errForX(error, x)
theta = Theta(theta, error, sqrError, errorForX, lr)
predictions = []
for e in x:
predictions.append(h(e, theta))
print("Theta: ")
print(theta)
print("Targets: ")
print(y)
print("Predictions: ")
print(predictions)
Train()
The numbers became too big and it throws an error.
This is my first ever script of a machine learning algorithm, the squared error became a really long number and i don't how to prevent that, tried to limit to 10 the number of digits of the number that is going to be raised to the second but it didn't work
This is the error:
Traceback (most recent call last):
File "C:/Users/flama/OneDrive/Desktop/rete neurale v3.py", line 74, in <module>
Train()
File "C:/Users/flama/OneDrive/Desktop/rete neurale v3.py", line 59, in Train
sqrError = sqrErr(error)
File "C:/Users/flama/OneDrive/Desktop/rete neurale v3.py", line 21, in sqrErr
sqrError.append(e ** 2)
OverflowError: (34, 'Result too large')

Optimization of CodeWars Python 3.6 code: Integers: Recreation One

I need help optimizing my python 3.6 code for the CodeWars Integers: Recreation One Kata.
We are given a range of numbers and we have to return the number and the sum of the divisors squared that is a square itself.
"Divisors of 42 are : 1, 2, 3, 6, 7, 14, 21, 42. These divisors squared are: 1, 4, 9, 36, 49, 196, 441, 1764. The sum of the squared divisors is 2500 which is 50 * 50, a square!
Given two integers m, n (1 <= m <= n) we want to find all integers between m and n whose sum of squared divisors is itself a square. 42 is such a number."
My code works for individual tests, but it times out when submitting:
def list_squared(m, n):
sqsq = []
for i in range(m, n):
divisors = [j**2 for j in range(1, i+1) if i % j == 0]
sq_divs = sum(divisors)
sq = sq_divs ** (1/2)
if int(sq) ** 2 == sq_divs:
sqsq.append([i, sq_divs])
return sqsq
You can reduce complexity of loop in list comprehension from O(N) to O(Log((N)) by setting the max range to sqrt(num)+1 instead of num.
By looping from 1 to sqrt(num)+1, we can conclude that if i (current item in the loop) is a factor of num then num divided by i must be another one.
Eg: 2 is a factor of 10, so is 5 (10/2)
The following code passes all the tests:
import math
def list_squared(m, n):
result = []
for num in range(m, n + 1):
divisors = set()
for i in range(1, int(math.sqrt(num)+1)):
if num % i == 0:
divisors.add(i**2)
divisors.add(int(num/i)**2)
total = sum(divisors)
sr = math.sqrt(total)
if sr - math.floor(sr) == 0:
result.append([num, total])
return result
It's more the math issue. Two maximum divisors for i is i itself and i/2. So you can speed up the code twice just using i // 2 + 1 as the range stop instead of i + 1. Just don't forget to increase sq_divs for i ** 2.
You may want to get some tiny performance improvements excluding sq variable and sq_divs ** (1/2).
BTW you should use n+1 stop in the first range.
def list_squared(m, n):
sqsq = []
for i in range(m, n+1):
divisors = [j * j for j in range(1, i // 2 + 1 #speed up twice
) if i % j == 0]
sq_divs = sum(divisors)
sq_divs += i * i #add i as divisor
if ((sq_divs) ** 0.5) % 1 == 0: #tiny speed up here
sqsq.append([i, sq_divs])
return sqsq
UPD: I've tried the Kata and it's still timeout. So we need even more math! If i could be divided by j then it's also could be divided by i/j so we can use sqrt(i) (int(math.sqrt(i)) + 1)) as the range stop. if i % j == 0 then append j * j to divisors array. AND if i / j != j then append (i / j) ** 2.

Convert text to decimal python3

I need to convert words to numbers for RSA cipher, so i found code which can convert text to decimal, but when i run it in terminal by python 3 i get:
Traceback (most recent call last):
File "test.py", line 49, in <module>
numberOutput = int(bit_list_to_string(string_to_bits(inputString)),2) #1976620216402300889624482718775150
File "test.py", line 31, in string_to_bits
map(chr_to_bit, s)
File "test.py", line 30, in <listcomp>
return [b for group in
File "test.py", line 29, in chr_to_bit
return pad_bits(convert_to_bits(ord(c)), ASCII_BITS)
File "test.py", line 14, in pad_bits
assert len(bits) <= pad
AssertionError
when i use "python convert_text_to_decimal.py" in terminal it works correctly.
Code:
BITS = ('0', '1')
ASCII_BITS = 8
def bit_list_to_string(b):
"""converts list of {0, 1}* to string"""
return ''.join([BITS[e] for e in b])
def seq_to_bits(seq):
return [0 if b == '0' else 1 for b in seq]
def pad_bits(bits, pad):
"""pads seq with leading 0s up to length pad"""
assert len(bits) <= pad
return [0] * (pad - len(bits)) + bits
def convert_to_bits(n):
"""converts an integer `n` to bit array"""
result = []
if n == 0:
return [0]
while n > 0:
result = [(n % 2)] + result
n = n / 2
return result
def string_to_bits(s):
def chr_to_bit(c):
return pad_bits(convert_to_bits(ord(c)), ASCII_BITS)
return [b for group in
map(chr_to_bit, s)
for b in group]
def bits_to_char(b):
assert len(b) == ASCII_BITS
value = 0
for e in b:
value = (value * 2) + e
return chr(value)
def list_to_string(p):
return ''.join(p)
def bits_to_string(b):
return ''.join([bits_to_char(b[i:i + ASCII_BITS])
for i in range(0, len(b), ASCII_BITS)])
inputString = "attack at dawn"
numberOutput = int(bit_list_to_string(string_to_bits(inputString)),2) #1976620216402300889624482718775150
bitSeq = seq_to_bits(bin(numberOutput)[2:]) #[2:] is needed to get rid of 0b in front
paddedString = pad_bits(bitSeq,len(bitSeq) + (8 - (len(bitSeq) % 8))) #Need to pad because conversion from dec to bin throws away MSB's
outputString = bits_to_string(paddedString) #attack at dawn
So when i use just python he have 2.7 version. Please, help me fix this code to python 3
Change line 22,
n = n / 2
to
n = n // 2
This solves the immediate error you get (and another one that follows from it). The rest of the routine may or may not work for your purposes; I did not check any further.
You get the assert error because the function convert_to_bits should be, theoretically speaking, returning a proper list of single bit values for a valid integer in its range. It calculates this list by dividing the integer by 2 until 0 remains.
However.
One of the more significant changes from Python 2.7 to 3.x was the behavior of the division operator. Prior, this always returned an integer, but with Python 3 it was decided to have it return a float instead.
That means the simple bit calculation loop
while n > 0:
result = [(n % 2)] + result
n = n / 2
does not return a steady list of 0s and 1s anymore, always ending because the source integer runs out of numbers, but instead you get a list of more than a thousand floating point numbers. At a glance it may be unclear what that list represents, but as it ends with
… 1.03125, 0.0625, 0.125, 0.25, 0.5, 1]
you can see it's the divide-by-two loop that keeps on dividing until its input finally runs out of floating point accuracy and stops dividing further.
The resulting array is not only way, way larger than the next routines expect, its data is also of the wrong type. The values in this list are used as an index for the BITS tuple at the top of your code. With the floating point division, you get an error when trying to use the value as an index, even if it is a round 0.0 or 1.0. The integer division, again, fixes this.

Length of the factorial

I tried running the program below:
from functools import lru_cache
#lru_cache(Maxsize = None)
def count(n):
factorial_num = 1
num_digits = 0
if n == 1:
factorial_num = 1
else:
factorial_num = n * count(n-1)
return len(str(factorial_num))
However, it didn't give me the length of the factorial number as anticipated.
I also wanted to use the code to find the factorial of very big numbers in range of billions and tried using lru_cache. Still, no luck.
As Aziz pointed out in the comments, your recursive case is wrong.
factorial_num = n * count(n-1)
This would do something useful if count(n-1) actually returned (n-1)!, but it doesn't, since you're trying to return a digit count instead.
>>> count(1)
1 # Base case is correct.
>>> count(2)
1 # 2 * count(1) = 2 * 1 = 2. Whose *length* is 1 digit.
>>> count(9)
1 # For all single-digit n, count(n) is still 1.
>>> count(10)
2 # 10 * count(9) = 10 * 1 = 10. Whose *length* is 2 digits.
You should write a function that just calculates the factorial, instead of trying to mix this logic with the digit counting.
#lru_cache(maxsize=None)
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
Note that recent versions of Python have a built-in math.factorial function, which you could use instead if your teacher is not requiring you to roll your own factorial code.
Then, you can simply use len(str(factorial(n))) to count the digits.
You can use Kamenetsky formula to return the number of digits in n!
For minor numbers use:
def findDigits(n):
if (n < 0):
return 0;
if (n <= 1):
return 1;
digits = 0;
for i in range(2, n + 1):
digits += math.log10(i);
return math.floor(digits) + 1;
For bigger numbers use:
def findDigits(n):
if (n < 0):
return 0;
if (n <= 1):
return 1;
x = ((n * math.log10(n / math.e) +
math.log10(2 * math.pi * n) /2.0));
return math.floor(x) + 1;
source: https://www.geeksforgeeks.org/count-digits-factorial-set-1/?ref=lbp and https://www.geeksforgeeks.org/count-digits-factorial-set-2/?ref=lbp

Resources