Posts: 32
Threads: 10
Joined: Jan 2018
import random
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def get_width(self):
return self.width
def get_height(self):
return self.height
def compute_area(self):
return self.width * self.height
myList = []
for i in range (random.randint(1, 10)):
rand_Range = random.randint(1, 100)
rand_Rectangle = Rectangle(rand_Range, rand_Range)
myList += [rand_Rectangle]
total_area = 0
for r in myList:
total_area += r.compute_area()
print (myList)
print (total_area) Output: [<__main__.Rectangle object at 0x033C91F0>, <__main__.Rectangle object at 0x034631B0>]
Total area= 2245
So i have to make a program with a rectangle class. Then generate random number of rectangles from 1 to 10 and then print out the number of rectangles generated, the list of the heights and widths of each rectangle and then the total area of them all. The rectangles height and width are also randomly generated between 1 to 100. But I cannot seem to get the list to actually print the numbers from the rectangle.
desired output:
Output: Number of rectangles is 2.
[10, 100]
[5, 57]
Total area= 1285
Posts: 54
Threads: 0
Joined: Jan 2018
1) hint for number of rects... len(myList)
2) loop myList & call methods on each item to print out height and width
print [item.get_width(),item.get_height()]
swallow osama bin laden
Posts: 8,160
Threads: 160
Joined: Sep 2016
Posts: 32
Threads: 10
Joined: Jan 2018
Feb-17-2018, 10:22 PM
(This post was last modified: Feb-17-2018, 10:22 PM by Zatoichi.)
import random
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def get_width(self):
return self.width
def get_height(self):
return self.height
def compute_area(self):
return self.width * self.height
def __repr__(self):
return '[%d,%d]\n' % (self.width, self.height)
def main():
myList = []
for _ in range (random.randint(1, 10)):
rand_Rectangle = Rectangle(random.randint(1,100), random.randint(1,100))
myList += [rand_Rectangle]
total_area = 0
for items in myList:
total_area += items.compute_area()
print ('Number of rectangles is', len(myList))
print (myList)
print ('Total area=', total_area)
main() Output: Number of rectangles is 3
[[96,91]
, [24,47]
, [26,44]
]
Total area= 11008
So I am getting closer but is there way to clean it up or at least align the numbers nicely? i.e get rid of the comma in between sets and the extra set of brackets.
Posts: 54
Threads: 0
Joined: Jan 2018
with __repr__() added like what buran said, all we need to do is to print each item in myList, not the nested list myList itself.
swallow osama bin laden
Posts: 8,160
Threads: 160
Joined: Sep 2016
you don't need the new line '\n' in your __repr__() function.
also you don't need these get functions.
import random
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
def __repr__(self):
return 'Rectangle[width:{: >2}, height:{: >2}]'.format(self.width, self.height)
def main():
my_list = [Rectangle(random.randint(1,100), random.randint(1,100)) for _ in range (random.randint(1, 10))]
total_area = sum([rect.area for rect in my_list])
print ('Number of rectangles is', len(my_list))
for rect in my_list:
print(rect)
print ('Total area=', total_area)
if __name__ == '__main__':
main() Output: Number of rectangles is 5
Rectangle[width:89,height:10]
Rectangle[width:18,height:95]
Rectangle[width:19,height:49]
Rectangle[width:90,height: 9]
Rectangle[width:44,height: 2]
Total area= 4429
you can also buit-in the randomness in the class itself
import random
class Rectangle:
def __init__(self, width=0, height=0):
if width == 0:
width = random.randint(1,100)
if height == 0:
height = random.randint(1,100)
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
def __repr__(self):
return 'Rectangle[width:{: >3}, height:{: >3}]'.format(self.width, self.height)
def main():
my_list = [Rectangle() for _ in range (random.randint(1, 10))]
total_area = sum([rect.area for rect in my_list])
print ('Number of rectangles is', len(my_list))
for rect in my_list:
print(rect)
print ('Total area=', total_area)
if __name__ == '__main__':
main()
Posts: 2,126
Threads: 11
Joined: May 2017
Small improvement:
def __init__(self, width=0, height=0):
self.width = width or random.randint(1,100)
self.height = height or random.randint(1,100) The or operand looks up for truthiness. If the boolean is False it takes the next operand .
Following statement is True:
0 == 0.0 == False == bool(None) == bool([]) == bool({}) == bool(set()) This means the boolean of 0, 0.0 and None is False. This technique is used often for default arguments. A pitfall are negative numbers. They are True . You often see functions/methods with default arguments. Sometimes the function takes another object, which does not have __bool__ method implemented, then it is always True. In this case the default argument is None.
def get_beer(amount, brand=None):
beer = '\N{BEER MUG}' * amount
brand = brand or 'Warsteiner'
print(f'Here your {brand} {beer}') With this function you get always Warsteiner, if you don't supply the argument for brand.
Output: >>> get_beer(2, 'Tsingtao')
Here your Tsingtao ??
>>> get_beer(3, 0) # lets use a int
Here your Warsteiner ???
>>> get_beer(3, -1) # what will happen now?
Here your -1 ???
Posts: 32
Threads: 10
Joined: Jan 2018
Thanks for all the help!
I am curious buran what does the @property do?
Posts: 8,160
Threads: 160
Joined: Sep 2016
Feb-18-2018, 06:34 PM
(This post was last modified: Feb-18-2018, 06:35 PM by buran.)
in your code you have calculate_area() method. it calculates area and returns the result. That is fine, however area is actually more of a property, then method. i.e. it is more convenient to treat as a property.
so short answer is that in this particular case we use @property decorator to make area read-only, i.e. you cannot set it (i.e. you don't want to be able to set area to 10, if it is 5x3 rectangle, right?)
class Rectangle:
def __init__(self, width=0, height=0):
self.width = width
self.height = height
@property
def area(self):
return self.width * self.height
rect = Rectangle(3,5)
print(rect.area)
rect.area = 10 Output: 15
Traceback (most recent call last):
File "/home/boyan/geotag/misc/cli.py", line 18, in <module>
rect.area = 10
AttributeError: can't set attribute
Note that this is so, only because we didn't use also @area.setter decorator
for more in-depth introduction read https://www.programiz.com/python-programming/property
|