2
\$\begingroup\$

I`m writing a function for small pygame program. The ideas is that I have a 500 pixels square screen and I want to place 5 objects per row with the size of width and height in random order and I need a function to generate and store coordinates.

from random import randint

def gen_coords(width=50, height=50, side_of_scr=500):
    """Generates random coordinates for objects in rows
    that are positioned on 5x5 grid."""

    coords = []
    for row in range(5):
        # creating row container
        coords.append([])
        for pos in range(5):
            # range of values in randint reflects that i want the objects
            # to be placed with offset of the sides of the screen
            x = randint(0.5 * width, side_of_scr - 0.5 * width)

            # the distance between the rows is equal to the height of an object
            y = 0.5 * height + row * 2 * height
            coords[row].append((x, y))
    return coords

So this

for coord in gen_coords():
    print(coord)

returns

[(177, 25.0), (367, 25.0), (214, 25.0), (284, 25.0), (125, 25.0)]
[(425, 125.0), (446, 125.0), (126, 125.0), (409, 125.0), (187, 125.0)]
[(210, 225.0), (188, 225.0), (215, 225.0), (132, 225.0), (431, 225.0)]
[(303, 325.0), (471, 325.0), (252, 325.0), (26, 325.0), (111, 325.0)]
[(468, 425.0), (127, 425.0), (452, 425.0), (30, 425.0), (345, 425.0)]

I've done this using list of lists and it's working so far, but im looking for the better way to do it. Thanks for help.

\$\endgroup\$
3
\$\begingroup\$

I am not entirely sure what you are unhappy about, so I am going to assume you find it too cumbersome, so here is a "one line" way to do it:

import random
gen_coords = (lambda rows=range(5), cols=range(5): lambda width=50, height=50, side_of_scr=500: [[
    (random.randint(width/2, side_of_scr - width/2), height/2 + row * 2 * height)
    for col in cols] for row in rows])()

That is still ugly, so let us make an elegant solution, with better performance:

import random
def gen_coords(width=50, height=50, side_of_scr=500, rows=5, cols=5):
    lower = width/2
    upper = side_of_scr - width/2
    height_step = 4 * height
    gen_x = lambda : random.randint(lower, upper)
    def gen_row(row):
        y = (row + 0.25) * height_step
        return [(gen_x,y) for col in range(cols))]
    return [gen_row(row) for row in range(rows)]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.