如何将矩形递归包装成正方形

时间:2019-03-30 19:15:16

标签: python python-3.x recursion

我正在编写一个程序,该程序将根据文件的大小在PyGame中显示矩形。这完全基于搜索树,根是文件夹,其子树是文件夹或文件,文件是叶子,因为它们没有任何子树。我希望我的程序根据与根文件夹有关的文件大小,用矩形递归地填充正方形。即:根文件夹的大小为151,file1的大小为50,因此file1约占整个正方形的33%。我还需要使它能够在需要时制作水平矩形(即,如果没有足够的空间垂直放置,则可以制作水平矩形)。该函数需要一个rect使用,这与我的对象Filetree中定义的self.rect不同(如下所述)

所以我的程序基于一个名为FileTree的对象,该对象具有self.rect,即矩形大小(x,y为起点,宽度,高度,宽度和高度)。它具有随机分配的颜色,并且具有子树。基本上我只是不知道程序在哪里出错,因为当我调用该函数时,我得到了一堆具有正确比率的矩形,它们只是一个在另一个之上,因此无法正确地隔开它。我想知道我使用的递归公式是否存在问题,因为调试它会给我多个具有相同起点的矩形,前提是它们应该彼此相邻(即一个矩形从另一个矩形开始)结束)

 x, y, width, height = rect
#rect is a tuple (x, y, width, height)

        if self.is_empty():
            self.rect = (0, 0, 0, 0)

        if self._parent_tree is None:
            self.rect = rect

        else:
            p = self
            while p._parent_tree is not None:
                p = p._parent_tree
            percentsize = self.data_size / p.data_size
            newsize = math.floor(p.data_size * percentsize)
            if p.rect[2] >= newsize + x > y + newsize and percentsize != 1:
                self.rect = (x, y, width, newsize)
            elif p.rect[3] >= newsize + y >= newsize + x and percentsize != 1:
                self.rect = (x, y, newsize, height)
            elif percentsize == 1:
                self.rect = rect
            else:
                if newsize + width > height + newsize:
                    self.rect = (x, y, width, p.rect[3])
                elif newsize + height >= newsize + width:
                    self.rect = (x, y, p.rect[2], height)

        for sub in self._subtrees:
            sub.update_rectangles(self.rect)

1 个答案:

答案 0 :(得分:2)

您没有提出问题。无论如何,我都会提供一些建议。

诸如p.rect[3]之类的表达不是特别清楚, 尽管您撰写了有益而翔实的评论。 如果需要使用元组,请在使用前考虑拆包: x, y, w, h = p.rect,然后使用高度h。 更好的是,将rect设置为namedtuple

  

我希望我的程序以矩形递归地填充正方形...

是的,这很清楚。 但最好将其表述为“用较小的矩形填充矩形 ...”。 这样可以很好地进行递归。

  

还需要使其能够制作水平矩形

是的。 写一个谓词def is_vertical(rect), 当height > width时返回true。 这样,您关于如何分割矩形的if语句就很清楚了。

percentsize != 1测试似乎有些武断。 以像素为单位的所有操作都足够。

文件空间与子目录

到目前为止,还有一个更大的设计问题似乎没有解决。

矩形内的空间基本上会到达两个不同的位置:

  1. 直接的孩子
  2. 子树

您可能至少要为它们分配不同的颜色。

对于空间分配,您可能希望一次处理所有直属子项的和, 在分割出每个分割点之前,先找到一个可以容纳所有分割点的分割点, 然后在子树上递归。

编辑:

我知道这听起来很无聊,但我还是会说。 吃你的蔬菜! 告诉我你的单元测试! 拜托。

老实说,它们对您有好处。 您在抱怨“它应该很简单”,“它应该可以正常工作”, 但是“它不起作用”。 每当遇到这种情况 总是使它更简单, 总是写下您能想到的最愚蠢的单元测试。 您的主张是“这完全可行”,单元测试将证明或反对这一点。

通常编写测试的行为会让您相信“这很难测试”,这很好,甚至很棒。 一旦测试为您提供了这种见识,您可能会被激励去重构, 更改API,因此非常容易测试, 即使测试“怪异”案例也很容易。 (或者您驱逐这些怪异的案例,使它们不再是主线API的一部分,而在其他地方处理。)

请给我们展示一个细分的矩形的单元测试。 希望至少有一个或两个有效的测试,以及一个失败的测试。 另外,显示一些数字输入和图形输出也无妨。