0

我现在正在编写一个程序,它将根据文件的大小在 PyGame 中显示矩形。这完全基于搜索树,根是文件夹,其子树是文件夹或文件,文件是叶子,因为它们没有任何子树。我希望我的程序根据文件相对于根文件夹的大小递归地用矩形填充正方形。IE:根文件夹的大小为 151,file1 的大小为 50,因此 file1 将占据整个正方形的大约 33%。如果需要,我还需要制作水平矩形(即如果没有任何空间可以垂直做,做一个水平矩形)。该函数需要使用一个矩形,这与我的对象 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)
4

1 回答 1

2

你没有问一个问题。无论如何,我会提供一些建议。

尽管您写了有用且内容丰富的评论,但诸如此类p.rect[3]的表达并不是特别清楚。如果你需要使用元组,那么在使用之前考虑解包: x, y, w, h = p.rect,然后使用高度h。更好的是,将 rect设为 namedtuple

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

是的,这很清楚。但最好将其表述为“用较小的矩形填充矩形......”。这为递归做好了准备。

还需要使我可以制作水平矩形

是的。编写一个谓词 ,def is_vertical(rect)当 时返回真height > width。那么你if关于如何分割一个矩形的陈述将是非常清楚的。

测试percentsize != 1似乎有点武断。以像素为单位做所有事情就足够了。

文件与子目录的空间

到目前为止,似乎缺少一个更大的设计问题。

矩形内的空间基本上去了两个不同的地方:

  1. 直系子女
  2. 子树

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

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

编辑:

我知道这听起来很无聊,但我还是会说出来。吃你的蔬菜!给我看看你的单元测试!请。

老实说,它们对你有好处。你抱怨“它应该很简单”,“它应该工作”,但“它不工作”。每当你遇到这种情况时,总是让它变得更简单,总是写下你能想到的最愚蠢的单元测试。您的主张是“这完全有效”,单元测试将证明或反驳这一点。

通常,编写测试的行为会让你相信“这很难测试”,这很好,甚至很棒。一旦测试为您提供了这种洞察力,您可能会被激励重构、更改 API,因此它非常容易测试,甚至可以轻松测试“奇怪”的案例。(或者你驱逐奇怪的案例,这样它们就不再是主线 API 的一部分,而是在其他地方处理。)

请向我们展示一个正在细分的矩形的单元测试。希望至少有一个或两个有效的测试,以及一个失败的测试。此外,显示一些数字输入和图形输出也没有什么坏处。

于 2019-03-30T19:34:10.893 回答