我正在阅读John Zelle的Python编程,并且只限于下图所示的一种练习。

您可以在下面查看我的代码。我知道代码很丑陋。 (任何提示都表示赞赏)

到目前为止,这是我的代码:

from graphics import *

def regression():

# creating the window for the regression line
        win = GraphWin("Regression Line - Start Clicking!", 500, 500)
        win.setCoords(0.0, 0.0, 10.0, 10.0)

        rect = Rectangle(Point(0.5, 0.1), Point(2.5, 2.1))
        rect.setFill("red")
        rect.draw(win)
        Text(rect.getCenter(), "Done").draw(win)

        message = Text(Point(5, 0.5), "Click in this screen")
        message.draw(win)

        points = [] # list of points
        n = 0 # count variable
        sumX = 0
        sumY = 0

        while True:
                p = win.getMouse()
                p.draw(win)

# if user clicks in a red square it exits the loop and calculates the regression line
                if (p.getX() >= 0.5 and p.getX() <= 2.5) and (p.getY() >= 0.1 and p.getY() <= 2.1):
                        break

                n += 1 # count of the points

# get the sum of the X and Y points
                sumX = sumX + p.getX()
                sumY = sumY + p.getY()

# tuple of the X and Y points
                dot = (p.getX(), p.getY())
                points.append(dot)

        avgX = sumX / n
        avgY = sumY / n

        top = 0
        bottom = 0

# my ugly attempt at the regression equation shown in the book

        for i in points:
                gp = 0
                numer = points[gp][0] * points[gp][1]
                top = top + numer

                denom = points[gp][0] ** 2
                bottom = bottom + denom
                gp += 1

        m = (top - sumX * sumY) / (bottom - sumX ** 2)

        y1 = avgY + m * (0.0 - avgX)
        y2 = avgY + m * (10.0 - avgX)

        regressionline = Line(Point(0, y1), Point(10.0, y2))
        regressionline.draw(win)

        raw_input("Press <Enter> to quit.")
        win.close()

regression()

当我运行程序时,回归线似乎永远不是最合适的。我相信我在代码中错误地解释了回归方程。需要更改什么才能获得正确的回归线?

最佳答案

问题:

  • from my_library import *应该避免;最好准确地指定您要从中获得什么。这有助于使您的命名空间保持整洁。
  • 您有一大堆代码;最好将其拆分为单独的功能。这使思考和调试变得更加容易,并且可以帮助您以后重用代码。当然,这是一个玩具问题,您不会重复使用它-但进行练习的全部目的是养成良好的习惯,以这种方式分解代码绝对是一个好习惯!一般的经验法则-如果一个函数包含大约十几行代码,则应考虑将其进一步拆分。
  • 练习
  • 要求您在获取输入点时跟踪x,y,xx和xy的运行总和。我认为这是一个坏主意-或至少比Python-ish更多的C-ish-因为它迫使您一次执行两个不同的任务(获取积分并对其进行数学运算)。我的建议是:如果您要获得积分,请获得积分;如果您要获得积分,请获得积分。如果你在做数学,那就做数学;不要尝试同时做两个。
  • 同样,我不喜欢您担心窗口的侧面在哪里进行回归计算的方式。为什么它应该知道或关心Windows?我希望你喜欢我的解决方案;-)

  • 这是我的代码的重构版本:
    from graphics import GraphWin, Point, Line, Rectangle, Text
    
    def draw_window()
        # create canvas
        win = GraphWin("Regression Line - Start Clicking!", 500, 500)
        win.setCoords(0., 0., 10., 10.)
        # exit button
        rect = Rectangle(Point(0.5, 0.1), Point(2.5, 2.1))
        rect.setFill("red")
        rect.draw(win)
        Text(rect.getCenter(), "Done").draw(win)
        # instructions
        Text(Point(5., 0.5), "Click in this screen").draw(win)
        return win
    
    def get_points(win):
        points = []
        while True:
            p = win.getMouse()
            p.draw(win)
            # clicked the exit button?
            px, py = p.getX(), p.getY()
            if 0.5 <= px <= 2.5 and 0.1 <= py <= 2.1:
                break
            else:
                points.append((px,py))
        return points
    
    def do_regression(points):
        num = len(points)
        x_sum, y_sum, xx_sum, xy_sum = 0., 0., 0., 0.
        for x,y in points:
            x_sum += x
            y_sum += y
            xx_sum += x*x
            xy_sum += x*y
        x_mean, y_mean = x_sum/num, y_sum/num
        m = (xy_sum - num*x_mean*y_mean) / (xx_sum - num*x_mean*x_mean)
        def lineFn(xval):
            return y_mean + m*(xval - x_mean)
        return lineFn
    
    def main():
        # set up
        win = draw_window()
        points = get_points(win)
        # show regression line
        lineFn = do_regression(points)
        Line(
            Point(0.,  lineFn(0. )),
            Point(10., lineFn(10.))
        ).draw(win)
        # wait to close
        Text(Point(5., 5.), "Click to exit").draw(win)
        win.getMouse()
        win.close()
    
    if __name__=="__main__":
        main()
    

    关于python - Python初学者-如何使点击次数等于回归线并以图形方式显示?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10610391/

    10-13 09:06