I'm currently developing a flood fill code to fill polygons in a software renderer I made for my Computer Graphics class. Here's the code below of my recursion, I based it on an algorithm from geeksforgeeks.
def flood(self, x, y, colorOld, colorNew):
if (x < 0 or x >= self.width or y < 0 or y >= self.height):
print("height/width not in range")
return
if (self.framebuffer[x][y] != colorOld):
print("color is old")
return
print(str(x) + ", " + str(y))
self.point(x, y, colorNew)
self.flood(x+1, y, colorOld, colorNew)
self.flood(x-1, y, colorOld, colorNew)
self.flood(x, y+1, colorOld, colorNew)
self.flood(x, y-1, colorOld, colorNew)
return
def floodFill(self, x, y, colorN):
colorO = self.framebuffer[x][y]
self.flood(x, y, colorO, colorN)
However, it gets stuck when it reaches the end of the width, it's not returning even though it reaches one of the flags.
If I need to provide my whole renderer, just tell me.
Related
This is an exercise 6.1 in the book "Think Python". The question is to find the print result.
This is what I can get so far.
x = 1, y = 2
bring to a(x, y), return 4
b(z), return z**2 + z
I couldn't find the valve z from c(x, y, z) function.
def b(z):
prod = a(z, z)
print(z, prod)
return prod
def a(x, y):
x = x + 1
return x * y
def c(x, y, z):
total = x + y + z
square = b(total)**2
return square
x = 1
y = x + 1
print(c(x, y+3, x+y))
The x and y in def a(x, y): are not the same x and y defined elsewhere in the script. It might as well say def a(j, k):. When you see prod = a(z, z), you need to know what the value of z is, and then go to the definition of def a(j, k): and think j = z and k = z.
If we just tell you what the output is, then you wouldn't learn to "Think Python"
I've been working on some introductory Graph Theory lately, and came across the following problem statement:
Given a 2D matrix as input, representing a maze (where 'E' is the start of the matrix and 'S' is the end), find the length of the shortest path from E to S. Walls in the maze are represented by '#', while accessible spaces are indicated with '.'. It's also a given that the outer edge of the matrix is covered with walls. If no path exists from E to S, return -1.
Since the graph isn't weighted, I tried implementing a BFS algorithm, using deque. However, when the mazes start hitting around 500x500, execution time hits 10s, and when I try to go up to 1000x1000, it's obviously a lot worse.
Here's my code:
from collections import deque
def shortest_path_1(maze):
wall, clear, endchar, startchar = '#', '.', 'S', 'E'
height = len(maze)
width = len(maze[0])
def find_start(grid):
for y in range(1, height-1):
for x in range(1, width-1):
if grid[y][x] == startchar:
return tuple([x, y])
start = find_start(maze)
queue = deque([[start]])
seen = {start}
while queue:
path = queue.popleft()
x, y = path[-1]
if maze[y][x] == endchar:
return len(path)-1
for (x2, y2) in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
if 0 < x2 < width-1 and 0 < y2 < height-1 and maze[y2][x2] != wall and (x2, y2) not in seen:
queue.append(path + [(x2, y2)])
seen.add((x2, y2))
return -1
I found some very useful answers on the site so far, but none of the current ones seem to give any other optimizations that I haven't implemented yet...
Thanks!
EDIT: Thanks to the lovely person who edited my question to make the key words pop :). Here's an example of a matrix that you can run the algorithm on:
#####
#E#S#
#.#.#
#...#
#####
This should return the value 6.
EDIT2: Fixed some small mistakes.
As suggested in the comments, you don't have to store the paths. Try this:
from collections import deque
def shortest_path_1(maze):
wall, clear, endchar, startchar = '#', '.', 'S', 'E'
height = len(maze)
width = len(maze[0])
def find_start(grid):
for y in range(1, height-1):
for x in range(1, width-1):
if grid[y][x] == startchar:
return (x, y, 0)
start = find_start(maze)
queue = deque([start])
seen = set()
while queue:
x, y, d = queue.popleft()
if not 0 <= x < width:
continue
if not 0 <= y < height:
continue
if maze[y][x] == wall:
continue
if maze[y][x] == endchar:
return d
if (x, y) in seen:
continue
seen.add((x, y))
queue.append((x+1, y, d+1))
queue.append((x-1, y, d+1))
queue.append((x, y+1, d+1))
queue.append((x, y-1, d+1))
return -1
maze = [x for x in """
#####
#E#S#
#.#.#
#...#
#####
""".split('\n') if x]
print shortest_path_1(maze)
I have multiple lists namely, X, Y, VX, VY, R, T, KE, PE, TE, for which I need to delete their (i+1)th value off once their iterations break. The way I can do it currently is if I do:
del X[i+1:]
del Y[i+1:]
del VX[i+1:]
del VY[i+1:]
del R[i+1:]
del T[i+1:]
del KE[i+1:]
del PE[i+1:]
del TE[i+1:]
Which I think it looks rather ugly. Is there a way to minimize the use of lines in this case. Maybe a loop which does that but in just 1 or 2 lines?
Edit:
I didn't want to include the body of my code because I'm aware that a lot of my colleagues are doing the same problem and I don't want anyone to plagiarize. Anyway, here's what I did.
def F_1(X):
return VX
def F_2(X):
return VY
def F_3(X, Y):
return -G*EM*X/((X**2 + Y**2)**(3/2))
def F_4(X, Y):
return -G*EM*Y/((X**2 + Y**2)**(3/2))
def RKutta(F_1, F_2, F_3, F_4, XSTART, YSTART, VXSTART, VYSTART):
N = 100000
X, Y = np.zeros([N+1]), np.zeros([N+1])
VX, VY = np.zeros([N+1]), np.zeros([N+1])
R, T = np.zeros([N+1]), np.zeros([N+1])
KE, PE, TE = np.zeros([N+1]), np.zeros(N+1), np.zeros([N+1])
X[0], Y[0] = XSTART, YSTART
VX[0], VY[0] = VXSTART, VYSTART
T[0] = 0
# KE[0], PE[0], TE[0] = KE, PE, TE
for i in range (1,N):
K_1X = F_1(VX[i-1])
K_1Y = F_2(VY[i-1])
K_1VX = F_3(X[i-1], Y[i-1])
K_1VY = F_4(X[i-1], Y[i-1])
K_2X = F_1(VX[i-1] + (H*K_1VX/2))
K_2Y = F_2(VY[i-1] + (H*K_1VY/2))
K_2VX = F_3(X[i-1] + (H*K_1X/2), Y[i-1] + (H*K_1Y/2))
K_2VY = F_4(X[i-1] + (H*K_1X/2), Y[i-1] + (H*K_1Y/2))
K_3X = F_1(VX[i-1] + (H*K_2VX/2))
K_3Y = F_2(VY[i-1] + (H*K_2VY/2))
K_3VX = F_3(X[i-1] + (H*K_2X/2), Y[i-1] + (H*K_2Y/2))
K_3VY = F_4(X[i-1] + (H*K_2X/2), Y[i-1] + (H*K_2Y/2))
K_4X = F_1(VX[i-1] + H*K_3VX)
K_4Y = F_2(VY[i-1] + H*K_3VY)
K_4VX = F_3(X[i-1] + H*K_3X, Y[i-1] + H*K_3Y)
K_4VY = F_4(X[i-1] + H*K_3X, Y[i-1] + H*K_3Y)
X[i] = X[i-1] + (H/6)*(K_1X + 2*K_2X + 2*K_3X + K_4X)
Y[i] = Y[i-1] + (H/6)*(K_2Y + 2*K_2Y + 2*K_3Y + K_4Y)
VX[i] = VX[i-1] + (H/6)*(K_1VX + 2*K_2VX + 2*K_3VX + 2*K_4VX)
VY[i] = VY[i-1] + (H/6)*(K_1VY + 2*K_2VY + 2*K_3VY + 2*K_4VY)
R[i] = ((X[i])**2 + (Y[i])**2)**(0.5)
T[i] = T[i-1] + H
KE[i] = ((VX[i]**2 + VY[i]**2)/2)
PE[i] = (-1*G*EM/R[i])
TE[i] = KE[i] + PE[i]
if R[i] < 6.371E6: #if orbit radius is less than Earth radius
break
for sublist in [X, Y, VX, VY, R, T, KE, PE, TE]:
del sublist[i+1:]
return X, Y, VX, VY, R, T, KE, PE, TE
X = 3.84E8
Y = 0
X, Y, VX, VY, R, T, KE, PE = RKutta(F_1, F_2, F_3, F_4, X, Y, VX, VY)
plt.plot(X, Y, label = "")
plt.xlabel("X distance (m)")
plt.ylabel("Y distance (m)")
plt.title("X against Y")
plt.legend()
plt.show()
I'm trying to implement 4th-order Runge-Kutta method to simulate a rocket orbiting the Earth. The goal is to finally print out the orbit of the rocket. I'm still figuring out my code so they're still not working yet. How would using class improve this?
Keep references of your list in another data structure and then loop through that to delete everything at once:
for sublist in [X, Y, VX, VY, R, T, KE, PE, TE]:
del sublist[i+1:]
Edit:
You wanted to use classes instead of lists.
Right now you have nine lists, and the ith element in each list corresponds to an attribute about the ith rocket. So you can create a rocket class:
class Rocket:
def __init__(self, X, Y, VX, VY, R, T, KE, PE, TE):
self.X = X
self.Y = Y
self.VX = VX
...
This will let you access the attributes of each rocket like so:
Saturn_V = Rocket(1, 2, 3, 4, 5, 6, 7, 8, 9)
Saturn_V.X
>>>1
Now instead of nine seperate lists you can use one list of rockets:
rocket_list = [Saturn_V, Sputnik, Atlas-Agena ...]
An to remove all the information about on specifc rocket you only need to remove one element from the list:
del rocket_list[0] #removes Saturn_V and all its attributes
Here's what I was trying to explain in my comment(s). Although I don't know the details of what you're doing, hopefully this will be enough give you the general idea:
# Define a class to hold each group of values.
class Example:
def __init__(x, y, vx, vy, r, t, ke, pe, te):
self.x = x
self.y = y
self.vx = vx
self.vy = vy
self.r = r
self.t = t
self.ke = ke
self.pe = pe
self.te = te
# Somehow create a list of Example instances.
my_data = [Example(x1, y1, vx1, vy1, r1, t1, ke1, pe1, te1),
Example(x2, y2, vx2, vy2, r2, t2, ke2, pe2, te2),
...
Example(xN, yN, vxN, vyN, rN, tN, keN, peN, teN)]
# Then you could do what you asked about like this:
for i, elem in enumerate(my_data):
if elem.ke > elem.pe: # Done?
break
del my_data[i+1:] # Delete remaining elements in my_data.
This question already has answers here:
pick a subclass based on a parameter
(4 answers)
Closed 7 years ago.
So i have a class:
class Unit(object):
def __init__(self, name, x , y, z):
self.name = name
self.strength = x + y
self.intelligence = x + z
self.speed = y + z - x
and two species of these Units
class Red(Unit):
def __init__(self, name, x, y, z):
Unit.__init__(self,name, x, y, z)
self.strength = self.strength * 2
class Blue(Unit):
def__init__(self, name, x, y, z):
Unit.__init__(self, name, x, y, z)
self.speed = self.speed * 2
I want the race to be decided based on what x, y, z, was used as input (z > x means the unit belongs to class Red and x > z means the unit belongs to class Blue) without having to set one before hand, how do I do this?
You could create function for that:
def builder(name, x, y, z):
if z > x:
return Red(name, x, y, z)
elif x > z:
return Blue(name, x, y, z)
You can set the __class__ attribute in your __init__:
class Unit(object):
def __init__(self, name, x , y, z):
self.name = name
self.strength = x + y
self.intelligence = x + z
self.speed = y + z - x
if z > x:
self.__class__ = Red
else:
self.__class__ = Blue
red = Unit("foo", 1,2,3)
blue = Unit("bar", 3,2,1)
You can also create a factory method that instantiates the appropriate class. You can do this as a stand-alone function, or you could make a class method. Here's the stand-alone version:
def unit_factory(name, x, y, z):
if x > z:
return Red(name, x, y, z)
return Blue(name, x, y, z)
red = unit_factory("foo", 1, 2, 3)
blue = unit_factory("bar", 3, 2, 1)
I have cython code I'm using to speed up a bottleneck in an otherwise pure python calculation. I have a pair of points in a periodic box of length Lbox (1d case is fine for this question). I need to compute the sign of y-x, and I need to flip this sign when the periodic boundary conditions are operative.
In the absence of PBCs, the following question provides the solution: Is there a standard sign function (signum, sgn) in C/C++?. That solution is what I use to compute the sgn function.
def sgn(x, y):
""" If x > y, returns 1.
If x < y, returns -1.
If x == y, returns 0.
"""
return (y < x) - (x < y)
The sgn_pbc function as written below returns the correct result, but is written inefficiently: the control flow within the sgn_pbc is the culprit for slowing down the PBC version. How can I write sgn_pbc in an analogous way to the sgn function, so that I avoid the clumsy control flow?
def sgn_pbc(x, y, Lbox):
d = abs(x-y)
if d <= Lbox/2.:
return sgn(x, y)
else:
return -1*sgn(x, y)
First,
-1*sgn(x, y) == sgn(y, x)
then,
def sgn_pbc(x, y, Lbox):
d = abs(x-y)
if d <= Lbox/2.:
return sgn(x, y)
else:
return sgn(y, x)
Also in Python, function calls are the most expensive operations. You can inline your sgn.
def sgn_pbc(x, y, Lbox):
d = abs(x-y)
if d <= Lbox/2.:
return (y < x) - (x < y)
else:
return (x < y) - (y < x)
But then the if can be (mostly) rewritten as:
def sgn_pbc(x, y, Lbox):
d = abs(x-y)
w = sgn(Lbox/2., d)
return w * sgn(x, y)
And again, inlining the sgn,
def sgn_pbc(x, y, Lbox):
d = abs(x-y)
w = sgn(Lbox/2., d)
return w * (y < x) - (x < y)
I say mostly because the case where d == Lbox/2. this returns a wrong value.
Haven't timed it, though.