【问题标题】:designing class structures设计类结构
【发布时间】:2016-01-07 11:36:30
【问题描述】:

我是面向对象编程的完全初学者,我有一个奇怪的家庭作业。

基本上是关于圣诞老人,他如何在某个城市,挨家挨户地向人们赠送礼物。

我的作业的第一部分是这样的:

写一个类City

  • 构造函数没有参数。它的作用取决于您:它必须为其他方法准备地形。
  • 方法gift(x, y)记录坐标(x, y)的房子收到了礼物
  • 如果(x, y)的房子收到礼物,方法was_gifted(x, y)返回TrueFalse 否则。
  • 方法all_gifted()返回一组获得礼物的所有房屋的坐标。

到目前为止我有这个(不知道是否正确):

class City:
    def __init__(self):
        self.coordinates = set()

    def gift(self, x, y):
        self.coordinates.add((x, y))

    def was_gifted(self, x, y):
        if (x, y) in self.coordinates:
            return True

    def all_gifted(self):
        self.coordinates

我的作业的第二部分是这样的:

写一个类Santa

  • 构造函数有一个参数表示圣诞老人将在其中分发礼物的城市。一开始,他站在坐标(0, 0)
  • 方法move(c) 获取字符"v""^""<"">" 并将圣诞老人向下、向上、向左或向右移动一个字段。这次坐标y向上增加;即"^" 将其增加一,"v" 将其减少。
  • 方法moves(path) 获取一串这样的字符并相应地移动圣诞老人。
  • 方法gift() 向位于当前圣诞老人坐标的房子赠送礼物。请注意,gift 没有参数(self 除外)。

除此之外,编写 classRapidSanta,它派生自 Santa。它的构造函数得到cityspeedRapidSanta 与普通的不同之处在于它不会按单个字段移动,而是使用我们在构造函数中设置的speed

有人可以帮助我吗,因为我什至不知道如何以及从哪里开始。如果有人知道类似的“问题”,请在论坛上链接或发帖。我想掌握这一点,但坦率地说,我不是编程天才。感谢您提前提供的所有帮助。以下是我的作业必须通过的测试。

import unittest

class TestCity(unittest.TestCase):
    def test_City(self):
        a = City()
        b = City()

        self.assertSetEqual(a.all_gifted(), set())
        self.assertSetEqual(b.all_gifted(), set())
        self.assertFalse(a.is_gifted(1, 3))
        self.assertFalse(b.is_gifted(1, 3))

        a.gift(1, 3)
        self.assertSetEqual(a.all_gifted(), {(1, 3)})
        self.assertSetEqual(b.all_gifted(), set())
        self.assertTrue(a.is_gifted(1, 3))
        self.assertFalse(b.is_gifted(1, 3))

        a.gift(1, 3)
        self.assertSetEqual(a.all_gifted(), {(1, 3)})
        self.assertSetEqual(b.all_gifted(), set())
        self.assertTrue(a.is_gifted(1, 3))
        self.assertFalse(a.is_gifted(-2, -3))
        self.assertFalse(b.is_gifted(1, 3))

        a.gift(-2, -3)
        self.assertSetEqual(a.all_gifted(), {(1, 3), (-2, -3)})
        self.assertSetEqual(b.all_gifted(), set())
        self.assertTrue(a.is_gifted(1, 3))
        self.assertTrue(a.is_gifted(-2, -3))
        self.assertFalse(b.is_gifted(1, 3))

        b.gift(0, 0)
        self.assertSetEqual(a.all_gifted(), {(1, 3), (-2, -3)})
        self.assertSetEqual(b.all_gifted(), {(0, 0)})
        self.assertTrue(a.is_gifted(1, 3))
        self.assertTrue(a.is_gifted(-2, -3))
        self.assertFalse(b.is_gifted(1, 3))
        self.assertTrue(b.is_gifted(0, 0))
        self.assertFalse(a.is_gifted(0, 0))


class TestSanta(unittest.TestCase):
    def test_gift(self):
        m = City()
        n = City()
        b = Santa(m)
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0)})
        self.assertSetEqual(n.all_gifted(), set())

    def test_move(self):
        m = City()
        n = City()
        b = Santa(m)
        c = Santa(m)
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0)})
        self.assertSetEqual(n.all_gifted(), set())
        b.move("^")
        b.move("<")
        b.move("<")
        b.gift()
        b.move("v")
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1)})
        self.assertSetEqual(n.all_gifted(), set())
        c.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1)})
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1), (-2, 0)})
        b.move(">")
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1), (-2, 0)})
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1), (-2, 0), (-1, 0)})
        c.move("v")
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1), (-2, 0), (-1, 0)})
        c.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (-2, 1), (-2, 0), (-1, 0), (0, -1)})
        self.assertSetEqual(n.all_gifted(), set())


    def test_moves(self):
        m = City()
        b = Santa(m)
        b.moves("v<<^^^>>>>>")
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(3, 2)})

        cc = ""
        def p(c):
            nonlocal cc
            cc += c
        b.move = p
        b.moves("v<<^^^>>>>>")
        self.assertEqual(
            cc, "v<<^^^>>>>>",
            "Write a method `moves` so that it will use method `move`")

    def test_rapid_Santa(self):
        m = City()
        b = RapidSanta(m, 2)
        c = RapidSanta(m, 3)
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0)})
        b.move("^")
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (0, 2)})
        b.move("<")
        b.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (0, 2), (-2, 2)})
        c.move("<")
        c.gift()
        self.assertSetEqual(m.all_gifted(), {(0, 0), (0, 2), (-2, 2), (-3, 0)})

    def test_methods(self):
        self.assertIs(RapidSanta.moves, Santa.moves,
                      "RapidSanta has to inherit method moves")
        self.assertIs(RapidSanta.gift, Santa.gift,
                      "RapidSanta has to inherit method gift")

【问题讨论】:

  • 我觉得这个问题有点太笼统了,你能缩小范围吗?有什么问题,Python OOP 还是任务?就个人而言,我认为“它的作用取决于您:它必须为其他方法准备地形。”当您开始使用 OOP 时,这只是一个可怕的练习。任务本身应该更清楚。如果我是你,我会尝试将其分解为可以自行解决的子任务,并就这些问题提出几个更具体的问题,因为完整的练习相当冗长,很少有人会全部阅读。在继续编码之前画出一个基本的类图可能会有所帮助。

标签: python class constructor structure


【解决方案1】:

感谢您的回答。首先,我使用的是 python 3.4.3。

我这样更正了这个程序:

class City:

def __init__(self):
    self.coordinates = set()

def gift(self, x, y):
    self.coordinates.add((x, y))

def was_gifted(self, x, y):
    return (x, y) in self.coordinates # Does this return True or False?????

def all_gifted(self):
    return self.coordinates


class Santa(City):

def __init__(self, City):
    self.city = City
    self.coords = (0, 0)

def move(self, c):
    if c == "^":
        self.coords[1] -= 1
    elif c == "ˇ":
        self.coords[1] += 1
    elif c == "<":
        self.coords[0] -= 1
    elif c == ">":
        self.coords[0] += 1

def moves(self, path):
    for i in path:
        self.move(i)

def gift(self):
    self.city.gift

class FastSanta:
?????????????

这看起来好吗?我还没有通过测试运行程序。首先我要确定我写的内容是正确的。

我还想问你,你改变的那个 was_gifted(self, x, y) 函数是怎么回事?它会返回 True 还是 False 或其他什么?

而且我不知道如何处理 FastSanta 类。我尝试了几个选项,但似乎都没有问题。

如果我听起来像个菜鸟,我很抱歉,但在学校我没有得到任何关于事情如何运作的很好的解释。只是一些无用的理论。

【讨论】:

  • 仅供参考,这不是一个类似论坛的网站,上面有很多帖子。每个帖子都应该是对顶部原始问题的回答。如果您对特定答案有进一步的疑问,请在所述答案下留下评论。您想要进行的任何一般性陈述/澄清/补充/等,请编辑顶部的问题。
  • 对不起,我不知道。我刚加入这里,所以我不熟悉事情的运作方式。
【解决方案2】:

首先修复您的 City 类(注意:假设 python 2.x - 无需从 python 3.x 中的 object 继承)

class City(object):   
    def __init__(self):
        self.coordinates = set()

    def gift(self, x, y):
        self.coordinates.add((x, y))

    def was_gifted(self, x, y):
        return (x, y) in self.coordinates

    def all_gifted(self):
        return self.coordinates

就我而言,Santa 类的规范非常清楚。你的类需要cityCity 的实例)和coords 实例属性,第一个作为参数传递,第二个默认为(0, 0)

move(self, c) 方法将根据字符c 的值更新self.coords - 即假设(0, 0) 作为当前坐标,santa.move('^') 应该将self.coords 更新为(0, 1),- 和@987654336 @ 方法只需遍历 moves 并为 moves 中的每个字符调用 self.move(c)

gift(self) 方法仅使用当前坐标调用self.city.gift()(实际上是单行)。

wrt/ FastSanta,一旦你有 Santa 工作,它只是覆盖move() 的问题,以便坐标被多个单元更新......

我先给你一个 Santa 的初始化器,然后你应该能够尝试并实现其他方法 - 如果你有问题,可以发布一个更有针对性的问题:

class Santa(object):
    def __init__(self, city):
        self.city = city
        self.coords = (0, 0)

编辑:修复更新的 OP 代码:

class Santa(City):

为什么让它成为City 的子类???圣诞老人是一座城市???显然不是......你想要class Santa(object): (python 2.x) 或只是 class Santa: (python 3.x)

    def __init__(self, City):
        self.city = City

命名约定:对类使用CapNames,对实例使用all_lower。这里,第二个参数应该是Cityinstance,所以应该是:

    def __init__(self, city):
        self.city = city

(截图)

    def gift(self):
        self.city.gift

这将在self.city 上查找名称“gift”——这应该会产生一个method 对象——丢弃方法对象,并返回None。您在这里想要调用城市的gift 方法,将所需的xy 参数传递给它。

回答您的其他问题(在代码中或在下面的 cmets 中):

(x, y) in self.coordinates 是一个布尔表达式,在执行return 语句之前将被评估(替换为它的有效值)。所以 返回

在功能上与

完全相同
 if <some-boolean-expression>:
     return True
 else:
     return False

但以不那么冗长的方式。

wrt/ FastSanta 这实际上很简单,您只需将Santa.move() 中使用的默认“运动”值1 替换为传递给FastSanta 构造函数的值。

最后一点:为您提供的单元测试不仅是一种验证代码的方式,它们还为您提供了一些有关预期行为甚至实现的线索,甚至可以让您测试不同的实现(例如was_gifted()) 的详细和非详细实现,并自行找出它们是否产生相同的结果。

【讨论】:

  • 感谢您的回答。我正在使用 python 3.4.3 这看起来还可以吗?我还没有通过测试运行程序。首先,我想确定我所写的内容实际上是正确的。我还想问一下您更改的那个 was_gifted(self, x, y) 函数是什么?它会返回 True 或 False 还是其他什么?而且我不知道如何处理 FastSanta 类。我尝试了几个选项,但没有一个看起来不错。如果我听起来像个菜鸟,我很抱歉,但在学校里,我对事情的运作方式没有任何很好的解释。只是一些无用的理论。
  • cd 我编辑的答案。 wrt/ |=was_gifted(),你可以自己尝试一下,Python 作为一个交互式 shell 可以很容易地尝试代码。
  • 不幸的是,这些都不起作用。首先,我必须将 self.coords = (0, 0) 更正为 [0, 0] 因为您无法更改元组。我遇到的第二个问题是测试说圣诞老人班没有城市。我不知道为什么。 FastSanta 对我来说仍然是个谜。唯一有效的是 City 类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-27
  • 2013-11-21
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2016-04-22
  • 2014-12-06
相关资源
最近更新 更多