Python Forum
printing list of random generated rectangles
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
printing list of random generated rectangles
#1
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
Reply
#2
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
Reply
#3
yet another option is to define special __str__() method for your class
Reply
#4
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.
Reply
#5
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
Reply
#6
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()
Reply
#7
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 ???
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
Thanks for all the help!
I am curious buran what does the @property do?
Reply
#9
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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Array and rectangles pythonuser1 3 2,305 Apr-24-2020, 04:52 PM
Last Post: deanhystad
  Random selection from list Mohsky 1 8,833 Mar-31-2020, 10:27 PM
Last Post: deanhystad
  How to generate multiple rectangles with randrange without overlapping? rafaberec 1 1,850 Dec-10-2018, 10:12 AM
Last Post: buran
  bubble sort random list atux_null 7 7,833 Nov-03-2017, 07:28 PM
Last Post: sparkz_alot
  List with Random Numbers AnjyilLee 5 9,262 Oct-14-2017, 09:22 PM
Last Post: buran
  Help printing any items that contains a keyword from a list Liquid_Ocelot 13 64,647 May-06-2017, 10:41 PM
Last Post: ichabod801
  Random Shuffle List simon 10 9,963 Oct-24-2016, 04:02 PM
Last Post: simon

Forum Jump:

User Panel Messages

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