Why did I get all unit ones in this random walk test using Python3? - python-3.x

I am a python beginer and I was wondering why I got all unit ones in below script. I expected to get some integer numbers from 1-10.
import random
def random_walk(n):
"""Return coordinates after 'n' block random walk"""
x, y = 0, 0
for i in range(n):
(dx, dy) = random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
x += dx
y += dy
return (x, y)
for i in range(5):
walk = random_walk(10)
print(walk, "Distance from home = ",
abs(walk[0]) + abs(walk[1]))
Output:
(-1, 0) Distance from home = 1
(-1, 0) Distance from home = 1
(-1, 0) Distance from home = 1
(-1, 0) Distance from home = 1
(0, -1) Distance from home = 1

I think this line:
return (x, y)
should be outside of the loop:
import random
def random_walk(n):
"""Return coordinates after 'n' block random walk"""
x, y = 0, 0
for i in range(n):
(dx, dy) = random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
x += dx
y += dy
return (x, y)
for i in range(5):
walk = random_walk(10)
print(walk, "Distance from home = ",
abs(walk[0]) + abs(walk[1]))
Output:
(1, 1) Distance from home = 2
(-1, 1) Distance from home = 2
(-3, 3) Distance from home = 6
(0, -2) Distance from home = 2
(1, 3) Distance from home = 4

Related

How to get the first number in each line of a file in python?

inputFile = open(filename, "r")
with open(filename) as f:
content = f.readlines()
li = [x.strip() for x in content]
print(li)
Output:
['4', '0 1 2 3', '1 0 2 3', '2 0 1 3', '3 0 1 2']
Expected Output:
The number of total vertices is 4
Vertex 0: (0, 1) (0, 2) (0, 3)
Vertex 1: (1, 0) (1, 2) (1, 3)
Vertex 2: (2, 0) (2, 1) (2, 3)
Vertex 3: (3, 0) (3, 1) (3, 2)
I know how to convert a element into an integer but each line is different and the txt file is in this format:
4
0 1 2 3
1 0 2 3
2 0 1 3
3 0 1 2
should I need to separated by.split() method?
Try:
with open("your_file.txt", "r") as f:
total_vertices = int(next(f))
vertices = []
for _ in range(total_vertices):
row = list(map(int, next(f).split()))
vertices.append([(row[0], v) for v in row[1:]])
print("The number of total vertices is", total_vertices)
for i, v in enumerate(vertices):
print(f"Vertex {i}:", *v)
Prints:
The number of total vertices is 4
Vertex 0: (0, 1) (0, 2) (0, 3)
Vertex 1: (1, 0) (1, 2) (1, 3)
Vertex 2: (2, 0) (2, 1) (2, 3)
Vertex 3: (3, 0) (3, 1) (3, 2)

Python List Comprehension: assign to multiple variables

Is there a way to assign to multiple variables in a one-liner?
Let's say I have a list of 3D points and I want x, y and z lists.
polygon = [(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)]
# this works to get the expected result, but is not a single list comprehension
x = [x for x, y, z in polygon ]
y = [y for x, y, z in polygon ]
z = [z for x, y, z in polygon ]
I am thinking of something like:
x, y, z = [... for x, y, z in polygon ]
You can use zip() function:
polygon = [(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)]
x, y, z = zip(*polygon)
print(x)
print(y)
print(z)
Prints:
(0, 1, 1, 0)
(0, 0, 1, 1)
(0, 0, 0, 0)
Or if you want lists instead of tuples:
x, y, z = map(list, zip(*polygon))
Unpack the list of tuples using zip():
polygon = [(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)]
x,y,z = zip(*polygon)
print(list(x))
print(list(y))
print(list(z))
OUTPUT:
[0, 1, 1, 0]
[0, 0, 1, 1]
[0, 0, 0, 0]
EDIT:
If you want the lists:
x,y,z = [list(a) for a in zip(*polygon)]

How to find 5 closest points based on cosine distance in S from P

Consider you are given n data points in the form of list of tuples like S=[(x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5),..,(xn,yn)] and a point P=(p,q)
your task is to find 5 closest points(based on cosine distance) in S from P
Ex:
S= [(1,2),(3,4),(-1,1),(6,-7),(0, 6),(-5,-8),(-1,-1)(6,0),(1,-1)]
P= (3,-4)
I have tried with below code
import math
data = [(1,2),(3,4),(-1,1),(6,-7),(0, 6),(-5,-8),(-1,-1)(6,0),(1,-1)]
data.sort(key=lambda x: math.sqrt((float(x.split(",")[0]) - 3)**2 +
(float(x.split(",")[1]) -(-4))**2))
print(data)
I should get 5 closest points in S from P.
You have a missing comma in the defenition of data
You have a list of tuples but for some reason you used split as if it was a list of strings.
If you fix these 2 errors it works. You just need to grab the first 5 elements from data:
import math
data = [(1, 2), (3, 4), (-1, 1), (6, -7), (0, 6), (-5, -8), (-1, -1), (6, 0), (1, -1)]
data.sort(key=lambda x: math.sqrt((float(x[0]) - 3) ** 2 +
(float(x[1]) - (-4)) ** 2))
print(data[:5])
Outputs
[(1, -1), (6, -7), (-1, -1), (6, 0), (1, 2)]
(Next time, if you get an error please explain it in your question)
cosine_dist = []
for a, b in S:
num = a * P[0] + b * P[1]
den = math.sqrt(a * a + b * b) * math.sqrt(P[0] * P[0] + P[1] * P[1])
cosine_dist.append(math.acos(num/den))
X = cosine_dist
Y = [S for S in sorted(zip(S,X), key=lambda i:i[1])]
k = Y[:5]
for i, j in k:
print(i)
P = (3, -4)
S = [(1, 2), (3, 4), (-1, 1), (6, -7), (0, 6), (-5, -8), (-1, -1), (6, 0), (1, -1)]

how to get all coordinates in the rectangle between two coordinates?

say i have a rectangle, and its top-left and bottom-right coordinates are A(0,0) and B(2,3) respectively. is there a method/formula that i can use to get all the coordinates inside this rectangle? I want my output to be like this if the input was these two coordinates:
input: [(0, 0), (2, 3)]
output: [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2), (0, 3,) (1, 3,) (2, 3)]
also, a python 3 implementation would be greatly appreciated, although not necessary.
thanks
EDIT: full story: i'm using python, and at first i thought i could achieve what i want by getting all the values between x1 and x2, y1 and y2. so for example i have x = 0, x = 1, x = 2 and y = 0, y = 1, y = 2, y = 3, but i honestly don't know where to go from there, or if this is correct in the first place. i thought i could get all the coordinates by somehow getting all the coordinates with y = 0 with different x values, then all the coordinates with y = 1... but i can't seem to wrap my head around a way of doing this. any help is appreciated, thanks.
One thing you could do is make a list of all x coordinates inside the rectangle [x1..x2] and all y coordinates inside the rectangle [y1..y2] and then take the Cartesian product of the two lists using itertools:
import itertools
...
input = [(0, 0), (2, 3)]
x_coords = [x for x in range(input[0][0], input[1][0] + 1)]
y_coords = [y for y in range(input[0][1], input[1][1] + 1)]
output = list(itertools.product(x_coords, y_coords))
If you don't want to use itertools to compute the product, you could also easily use a for loop or a list comprehension to do it instead, which is roughly equivalent to what itertools is doing behind the scenes anyway:
output = [(x, y) for x in x_coords for y in y_coords]

python performance improvement

I am trying to obtain intensity values from an RGB image based on this formula:
And my code is:
def normalize(image): #normalize values to between 0 and 1
image -= image.min()
image /= image.max()
image = np.uint8(image * 255) #convert values to uint8 between 0-255
return image
def custom_intensity(image):
h, w, c = image.shape
intensity = np.zeros((h, w))
image = image.astype(float)
for i in range(h):
for j in range(w):
divider = image[i, j, 0] + image[i, j, 1] + image[i, j, 2]
if(divider == 0):
intensity[i, j] == 0
else:
intensity[i, j] = image[i, j, 0] * (image[i, j, 0] / divider) + \
image[i, j, 1] * (image[i, j, 1] / divider) + \
image[i, j, 2] * (image[i, j, 2] / divider)
intensity = normalize(intensity)
return intensity
Which works well but slow. I am beginner in python so could not improve this further. How can I make this code more efficient?
Try this:
image += (pow(10, -6), pow(10, -6), pow(10, -6))
intensity = (pow(image[:, :, 0], 2) + pow(image[:, :, 1], 2) + pow(image[:, :, 2], 2)) \
/ (image[:, :, 0] + image[:, :, 1] + image[:, :, 2])
You don't need to be an expert in Python.
Simplify your equation:
(R**2 + G**2 + B**2) / (R+G+B)

Resources