I have two lists that represent the x and y coordinates as a plane, and each point on the plane has a random number assigned to it which i use as a key to search for the coordinates, the problem is i need there to be a chance that the random number assigned to a point is a duplicate so i used float but now i need to search through the dictionaries using an int as the key to see if that number exists and what point it is assigned to. So essentially I'm wondering if it's possible to search for the rounded version of a key for example if the key is 10.3 i need to find it using an int equal to 10.
x_amount = int(input("Height of room: "))
y_amount = int(input("Width of room: "))
# Asks for height and width of plane
Room_Total = x_amount * y_amount
numbers = []
length = len(str(Room_Total)) + 1
x_values = {}
y_values = {}
create_number = y_amount
def num_find(num):
y_coord = y_values[num]
x_coord = x_values[num]
# Here is where i want to search for the coordinates using an int
for num in range(1, (y_amount + 1)):
for n in range(1, (x_amount + 1)):
number = 1
while number != 0:
number = random.uniform(1, Room_Total)
if number not in numbers:
numbers.append(round(number))
x_values[number] = num
y_values[number] = n
number = 0
# Randomly generates a number for every place in the grid
plane = input("Want to see the plane? y/n ")
if plane == "y":
for i in numbers:
num_gap = length - len(str(i))
create_number = create_number - 1
if create_number == -1:
print("")
create_number = y_amount - 1
print(i,end=" ")
for num in range(1, num_gap):
print(" ", end="")
else:
print(i,end=" ")
for num in range(1, num_gap):
print(" ", end="")
# Prints grid if the user wants it (So that if the grid is 100 by 100 for example it doesn't print it)
I searched for similar problems that have an answer but haven't quite found anything that applies to this situation and haven't been sure what else to try.
[If I understand correctly, you want help with the num_find
function.] An integer num
might have multiple float keys that round to it, so you can return a list of coordinates for keys that round to num
using list comprehension.
def num_find(num):
knums = [k for k in x_values if round(k)==num] ## random `number`s that round to num
return [{'value':k, 'x':x_values[k], 'y':y_values[k]} for k in knums]
With the 5x5 plane described below:
numbers = [22, 17, 17, 1, 7, 5, 23, 4, 21, 15, 7, 17, 12, 22, 12, 6, 24, 17, 7, 3, 11, 3, 9, 10, 16]
x_values = { 21.56616443204579: 1, 16.88672504030793: 1, 16.61564085529154: 1, 1.4623292817213773: 1, 7.186315822551395: 1, 5.387703554349793: 2, 23.004220335362547: 2, 4.30105672619399: 2, 20.7082214032309: 2, 15.161515180582256: 2, 7.038981849299793: 3, 17.32470245778697: 3, 11.939846516953184: 3,
21.985484460089975: 3, 12.186946846244577: 3, 5.953912098756866: 4, 24.077177195496617: 4, 16.932061089221378: 4, 6.965151311285224: 4, 2.8087793024821837: 4, 10.66278368789144: 5, 3.2461449455136293: 5, 8.615396657669486: 5, 9.667998604001081: 5, 15.636821583006896: 5 }
y_values = { 21.56616443204579: 1, 16.88672504030793: 2, 16.61564085529154: 3, 1.4623292817213773: 4, 7.186315822551395: 5, 5.387703554349793: 1, 23.004220335362547: 2, 4.30105672619399: 3, 20.7082214032309: 4, 15.161515180582256: 5, 7.038981849299793: 1, 17.32470245778697: 2,
11.939846516953184: 3, 21.985484460089975: 4, 12.186946846244577: 5, 5.953912098756866: 1, 24.077177195496617: 2, 16.932061089221378: 3, 6.965151311285224: 4, 2.8087793024821837: 5, 10.66278368789144: 1, 3.2461449455136293: 2, 8.615396657669486: 3, 9.667998604001081: 4, 15.636821583006896: 5 }
num_find(7)
would return
[ {'value': 7.186315822551395, 'x': 1, 'y': 5}, {'value': 7.038981849299793, 'x': 3, 'y': 1}, {'value': 6.965151311285224, 'x': 4, 'y': 4} ]
num_find(5)
would return [{'value': 5.387703554349793, 'x': 2, 'y': 1}]
, andnum_find(29)
would return []
(an empty list because there would be no matches)On another note,
It's a bit redundant to have two separate dictionaries (x_values
and y_values
) with the exact same set of keys. It might be better to have a dictionary of tuple
s instead. Instead of x_values[number]=num
and y_values[number]=n
(in if number not in numbers...
), you can just have one dictionary xy_values
that you fill up with xy_values[number] = (num, n)
.
Since number
is a float and numbers
is being built as a list of integers, it's somewhat superfluous to check for number not in numbers
:
if number not in numbers: numbers.append(round(number))
I know you can't use if round(number) not in numbers:
since you want duplicate integers, but this is only checking against duplicate whole-number keys. The chances of repeating a "random" float (without specifying a limit on the decimal places) is miniscule, but if you're checking against duplicate keys (which you should be, if you don't want to risk losing any coordinates by over-writing them), you should be checking against all of them, not just whole numbers.
I would suggest filling up your "plane" with something like:
xy_values = {} ## instead of `x_values={}` and `y_values={}`
for num in range(1, (y_amount + 1)):
for n in range(1, (x_amount + 1)):
number = random.uniform(1, Room_Total)
while number in xy_values: ## [ `in xy_values` <===> `in xy_values.keys()` ]
number = random.uniform(1, Room_Total)
numbers.append(round(number))
xy_values[number] = (num, n) ## [ only one dictionary to fill ]
While numbers
would be unaffected by this change, xy_values
for the plane I described as an example above would look like:
# xy_values = \ { 21.56616443204579: (1, 1), 16.88672504030793: (1, 2), 16.61564085529154: (1, 3), 1.4623292817213773: (1, 4), 7.186315822551395: (1, 5), 5.387703554349793: (2, 1), 23.004220335362547: (2, 2), 4.30105672619399: (2, 3), 20.7082214032309: (2, 4), 15.161515180582256: (2, 5), 7.038981849299793: (3, 1), 17.32470245778697: (3, 2), 11.939846516953184: (3, 3), 21.985484460089975: (3, 4), 12.186946846244577: (3, 5), 5.953912098756866: (4, 1), 24.077177195496617: (4, 2), 16.932061089221378: (4, 3), 6.965151311285224: (4, 4), 2.8087793024821837: (4, 5), 10.66278368789144: (5, 1), 3.2461449455136293: (5, 2), 8.615396657669486: (5, 3), 9.667998604001081: (5, 4), 15.636821583006896: (5, 5) }
and num_find
could just be defined as
def num_find(num):
return [{'value':k, 'x':x, 'y':y} for k,(x,y) in xy_values.items() if round(k)==num]
[It will produce the same results as before, but will be a bit more efficient since there's only one loop (for going through one dictionary) rather than two loops where you have to loop through a dictionary to gather keys that match, and then loop through the matched keys and fetch values from two separate dictionaries...]
In addition, I recommend looking into f-strings and the built-in enumerate
function, and maybe into conditional expressions as well, because your if plane == "y":...
block can be reduced to:
# plane = input("Want to see the plane? y/n ")
if plane == "y":
for n, i in enumerate(numbers, 1):
print(f'{i:<{length}}', end=' ' if n%y_amount else '\n')
[You can use if n%y_amount
instead of if n%y_amount!=0
as 0
evaluates as False
.]