1

I really don't understand classes very much and any help would be great.

Rectangle class should have the following private data attributes:

  • __length
  • __width

The Rectangle class should have an __init__ method that creates these attributes and initializes them to 1. It should also have the following methods:

  • set_length – this method assigns a value to the __length field

  • set_width – this method assigns a value to the __width field

  • get_length – this method returns the value of the __length field

  • get_width – this method returns the value of the __width field

  • get_area – this method returns the area of Rectangle

  • __str__ – this method returns the object’s state

class Rectangle:

  def __init__(self):
      self.set_length = 1
      self.set_width = 1
      self.get_length = 1
      self.get_width = 1
      self.get_area = 1

def get_area(self):
    self.get_area = self.get_width * self.get_length
    return self.get_area


def main():

  my_rect = Rectangle()

  my_rect.set_length(4)
  my_rect.set_width(2)

  print('The length is',my_rect.get_length())
  print('The width is', my_rect.get_width())

  print('The area is',my_rect.get_area())
  print(my_rect)

  input('press enter to continue')
Kevin
  • 74,910
  • 12
  • 133
  • 166
Rsherrill
  • 129
  • 3
  • 4
  • 12
  • 1
    And your question is ... ? – Fred Larson Dec 05 '14 at 19:39
  • 4
    Whoever is teaching this class obviously is not very good at Python, and is going to teach you how to write Java code instead, which Python is very bad at. I'd suggest finding a better class. Or, if you need this for a requirement, finding an online tutorial or class that you can actually learn from, ahead of what the teacher is teaching, so you can just do the assignments without expecting to learn anything from them. – abarnert Dec 05 '14 at 20:05
  • To elaborate a little on @abarnert's completely correct comment: Python is not Java, and your instructor doesn't seem to understand that, and is teaching you bad Python practices as a result. Especially regarding `__` "dunder" variables, which have special meanings in Python that don't apply to other languages. See [this](http://stackoverflow.com/q/7456807/2069350) and [this](http://stackoverflow.com/q/70528/2069350) for more detail on dunder variables and "privacy" in Python. – Henry Keiter Dec 05 '14 at 21:22

4 Answers4

4

Python does not restrict the access to private data attributes, so you seldom get yourself writing "getters" and "setters" like in more restrictive languages (we are all consenting adults).

Except when it is something for internal use (an implementation detail that you may change in the future) you just expose the property to the world - so a more idiomatic Rectangle would be just this:

class Rectangle(object):
    def __init__(self, width=1, height=1):
        self.width = width
        self.height = height
    @property
    def area(self):
        return self.width * self.height

Then:

>>> r = Rectangle(5, 10)
>>> r.area
50
>>> r.width = 100
>>> r.area
1000

Of course you can write the Rectancle class using getters and setters, but you only do that when you want to validate or transform the input - then you probably want to learn more about the @property decorator.

Community
  • 1
  • 1
Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153
2

You've got a few issues with your class. See the below comments

class Rectangle:
    # Init function
    def __init__(self):
        # The only members are length and width
        self.length = 1
        self.width = 1

    # Setters
    def set_width(self, width):
        self.width = width

    def set_length(self, length):
        self.length = length

    # Getters
    def get_width(self):
        return self.width

    def get_length(self):
        return self.length

    def get_area(self):
        return self.length * self.width

    # String representation
    def __str__(self):
        return 'length = {}, width = {}'.format(self.length, self.width)

Testing the class

>>> a = Rectangle()
>>> a.set_width(3)
>>> a.set_length(5)
>>> a.get_width()
3
>>> a.get_length()
5
>>> a.get_area()
15
>>> print(a)
length = 5, width = 3

As others have noted, setter's and getter's are superfluous in Python, as all member variables are public. I understand that these methods are required for your assignment, but in the future, know that you can save yourself the trouble and just directly access the members

>>> a.length       # Instead of the getter
5
>>> a.length = 2   # Instead of the setter
>>> a.length
2
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
2

First, this assignment is a very bad idea. In Python, you almost never want "private" attributes and getter and setter functions, and whoever's teaching you to do this is leading you astray.

But, if you just want to pass the assignment instead of learning how to write decent Python code, here's how you do it.

First, to create an attribute named __length, you just assign to it, the same as any other attribute:

def __init__(self):
    self.__length = 1

Now, to write getters and setters for that attribute, do the same thing:

def get_length(self):
    return self.__length

def set_length(self, length):
    self.__length = length

Now, get_area is a bit trickier, because you don't have an __area to get. (This is a stupid idea, because it looks like a getter function even though it isn't…) But you know how to figure out the area of a rectangle: it's just the length times the width, right?

def get_area(self):
    return self.__length * self.__width

The __str__ method is the only good idea in the whole assignment—although it's probably a bad idea to write a __str__ without a __repr__ for a class like this. Anyway, both of these are methods that just return a string with some useful representation of your objects. The str should be something friendly to an end-user, while the repr should be something useful to the programmer (you, or someone using your class). For example:

def __str__(self):
    return '{} x {} rectangle'.format(self.__length, self.__width)

def __repr__(self):
    return '{}({}, {})'.format(type(self).__name__, self.__length, self.__width)
abarnert
  • 354,177
  • 51
  • 601
  • 671
  • I agree, the premise of this assignment is strange. I understand they're trying to get across the idea of members and methods, but they make this class smell like `C++`. Sometimes these academic problems come with the strangest of requirements under the guise of learning. – Cory Kramer Dec 05 '14 at 20:10
  • 1
    @Cyber: Usually when you see assignments like this, it's not because there's a point they're trying to make. (Unless that point is "damn administrators making me teach in Python after I just spent 3 years learning how to teach Java… well, I'll just mechanically translate all my course materials from Java to Python and if they complain I'm going to have to burn down the building…") If you really wanted to teach about private variables and getters and setters in Python, you'd teach `@property` first (and give an example of a computed getter that wasn't originally computed). – abarnert Dec 05 '14 at 20:21
  • 1
    *"I'll just mechanically translate all my course materials from Java to Python"* I wish I could say I didn't see this in industry too :/ The amount of Fortran code that was "translated" to C++ that I have to deal with is painful. You can have variable names longer than 8 characters, use actual classes, utilize the STL, etc. Some people that are otherwise very good programmers do not understand that syntax translation does not equal idiom translation. – Cory Kramer Dec 05 '14 at 20:42
  • @Cyber: Yes, Fortran code in C++ is sometimes even more annoying than Java code in Python, because you end up with segfaults and leaks all over the place that would be trivial to eliminate if you just wrote idiomatic C++ instead, not to mention performance problems by doing things at runtime that could easily be done at compile time, etc. I'm happy I haven't had to deal with C++ numeric code in a long time, and sorry that you have… – abarnert Dec 05 '14 at 21:09
1

You would do absolutely fine without the set_'s and get_'s functions, and you should perhaps be more careful when using mangled variables (such as __variablename), but here's a less-than-brilliant code that fulfills your requirements. Hopefully that helps.

PS: print statements in Python 2.7 format.

class Rectangle():

    def __init__(self):
        self.__length = 1.0
        self.__width = 1.0
        
    def __str__(self):
        return "This is class Rectangle"
      
    def set_length(self,len=1.0):     #len=1 --> default value
        self.__length = len
    
    def set_width(self,wid=1.0):      #wid=1 --> default value
        self.__width = wid
       
    def get_length(self):
        return self.__length
        
    def get_width(self):
        return self.__width

    def get_area(self):
        return self.get_width() * self.get_length()


if __name__ == '__main__':

    my_rect = Rectangle()

    my_rect.set_length(4.0)
    my_rect.set_width(2.0)

    print "The length is ", my_rect.get_length()
    print "The width is  ", my_rect.get_width()
    print "The area is   ", my_rect.get_area()
    print my_rect
    
    raw_input('Press enter to continue')