예제 #1
0
    def test_incomplete_table(self):
        """
        Table with missing bottom border:

        point = *
        link = - or |
        missing point = .

        9 *--*---*--*
             |   |
        8 *--*---*--*
             |   |
             |   |
        0 .  *   *  .
          0  3   5  8

        """
        points = [
            Point((0, 8)),
            Point((0, 9)),
            Point((3, 0)),
            Point((3, 8)),
            Point((3, 9)),
            Point((5, 0)),
            Point((5, 8)),
            Point((5, 9)),
            Point((8, 8)),
            Point((8, 9))
        ]

        network = LTNetwork()
        for point in points:
            network.add_point(point)

        network.add_link(points[0], points[3])
        network.add_link(points[1], points[4])
        network.add_link(points[2], points[3])
        network.add_link(points[3], points[4])
        network.add_link(points[3], points[6])
        network.add_link(points[4], points[7])
        network.add_link(points[5], points[6])
        network.add_link(points[6], points[7])
        network.add_link(points[6], points[8])
        network.add_link(points[7], points[9])

        self.assertEqual(10, len(network.links_list()))
        self.assertEqual(10, len(network.points))
        network.close_network()
        self.assertEqual(12, len(network.points))
        self.assertEqual(10 + 7, len(network.links_list()))

        table = Table(network)

        self.assertEqual(6, len(table.cells))
예제 #2
0
    def _align_nodes(self):
        """
        Makes the links horizontal/vertical by aligning nodes.
        """
        # make an histogram of the most common x and y values
        raw_x_values = defaultdict(int)
        raw_y_values = defaultdict(int)
        for point in self:
            raw_x_values[point.x] += 1
            raw_y_values[point.y] += 1

        # stores which values to replace (remove close values)
        replace_x = {}
        for x in raw_x_values:
            for x_prime in raw_x_values:
                if x != x_prime and abs(x - x_prime) < 5:
                    if raw_x_values[x_prime] > raw_x_values[x]:
                        replace_x[x] = x_prime
                    elif raw_x_values[x_prime] == raw_x_values[x]:
                        # in case they are the same, we must ensure
                        # we don't substitute both by each other.
                        if x > x_prime:
                            replace_x[x] = x_prime
                        else:
                            replace_x[x_prime] = x
                    else:
                        replace_x[x_prime] = x

        replace_y = {}
        for y in raw_y_values:
            for y_prime in raw_y_values:
                if y != y_prime and abs(y - y_prime) < 5:
                    if raw_y_values[y_prime] > raw_y_values[y]:
                        replace_y[y] = y_prime
                    elif raw_y_values[y_prime] == raw_y_values[y]:
                        # in case they are the same, we must ensure
                        # we don't substitute both by each other.
                        if y > y_prime:
                            replace_y[y] = y_prime
                        else:
                            replace_y[y_prime] = y
                    else:
                        replace_y[y_prime] = y

        for point in list(self)[:]:
            if point.x in replace_x:
                self.replace(point, Point((replace_x[point.x], point.y)))

        for point in list(self)[:]:
            if point.y in replace_y:
                self.replace(point, Point((point.x, replace_y[point.y])))
예제 #3
0
    def _fix_intersections(self):
        """
        Computes all intersections of links and creates points in the
        intersections, subdividing the links accordingly.
        """
        links = self.links_list()

        vertical_links = [link for link in links if link[0].x == link[1].x]
        horizontal_links = [link for link in links if link[0].y == link[1].y]
        assert(len(links) == len(vertical_links) + len(horizontal_links))

        v_links_to_subdivide = defaultdict(set)
        h_links_to_subdivide = defaultdict(set)
        for link in vertical_links:
            for link_prime in horizontal_links:
                if intersect(link[0], link[1], link_prime[0], link_prime[1]):
                    point = Point((link[0].x, link_prime[0].y))
                    v_links_to_subdivide[link].add(point)
                    h_links_to_subdivide[link_prime].add(point)

        for link in h_links_to_subdivide:
            points = sorted(h_links_to_subdivide[link], key=lambda p: p.x)
            self._subdivide(link[0], link[1], points)
        for link in v_links_to_subdivide:
            points = sorted(v_links_to_subdivide[link], key=lambda p: p.y)
            self._subdivide(link[0], link[1], points)
예제 #4
0
    def close_network(self):
        """
        Adds possible missing corners and border links to close the network.
        """
        rows_borders = sorted(list(set(point.y for point in self)))
        columns_borders = sorted(list(set(point.x for point in self)))

        x0 = columns_borders[0]
        y0 = rows_borders[0]
        x1 = columns_borders[-1]
        y1 = rows_borders[-1]

        # add possible missing corners
        for corner in ((x0, y0), (x0, y1), (x1, y1), (x1, y0)):
            self.add_point(Point(corner))

        # add possible missing bottom and top borders
        for row in (rows_borders[0], rows_borders[-1]):
            points = sorted([point for point in self if point.y == row],
                            key=lambda p: p.x)
            for i, point in enumerate(points):
                if i == 0:
                    continue
                self.add_link(points[i - 1], point)

        # add possible missing left and right borders
        for column in (columns_borders[0], columns_borders[-1]):
            points = sorted([point for point in self if point.x == column],
                            key=lambda p: p.y)
            for i, point in enumerate(points):
                if i == 0:
                    continue
                self.add_link(points[i - 1], point)
예제 #5
0
    def test_missing_intersection_points(self):
        points = [Point((0, 0)), Point((2, 0)), Point((1, -1)), Point((1, 1))]

        network = LTNetwork()
        for point in points:
            network.add_point(point)

        network.add_link(points[0], points[1])
        network.add_link(points[2], points[3])

        network._fix_intersections()

        self.assertTrue(Point((1, 0)) in network)
        self.assertEqual(network.links[Point((1, 0))], set(points))
예제 #6
0
    def test_missing_intersection_links(self):
        points = [
            Point((0, 0)),
            Point((2, 0)),
            Point((1, -1)),
            Point((1, 1)),
            Point((1, 0))
        ]

        network = LTNetwork()
        for point in points:
            network.add_point(point)

        network.add_link(points[0], points[1])
        network.add_link(points[2], points[3])

        network._fix_missing_links()

        expected = points[:-1]
        self.assertEqual(network.links[Point((1, 0))], set(expected))
예제 #7
0
    def test_a(self):
        network = UndirectedNetwork()

        points = {Point((0, 0)), Point((1, 0)), Point((0, 1)), Point((1, 1))}
        for point in points:
            network.add_point(point)

        network.add_link(Point((0, 0)), Point((0, 1)))
        network.add_link(Point((0, 0)), Point((1, 0)))
        network.add_link(Point((0, 1)), Point((1, 1)))
        network.add_link(Point((1, 0)), Point((1, 1)))

        self.assertEqual(4, len(network))
        self.assertEqual(4, len(network.links_list()))

        network.remove_point(Point((0, 0)))

        self.assertEqual(3, len(network))
        self.assertEqual(2, len(network.links_list()))

        network.remove_link(Point((0, 1)), Point((1, 1)))
        self.assertEqual(3, len(network))
        self.assertEqual(1, len(network.links_list()))
예제 #8
0
    def test_a(self):
        network = LTNetwork()

        points = {Point((0, 0)), Point((1, 0)), Point((0, 1)), Point((1, 1))}
        for point in points:
            network.add_point(point)

        network.add_link(Point((0, 0)), Point((0, 1)))
        network.add_link(Point((0, 0)), Point((1, 0)))
        network.add_link(Point((0, 1)), Point((1, 1)))
        network.add_link(Point((1, 0)), Point((1, 1)))

        table = Table(network)

        self.assertEqual('<table>\n<tr>\n<td></td>\n</tr>\n</table>',
                         table.as_html())
예제 #9
0
    def test_non_squared_cells(self):
        """
        Table with non-squared cells

        point = *
        link = - or |

        9 *--*---*
          |  |   |
        1 *--*---*
          |      |
        0 *------*
          0  1   9

        """
        network = LTNetwork()

        points = {
            Point((0, 0)),
            Point((9, 0)),
            Point((0, 9)),
            Point((9, 9)),
            Point((0, 1)),
            Point((9, 1)),
            Point((1, 1)),
            Point((1, 9))
        }

        for point in points:
            network.add_point(point)

        network.add_link(Point((0, 0)), Point((0, 1)))
        network.add_link(Point((0, 0)), Point((9, 0)))
        network.add_link(Point((0, 1)), Point((1, 1)))
        network.add_link(Point((0, 1)), Point((0, 9)))
        network.add_link(Point((0, 9)), Point((1, 9)))
        network.add_link(Point((9, 0)), Point((9, 1)))
        network.add_link(Point((1, 1)), Point((1, 9)))
        network.add_link(Point((1, 1)), Point((9, 1)))
        network.add_link(Point((1, 9)), Point((9, 9)))
        network.add_link(Point((9, 1)), Point((9, 9)))

        self.assertEqual(10, len(network.links_list()))
        network.add_collinear_links()
        self.assertEqual(10 + 4, len(network.links_list()))

        table = Table(network)

        self.assertEqual(3, len(table.cells))

        expected = '<table>\n' \
                   '<tr>\n<td></td>\n<td></td>\n</tr>\n' \
                   '<tr>\n<td colspan="2"></td>\n</tr>\n' \
                   '</table>'

        self.assertEqual(expected, table.as_html())