##### Calculating surface area - - OOP or functional? Derek Banas Udemy course
 Calculating surface area - - OOP or functional? Derek Banas Udemy course Drone4four Splitter Posts: 167 Threads: 69 Joined: Nov 2017 Reputation: Mar-12-2021, 09:57 PM (This post was last modified: Mar-14-2021, 03:40 AM by Drone4four. Edit Reason: Correct subject ) I’m taking a Udemy course by Derek Banas titled, Python Programming Bootcamp. Derek demonstrates the basics of OOP using a script which calculates the area using a height and width value collected from the user (user input). I’ve ventured to re-write Derek’s script using functions and variables instead of methods and attributes. Derek’s script is 52 lines long. Mine is 13 lines long. (Both scripts can be found below.) My first question for all of you: Is there really a benefit to OOP with all the added complexity required when the same outcome can be achieved with 75% less code? Here is Derek’s original script: ```class Square: def __init__(self, height="0", width="0"): self.height = height self.width = width # This is the getter # @property defines that any call to height runs the code in the height method below it @property def height(self): print("Retrieving the height") # Put a __ before this private field return self.__height # This is the setter @height.setter def height(self, value): # We protect the height from receiving a bad value if value.isdigit(): # Put a __ before this private field self.__height = value else: print("Please only enter numbers for height") # This is the getter @property def width(self): print("Retrieving the width") return self.__width # This is the setter @width.setter def width(self, value): if value.isdigit(): self.__width = value else: print("Please only enter numbers for width") def get_area(self): return int(self.__width) * int(self.__height) def main(): square = Square() height = input("Enter height : ") width = input("Enter width : ") square.height = height square.width = width print("Height :", square.height) print("Width :", square.width) print("The Area is :", square.get_area()) main()```Here is my script: ```width = input("Enter your width: ") height = input("Enter your height: ") def calculate_area(width, height): try: return int(width) * int(height) except ValueError: print("Please enter a digit, not a character") width = input("Enter your width: ") height = input("Enter your height: ") calculate_area(width, height) print(calculate_area(width, height))```My second question for all of you: Since the purpose of this script is so basic, it was relatively easy for me to emulate the outcome. But how might you people re-write my script or even Derek’s script to optimize and improve them? Reply Posts: 3,081 Threads: 44 Joined: Jan 2018 Reputation: Mar-12-2021, 11:12 PM (This post was last modified: Mar-12-2021, 11:13 PM by Gribouillis.) The problem is not with OOP, the problem is with the way this course uses OOP. Normally in Python we don't write getter and setter methods like this. Also using private attributes such as `__height` is most of the time a bad idea. Above all the fact that the getters and setters print something when they receive a bad value is a pure nonsense. These functions should raise an exception in this case. I would learn from another course if I were in your position. buran likes this post Reply bowlofred Da Bishop Posts: 1,190 Threads: 3 Joined: Mar 2020 Reputation: Mar-12-2021, 11:38 PM Depends on what you're optimizing for. If you have one task that will never be repeated or extended, and it's not huge, then creating a complex class isn't very useful. The code you've shown appears to be written as an example to show the basics of OOP, not to solve a particular problem. As the task grows larger, with more components (and especially more authors), the benefits of cleaner separation between the parts of the code become greater and OOP practices can help with that. That being said, the code looks horrible to me as an example of python OOP. It's using both regular and hidden attributes. Yes, they're possible to do, but I wouldn't recommend a python class to look like that, especially as an example for someone looking to learn it. Your script is relatively fine for a quick script, but my concerns would be:You're performing input both inside and outside the function. I'd rather do it in one place. You're handling errors by recursion rather than a simple loop. Unlikely to be a huge problem, but not a good habit. Recursion has memory and depth limits that are smaller than some other cases. Don't invoke it arbitrarily. This case could be replaced with a loop and remove the recursion. Minor (and done in the example as well), but you're truncating inputs to int(). I see no reason to do so. This could handle float() input just as easily. To "optimize" or "improve" it requires some metric to optimize against. Do you want it to be able to run faster? Have more understandable code? Be able to use as an example of OOP programming? Reply Drone4four Splitter Posts: 167 Threads: 69 Joined: Nov 2017 Reputation: Mar-12-2021, 11:48 PM (Mar-12-2021, 11:38 PM)bowlofred Wrote: Your script is relatively fine for a quick script, but my concerns would be:You're performing input both inside and outside the function. I'd rather do it in one place. You're handling errors by recursion rather than a simple loop. Unlikely to be a huge problem, but not a good habit. Recursion has memory and depth limits that are smaller than some other cases. Don't invoke it arbitrarily. This case could be replaced with a loop and remove the recursion. Minor (and done in the example as well), but you're truncating inputs to int(). I see no reason to do so. This could handle float() input just as easily. Thank you. I appreciate your suggestions here. Quote:To "optimize" or "improve" it requires some metric to optimize against. Do you want it to be able to run faster? Have more understandable code? Be able to use as an example of OOP programming? With my word choice of 'optimize', I didn't mean tweak to improve run-time performance. I meant make my code more understandable and readable. You've already provided three suggestions in this regard. Thank you for this. I will more carefully use the word 'optimize' in the context of programming especially on this forum but elsewhere too. Reply deanhystad So-and-so of the Yard Posts: 2,136 Threads: 11 Joined: Feb 2020 Reputation: Mar-12-2021, 11:54 PM (This post was last modified: Mar-12-2021, 11:54 PM by deanhystad.) This is not OOP. This is using class for something that is not a class. OOP is a design method, not a coding method. You can do OOP without any classes, and you can do procedural programming with classes. Using classes does not equate to OOP. The getter and setter methods should do something. At least one of them should do something with the data, otherwise it a bunch of confusing code that does nothing useful. This example "checks" for "bad values", but it barely does that. It's also an odd place to do that kind of check. I would check the input in main and have the square class assume the properties are set correctly. Not only would I not make this a class, I wouldn't make it a function. I would make a function, but it would not be a replacement for one multiplicaltion. This would be my code: ```def get_number(prompt): while True: try: value = float(input(prompt)) if value > 0: return value except ValueError: pass print('Please enter a positive number') print('Area = ', get_number('Enter width ') * get_number('Enter height '))``` Drone4four and Gribouillis like this post Reply Posts: 7,567 Threads: 133 Joined: Sep 2016 Reputation: Mar-13-2021, 06:22 AM (This post was last modified: Mar-13-2021, 06:22 AM by buran.) (Mar-12-2021, 09:57 PM)Drone4four Wrote: the same outcome can be achieved with 75% less codeActually, your code is not replicating all the functionality of the original script. e.g. in original script you can change height/weight of the instance, they print the square attributes, their code is heavily commented (which amounts for big part of these extra lines), etc. i.e. you emulate just the outcome, not 100% of the functionality/level of documenting the code. Of course, their code can be refactored - get rid of redundant things like printing `"Retrieving the height"`. All that said, I agree with others who pointed out that their code is terrible. Like @Gribouillis said - it may be better to find another course, learning material. Others have pointed enough of deficiencies, but here are some more:Having a `Square` class that allows for different `height` and `width` is poor choice of class name, confusing and misleading, and a real math non-sense. `Rectangle` is what you have right now. One may have a `Rectangle` class like this one, then have e.g. `Square` class that inherits from it, that ensure equal sides. One may even have a `Polygon` or `Shape` class that `Rectangle` will inherit from. That is also an example of the benefit of OOP over your approach - extensibility. `height` and `width` default values are strings and the values are expected and stored as `str`, converted every time when area is calculated. Even if they want to allow to instantiate the class by passing `str` as arguments, then they can convert inside the setter and store value stored as int, float or other numeric type. I understand they want to use str.isdigit for validation, but it will raise error if you pass int (and that is what I find way more logical to do, than pass `str`). the dubious use of getters/setters was already mentioned, but I am ready to give them the benefit of the doubt - i.e. if they wanted to show it as an existing option (i.e. there are legit cases when it makes sense ti use the). In addition, if it was me I would make the area a property, not method So, something like ```class Rectangle: def __init__(self, height, width): self.height = float(height) # allow to take str as input, but raise error when not valid one self.width = float(width) @property def area(self): return self.width * self.height class Square(Rectangle): def __init__(self, side): super().__init__(side, side) self.side = float(side) @property def side(self): return self._side @side.setter def side(self, value): self._side = self._width = self._height = value @property def height(self): return self._height @height.setter def height(self, value): self._side = self._width = self._height = value @property def width(self): return self._width @height.setter def width(self, value): self._side = self._width = self._height = value if __name__ =='__main__': rectangle = Rectangle(3, 4.5) print(f'Height: {rectangle.height}') print(f'Width: {rectangle.width}') print(f'{rectangle.height} X {rectangle.width} rectangle has area of {rectangle.area}') square = Square('2') print(f'Height: {square.height}') print(f'Width: {square.width}') print(f'Square with side {square.side} has area of {square.area}') square.side = 5.5 print(f'Height: {square.height}') print(f'Width: {square.width}') print(f'Square with side {square.side} has area of {square.area}') square.area = 5 # this will raise AttributeError: can't set attribute`````````Output:Height: 3.0 Width: 4.5 3.0 X 4.5 rectangle has area of 13.5 Height: 2.0 Width: 2.0 Square with side 2.0 has area of 4.0 Height: 5.5 Width: 5.5 Square with side 5.5 has area of 30.25 Height: 6 Width: 6 Square with side 6 has area of 36 Traceback (most recent call last): File "/home/boyan/sandbox2/forum.py", line 95, in square.area = 5 # this will raise AttributeError: can't set attribute AttributeError: can't set attribute`````` If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein How to Ask Questions The Smart Way: link and another link Create MCV example Debug small programs Reply

 Possibly Related Threads… Thread Author Replies Views Last Post OOP vs functional - - elaborate turn based RPG game (Derek Banas Udemy course again) Drone4four 6 883 Mar-14-2021, 08:38 AM Last Post: ndc85430 3d Surface where Z is not a function of X and Y richterjan 2 426 Nov-11-2020, 04:22 PM Last Post: michael1789 Plotting 3D surface plot for non-linear multivariate regression with 5 variables khwajaosama 0 918 Jul-02-2020, 04:50 AM Last Post: khwajaosama matplotlib recursion error when repeatedly displaying a surface AdeIsHere 0 732 Sep-19-2019, 04:36 PM Last Post: AdeIsHere Learning functional programming vndywarhol 2 1,181 Aug-15-2018, 02:17 AM Last Post: micseydel Projected Surface in 2D [Difficult topic] Hans_K 6 1,947 Aug-02-2017, 09:16 AM Last Post: Hans_K

Forum Jump:

### User Panel Messages

##### Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020