What is wrong with my merge sort in python? - python

I am trying to write merge sort and stuck here.
What is the problem here with my code? I am trying to implement it without referring any resources and unnecessarily writing this line since some dumb rule in Stackoverflow forces to me explain my code.
def merge_sort(A):
if len(A) <= 1:
return A
#split list in 2
mid = len(A)/2
B = A[:mid]
C = A[mid:]
B = merge_sort(B)
C = merge_sort(C)
#merge
result = []
while len(B) > 0 and len(C) > 0:
if B[0] > C[0]:
result.append(C.pop(0))
else:
result.append(B.pop(0))
if len(B) > 0:
result.extend(merge_sort(B))
else:
result.extend(merge_sort(C))
print merge_sort([8, 2, 1, 1, 4, 45, 9, 3])
I get this error:
Traceback (most recent call last):
File "merge_sort.py", line 31, in <module>
print merge_sort([8, 2, 1, 1, 4, 45, 9, 3])
File "merge_sort.py", line 11, in merge_sort
B = merge_sort(B)
File "merge_sort.py", line 16, in merge_sort
while len(B) > 0 and len(C) > 0:
TypeError: object of type 'NoneType' has no len()

You merge_sort() function needs to
return result
at the end but it does not. Functions return None by default and this is why you get the error.

You forgot to write return result at the end of the function. Without that line, the function returns None, which eventually leads to a len(None) and the subsequent TypeError: object of type 'NoneType' has no len().

Related

Rewriting R's density() (not really)

In response to this question, I took upon the challenge to make my understanding on R's density() function.
Since I'm pretty much very new to R, I have no ideas about vectors regarding the c() function, which made me use a list as the closest form.
I would make this function:
def density(x, bw, adjust):
bw2 = None
result = 0
if bw == "nrd0":
bw2 = 31.39367
else:
print("No such bandwidth.")
for i in range[len(x)]:
x[i] = x[i] * bw2
for i in range[len(x)]:
result = result + x[i]
return result * adjust
And I wanted to test it:
x = [1, 3, 5]
kern = density(x, "nrd0", 1)
print(kern)
And I gained 2 errors, the main one being a TypeError.
If you want to look into it further, here's the whole terminal message:
Traceback (most recent call last):
File "density.py", line 15, in <module>
kern = density(x, "nrd0", 1)
File "density.py", line 8, in density
for i in range[len(x)]:
TypeError: 'type' object is not subscriptable
How do I fix the TypeError?
for i in range[len(x)]:
x[i] = x[i] * bw2
You have range with [] while it should be (). Try to change it.
Below is an example:
l = [10, 20, 30, 40]
for i in range(len(l)):
print(l[i], end =" ")
print()

After running multiple time with same code with same input size in Python 3.4 throw IndexError: list index out of range

I am new to Python. I wrote a code for quick sort to sort integer numbers in ascending order.
Using - Ubuntu 16.10 and python3.5
Code -
import random
a=[]
n=int(input("Enter size :\n"))
for i in range(0,n):
a.append(int(random.randrange(0,100)))
print("Before Sorting:",a)
def quick(a,low,high):
if(low<high):
i=low
j=high
key=a[low]
flag=1
while (flag==1):
i += 1
while(a[i]<key):
i += 1
while (a[j]>key):
j -= 1
if (i<j):
a[i],a[j]=a[j],a[i]
else:
flag=0
a[low],a[j]=a[j],a[low]
quick(a,low,j-1)
quick(a,j+1,high)
# Calling function quick where a = List, 0 = Start Index ,n-1 = Last Index
quick(a,0,n-1)
print("After Sorting:",a)
When i run the code it throws IndexError: list index out of range but if i run the same code with same input it gives correct output.
For example -
Running the code for 1st time with n = 5
linux#linux-Lenovo-G50-30:~/PYTHON/practice/run1$ python3 quick.py
Enter size :
5
Before Sorting : [55, 23, 57, 86, 20]
Traceback (most recent call last):
File "quick.py", line 30, in <module>
quick(a,0,n-1)
File "quick.py", line 27, in quick
quick(a,j+1,high)
File "quick.py", line 17, in quick
while(a[i]<key):
IndexError: list index out of range
Running the code for 2nd time with n = 5
Enter size :
5
Before Sorting : [6, 5, 93, 84, 32]
Traceback (most recent call last):
File "quick.py", line 30, in <module>
quick(a,0,n-1)
File "quick.py", line 27, in quick
quick(a,j+1,high)
File "quick.py", line 17, in quick
while(a[i]<key):
IndexError: list index out of range
Running the code for 3rd time with n = 5
linux#linux-Lenovo-G50-30:~/PYTHON/practice/run1$ python3 quick.py
Enter size :
5
Before Sorting : [87, 18, 94, 1, 64]
After Sorting : [1, 18, 64, 87, 94]
I am not able to figure out why this happens.
I am using Ubuntu 16.10 and python3.5
The reason your code sometimes works and sometimes doesn't is that you are setting up a random array of numbers. As your post shows, even with the same input data (length of list) the numbers are different every time. Your quick() function works with some input data and fails with other input data. It is failing because a[i]<key assumes that there are i-1 elements in a, and depending on your data, sometimes there aren't.
The fix below makes your out-of-range error go away. I've run it a couple of dozen times and the results seem okay. I can't promise that the code is a correct implementation of Quicksort, though.
def quick(a,low,high):
if(low<high):
i=low
j=high
key=a[low]
flag=1
while (flag==1):
i += 1
while(i < len(a) and a[i]<key):
i += 1
while (j < len(a) and a[j]>key):
j -= 1
if (i<j):
a[i],a[j]=a[j],a[i]
else:
flag=0
a[low],a[j]=a[j],a[low]
quick(a,low,j-1)
quick(a,j+1,high)
import random
a=[]
n=int(input("Enter size :\n"))
for i in range(0,n):
a.append(int(random.randrange(0,100)))
print("Before Sorting:",a)
def sort(a):
less = []
equal = []
greater = []
if len(a) > 1:
pivot = a[0]
for x in a:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
return sort(less)+equal+sort(greater)
else:
return a
a = sort(a)
print("After Sorting:",a)

Cannot import cProfile in Python 3

I am trying to import the cProfile module into Python 3.3.0, but I got the following error:
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
import cProfile
File "/.../cProfile_try.py", line 12, in <module>
help(cProfile.run)
AttributeError: 'module' object has no attribute 'run'
The complete code (cProfile_try.py) is as follows
import cProfile
help(cProfile.run)
L = list(range(10000000))
len(L)
# 10000000
def binary_search(L, v):
""" (list, object) -> int
Precondition: L is sorted from smallest to largest, and
all the items in L can be compared to v.
Return the index of the first occurrence of v in L, or
return -1 if v is not in L.
>>> binary_search([2, 3, 5, 7], 2)
0
>>> binary_search([2, 3, 5, 5], 5)
2
>>> binary_search([2, 3, 5, 7], 8)
-1
"""
b = 0
e = len(L) - 1
while b <= e:
m = (b + e) // 2
if L[m] < v:
b = m + 1
else:
e = m - 1
if b == len(L) or L[b] != v:
return -1
else:
return b
cProfile.run('binary_search(L, 10000000)')
As noted in a comment, it is likely that there unexpectedly exists a file named profile.py, possibly in the current directory. This file is being unintentionally used by cProfile, thereby masking Python's profile module.
A suggested solution is:
mv profile.py profiler.py
Next, for good measure,
If using Python 3:
rm __pycache__/profile.*.pyc
If using Python 2:
rm profile.pyc
try to use "import profile as cProfile"

Python - can't convert to int

My entire code is below (didn't want to miss anything). For some reason I keep getting an error where I can't convert a float to an int?
import math
def getRange(input):
if (1 <= input < 10):
return [1,1,9]
elif (10 <= input < 190):
return [2,10,99]
elif (190 <= input < 2890):
return [3,100,999]
elif (2890 <= input < 38890):
return [4,1000,9999]
elif (38890 <= input < 488890):
return [5,10000,99999]
elif (488890 <= input < 5888889):
return [6,100000,999999]
def getDigit(input):
workingRange=getRange(input)
multi_digit_dec = ((input-workingRange[1])/workingRange[0])+workingRange[1]
multi_digit_float = math.floor((input-workingRange[1])/workingRange[0])+workingRange[1]
print multi_digit_float
multi_digit_int = input(multi_digit_float)
decimal_remainder = multi_digit_int - multi_digit_dec
## digit_id = decimal_remainder * len(str(multi_digit_int))
## actual_digit = str(multi_digit_dec)[digit_id]
## return actual_digit
getDigit(100)
My error is:
Traceback (most recent call last):
File "C:\Users\Samuel\Desktop\Python\concatenate string of variables and product values.py", line 29, in <module>
getDigit(100)
File "C:\Users\Samuel\Desktop\Python\concatenate string of variables and product values.py", line 22, in getDigit
multi_digit_int = int(multi_digit_float)
TypeError: 'int' object is not callable
>>>
Code updated above to reflect change of variable called int to input
The problem is that you're using int as a variable name, and that shadows the built-in function. Rename the variable.
In general, it's worth familiarizing oneself with the names of the built-in functions, to avoid this type of problems.
Don't use int as variable name (function getDigit).
In your stack of elif statements, if you start by testing if the input number is less than 1, then there's no need to check the lower ends of ranges other than the first. This will cut out half of the verbiage in the elif's. Also, it is more compact to use a loop for tests like this. For example, the following code produces the output shown below it.
def getRange(k):
if k < 1: return None
e = 1
for d in [10, 190, 2890, 38890, 488890, 5888889]:
if k<d:
return [e, 10**(e-1), 10**e -1]
e += 1
return None
for i in range(14):
print '{:8} {:20}'.format(i * 3**i, getRange(i * 3**i)),
if i&1: print
Output:
0 None 3 [1, 1, 9]
18 [2, 10, 99] 81 [2, 10, 99]
324 [3, 100, 999] 1215 [3, 100, 999]
4374 [4, 1000, 9999] 15309 [4, 1000, 9999]
52488 [5, 10000, 99999] 177147 [5, 10000, 99999]
590490 [6, 100000, 999999] 1948617 [6, 100000, 999999]
6377292 None 20726199 None
I think you want:
multi_digit_int = math.floor(multi_digit_float)
Also, don't use int as a variable name.
The problem with the line multi_digit_int = input(multi_digit_float) in your updated code is that the argument input in def getDigit(input): is hiding the built-in input() function. Since you calle getDigit with an argument of 100, inside the function input is an int instance so the input(multi_digit_float) part is being interpreted as 100(multi_digit_float), i.e. an int calling something.

python - TypeError: tuple indices must be integers

I don't get what's wrong. I'll post the part of the code that's relevant.
Error:
Traceback (most recent call last):
File "C:\Python\pygame\hygy.py", line 104, in <module>
check_action()
File "C:\Python\pygame\hygy.py", line 71, in check_action
check_portal()
File "C:\Python\pygame\hygy.py", line 75, in check_portal
if [actor.x - 16, actor.y - 16] > portal[i][0] and [actor.x + 16, actor.y + 16] < portal[i][0]:
TypeError: tuple indices must be integers
function:
def check_portal():
for i in portal:
if [actor.x - 16, actor.y - 16] > portal[i][0] and [actor.x + 16, actor.y + 16] < portal[i][0]:
if in_portal == False:
actor.x,actor.y=portal[i][1]
in_portal = True
elif [actor.x - 16, actor.y - 16] > portal[i][1] and [actor.x + 16, actor.y + 16] < portal[i][1]:
if in_portal == False:
actor.x,actor.y=portal[i][1]
in_portal = True
else:
in_portal = False
initializing actor:
class xy:
def __init__(self):
self.x = 0
self.y = 0
actor = xy()
initializing portal:
portal = [[100,100],[200,200]],[[300,300],[200,100]]
Given the initialisation of portal, the loop
for i in portal:
...
will only do two iterations. In the first iteration, i will be [[100,100],[200,200]]. Trying to do portal[i] will be equivalent to portal[[[100,100],[200,200]]], and this doesn't make sense. You probably just want to use i instead of portal[i]. (You probably want to rename it to something more meaningful than i, too.)
When you said for i in portal, in each iteration, instead of the indices in portal which you may think of, i is actually elements of portal. So it is not integer and causes error in portal[i][0].
So a quick fix is just replace that with for i in xrange(len(portal)), in which i is indices.
Within the for loop, i = ([100, 100], [200, 200]), which is not a valid index for a list.
Given the comparison in the if statements, it looks like your intention was more like:
for coords in portal:
if [actor.x - 16, actor.y - 16] > coords[0] and [actor.x + 16, actor.y + 16] < coords[0]:
where coords[0] == [100, 100] on the first iteration of the loop.

Categories