开发者

Why does the print statement at the bottom of my main method not print anything?

I'm working on the MIT open courseware for CS-600 and I can't figure out why the last print statement isn't printing anything. Here's the code I wrote:

#!/usr/bin/env python
# encoding: utf-8
# 6.00 Problem Set 9
#
# Name:
# Collaborators:
# Time:

from string import *

class Shape(object):
    def area(self):
        raise AttributeException("Subclasses should override this method.")

class Square(Shape):
    def __init__(self, h):
        """
        h: length of side of the square
        """
        self.side = float(h)
    def area(self):
        """
        Returns area of the square
        """
        return self.side**2
    def __str__(self):
        return 'Square with side ' + str(self.side)
    def __eq__(self, other):
        """
        Two squares are equal if they have the same dimension.
        other: object to check for equality
        """
        return type(other) =开发者_如何学C= Square and self.side == other.side

class Circle(Shape):
    def __init__(self, radius):
        """
        radius: radius of the circle
        """
        self.radius = float(radius)
    def area(self):
        """
        Returns approximate area of the circle
        """
        return 3.14159*(self.radius**2)
    def __str__(self):
        return 'Circle with radius ' + str(self.radius)
    def __eq__(self, other):
        """
        Two circles are equal if they have the same radius.
        other: object to check for equality
        """
        return type(other) == Circle and self.radius == other.radius

#
# Problem 1: Create the Triangle class
#
## TO DO: Implement the `Triangle` class, which also extends `Shape`.

class Triangle(Shape):
    def __init__(self, base, height):
        self.base = float(base)
        self.height = float(height)
    def area(self):
        return self.base*self.height/2
    def __str__(self):
        return 'Triangle with base ' + str(self.base) + 'and height ' + str(self.height)
    def __eq__(self, other):
        return type(other) == Triangle and self.base == other.base and self.height == other.height
#
# Problem 2: Create the ShapeSet class
#
## TO DO: Fill in the following code skeleton according to the
##    specifications.

class ShapeSet(object):
    def __init__(self):
        """
        Initialize any needed variables
        """
        self.allCircles = []
        self.allSquares = []
        self.allTriangles = []
        self.allShapes = self.allCircles + self.allSquares + self.allTriangles
        self.place = None 
    def addShape(self, sh):
        """
        Add shape sh to the set; no two shapes in the set may be
        identical
        sh: shape to be added
        """
        if not isinstance(sh, Shape): raise TypeError('not a shape')
        if isinstance(sh, Square):
            for sq in self.allSquares:
                if sh == sq:
                    raise ValueError('shape already in the set')
            self.allSquares.append(sh)
        if isinstance(sh, Triangle):
            for tri in self.allTriangles:
                if sh == tri:
                    raise ValueError('shape already in the set')
            self.allTriangles.append(sh)
        if isinstance(sh, Circle):
            for circ in self.allCircles:
                if sh == circ:
                    raise ValueError('shape already in the set')
            self.allCircles.append(sh)
    def __iter__(self):
        """
        Return an iterator that allows you to iterate over the set of
        shapes, one shape at a time
        """
        self.place = 0
        return self
    def next(self):
        if self.place >= len(self.allShapes):
            raise StopIteration
        self.place += 1
        return self.allShapes[self.place - 1]

    def __str__(self):
        """
        Return the string representation for a set, which consists of
        the string representation of each shape, categorized by type
        (circles, then squares, then triangles)
        """
        shapeList = ""
        for item in self.allShapes:
            shapeList += item.get__str__ + "br/"
        return shapeList

#
# Problem 3: Find the largest shapes in a ShapeSet
#
def findLargest(shapes):
    """
    Returns a tuple containing the elements of ShapeSet with the
       largest area.
    shapes: ShapeSet
    """
    ## TO DO

#
# Problem 4: Read shapes from a file into a ShapeSet
#
def readShapesFromFile(filename):
    """
    Retrieves shape information from the given file.
    Creates and returns a ShapeSet with the shapes found.
    filename: string
    """
    ## TO DO

def main():
    sq1 = Square(4.0)
    sq2 = Square(5.0)
    sq3 = Square(3.0)
    circ1 = Circle(3.0)
    circ2 = Circle(3.2)
    tri1 = Triangle(3.0, 4.0)
    tri2 = Triangle(4.0, 3.0)
    tri3 = Triangle(1.0, 1.0)
    thisSet = ShapeSet()
    thisSet.addShape(sq1)
    thisSet.addShape(sq2)
    thisSet.addShape(sq3)
    thisSet.addShape(circ1)
    thisSet.addShape(circ2)
    thisSet.addShape(tri1)
    thisSet.addShape(tri2)
    thisSet.addShape(tri3)
    print thisSet



if __name__ == '__main__':
    main()


This line:

self.allShapes = self.allCircles + self.allSquares + self.allTriangles

doesn't do what you think it does. It sets allShapes to an empty list, and then as you add shapes later, nothing updates allShapes.

Then your __str__ function just loops over allShapes, which is still empty, so your __str__ returns an empty string.


This line makes allShapes an empty list:

self.allShapes = self.allCircles + self.allSquares + self.allTriangles

If you modify allCircles, that doesn't affect allShapes. I would personally eliminate allShapes, and in the str method, add them at the last possible second:

for item in self.allCircles + self.allSquares + self.allTriangles:


The problem is here:

self.allShapes = self.allCircles + self.allSquares + self.allTriangles

When you concatenate lists like this, the result is a copy of the component lists. So when those lists are changed later, the concatenated list isn't changed. In this case, self.allCircles, etc. are all empty. So self.allShapes is an empty list too; the for loop in ShapeSet.__str__ doesn't append anything to ShapeList, and so the result is an empty string.

One simple way to fix this would be to make allShapes a method that you call, and that returns a new concatenation of self.allCircles... etc. each time it's called. That way, allShapes is always up-to-date.


If this is your actual code, then it must be because of

item.get__str__

which should raise an exception.

Edit: as others have noted, this isn't the actual problem, but I leave this here as a hint for further progress. Mind you, it's considered bad style ("unpythonic") to call x.__str__() directly, as you probably intended. Call str(x) instead, even in the implementation of __str__.


You assign allShapes to be the value of self.allCircles + self.allSquares + self.allTriangles at the start in your init method (when the other lists are empty).

It's value is then never changed, so it remains empty.

You need this in addShape:

self.allShapes.append(sh)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜