Getting MemoryError in Python - python

I am running following code on python to print nos. in the range specified for even floating nos.:
def float_range(begin,end,step):
i=begin-step
numbers=[]
while i!=end:
i=i+step
numbers.append(i)
return numbers #returning the list
a=2
b=4
c=.1
for j in float_range(a,b,c): #calling function
print j
and it gives following error
Traceback (most recent call last):
File "C:\Users\b53659\Desktop\My python\float_range.py", line 13, in <module>
for j in float_range(a,b,c):
File "C:\Users\b53659\Desktop\My python\float_range.py", line 7, in float_range
numbers.append(i)
MemoryError.
but in above code if i replace
a=1
b=1000
c=1
it gives correct output i.e. prints no. from 1 to 1000.
why is it happening? thanks in advance

The problem is that you're using c=.1, which makes the counter floating point. When the loop gets to the 'end' (in float_range), i will be something like 4.00000000001 or 3.9999999999998, and so it doesn't compare equal to the integer 4.
There are a few possible solutions:
Only use integers (whole numbers, not 0.1)
Use python's fixed-point numbers (the decimal.Decimal class)
Make the loop end condition i < end instead of i!=end

You should do something like this
def float_range(begin,end,step):
i = begin-step
numbers = []
while i < end:
i += step
numbers.append(i)
return numbers #returning the list
for j in float_range(2,4,0.1): #calling function
print round(j, 2)
This way you'll be sure that the loop stops when it's above end even if the float doesn't hit the exact integer value.
I also made two other changes apart from while i < end:. You can use += instead of i = i+step. I've also rounded the floats down, since it'll print something like 3.9000000000000017 if you don't.
I hope this helps.

main flaw in code is while condition !=.
You are checking if i!=end. Here step is 0.1, which is actually something like 0.100000000000001. So when you reach to last iteration(as per your logic)
i = 3.9 + step = 4.000000001
and you have end= 4.0
and i!=end
So your while loops condition i!=end is True always and loop continues forever and throw memory error
I have debugged you code And found the actual values in the list. You can see from the screen shot then 4.0 value never generated instead 4.0000001 get generated
This code would work as you expected:
def float_range(begin,end,step):
i=begin-step
numbers=[]
while i < end:
i=i+step
numbers.append(i)
return numbers #returning the list

Related

I don't see my error here - Trying to learn Python

I'm trying to become comfortable with python. I've been trying some simple activities that I've given in my beginning c++ classes when I was teaching. I did one involving functions and writing a file which worked flawlessly. I thought this one would be easier. It acts like it is in a silent endless loop, but it won't even let me trace it. Can someone see where I am going awry?
# Find Adam Numbers
def isAdamNumber(candidate):
isAdam = False
rev = reverse(candidate)
square = candidate * candidate
revsq = rev*rev
if revsq == reverse(square):
isAdam = True
return isAdam
def reverse(num):
rev=0
while num > 0:
rev = rev * 10 + num%10
num/=10
return rev
for x in range (11,25):
if isAdamNumber(x):
print(x, " is an adam number\n")
The quick fix is to change /= with the integer division version, //=
Inside the reverse function, you are going into an infinite loop. num value always will be greater than 0, therefore the while loop will continuously run. In python, you can get the reverse of the function without much effort. Convert the integer to string and reverse the string and now change the string back to integer.
def reverse(num):
num_str = str(num)[::-1]
return int(num_str)
I think this function definition can solve your problem.
To visualize the python to learn and teach, use this link
The problem has already been addressed by the other answers, so here's the expanded and simplified version of the slicing that's going on [this doesn't actually use slicing]:
def reverse(num):
rev = ''
num = str(num)
for i in range(len(num) - 1, -1, -1):
rev += num[i]
return int(rev)
This counts backward from the last element in the string version of num, and adds all the elements of num (in reverse order) to rev.
num > 0 is never False. Dividing a positive number by 10 repeatedly makes it smaller, but it never becomes zero, so the while loop keeps repeating.
Use //= instead. It rounds to the nearest integer, so it will reach 0.
This also wouldn't reverse numbers (unless I'm missing something). Alternatively, you can use
int(str(num)[::-1])
which converts the number to a string, reverses it using slicing, and turns it back into an integer.

Converting binary number to decimal useing string

I've tried to write a simple function, which input is binary number in string format and converts binary to decimal. But in the output I always get the wrong thing: the 'res' value in line 3, no matter what the input is ('1010', '10010111010', etc.). Also, I've tried to debug the code and the function doesn't even start the loop, as if it wasn't there... So, I just don't see my mistake
def bin_to_dec(bin):
bin = bin[::-1]
res = 0
for i in range(len(bin)):
if bin[i] == 0:
res += 2**i
return res
You are comparing the string "0" to the number 0 and they are, trivially, unequal.
So, contrary to what you say, the loop is actually looping; but the if statement will never be true.
Of course, also, you should probably add when the number is 1, not when it's 0.
def bin_to_dec(bin):
bin = bin[::-1]
res = 0
for i in range(len(bin)):
if int(bin[i]) == 1:
res += 2**i
return res
Notice the addition of int().
if bin[i] == '1'
This will correct the problem. bin[i] is a character and you are comparing it to a number which always results in false.
You can just use the built in int function:
def binaryToDecimal(n):
return int(n,2)

How to keep track the amount of even integers when looking through randomized list using recursion

Sorta newbie here. So in trying to wrap my head around using recursive functions I wanted to try to make a program that:
1: Generates a list containing 10 random integers ranging from 0 - 20
2: Using a recursive function goes trough the list and finds out what elements of the list are even integers
3: Prints out only the aformentioned even numbers
Where I have gotten stuck is in how to print out the result. I can't seem to figure out what value i want to put inside the function when calling it ( F(?) )
I tried to integrate a counter that kept track on how many times the program found a even number but it always resulted in an error that the variable is not defined no matter how hard I tried to make it global.
How could I go about this? Am I totally in the wrong?
import random
numL = []
for i in range(10):
x = random.randint(0,20)
numL.append(x)
print(numL)
def F(x):
if numL[x] % 2 == 0:
return numL[x]
else:
return F(x+1)
print(F( ??? ))
First question asked on this forum, hopefully I did okay, appreciate any help!
Assuming you want to return a list of the even numbers then you have 4 cases to consider
This is the last number in the list and its even so return this number
This is the last number in the list and its odd dont retrun this number
There are more numbers to check and this number is even so return
this plus the function result
There are more numbers to check and this number is odd to return
only the function result and not this num
So we can code this as
import random
def get_even_nums(nums):
num = nums[0]
#This is our terminating case we definitivly return a value here
if len(nums) == 1:
return [num] if num % 2 == 0 else []
else:
#If we got here we will be recursivly calling the function
#If its even number return that number plus the result of the function
#it its not even then just return the reult of the function and not this num
if num % 2 == 0:
return [num] + get_even_nums(nums[1:])
else:
return get_even_nums(nums[1:])
numL = [random.randint(0, 20) for _ in range(10)]
print(numL)
print(get_even_nums(numL))
OUTPUT
[3, 6, 5, 10, 20, 18, 5, 0, 3, 9]
[6, 10, 20, 18, 0]
So I took your function and changed it up slightly (using a slightly different approach). There's no need to a global list, though you could do that as well, if you wanted. The problem that you have is the lack of a base case or rather an incorrect one.
If you run your original function with an argument 0, which basically is the first element of your generated array, the fucntion will run until it hits one even number. At that point it'll exit recursion, because the base case basically stops recursive calls once you hit an even number.
Now, to fix this, you have to approach the problem differently. I would put your generated array as the input argument to your function, then ask myself "What would be a good base case?" Probably one that stops your recursive calls once you reach the end of the input list.
if len(numL) == 0:
return ...
Also, we need a way to return the even numbers that we found during our search through the list. For that reason I'd introduce a new acc list, where we would append the even numbers that we found. Thus the function input arguments would be
def F(numL, acc):
...
Now, in the recursive call we should check wether the current element is even or not. If it is, great, we add it to the acc list and continue into the recursive call. If it's not, we don't add anything to the acc but just continue with recursion.
if numL[0] % 2 == 0:
acc.append(numL[0])
return F(numL[1:], acc)
Putting it all together, we get:
def F(numL, acc):
if len(numL) == 0:
return acc
else:
if numL[0] % 2 == 0:
acc.append(numL[0])
return F(numL[1:], acc)
where numL represents your generated list and acc represents the resulting list we'll return after we traverse the list.
This is your function (as I understand it, you wanted this):
import random
def F(i):
r = random.randint(0,20)
if r % 2 == 0:
print(r)
i += 1
if i != 10:
F(i)
F(0)

Calculating a factorial using loops in Python3

I am currently studying Software Development as a beginner and I have a task in my programming class to calculate and display a factorial using a loop. I've been given the pseudo-code and have to translate it into true code and test it in the REPL to make sure it returns the expected results.
I almost have it but I've run into two issues that I just can't seem to resolve.
1) The function is returning an extra line of "None" after the calculation and
2) The answer is displaying over multiple lines when I want it to display on a single line.
My current code (which does return the correct answer) is as follows:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
When I test, using 3 for example, the REPL returns the following:
>>> print(calcFactorial(3))
3! = 3
x 2
x 1
= 12
None
So I have the correct answer but with an extra line of "None" which I would like to remove (I believe it has something to do with the print function?) and I don't know how to format it correctly.
Any help would be much appreciated.
your function calcFactorial(3) prints already, so you shouldn't call it with
print(calcFactorial(3))
just call it with
calcFactorial(3)
without the print function.
you might think about calling the function calc_and_print_factorial() in order to make it clear, that this function does already the printing
Regarding your second question:
Blockquote
2) The answer is displaying over multiple lines when I want it to display on a single line.
You can fix it by using a single print statement:
def calcFactorial(number):
factorial = 1
string = str(number) + "! = " + str(number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*(number-count)
string = string + " x " + str(number-count)
factorial = factorial * number
print(string + " = " + str(factorial))
This will give you:
IN: calcFactorial(3)
OUT: 3! = 3 x 2 x 1 = 6
On a side note: you might want to think of how to implement this recursively. Maybe that comes later in your class but this would be one of the first go-to examples for it.
Adding to the blhsing's answer, you should choose between these built-in ways to print the "returned" value.
First way:
def calcFactorial(number):
... # <- Your function content
return factorial
Then, call your function with a print() to get the explicitly returned value, as you can see in the return factorial line. See this reference for more details:
print(calcFactorial(3))
Second way:
Having the same function definition with its return statement, just call the function with its instance statement:
calcFactorial(8)
By default, python will print the returned value without a print()
Third way:
Just call the function (without the explicit return statement, this will return a "None" (null-like) value by default), using the print() method. Do NOT use print() inside another print().
Your calcFactorial function does not explicitly return a value, so it would return None by default, so print(calcFactorial(3)) would always print None.
You should make the calcFactorial function return factorial as a result at the end:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
return factorial
So I have the correct answer but with an extra line of "None" which I would like to remove
You are printing the return value from your function. In this case, you haven't specified a return value with a return statement so the function automatically returns None.
To fix the problem, you should return a value from your function. Note that you don't need to call print() for final answer because the REPL already does this for you.
Note that the REPL will automatically print the return value for you, so you can just type calcFactorial(3) instead of print(calcFactorial(3)).
Additionally, you are not getting the correct answer. You should get 6 instead of 12. It looks like you are trying to count down from number and multiplying each number together. You can get the same result by counting up from 1. This will lead to much simpler code and avoid the error.
If you want to understand why your code isn't doing the correct thing, look closely at factorial = factorial*number-count and think about the order of operations that are used to calculate the result here.

python IDLE fibonocci sequence my model doesn't work

need help with this, i tried something but it didn't work for some reason. I need some help to figure it out.
def F(n):
if n == 0: return 0
elif n == 1: return 1
else: return F(n-1)+F(n-2)
F('3')
and here is the original problem- Write a function called fib which takes as a parameter an integer, n, and returns the nth number in the Fibonocci sequence (see definition below). If n is zero or a negative number, your function should return an error message in the form of a string "Error: Invalid input.".
The Fibonocci sequence is 1, 1, 2, 3, 5, 8, 13, 21, ... where the first two numbers are 1, and each number beyond that is calculated as the sum of the previous two numbers (2 = 1+1, 3 = 2+1, 5 = 3+2, 8=5+3, etc).
i guess the problem is that you use string instead of integer.
try F(3) instead of F('3')
or give more information about the error you get
First, for the invalid numbers error you are supposed to print out, I would suggest adding another if statement in. Below shows an example of how you could set any negative number to return an error message.
if n < 0: return "Error: Invalid Input"
For the F function, it goes back to data types. When you put in quotes around something, that specifies an actual string. When you just have a number, it will be an integer data type. For this, we want an integer data type since we want to do math operations on our number. This is why you should remove the quotes.

Categories

Resources