Verify that the geometry for the triangle is in the row list

I have a list of lines Lines=([('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')]) , and geometry = ('B', 'C', 'D') is a list of points that establish a triangle (B,C,D) .

I want to check if geometry can be set from a list of lines in Lines . How to create a function to check the status? True or False .

Functionality example with input lines:

 >> Lines=([('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B'),]) >> geometry1 = ('B', 'C', 'D') >> check_geometry(Lines, geometry1) True >> geometry2 = ('A', 'B', 'E') >> check_geometry(Lines, geometry2) False 

This is my code, but the result is incorrect:

 import itertools def check_geometry(line, geometry): dataE = [set(x) for x in itertools.combinations(geometry, 2)] for data in dataE: if data not in line: return False return True Lines = [('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B'),] geometry1 = ('B', 'C', 'D') print check_geometry(Lines, geometry1) 

Output:

 False 
+5
source share
2 answers

For triangles:

You can use the built-in all to sort the list of contents first, as their order may differ from what is generated from itertools.combinations :

 sLines = [tuple(sorted(l)) for l in Lines] dataE = itertools.combinations('BCD', 2) 

Now you can call all , which will check that every value in dataE present in sLines :

 all(l1 in sLines for l1 in dataE) 

which will return True .

So your check_geometry function might look something like this:

 def check_geometry(line, geometry): sLines = [tuple(sorted(l)) for l in line] dataE = itertools.combinations(geometry, 2) return all(l1 in sLines for l1 in dataE) 

Now the calls made will check if the Lines geometry contains:

 check_geometry(Lines, 'BCD') # returns True check_geometry(Lines, 'ABE') # returns False 

A bit more general:

To summarize this a bit, we can opt out of itertools.combinations and use zip instead. The following makes some relevant changes to the function in order to put a zip , but does similar things:

 def check_geometry(line, geometry): sLines = [sorted(l) for l in line] dataE = [sorted(x) for x in zip(geometry, geometry[1:] + geometry[:1])] return all(l1 in sLines for l1 in dataE) 

The key difference here is:

dataE now presents a list of lists containing the result of zip(geometry, geometry[1:] + geometry[:1]) . What zip does in this case is that it takes the line as "BCDA" and the same line with the first element added to the end of geometry[1:] + geometry[:1] (ie "CDAB" ), and creates records indicating the sides of the form:

 >>> s = "BCDA" >>> s[1:] + s[:1] >>> 'CDAB' >>> list(zip(s, s[1:] + s[:1])) [('B', 'C'), ('C', 'D'), ('D', 'A'), ('A', 'B')] 

Now we can verify that the geometry with the "BCDA" points can be built with lines in Lines :

 check_geometry(Lines, "BCD") # True check_geometry(Lines, "BCDA") # True check_geometry(Lines, "BCDF") # False 

Note 1 : Lines can be written as:

 Lines=[('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')] 

In brackets () and a comma , there is no additional effect, you can leave them :-).

Note 2 The geometry parameter for check_geometry can be any iterable (tuples, lists, strings):

 check_geometry(lines, "BCD") == check_geometry(lines, ('B', 'C', 'D')) 

Creating and tuple in this case seems somewhat strange (alas, you may have good reason for this). If the reason does not require this, I would suggest going with the strings as the value of the geometry parameter.

+3
source

I think A, B, C can be a string or what defines a point that sets a string

Well, I will use the lines for my answer, then you can customize the code according to your needs.

 def check_for_triangle(tri, lines): lines_needed = zip(tri, (tri[1], tri[2], tri[0])) return all(line in lines or line[::-1] in lines for line in lines_needed) lines=[('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')] tri1 = ('B', 'C', 'D') tri2 = ('A', 'B', 'E') print(check_for_triangle(tri1, lines)) # True print(check_for_triangle(tri2, lines)) # False 

The idea is to generate all lines (represented by a pair of points), we need to find in lines for a given triangle with zip . After that, we check to see if all these lines can be found in lines . It also requires checking on line[::-1] , because the line ('A', 'B') matches the same line as ('B', 'A') .

+3
source

Source: https://habr.com/ru/post/1240254/


All Articles