Giving positional arguments for Co-ordinates and Clustering them together - python

so I have a data file and I'm wanting to find two things:
Whether the coordinates I give are inside or outside an area and returning if its true or not
Put each coordinates of "1" together in each line in its own list. This should return it in a dictionary.
The file has the following:
1 1 0 1 0 1
0 0 1 1 1 0
1 1 1 1 1 0
1 0 0 0 0 1
0 0 1 1 0 1
1 0 0 0 0 1
I've put the above into a list and each with the code:
lines = []
with open('area.dat', 'r') as a:
for line in a:
line = line.strip()
if not line:
continue
lines.append(list(map(int, line.split())))
data.extend(map(int, line.split()))
print(lines)
My attempts at code to get the coordinates and whether it's outside or inside the area (for both x and y)
area is the list of lists
x = int(input('enter x: '))
y = int(input('enter y: '))
def cords(x, y, area):
if x > 6 or y > 6:
print('Outside Area')
return(False)
else:
print('Inside Area')
return(True)
I want to get a coordinate x and y within the list "area" and return whether it is in or out this.
So for example if I put in cords(0,4,area) it will return "True" and if I put cords(3,7,area) it will return "False".
After this I then want to put them together in groups of 1's by each line.
so for example line 1 and 2 would give:
{1: [(0,4), (0,5)], 2: [(1,0), (1,1)]}
All help is appreciated thanks.

For the first part you have two options:
def cords(x, y):
return x >= 0 and x < 6 and y >= 0 and y < 6
This first option is static for an area size of 6x6, note that array indexing starts at 0 so 6 would already be out of bounds.
def cords(x, y, area):
return x >= 0 and x < len(area) and y >= 0 and y < len(area[0])
This second option dynamically checks whether the coordinates are in bounds of the given nested list. You might have to adjust it based on whether x and y relate to rows and columns or vice versa.
Now for your second part, you're creating a dictionary with redundant information, since the index (1 and 2 in your example) directly relates to the first axis (0 and 1 in your example), you might want to reconsider what you actually want to achieve here.
d = {}
for i,row in enumerate(lines):
n = []
for j,v in enumerate(row):
if v == 1:
n.append([i,j])
d[i+1] = n

Related

String index problem on my sudoku solver program

This is my code for a sudoku solver and I am getting this error:
File "c:/Users/Documents/untitled-17.py", line 85, in <module>
if board[i][j] == 0:
builtins.IndexError: string index out of range
My code is below and I am unsure of the error and how to fix it. I am not sure if the error is because of the main function or the solveBoard function. I am also unsure if this is the only error I will run into after I fix this one error. I am afraid that if I fix this one error I might screw up my whole program. This is the import file I am reading from, only difference is there is no extra new line in between the numbers. Here is the file:
9 0 5 0 0 0 0 0 0
0 6 3 1 0 0 0 0 5
4 0 0 6 5 0 0 7 2
0 7 0 9 6 0 0 2 3
2 0 9 0 0 0 1 0 6
3 4 0 0 1 5 0 8 0
1 9 0 0 2 7 0 0 8
6 0 0 0 0 1 2 4 0
0 0 0 0 0 0 7 0 1
def main():
L = []
fileName = input('Enter input file name: ')
inFile = open(fileName,'r')
print('Initial Game')
line = 9
for x in range(line):
a = inFile.readline()
first = a.split()
H = first
H = (str(H).replace("'",""))
L.append(H)
x = (str(L).replace("'",""))
y = x.replace("],", "],\n")
return y
myBoard = main()
def isValid(board, row, col, num):
#check row
for i in range(9):
if board[row][i] == num:
return False
#check col
for i in range(9):
if board[i][col] == num:
return False
#get top-left corner
c_row = row - row%3
c_col = col - col%3
#check 3x3 square
for i in range(c_row, c_row+3):
for j in range(c_col, c_col+3):
if board[i][j] == num:
return False
#return True if none of the cases above returns False
return True
def solveBoard(board):
for i in range(9):
for j in range(9):
if board[i][j] == 0:
for num in range(1,10):
if isValid(board, i, j, num):
board[i][j] = num
result = solveBoard(board)
if result == True:
return True
else:
board[i][j] = 0
return False
return True
solveBoard(myBoard)
for line in myBoard:
print(line)
#check col
for i in range(9):
should be
for j in range(9):
Running this code, it looks like the board array being passed to solveBoard() is 269 x 1 and you're treating it like it's 9 x 9
I can't check without the full input file, but I think the following is likely to fix your file input parsing:
def parse_board_file(filepath):
board = []
with open(filepath, 'r') as input_file:
print('Initial Game')
row = []
for line in input_file:
for character in line:
if character.isdigit():
row.append(str(character))
if len(row) == 9:
board.append(row)
row = []
if len(board) == 9:
return board
# if you make it to here, you reached the end of the file before
# finding enough numbers
print("ERROR: a full 9x9 grid could not be parsed from the given file.")
return board
def isValid(board, row, col, num):
# ...rest of function...
def solveBoard(board):
# ...rest of function...
def main():
filepath = input('Enter input file name: ')
board = parse_board_file(filepath)
solveBoard(board)
for line in board:
print(line)
if __name__ == "__main__":
main()
However, with the given test case this still did not succeed in completing the board. Sudoku requires iteratively filling in the next cell that has been narrowed down, so it would be very very unusual for only one pass over the board from top to bottom to be able to solve each square. But even wrapping your code in an extra loop to run until the board is solved likely won't help here.
The following datapoints may help you refine your approach:
The condition to fill in a cell in your code is just that there is no reason that number cannot go there. However, when just starting out more cells will be blank than not, so lots of cells will be able to be filled with this logic. Once some have been filled in, you may find there are no valid moves remaining so some of the earlier moves may have been in error. This is because the condition you are looking for in Sudoku is not "can this number go here?" but in fact "does this number have to go here?" and "is this the only number that can go here?" The cell should remain blank until there is only one option that fits it.
Harder sudoku do not rely only on knowing which numbers are already present in a row, column or square. They may rely on conditions such as if the places a certain number can go has been refined to one of a few options that are all in a certain place. e.g.
1 2 3 7 8
4 5 6 7 8 9 1 2
7 8 9 1 2 3 4 5
Square A Square B Square C
In this scenario, there are 3 cells remaining in Square C and if you only considered rows and squares then a 6 could go in either the top or bottom of those cells. However, even though the 6 has not been placed in Square B, we can still know that it will have to be placed in the top row. Therefore, the 6 would need to go in the bottom empty cell in Square C.
I hope this sets you on your way to a solution :)

Matplotlib connect scatterplot points with line

I read the question Matplotlib connect scatterplot points with line - Python but it doesn't work for me...
I tried to use plt.scatter(x, y) and after that plt.show(), but all that I see is a set of separated dots from each other.
I think, that problem consists in that I use a loop for generating each point on the plot and after that loop, I use plt.show().
All my code looks like this:
x = 0
y = 0
def eye_gaze1(a,b):
global x,y
image_plot1 = plt.imshow(image1)
for i in range(len(a)):
if stimulus_name[x+y+1] == '5_01.jpg' and a[x+y+1] != '-':
plt.scatter([a[x+y+1]], [b[x+y+1]]) #here I putting new point on the image_plot1 and this process repeats (something like 1000 times) before in my massive of data cycle will find '-' symbol
x += 1
else:
x += 1
break
plt.show() #final image
y += x
x = 0
j = 0
while j < 15: #just repeat this function for another cells in data-massive
eye_gaze1(col_values_X_right,col_values_Y_right)
j += 1
So, question is, how can I connect points?
If I try to use the comment of JohanC, I see this error: TypeError: ufunc 'sqrt' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
x = 0
y = 0
def eye_gaze1(a,b):
global x,y
image_plot1 = plt.imshow(image1)
for i in range(len(a)):
if stimulus_name[x+y+1] == '5_01.jpg' and a[x+y+1] != '-':
X_coordinates = list().append(a[x+y+1])
Y_coordinates = list().append(b[x+y+1])
x += 1
else:
x += 1
break
plt.scatter(X_coordinates, Y_coordinates, '-o')
plt.show()
y += x
x = 0
j = 0
while j < 15:
eye_gaze1(col_values_X_right,col_values_Y_right)
print(x)
print(y)
j += 1

Splitting user input into lists of increasing size [python]

I am trying to produce a code that verifies whether or not a user input meets the criteria of a pascal triangle. I know how to go about inputting the number of lines and having it develop a pascal triangle, but I am having trouble figuring out how to get a user to input something like 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1, and having my program say whether it is a pascal triangle or not.
values = input("Enter the numbers: ").split()
pascals_triangle = list(map(list, values))
I know the first line could split the numbers, and the second line would assign the numbers into individual lists of a list. Every time I attempt to have the lists increase by 1 in every row, I get str/int errors. Once I get past this little road block, I should be able to figure out the rest of the code.
data = input("Enter values: ").split()
def pascal_triangle(data):
size = int(data[0])
n = 2 * size + 1
grid = [[0 for x in range(n)] for y in range(size)]
left = 1
for i in range(size, 0, -1):
grids = data[i].split(' ')
count = 0
for g in grids:
grid[i - 1][left + 2 * count] = int(g)
count += 1
left += 1
if count != i:
return False
left = 1
for i in range(size - 1, -1, -1):
if i == 0:
return grid[i][left] == 1
numbers = i + 1
count = 0
while count < numbers:
current = grid[i][left + count * 2]
upper_left = grid[i - 1][left - 1 + count * 2]
upper_right = grid[i - 1][left + 1 + count * 2]
if current != (upper_left + upper_right):
return False
count += 1
left += 1
return False
status = pascal_triangle(data)
if status:
print('It is a pascal triangle')
else:
print('It is not a pascal triangle')
So, in this code, why am I still not getting the accurate answers?
If you're trying to do this in some fancy way, like adapting the grouper recipe in the itertools docs to take an iterable of group sizes instead of a fixed group size… take a step back and write the "dumb" version first.—just write a loop.
First, split the whole string, the same way you split each line in your line-by-line version.
One thing: mapping list over your values won't do any good; that'll just turn, e.g., '23' into ['2', '3'], and there's not much good you can do with that. You want a list of numbers, which you're then going to break up into a rows (each row also being a list of numbers—the same row you got by mapping int over line.split() in your line-by-line version).
So, here's some pseudocode:
values = input("Enter the numbers: ").split()
nums = [int(value) for value in values]
size = 1
start = 0
while start < len(nums):
rownums = nums[start:start+size]
make sure len(rownums) == size
check rownums the same way you checked each line
update size and start
if you got here without seeing any errors, it's valid
One way to do this is to generate each row of Pascal's triangle, and use islice to grab a list of the current row length from the user data and see if the data matches the row.
from itertools import islice
def pascal():
""" Pascal's triangle generator """
a = [1]
while True:
yield a
#Generate next row from current row
a = [x + y for x, y in zip([0] + a, a + [0])]
def test_pascal(values):
it = map(int, values.split())
ok = True
for row in pascal():
data = list(islice(it, len(row)))
if not data:
break
if data != row:
ok = False
print('bad data', data, row)
break
return ok
# Test
values = '1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1'
print(test_pascal(values))
values = '1 1 1 1 2 1 1 3 3 1 1 4 6 5 1'
print(test_pascal(values))
output
True
bad data [1, 4, 6, 5, 1] [1, 4, 6, 4, 1]
False

screen output of tuples

I got a question about displaying my output data. Here is my code:
coordinate = []
z=0
while z <= 10:
y = 0
while y < 10:
x = 0
while x < 10:
coordinate.append((x,y,z))
x += 1
coordinate.append((x,y,z))
y += 1
coordinate.append((x,y,z))
z += 1
for point in coordinate:
print(point)
My output data contains commas and parenthesis which I want to get rid of. I want my output to look like this:
0 0 0
1 0 0
2 0 0
etc. No comma and parenthesis, just the values.
Write the last two lines like this:
for x, y, z in coordinate:
print(x, y, z)
In addition to the answer by #flornquake, you can do something with those while
import itertools
# If you just want to print this thing, forget about building a list
# and just use the output of itertools.product
coordinate = list(itertools.product(range(0, 10), range(0, 10), range(0, 11)))
for point in coordinate:
print('{} {} {}'.format(*point))
Presuming you are using Python 3, you could do this:
for point in coordinate:
print(*point)
The "star" notation unpacks the tuple into its individual elements. The print function then displays the elements using the default separator, which is a single space character.

Check for pattern recursively

*Note i refer to thing as a matrix but it is not, it is just a collection of 1's and zeros
Suppose you have a matrix that is always square (n x n). Is it possible to determine if there exists a single column/row/diagonal such that each item is a 1.
Take the matrix below for instance (True):
1 0 0
1 1 0
0 0 1
Another example (True):
1 1 1
0 0 0
0 1 0
And finally one without a solution (False):
0 1 1
1 0 0
0 0 0
Notice how there is a diagonal filled with 1's. The rule is there is either there is a solution or there is no solution. There can be any number of 1's or zeros within the matrix. All i really need to do is, if you have (n x n) then there should be a row/column/diagonal with n elements the same.
If this is not possible with recursions, please let me know what is the best and most efficient method. Thanks a lot, i have been stuck on this for hours so any help is appreciated (if you could post samples that would be great).
EDIT
This is one solution that i came up with but it gets really complex after a while.
Take the first example i gave and string all the rows together so you get:
1 0 0, 1 1 0, 0 0 1
Then add zeros between the rows to get:
1 0 0 0, 1 1 0 0, 0 0 1 0
Now if you look closely, you will see that the distances between the 1's that form a solution are equal. I dont know how this can be implemented though.
In search for an elegant solution I came up with this:
class LineOfOnesChecker(object):
_DIAG_INDICES = (lambda i: i, lambda i: -i - 1)
def __init__(self, matrix):
self._matrix = matrix
self._len_range = range(len(self._matrix))
def has_any(self):
return self.has_row() or self.has_col() or self.has_diag()
def has_row(self):
return any(all(elem == 1 for elem in row)
for row in self._matrix)
def has_col(self):
return any(all(self._matrix[i][j] == 1 for i in self._len_range)
for j in self._len_range)
def has_diag(self):
return any(all(self._matrix[transf(i)][i] == 1 for i in self._len_range)
for transf in self._DIAG_INDICES)
Usage:
print LineOfOnesChecker(matrix).has_any()
You can have a list of n 1's and do an 'AND' for your sets of diagonal elements, row elements and column elements and if any of those AND operation results in a TRUE, then you have your valid pattern.
import sys
matrix = [[1,0,1],[1,0,1],[1,0,1]]
transpose = zip(*matrix)
diagonal1 = []
for n,elem in enumerate(matrix):
diagonal1.append(elem[n])
diagonal2 = []
for n,elem in enumerate(transpose):
diagonal2.append(elem[n])
for row in matrix:
if reduce(lambda x,y: x and y, row):
print True
sys.exit()
for row in transpose:
if reduce(lambda x,y: x and y, row):
print True
sys.exit()
if (reduce(lambda x,y: x and y, diagonal1) or reduce(lambda x, y: x and y, diagonal2)):
print True
sys.exit()
From what I understand of the problem, you just need to check whether any row, coloumn or diagonal consists entirely of '1's. This can be done very easily using all in Python, so I don't get why you want to do this recursively.
The more obvious solution (in my mind) is something like this:
#! /usr/bin/env python
boards=[
((0,1,0),(1,0,1),(0,1,0)),
((1,1,1),(0,0,0),(0,0,0)),
((0,0,0),(1,1,1),(0,0,0)),
((0,0,0),(0,0,0),(1,1,1)),
((1,0,0),(1,0,0),(1,0,0)),
((0,1,0),(0,1,0),(0,1,0)),
((0,0,1),(0,0,1),(0,0,1)),
((1,0,0),(0,1,0),(0,0,1)),
((0,0,1),(0,1,0),(1,0,0)),
((0,0,0),(0,0,0),(0,0,0))
]
def check(board):
for row in board:
if all(row):
return True
for col in xrange(len(board)):
vector=[board[row][col] for row in xrange(len(board))]
if all(vector):
return True
diag1=[board[i][i] for i in xrange(len(board))]
if all(diag1):
return True
diag2=[board[i][i] for i in xrange(len(board)-1,-1,-1)]
if all(diag2):
return True
return False
if __name__=='__main__':
for board in boards:
if check(board):
print "Yes"
else:
print "No"

Categories