为什么我的列表没有改变它应该的方式?

时间:2014-05-14 10:06:00

标签: python list class oop matrix

我试图在我的班级Circle中构建一个方法,该方法获取矩阵(由列表列表表示,每个子列表代表一行)作为输入。

矩阵在每个单元格中都为零,我应该将我的圆圈放在矩阵的中心,并检查代表(i,j)点的(i,j)单元格是否包含在圆圈,但由于某种原因,我得到了不同的输出。

以下是一个例子:

mat = [[0 for j in range(5)] for i in range(7)] 
Circle(40, 10, 1).draw(mat) 

我期望的输出是:

[[0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 0, 1, 0, 0], 
 [0, 1, 1, 1, 0], 
 [0, 0, 1, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0]]

但我得到的输出是:

[[0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 1], 
 [0, 0, 0, 1, 1], 
 [0, 0, 0, 0, 1], 
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0]]

这是我的代码:

class Point():
    """ Holds data on a point (x,y) in the plane """

    def __init__(self, x=0, y=0):
        assert isinstance(x,(int, float)) and isinstance(y,(int, float)) 
        self.x = x
        self.y = y

class Circle():
    """ Holds data on a circle in the plane """

    def __init__(self,*args):
        if len(args)==2:
            if isinstance(args[0],Point) and isinstance(args[1],(float,int)):
                assert args[1]>0
                self.center= args[0]
                self.radius= args[1]

        if len(args)==3:
            assert args[2]>0
            self.a=args[0]
            self.b=args[1]
            self.center= Point(self.a,self.b)
            self.radius= args[2]
    def contains(self,check): 

        if isinstance(check,(Point)):
            if math.sqrt((self.center.x-check.x)**2 + (self.center.y-check.y)**2) <= self.radius:
                return True
        if isinstance(check,Circle): 
            test= math.sqrt((self.center.x-check.center.x)**2 + (self.center.x-check.center.x)**2)
            if test < (abs((self.radius)-(check.radius))):
                return True

        else:
            return False

    def draw(self,mat):
        n=len(mat)
        m=len(mat[0])

        newcircle=Circle((int(m/2)+1),(int(n/2)+1),self.radius)
        for i,lst in enumerate(mat):
            for j,val in enumerate(lst):
                if  newcircle.contains(Point(i,j)):


                    mat[i][j]=1

2 个答案:

答案 0 :(得分:1)

您不是将圆圈放在矩阵的中间。

newcircle=Circle((int(m/2)+1),(int(n/2)+1),self.radius)

应该是

newcircle=Circle((int(n/2)),(int(m/2)),self.radius)

或者可能,因为这里不需要只使用整数。

newcircle=Circle((n-1)/2.0,(m-1)/2.0,self.radius)

答案 1 :(得分:0)

要绘制一个圆,您可以在矩阵的中心创建一个新圆,检查内部的单元格,然后将内部的值转换为1。

1)首先,函数contains存在问题:

def contains(...):
    if (cond1):
        if (cond11)
            return True
    if (cond2):
        if (cond21)
            return True
    else:
        return False

如果cond2为true且cond21为false,则会得到None。 要更加Pythonic,请尝试:

def contains(...):
    if (cond1) and (cond11):
        return True
    elif (cond2) and (cond21):
        return True
    else:
        return False

在这种情况下,你确定有一个真或假。

2)复制/粘贴错误

当实例为Circle时,函数中包含复制/粘贴错误。 您忘记将y转换为x

3)功能draw

此功能所需的全部是半径。 小心使用整数和浮点数;我们有:

(int(5 / 2)) == (5 / 2) != (5 / 2.)

为了确保有一个浮点数,将除数写为浮点2.而不是2

如果使用int(len(mat) / 2.) + 1定义中心,则在矩阵上创建圆圈,行和列索引从1开始。 不要忘记enumerate索引从0开始,而不是1。 因此,int((len(mat) - 1) / 2.) + 1(与len(mat) / 2相同)会更准确。

说真的,塔哈!