I am doing monte-carlo-integration of a rectangle that contains rectangle/s inside the enclosing rectangle. I want to find out the area of rectangle that is not covered by any of embedded rectangle.
Below are the class of rectangle and the montecarlo integration. I need help in checking whether a point is inside a given rectangle (def inside(...)). I get the error
File "/skeleton_assignment01_example1/example1/montecarlo.py", line 67, in inside
number_recs = len(rect)
TypeError: 'method' object cannot be interpreted as an integer
I don't know how to interpret this and not very familiar with working with objects. Maybe there is a different way to do it or my approach is wrong. Thanks
class Rectangle():
def __init__(self, origin_x, origin_y, length, width):
self.origin_x = origin_x
self.origin_y = origin_y
self.length = length
self.width = width
def rect_values(self):
return self.origin_x, self.origin_y, self.length, self.width
from random import random
class MonteCarlo:
def __init__(self, length, width, rectangles):
rect_specs = length or width or rectangles
if isinstance(rect_specs, type(None)):
raise ValueError
self.rec_length = length
self.rec_width = width
self.rects = rectangles
def area(self, num_of_shots):
"""Method to estimate the area of the enclosing rectangle that is not covered by the embedded rectangles
"""
if isinstance(num_of_shots, type(None)):
raise ValueError
inside = 0
total = num_of_shots
for i in range(num_of_shots):
x = random() * self.rec_length
y = random() * self.rec_width
if self.inside(x,y, self.rects) == True:
inside += 1
area = (total - inside) / (total * self.rec_length * self.rec_width)
return area
def inside(self, x, y, rect):
"""Method to determine if a given point (x,y) is inside a given rectangle
"""
if (x or y or rect) == None:
raise ValueError
number_recs = len(rect)
for i in range(number_recs):
origin_x, origin_y, length, width = rect[i].rect_values()
x_line = length+origin_x
y_line = width+origin_y
if (x <= x_line and y <= y_line) and (x >= origin_x and y >= origin_y):
return True
Here is the long unittest that throws the error when running! Hope this helps.
import unittest
from montecarlo import MonteCarlo
from rectangle import Rectangle
class Point():
def __init__(self, x, y):
self.x = x
self.y = y
def get_x(self):
return self.x
def get_y(self):
return self.y
class TestAssignment01ex01Student(unittest.TestCase):
def testMCwith3rects(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rect2 = Rectangle(6.0, 3.0, 6.0, 4.0)
rect3 = Rectangle(10.0, 5.0, 4.0, 4.0)
rects = [rect1, rect2, rect3]
mc = MonteCarlo(15.0, 10.0, rects)
area = mc.area(1000000)
self.assertTrue((area >= 97.5 and area <= 98.5),
"MonteCarlo.area(1000000) with the enclosing rectangle 15.0x10.0 " +
"and the following embedded rectangles failed (area should be +/- 0.5 to the result 98 but your result is: " + str(
area) + " " + self.printRectanglesData(rects))
def testMCwith2Rects(self):
# area of enclosing rectangle is 50
# area of embedded rectangles is 2+12=14
# result is: 50-14=36
#
# embedded rectangle 1 is at position (0,0) with a size of 1x2
rect1 = Rectangle(0.0, 0.0, 1.0, 2.0)
# embedded rectangle 2 is at position (7,1) with a size of 3x4
rect2 = Rectangle(7.0, 1.0, 3.0, 4.0)
rects = [rect1, rect2]
mc = MonteCarlo(10.0, 5.0, rects)
area = mc.area(10000)
# for 10k random points the estimated area should already be close to correct result of 36
self.assertTrue((area > 30 and area < 40),
"MonteCarlo.area() according to the provided unit test failed! Area should be between 30 and 40 but was " + str(
area))
def testInsideRectBorderline1Y(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rects = []
mc = MonteCarlo(15.0, 10.0, rects)
pt = Point(1.0, 4.0)
self.assertTrue(mc.inside(pt.get_x(), pt.get_y(), rect1),
"MonteCarlo.inside() with point (x=" + str(pt.get_x()) + "/y=" + str(
pt.get_y()) + ") and the rectangle "
+ self.printRectangleData(rect1) + " returned False but should be True!")
def testInsideRectBorderline2Y(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rects = []
mc = MonteCarlo(15.0, 10.0, rects)
pt = Point(1.0, 0.0)
self.assertTrue(mc.inside(pt.get_x(), pt.get_y(), rect1),
"MonteCarlo.inside() with point (x=" + str(pt.get_x()) + "/y=" + str(
pt.get_y()) + ") and the rectangle "
+ self.printRectangleData(rect1) + " returned False but should be True!")
def testInsideRectBorderline3Y(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rects = []
mc = MonteCarlo(15.0, 10.0, rects)
pt = Point(1.0, 4.01)
self.assertFalse(mc.inside(pt.get_x(), pt.get_y(), rect1),
"MonteCarlo.inside() with point (x=" + str(pt.get_x()) + "/y=" + str(
pt.get_y()) + ") and the rectangle "
+ self.printRectangleData(rect1) + " returned True but should be False!")
def testInsideRectBorderline4Y(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rects = []
mc = MonteCarlo(15.0, 10.0, rects)
pt = Point(1.0, -0.01)
self.assertFalse(mc.inside(pt.get_x(), pt.get_y(), rect1),
"MonteCarlo.inside() with point (x=" + str(pt.get_x()) + "/y=" + str(
pt.get_y()) + ") and the rectangle "
+ self.printRectangleData(rect1) + " returned True but should be False!")
def testInsideRectBorderline1X(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rects = []
mc = MonteCarlo(15.0, 10.0, rects)
pt = Point(0.0, 3.0)
self.assertTrue(mc.inside(pt.get_x(), pt.get_y(), rect1),
"MonteCarlo.inside() with point (x=" + str(pt.get_x()) + "/y=" + str(
pt.get_y()) + ") and the rectangle "
+ self.printRectangleData(rect1) + " returned False but should be True!")
def testInsideRectBorderline2X(self):
rect1 = Rectangle(0.0, 0.0, 4.0, 4.0)
rects = []
mc = MonteCarlo(15.0, 10.0, rects)
pt = Point(4.0, 3.0)
self.assertTrue(mc.inside(pt.get_x(), pt.get_y(), rect1),
"MonteCarlo.inside() with point (x=" + str(pt.get_x()) + "/y=" + str(
pt.get_y()) + ") and the rectangle "
+ self.printRectangleData(rect1) + " returned False but should be True!")
# /*************************************
# *
# * private methods
# *
# */
def printRectanglesData(self, rects):
i = 0
sb = ""
while i < len(rects):
sb += "\n{} Rectangle ".format(i + 1) + "(x="
sb += str(rects[i].origin_x) + " y=" + str(rects[i].origin_y)
sb += " length="
sb += str(rects[i].length) + " width=" + str(rects[i].width) + ")"
i += 1
return sb
def printRectangleData(self, rect):
sb = " (x="
sb += str(rect.origin_x) + " y=" + str(rect.origin_y)
sb += " length="
sb += str(rect.length) + " width=" + str(rect.width) + ")"
return sb
if __name__ == '__main__':
unittest.main()