2013-03-08 54 views
0

我今天在课堂上有一个测验,我失败了,它的测验是低于。 有人可以帮我解释一下。蟒蛇 - 努力设计这

  1. 添加的方法open()到链接,将链接断开它只是在它的左边“,从而打开了项链,同时保持链完整的权利。例如,如果在link1处抓住项链,则拨打link1.open()将断开link3link1的连接,但将一个链条从link1连接到link3

这是我目前有:

class Diamond(object): 
    def __str__(self): 
     return "Diamond" 

class Ruby(object): 
    def __str__(self): 
     return "Ruby" 

class Visitor: 
    def __str__(self): 
     return self.__class__.__name__ 

class Link(object): 
    def __init__(self, index, jewel = None): 
     self.jewel = jewel 
     self.index = index 

    def connectTo(self, link): 
     self.nextLink = link 

    def __next__(self): 
     return self.nextLink or None 

    def attach(self, jewel): 
     if not self.jewel: 
      self.jewel = jewel 

    def detatch(self): 
     stone = self.jewel 
     self.jewel = None 
     return stone 

    def open(self): 
     pass 

    def __str__(self): 
     return "link%d" % (self.index) 

class Necklace(object): 
    def __init__(self, base): 
     self.base = base 

    def describe(self): 
     link = self.base 
     while True: 
      print link, "with", link.jewel, "attatched to", link.nextLink, "with", link.nextLink.jewel 
      link = link.nextLink 
      if link == self.base: 
       break 

    def getJewel(self): 
     link = self.base 
     while True: 
      link = link 
      if isinstance(link.jewel, Diamond): 
       print "a", link.detatch() 
       break 
      link = link.nextLink 
      if link == self.base: 
       print "nothing..." 
       break 

    def acceptVisitor(self, visitor): 
     visitor.visit(self) 

class DiamondThief(object, Visitor): 
    def __init__(self, base): 
     self.base = base 
     self.jewel = self.base.jewel 

    def visit(self, necklace): 
     necklace.getJewel() 

    def searchForDiamond(self): 
     self.visit(myNecklace) 

link1 = Link(1, Ruby()) 
link2 = Link(2, Diamond()) 
link3 = Link(3, Ruby()) 
link1.connectTo(link2) 
link2.connectTo(link3) 
link3.connectTo(link1) 
myNecklace = Necklace(link1) 
myNecklace.describe() 

print "Uh on here comes a thief..." 
thief = DiamondThief(link1) 
print "Oh no he took " 
thief.searchForDiamond() 
myNecklace.describe() 
+0

你说的意思是“这个给我解释”? – pradyunsg 2013-03-08 07:49:25

+0

我不知道如何做到这一点,就像我得到了什么被问到,但我不能为我的生活设计它,而我现在正在尝试自己做,以了解它,但我根本找不到它。像什么类和功能看起来像 – user1758231 2013-03-08 07:51:44

+0

@ user1758231在目前的形式,你的问题太广泛。我怀疑如果我们其中一个公布此解决方案,您不会学习设计类似的问题。您至少可以通过编写类的签名和它们之间的交互来了解您的问题。 – sidi 2013-03-08 07:58:01

回答

1

让我们来看看我们需要在每个类什么功能呢?

  1. Link
    • 变量
      • name(仅仅是可能)
      • linked_tonextlink
      • jewel
    • 方法
      • connectTo(self,link)
      • attach(self,jewel)
      • detach(self)
      • open(self)
      • get_next(self)
  2. Necklace(而不是在下面的代码,使其对自己)
    • 变量
      • connections
    • 方法
      • __next__(self)next_link(self)
  3. DiamondThief
    • 变量
      • link
      • diamond
    • 方法
      • getDiamond(self)
      • search(self)
  4. JewelsDiamondRuby
    • 没有变量或方法

看到这个代码,我也加入了DiamondThief类...

class Necklace: 
    '''My version of necklace''' 
    def __init__(self, link): 
     self.first = link 
     self.current_link = link 
    def next(self): 
     self.current_link = self.current_link.get_next() 
     if self.current_link == self.first: 
      raise StopIteration 
     return self.current_link 
    def __iter__(self): 
     return self 

class Link(object): 
    """A link of a necklace""" 
    def __init__(self, name, jewel=None): 
     self.name = name 
     self.linkedTo = None 
     self.jewel = None 
     if jewel != None: 
      self.attach(jewel) 

    def connectTo(self, link): 
     '''Connect to link''' 
     if isinstance(link,Link): 
      self.linkedTo = link 
     else: 
      raise TypeError 

    def attach(self, jewel): 
     '''Attach jewel''' 
     if self.jewel == None: 
      self.jewel = jewel 
     else: 
      msg = 'There is already a %s attached' % jewel.__class__.__name__ 
      raise AttributeError(msg) 

    def detach(self): 
     '''Detach jewel''' 
     if self.jewel != None: # 
      je = self.jewel 
      self.jewel = None 
      return j 
     else: 
      msg = 'There is nothing to detach' 
      raise AttributeError(msg) 

    def __str__(self): 
     if self.linkedTo != None: 
      return "%s(%s) => %s" % \ 
        (self.name,self.jewel.__class__.__name__, self.linkedTo.name) 
     else: 
      return "%s(%s) => %s" % \ 
        (self.name,self.jewel.__class__.__name__,None) 

    def get_next(self): 
     '''Get the next chain''' 
     return self.linkedTo 

class Diamond(object): 
    pass 

class Ruby(object): 
    pass 

class DiamondThief: 
    def __init__(self, necklace): 
     self.necklace = necklace 
     self.diamond = None 

    def search(self): 
     '''Go link by link to find the Diamond''' 
     if self.diamond != None: 
      print 'Have a diamond already' 
      return 
     first = self.necklace.first 
     link = first 
     for link in self.necklace: # loop till 
      if isinstance(link.jewel, Diamond): # diamond is found 
       self.diamond = link.jewel 
       link.jewel = None 
       print 'Found Diamond' 
       break 

    def getDiamond(self): 
     if self.diamond != None: 
      return self.diamond 
     else: 
      return None 

def main(): 
    # create 
    l1 = Link('1',Diamond()) 
    l2 = Link('2',Ruby()) 
    l3 = Link('3', Ruby()) 
    l1.connectTo(l2) 
    l2.connectTo(l3) 
    l3.connectTo(l1) 
    i = DiamondThief() 
    try: 
     l2.attach(Ruby()) 
    except AttributeError,e: 
     print e 
    print l1 
    print l2 
    print l3 
    print '-'*16 
    i.search() 
    print l1 
    print l2 
    print l3 
main() 
+0

这是伟大的,但我们假设使用访客模式在小偷类多数民众赞成我想要现在做 – user1758231 2013-03-08 09:22:09

+0

为什么你想要访客? – pradyunsg 2013-03-08 10:11:17

0

第1部分简单地询问您要使用的Link类描述的方法建立一个指定的项链:

link1 = Link() 
link1.attach(Ruby()) 
link2 = Link() 
link2.attach(Diamond()) 
link3 = Link() 
link3.attach(Ruby()) 

link1.connectTo(link2) 
link2.connectTo(link3) 
link3.connectTo(link1) 

myNecklace = link1 

第2部分需要连接和DiamondThief类的实现。

下面是我如何实现Link,作为一个双向链表。您并不需要第二个链接来实现我们在这部分中需要做的基本方法,但如果我们引用了左侧和右侧的相邻链接,则在第3部分中添加open会更容易。

class Link(object): 
    def __init__(self): 
     """Initialize an empty link.""" 
     self.left = None 
     self.right = None 
     self.jewel = None 

    def connectTo(self, other): 
     """Connect another link to the right of this one.""" 
     if self.right or other.left: 
      raise ValueError("Links already have connections") 
     self.right = other 
     other.left = self 

    def attach(self, jewel): 
     """Add a jewel to this link.""" 
     if self.jewel: 
      raise ValueError("Link already has a jewel attached") 
     self.jewel = jewel 

    def detatch(self): 
     """Remove and return the jewel attached to this link." 
     jewel = self.jewel 
     self.jewel = None 
     return jewel 

这是我对DiamondThief访问者的实现。它的主要方法是visit递归访问后续Link实例,直到找到钻石或它循环(或从开放项链的末端流失)。你可以用while循环而不是递归来做同样的事情,但这看起来更简单。请注意,递归调用中的or表达式意味着如果first为无(默认情况下为),则link将作为first传递。

class DiamondThief(object): 
    def __init__(self): 
     """Initialize a DiamondThief""" 
     self.diamond = None 

    def visit(self, link, first=None): 
     """Recursively visit a necklace, searching for a Diamond to steal.""" 
     if link == first: # looped 
      return 
     if isinstance(link.jewel, Diamond): # diamond found 
      self.diamond = link.detatch() 
      return 
     if link.right is not None: # not at an open end 
      self.visit(link.right, first or link) 

    def getDiamond(self): 
     return self.diamond 

第3部分要求您的open方法添加到Link类。由于Link是双重链接的,因此很容易将列表分解到当前位置的左侧。如果您将它作为一个单独链接列表实施,您必须扫描整个项链(从每个链接到其右边的邻居),直到找到与第一个链接相关的项链为止。在没有形成循环的项链上完全不起作用。

总之,这里的简单实现:

def open(self): 
    """Disconnect this link from it's left neighbor.""" 
    if self.left is None: 
     raise ValueError("Link is not connected on the left") 
    self.left.right = None 
    self.left = None