ValueError in range function (to print 3^(2^n)) in python - python

while trying to print the sequence of power(3,2^n), i.e, 3^2,3^4,3^8 , I tried using the following line using range function.Is it possible to use the range function to get the desired output? If so please let me know where did I went wrong.
for i in range(3,1000, i*(i-1)): print (i*i)
for example, the following output is expected for i=3,9,81
i*i:=9,81,6561
But the error is :
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
for i in range(3,1000, i*(i-1)): print (i*i)
ValueError: range() arg 3 must not be zero
How can the step value be zero in this case?

You could use a list comprehension to build a list of all of your powers:
mylist = [3**(2**n) for n in range(1,10)] # or whatever range
and then iterate through the comprehension to print all of your results if you want. You can do other stuff with your results in this loop instead of print them.
for item in mylist:
print(item) # print each item on a new line

i = 2
while 3**i < 1000:
print(3**i)
i *= 2

I'm pretty sure what you want to do is very similar to this question. You want to be calling a list comprehension:
powersofthree = [3**(2**i) for i in range(10)]
which returns
[3, 9, 81, ... ]
Then you can print the result at you leisure.
Also, as many in the comments have pointed out, you used i before it was defined, which is why you encountered an error

Related

Merge sort in Python - `int` object is not iterable

Here is merge sort implementation in Python. I am getting the error int object is not iterable when merge_arrays() function is called. Any suggestions will be highly appreciated.
arr = [1,5,4,7,6,8,3,2,9]
def merge_arrays(_arr_left, _arr_right):
sorted_arr = []
left, right = 0, 0
for i in range(0, len(arr)):
if (_arr_left[left] < _arr_right[right]):
sorted_arr.extend(_arr_left[left])
left += 1
else:
print _arr_right[right], right
sorted_arr.extend(_arr_right[right])
right += 1
return sorted_arr
def merge_sort(_arr):
if (len(_arr) <= 1):
return _arr
_arr_left = merge_sort(_arr[:len(_arr)/2])
_arr_right = merge_sort(_arr[(len(_arr)/2):])
return merge_arrays(_arr_left, _arr_right)
try:
merge = merge_sort(arr)
print merge
except Exception as e:
print e
That particular error is coming from the fact that you're saying sorted_array.extend(_arr_left[left]). You're asking for sorted_array to have appended to it every element of the "iterable" _arr_left[left]. But _arr_left[left] isn't really iterable, it's just whatever int is at index left in _arr_left.
If you don't try then except and print the Exception, you'll see a full stack trace that will tell you which line is bad.
File "merge.py", line 27, in <module>
merge = merge_sort(arr)
File "merge.py", line 22, in merge_sort
_arr_left = merge_sort(_arr[:len(_arr)/2])
File "merge.py", line 22, in merge_sort
_arr_left = merge_sort(_arr[:len(_arr)/2])
File "merge.py", line 25, in merge_sort
return merge_arrays(_arr_left, _arr_right)
File "merge.py", line 9, in merge_arrays
sorted_arr.extend(_arr_left[left])
TypeError: 'int' object is not iterable
So you can see the problem starts at line 9. You can also insert import pdb; pdb.set_trace() before you think the Exception comes up to run the python debugger and step through your program's progression to see where the Exception appears.
As other answers have mentioned, you need to change extent to append. However, as you said in comments, you are getting list index out of range error because you are iterating over the size of arr which is 9 but subarrays have much lesser length. Try changing your merging two arrays code to the following.
while (len(_arr_left) > left) or (len(_arr_right) > right):
if (len(_arr_left) > left) and (len(_arr_right) > right):
if (_arr_left[left] < _arr_right[right]):
sorted_arr.append(_arr_left[left])
left += 1
else:
sorted_arr.append(_arr_right[right])
right += 1
elif (len(_arr_left) > left):
sorted_arr.append(_arr_left[left])
left += 1
else:
sorted_arr.append(_arr_right[right])
right += 1
As you can see in the above code, we have to test for various conditions. If both subarrays contains elements, then we compare them to each other and append to sorted_arr depending on the value evaluation. If not then we append values from individual sub-arrays. It would have been easier if instead of using left and right, you were using pop so you wouldn;t have to keep tracking of left and right
Finally, here is the working version of your code. You also need to modify
return merge_sort(...) to sorted_arr = merge_sort(...) return sorted_arr so it doesn't print everytime it returns sorted_arr
In your line 9:
sorted_arr.extend(_arr_left[left])
sorted_arr is a list
_arr_left is a list
left is an int
So, the problem is:
>>> a = [1,2,3,4]
>>> a.extend(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>>
Solution:
You can use list.append() instead of extend().
>>> a = [1,2,3,4]
>>> a.append(5)
>>> a
[1, 2, 3, 4, 5]
>>>
PS: You might have other issues with your code.

Using str.replace to replace letters in a string at different placeholders of the string

I have a problem that I am working on. The goal of the problem is to take the string placeholder i. If i is an even placeholder, replace the letter at i with the letter at i -1. If the i place holder is odd, then replace the letter i with the letter at i +1.
Here is my code so far:
def easyCrypto (s):
for i in range (0,len(s)-1):
if i % 2 == 0:
str(s).replace(i,((i-1)))
if i % 2 != 0:
str(s).replace(i,((i+2)))
print (s)
My error:
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
easyCrypto('abc')
File "C:/Python/cjakobhomework7.py", line 4, in easyCrypto
str(s).replace(i,((i-1)))
TypeError: Can't convert 'int' object to str implicitly
update!!
New code based on answers:
def easyCrypto (s):
for i in range (0,len(s)-1):
if i % 2 == 0:
s = str(s).replace(s(i),(s(i-1)))
else:
s = s.replace(s(i), s(i + 1))
print (s)
However I still have the following errors:
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
easyCrypto('abc')
File "C:/Python/cjakobhomework7.py", line 4, in easyCrypto
s = str(s).replace(s(i),(s(i-1)))
TypeError: 'str' object is not callable
Any ideas? thank you
Use s[i] instead of s(i), and likewise for the other indexes.
There are two things here:
str.replace does not automatically stringify its arguments. You need to manually convert them into strings. Remember that: "Explicit is better than implicit."
str.replace does not work in-place because strings are immutable in Python. You need to reassign s to the new string object returned by str.replace.
Your code should be:
s = s.replace(str(i), str(i-1))
Also, you can replace if i % 2 != 0: with else: since the condition of the second if-statement can only be true if the first is false:
if i % 2 == 0:
s = s.replace(str(i), str(i-1))
else:
s = s.replace(str(i), str(i+1))
Regarding your edited question, you are trying to call the string s as a function by placing parenthesis after it. You need to use square brackets to index the string:
>>> 'abcde'[0]
'a'
>>> 'abcde'[3]
'd'
>>>
In your case it would be:
s = s.replace(s[i], s[i-1])
As a general rule of thumb, parenthesis (...) are for calling functions while square brackets [...] are for indexing sequences/containers.

How to add elements of a list in Python 3.5.5?

My assignment is:
Write a function sumOfPairs that has one parameter of type list. The
list can be empty or contain integers. The length of the list must be
0 or an even number. If the length of the list is not 0 and is not
even, the function should print an error message and return None. You
can assume the list contains only integers. The function returns the
list of the sum of each consecutive pair of the numbers in the list.
Example: If the list is [1,5,2,10,15,2,9,3], the function returns
[6,12,17,12].
My attempt so far is:
def sumOfPairs (list1: list):
if len(list1) != 0 and len(list1)%2 != 0:
print ("Error")
return (None)
else:
x = list1.index(int)
answer = []
while x<=len(list1):
newListValue=list1(x)+list1(x+1)
answer.insert(x,newListValue)
x=x+2
return (answer)
print (sumOfPairs ([1,5,2,10,15,2,9,3]))
Yet it yields the following error upon execution:
Traceback (most recent call last):
File "C:\Users\Andrew\Desktop\lab3.py", line 79, in <module>
print (sumOfPairs ([1,5,2,10,15,2,9,3]))
File "C:\Users\Andrew\Desktop\lab3.py", line 71, in sumOfPairs
x = list1.index(int)
ValueError: <class 'int'> is not in list
How can I fix this?
def sum_of_pairs(l):
if len(l) % 2: # if the length of the list mod 2 has a remainder, the list length is uneven
print("Error, uneven length list")
else: # else, step through the list in pairs and add each pairing
return [l[i]+ l[i+1] for i in range(0,len(l),2)]
In [3]: (sum_of_pairs([1,5,2,10,15,2,9,3]))
Out[3]: [6, 12, 17, 12]
A python function that does not specify a return value as in the if len(l) % 2: will return None by default so we do not need to explicitly return None.
In [11]: l = [1,5,2,10,15,2,9,3]
In [12]: [sum(pair) for pair in zip(l[0::2],l[1::2])]
Out[12]: [6, 12, 17, 12]
I don't particularly like your approach here, but let's take a look at the error specifically.
Traceback (most recent call last):
File "C:\Users\Andrew\Desktop\lab3.py", line 79, in <module>
print (sumOfPairs ([1,5,2,10,15,2,9,3]))
File "C:\Users\Andrew\Desktop\lab3.py", line 71, in sumOfPairs
x = list1.index(int)
ValueError: <class 'int'> is not in list
Now look at the line it occurs on, and try to say it in English
x equals the first index in list1 where the value is 'int'
Note that it's not the value is AN int! This is crucial, and is the reason for the error. Your list does not INCLUDE the class int. That would be something like:
[1,2,3,int,5,6,7,8] # not your list
Much easier would be to test that ALL your indices contain ints, then just iterate through the list. Let's try that (even though your exercise says otherwise, partially to keep you from just copy/pasting this!! :D)
def sum_of_pairs(lst: list):
if len(lst) == 0 or len(lst) % 2 != 0:
raise ValueError("Invalid list length")
# makes more sense to raise an exception here than print an error
if any(not isinstance(int, el) for el in lst):
# if any element is not an int:
raise ValueError("Invalid list contents")
result_list = []
for element in lst:
first_el = element
second_el = next(lst)
# advance the iterator once to grab the next element
result_list.append(first_el + second_el) # add them and append
return result_list
Or even easier if you know how to use the grouper recipe, which is in the pydocs for the itertools module here:
def grouper(iterable, n):
return zip(*iter([iterable])*n)
def sum_of_pairs(lst: list):
# validate here, I'm not going to re-write it
return [sum(pair) for pair in grouper(lst, 2)]

zip function to store multiple outputs for a return statement

def somefunction():
outputs = []
a = 0
while a < 100:
if a%2 == 0:
b = 2*a + 1
outputs.append(list(zip(a,b)))
a += 1
return outputs
The above code is not what i'm using exactly but produces the same error, why does the above code return:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
TypeError: zip argument #1 must support iteration
Is this a particularly efficient way of returning all the items within a function as one? If not, what is a better method?
It returns that error because of its exact error message; that is, the zip arguments must support iteration. You just have two numbers that you are trying to "store together". In that case, I'm assuming what you are looking for is the tuple data type. Either that or "put them together" with the list data type you already have. The zip is entirely unnecessary. I would suggest reading more about Python's built-in types.
Just get a list of tuples!! (or list if you prefer, but since you can't change tuples and you want to return all the outputs, tuples make more sense)
def somefunction():
outputs = []
a = 0
while a < 100:
if a%2 == 0:
b = 2*a + 1
tup = (a,b)
outputs.append(tup)
a += 1
return outputs
There is no need to use zip here, zip is for joining two lists together, you only have two integers so you can store them in a tuple and then append the tuple to outputs
when zip would work for this
Zip would work if you stored all as in a_list and all bs in b_list. Then you could do:
outputs.append(zip(a_list,b_list))
this is unnecessary because you can just append a and b together in a tuple to output just like my example. But that is how it would be done.
You can also use list comprehension in this case:
def f():
return [(x, 2*x + 1) for x in range(100) if x%2 == 0]

Python dynamic size of integer arguments into list

I am having an issue with putting a dynamic number of arguments into a list, then being able to access them later. Here is the code. I am passing arguments such as '2,3,4,5'
def puesdoPrime(*args):
from string import ascii_lowercase
primeInput = []
print "puesdoPrime not yet implemeneted"
for arg in args:
primeInput.append(arg)
for i in primeInput:
print "primeInput value are %i" % primeInput[i]
I am getting the following error:
Traceback (most recent call last):
File "homework3.py", line 41, in <module>
main()
File "homework3.py", line 34, in main
puesdoPrime(printInput)
File "homework3.py", line 15, in puesdoPrime
print "primeInput value are %i" % primeInput[i]
TypeError: list indices must be integers, not tuple
This is how the function is being called:
userInput = input()
if userInput == 1:
print "What numbers do you want to find that are simultaneously Puesdo Prime?"
printInput = input()
puesdoPrime(printInput)
Any help would be very much appreciated in helping solve this.
Using for i in primeInput will loop over the values of your list, not the indices. So you would want to change your second for loop to the following:
for item in primeInput:
print "primeInput value are %i" % item
Or to loop over the indices:
for i in range(len(primeInput)):
print "primeInput value are %i" % primeInput[i]
It would also help to see how you are calling puesdoPrime(), but to use *args correctly your call should look something like the following:
puesdoPrime(2, 3, 4, 5)
Or if you have an existing collection of arguments:
the_args = (2, 3, 4, 5)
puesdoPrime(*the_args)
Without the * in the previous code you would only be passing a single argument which would be a four element tuple.
As a side note, I think you mean "pseudo", not "puesdo".

Categories