I am trying to create a class Tile and use it in another method. However, when I run the code (below), the error is raised: AttributeError: type object 'Tile' has no attribute 'row'.
As I pop the class from the queue (Python list) and try to print it, it prints the value of the row (which is 0) but then gives the AttributeError.
Why is it saying that the attribute row does not exist?
"""
Shortest distance between two cells in a matrix or grid
"""
class Tile:
def __init__(self, row, col, dist):
self.row = row
self.col = col
self.dist = dist
def min_path(rows, cols, lot):
start_node = Tile(0, 0, 0)
q = []
q.append(start_node)
visited = [[False]*cols for i in range(rows)]
for i in range(rows):
for j in range(cols):
if lot[i][j] == 0:
visited[i][j] = True
while q:
new_tile = q.pop(0)
print(new_tile.row)
if lot[new_tile.row][new_tile.col] == 9:
return new_tile.dist
if new_tile.row - 1 >= 0 and visited[new_tile.row - 1][new_tile.col] == False:
Tile(new_tile.row - 1, new_tile.col, new_tile.dist + 1)
q.append(Tile)
visited[new_tile.row - 1][new_tile.col] = True
if new_tile.row + 1 < rows and visited[new_tile.row + 1][new_tile.col] == False:
Tile(new_tile.row + 1, new_tile.col, new_tile.dist + 1)
q.append(Tile)
visited[new_tile.row + 1][new_tile.col] = True
if new_tile.col - 1 >= 0 and visited[new_tile.row][new_tile.col - 1] == False:
Tile(new_tile.row, new_tile.col - 1, new_tile.dist + 1)
q.append(Tile)
visited[new_tile.row][new_tile.col - 1] = True
if new_tile.col + 1 < cols and visited[new_tile.row][new_tile.col + 1] == False:
Tile(new_tile.row, new_tile.col + 1, new_tile.dist + 1)
q.append(Tile)
visited[new_tile.row][new_tile.col + 1] = True
return -1
if __name__ == "__main__":
lot = [
[1, 0, 0, 0],
[1, 0, 1, 0],
[1, 1, 0, 0],
[0, 1, 9, 0],
]
result = min_path(4, 4, lot)
print(result)
When I run this file, this is the output:
0
Traceback (most recent call last):
File "code.py", line 568, in <module>
result = min_path(4, 4, lot)
File "code.py", line 533, in min_path
print(new_tile.row)
AttributeError: type object 'Tile' has no attribute 'row'
Seems to be because of these lines: q.append(Tile). You are appending a reference to the class itself instead of an instance of it. Instead try something like
tile = Tile(new_tile.row - 1, new_tile.col, new_tile.dist + 1)
q.append(tile)
Related
I have some code that effectively replaces this excel spreadsheet where I am trying to find the difference between two times. Depending on the state of the second column of that value I want to segregate this into two columns.
I converted the data in the first two columns into a list of lists in the form
[...[2.96738, 0], [3.91727, 1], [3.9729, 0], [4.88419, 1], [4.93686, 0], [5.86113, 1], [5.91125, 0]...]
Running my code:
def Delta_Time_One_State(CleanState):
for counter, value in enumerate(CleanState[1:]):
DeltaT = value[0] - CleanState[counter][0]
Lgt_cut_Time = []
Lgt_Uncut_Time = []
if value[1] == 0:
Lgt_cut_Time.append([value[0] + DeltaT / 2, DeltaT])
else:
Lgt_Uncut_Time.append([value[0] + DeltaT / 2, DeltaT])
clean_state_A = [[0.0, 0], [0.03253, 1], [0.08479, 0], [0.98748, 1], [1.03717, 0], ... [483.8888, 0], [484.6563, 1]]
Delta_Time_One_State(clean_state_A)
gives me
Lgt_Uncut_Time = [[485.04004999999995, 0.7674999999999841]]
Lgt_cut_Time = []
Which can't be right because the for loop runs through almost all of clean_state_A. Since every loop passes through the if statement something appears to be wrong with the .append function but I can't tell what.
Every loop you are redefining the two lists. Move them outside of the for loop so you're appending to the same list every iteration.
def Delta_Time_One_State(CleanState):
Lgt_cut_Time = []
Lgt_Uncut_Time = []
for counter, value in enumerate(CleanState[1:]):
DeltaT = value[0] - CleanState[counter][0]
calculated_data = [value[0] + DeltaT / 2, DeltaT]
if value[1] == 0:
Lgt_cut_Time.append(calculated_data)
else:
Lgt_Uncut_Time.append(calculated_data)
You are recreating the Lgt_cut_Time and Lgt_Uncut_Time lists every loop.
def Delta_Time_One_State(CleanState):
for counter, value in enumerate(CleanState[1:]):
DeltaT = value[0] - CleanState[counter][0]
Lgt_cut_Time = []
Lgt_Uncut_Time = []
if value[1] == 0:
Lgt_cut_Time.append([value[0] + DeltaT / 2, DeltaT])
else:
Lgt_Uncut_Time.append([value[0] + DeltaT / 2, DeltaT])
Just move them outside of the loop so that they accumulate the results instead of replacing them on every loop.
def Delta_Time_One_State(CleanState):
Lgt_cut_Time = []
Lgt_Uncut_Time = []
for counter, value in enumerate(CleanState[1:]):
DeltaT = value[0] - CleanState[counter][0]
if value[1] == 0:
Lgt_cut_Time.append([value[0] + DeltaT / 2, DeltaT])
else:
Lgt_Uncut_Time.append([value[0] + DeltaT / 2, DeltaT])
I am trying to define a function, median, that consumes a list of numbers and returns the median number from the list. If the list is empty, then I want to return None. To calculate the median, I need to find the middle index of the list after it has been sorted. Do not use a built-in function.
SURVEY_RESULTS = [1.5, 1, 2, 1.5, 2, 3, 1, 1, 1, 2]
def median(SURVEY_RESULTS):
length = 0
order = sorted(SURVEY_RESULTS)
I'm not sure how to use indexing to now determine the median.
Here is my implementation:
def QuickSort(myList,start,end):
if start < end:
i,j = start,end
base = myList[i]
while i < j:
while (i < j) and (myList[j] >= base):
j = j - 1
myList[i] = myList[j]
while (i < j) and (myList[i] <= base):
i = i + 1
myList[j] = myList[i]
myList[i] = base
QuickSort(myList, start, i - 1)
QuickSort(myList, j + 1, end)
return myList
def median(l):
half = len(l) // 2
return (l[half] + l[~half])/2 # Use reverse index
SURVEY_RESULTS = [1.5, 1, 2, 1.5, 2, 3, 1, 1, 1, 2]
# Sort first
QuickSort(SURVEY_RESULTS, 0, len(SURVEY_RESULTS)-1)
result = median(SURVEY_RESULTS)
print (result)
My apologies, I'm new to StackOverFlow & Python. I've written a code for Merge_Sort but it's not running as the values of arrays are getting lost while returning from recursion calls.
Coding Environment: Python3.x
OS: Linux ( Ubuntu 18.04)
Below is my code:
class sort:
def __init__(self, arr, n):
self.arr = arr
self.n = n
def __init__(self, arr, m, n):
self.arr = arr
self.m = m
self.n = n
arrS = arr.copy()
arrL = [0] * (n - int((m + n)/2) + 1)
arrR = [0] * (n - (m + 1))
def Merge_sort(self,arr,first,last):
mid = int((first + last) / 2)
arrMain = arr[first:last+1]
arrLeft = arr[first:mid+1]
arrRight = arr[mid+1:last+1]
arrL = [0] * (mid - first + 1)
arrR = [0] * (last - mid + 1)
arrN = [0] * ( last - first + 1)
if first < last:
#Sort Left Array
self.Merge_sort(arr, first, mid)
#Sort Right Array
self.Merge_sort(arr, mid+1, last)
#I defined the below 3 variables while debugging to view the list
arrL = arr[first:mid+1]
arrR = arr[mid+1:last+1]
print("Left Array: " + str(arrL))
print("Right Array: " + str(arrR))
x = len(arrL)
y = len(arrR)
i = j = k = 0
while i < x and j < y:
if (arrL[i] <= arrR[j]):
arrN[k] = arrL[i]
i += 1
else:
arrN[k] = arrR[j]
j += 1
# end-if#001
k += 1
while (i < x):
arrN[k] = arrL[i]
i += 1
k += 1
while (j < y):
arrN[k] = arrR[j]
j += 1
k += 1
arr = arrN.copy()
print("Merged Array:" + str(arr))
return arrN
#End-if#001
from Sort import sort
arr = [7, 5, 4 ,9, 3, 2 , 0, 1, 6, 8]
n = 0
sort4 = sort(arr, 0, int(len(arr)))
sort4.arr = arr.copy()
sort4.Merge_sort(sort4.arr, 0, int(len(arr)) - 1)
Input of the program: arr = [7, 5, 4 ,9, 3, 2 , 0, 1, 6, 8]
Output of the program: Left Array: [7, 5, 4, 9, 3] Right Array: [2, 0, 1, 6, 8]
Merged Array:[2, 0, 1, 6, 7, 5, 4, 8, 9, 3]
At the end of program it just seems to merge my original array.
Kindly suggest.
Just to notify you, the problem is resolved. I wasn't returning the values correctly. Below is my code just for the reference.
def Merge_sort(self,arr,first,last):
mid = int((first + last) / 2)
arrMain = arr[first:last+1]
arrLeft = arr[first:mid+1]
arrRight = arr[mid+1:last+1]
arrL = [0] * (mid - first + 1)
arrR = [0] * (last - mid + 1)
arrN = [0] * ( last - first + 1)
if first < last:
#Sort Left Array
arrL = self.Merge_sort(arr, first, mid)
#Sort Right Array
arrR = self.Merge_sort(arr, mid+1, last)
#arrL = arr[first:mid+1]
#arrR = arr[mid+1:last+1]
print("Left Array: " + str(arrL))
print("Right Array: " + str(arrR))
x = int(len(arrL))
y = int(len(arrR))
i = j = k = 0
while i < x and j < y:
if (arrL[i] <= arrR[j]):
arrN[k] = arrL[i]
i += 1
else:
arrN[k] = arrR[j]
j += 1
# end-if#001
k += 1
while (i < x):
arrN[k] = arrL[i]
i += 1
k += 1
while (j < y):
arrN[k] = arrR[j]
j += 1
k += 1
arr = arrN.copy()
print("Merged Array:" + str(arr))
return arrN
#End-if#001
return arrMain
My denomination "5" is not showing up and how do you reverse the dict easily. i dont want extra 5 line of code.lol
Can you guys help me out with it?
the code is working so far.
here is my code with a test case
def change(target, coins):
result = dict()
i= len(coins) -1
while i> 0:
coin = coins[i]
numOfThisCoin= target // coin
result[coin] = numOfThisCoin
target -= coin * numOfThisCoin
i-= 1
return result
print(change(185, (5, 10, 25, 100, 200)))
i am getting output
{200: 0, 100: 1, 25: 3, 10: 1}
but want it like
{5: 0, 10: 1, 25: 3, 100: 1, 200: 0}
Here is the corrected code for your problem:
from collections import OrderedDict
def change(target, coins):
result = dict()
i= len(coins) -1
while i>= 0:
coin = coins[i]
numOfThisCoin= target // coin
result[coin] = numOfThisCoin
target -= coin * numOfThisCoin
i-= 1
res = OrderedDict(sorted(result.items()))
return res
print(change(185, (5, 10, 25, 100, 200)))
If you (not only 25 you can access any coin denomination)
print(res[25])
Output will be
3
in this case.
dict- it does not keep the elements in order. You have to use OrderedDict for sorting the elements in the order you want. For more info follow the below link:
http://docs.python.org/library/collections.html#collections.OrderedDict
def change(target, coins):
result = dict()
i= len(coins) -1
while i>= 0:
coin = coins[i]
numOfThisCoin= target // coin
result[coin] = numOfThisCoin
target -= coin * numOfThisCoin
i-= 1
return dict(sorted(result.items()))
print(change(185, (5, 10, 25, 100, 200)))
I am having problems with my quicksort function constantly re cursing the best of three function. I dont know why it is doing that and i need help. I am trying to practice this for my coding class next semester and this is one of the assignments from last year that my friend had and im lost when it comes to this error
This is my quicksort function:
def quick_sort ( alist, function ):
if len(alist) <= 1:
return alist + []
pivot, index = function(alist)
#print("Pivot:",pivot)
left = []
right = []
for value in range(len(alist)):
if value == index:
continue
if alist[value] <= pivot:
left.append(alist[value])
else:
right.append(alist[value])
print("left:", left)
print("right:", right)
sortedleft = quick_sort( left, function )
print("sortedleft", sortedleft)
sortedright = quick_sort( right, function )
print("sortedright", sortedright)
completeList = sortedleft + [pivot] + sortedright
return completeList
#main
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
x = quick_sort(alist, best_of_three)
print(x)
this is my best of three function:
def best_of_three( bNlist, nine = False ):
rightindex = 2
middleindex = 1
if nine == False:
left = blist[0]
rightindex = int(len(blist) - 1)
rightvalue = int(blist[rightindex])
middleindex = int((len(blist) - 1)/2)
middlevalue = int(blist[middleindex])
bNlist.append(left)
bNlist.append(middlevalue)
bNlist.append(rightvalue)
BN = bNlist
print("Values:",BN)
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]
if left <= middle <= right:
return middle , middleindex
elif left >= middle >= right:
return middle, middleindex
elif middle <= right <= left:
return right, rightindex
elif middle >= right >= left:
return right, rightindex
else:
return left, 0
#main
bNlist = []
print('Best of Three')
blist = [54,26,93,17,77,31,44,55]
print("")
print( "List: [54,26,93,17,77,31,44,55]" )
x, index = best_of_three(bNlist)
print("Pivot: ",x)
print("----------------------------")
i really dont know why it keeps infinitely re cursing,
There is also a third function called ninther
def ninther( bNlist ):
stepsize = int(len(blist) / 9)
left = 0
middle = left + 2
right = left + 2 * stepsize
blist[left]
blist[middle]
blist[right]
leftvalue = blist[left]
rightvalue = blist[right]
middlevalue = blist[middle]
left2 = right + stepsize
middle2 = left2 + 2
right2 = left2 + 2 * stepsize
blist[left2]
blist[middle2]
blist[right2]
left2value = blist[left2]
middle2value = blist[middle2]
right2value = blist[right2]
left3 = right2 + stepsize
middle3 = left3 + 2
right3 = left3 + 2 * stepsize
blist[left3]
blist[middle3]
blist[right3]
left3value = blist[left3]
middle3value = blist[middle3]
right3value = blist[right3]
bN3list = []
bN2list = []
bNlist = []
bNlist.append(leftvalue)
bNlist.append(middlevalue)
bNlist.append(rightvalue)
bN2list.append(left2value)
bN2list.append(middle2value)
bN2list.append(right2value)
bN3list.append(left3value)
bN3list.append(middle3value)
bN3list.append(right3value)
BN3 = bN3list
BN2 = bN2list
BN = bNlist
print("Ninter ")
print("Group 1:", BN)
print("Group 2:", BN2)
print("Group 3:", BN3)
x = best_of_three(bNlist, True)[0]
c = best_of_three(bN2list, True)[0]
d = best_of_three(bN3list, True)[0]
print("Median 1:", x)
print("Median 2:", c)
print("Median 3:", d)
bN4list = [x,c,d]
print("All Medians:", bN4list)
z = best_of_three(bN4list, True)
return z[0], z[1]
#main
blist = [2, 6, 9, 7, 13, 4, 3, 5, 11, 1, 20, 12, 8, 10, 32, 16, 14, 17, 21, 46]
Y = ninther(blist)
print("Pivot", Y)
print("----------------------------")
i have looked everywhere in it and i cant figure out where the problem is when calling best of three
Summary: The main error causing infinite recursion is that you don't deal with the case where best_of_three receives a length 2 list. A secondary error is that best_of_three modifies the list you send to it. If I correct these two errors, as below, your code works.
The details: best_of_three([1, 2]) returns (2, 3), implying a pivot value of 2 at the third index, which is wrong. This would give a left list of [1, 2], which then causes exactly the same behavior at the next recursive quick_sort(left, function) call.
More generally, the problem is that the very idea of choosing the best index out of three possible values is impossible for a length 2 list, and you haven't chosen how to deal with that special case.
If I add this special case code to best_of_three, it deals with the length 2 case:
if len(bNlist) == 2:
return bNlist[1], 1
The function best_of_three also modifies bNlist. I have no idea why you have the lines of the form bNlist.append(left) in that function.
L = [15, 17, 17, 17, 17, 17, 17]
best_of_three(L)
print(L) # prints [15, 17, 17, 17, 17, 17, 17, 54, 17, 55]
I removed the append lines, since having best_of_three modify bNlist is unlikely to be what you want, and I have no idea why those lines are there. However, you should ask yourself why they are there to begin with. There might be some reason I don't know about. When I do that, there are a couple of quantities you compute that are never used, so I remove the lines that compute those also.
Then I notice you have the code
rightindex = 2
middleindex = 1
if nine == False:
rightindex = int(len(blist) - 1)
middleindex = int((len(blist) - 1)/2)
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]
This doesn't seem to make any sense, since you set rightindex and middleindex to other values, but then you still access values using the old indices (2 and 1 respectively). So I removed the if nine == False block. Again, ask yourself why you had this code to begin with, maybe there's some other way you should modify this to account for something I don't know about.
The result is the following for best_of_three:
def best_of_three(bNlist):
print(bNlist)
if len(bNlist) == 2:
return bNlist[1], 1
rightindex = 2
middleindex = 1
left = bNlist[0]
middle = bNlist[1]
right = bNlist[2]
if left <= middle <= right:
return middle , middleindex
elif left >= middle >= right:
return middle, middleindex
elif middle <= right <= left:
return right, rightindex
elif middle >= right >= left:
return right, rightindex
else:
return left, 0
If I use this, your code does not recurse infinitely, and it sorts.
I don't know why you mentioned ninther at all, since it seems to have nothing to do with your question. You should probably edit it to remove that code.