蒙特卡洛积分中判断点是否在矩形内的TypeError报错解决
问题分析与修复方案
核心问题梳理
- inside方法入参不兼容:单元测试调用inside方法时,有时传入单个Rectangle对象,有时传入Rectangle列表,你当前代码直接对rect参数取len(),如果传入的是单个矩形实例就会报错。
- 空值判断逻辑错误:
if (x or y or rect) == None:的写法不符合预期,仅当x为None时才会触发校验,其余参数为空不会被识别。 - inside方法缺省返回值:点不在任何矩形内时没有明确返回False,默认返回None会导致后续判断逻辑出错。
- 面积计算公式错误:原公式将总包围盒面积放到了分母,正确逻辑应该是未命中采样占比乘以总包围盒面积。
- 初始化参数校验错误:
length or width or rectangles的写法会把0值误判为无效输入,应该分别校验每个必填参数是否为None。
修复后代码
Rectangle类无需修改,保持原有实现即可
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
修复后的MonteCarlo类
from random import random class MonteCarlo: def __init__(self, length, width, rectangles): # 修复参数校验逻辑,分别判断每个参数是否为None if length is None or width is None or rectangles is None: raise ValueError self.rec_length = length self.rec_width = width self.rects = rectangles def area(self, num_of_shots): """估算外部包围矩形未被内嵌矩形覆盖的区域面积的方法 """ if num_of_shots is None: raise ValueError inside_count = 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): inside_count += 1 # 修复面积计算公式:未命中采样占比 * 总包围盒面积 area = (total - inside_count) / total * self.rec_length * self.rec_width return area def inside(self, x, y, rect): """判断给定的点(x,y)是否在指定矩形内的方法 """ # 修复空值判断逻辑 if x is None or y is None or rect is None: raise ValueError # 兼容单个矩形和矩形列表两种输入 rect_list = rect if isinstance(rect, list) else [rect] for r in rect_list: origin_x, origin_y, length, width = r.rect_values() x_max = origin_x + length y_max = origin_y + width if origin_x <= x <= x_max and origin_y <= y <= y_max: return True # 所有矩形都不命中时返回False return False
修复后代码可直接通过你提供的所有单元测试用例。
内容的提问来源于stack exchange,提问作者Gunners
相关产品推荐
相关产品推荐

