Why doesn't the print expression at the bottom of my main method print anything?

I am working on MIT's open source training materials for CS-600, and I cannot understand why the last print expression does not print anything. Here is 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) == 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() 
+4
source share
5 answers

This line makes allShapes an empty list:

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

If you modify allCircles, this does not affect allShapes. I personally destroy allShapes, and in the str method add them at the last possible second:

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

This line:

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

Don't do what you think. It sets allShapes to an empty list, and then when you add shapes later, allShapes is not updated.

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

+6
source

The problem is here:

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

When combining lists like this, the result is a copy of the lists of components. Therefore, when these lists are changed later, the concatenated list will not be changed. In this case, self.allCircles , etc. All are empty. So self.allShapes also an empty list; the for loop in ShapeSet.__str__ does not add anything to the ShapeList , so the result is an empty string.

One easy way to fix this would be to make the allShapes method that you call, and which returns a new concatenation of self.allCircles ... etc. every time he calls. Thus, allShapes always updated.

+1
source

If this is your actual code, then this should be due to

 item.get__str__ 

which should throw an exception.

Edit : as others have noted, this is not a real problem, but I leave it here as a hint for further progress. Keep in mind that he considered bad style ("unpythonic") to be a direct call to x.__str__() , as you probably planned. Call str(x) instead, even in the __str__ implementation.

0
source

You set allShapes to self.allCircles + self.allSquares + self.allTriangles at the beginning in the init method (when the rest of the lists are empty).

This value never changes, therefore it remains empty.

This is needed in addShape:

 self.allShapes.append(sh) 
0
source

All Articles