<p>问题:</p>
<ul>
<li><p><code>from my_library import *</code>应该避免;最好确切地指定您想要从中得到什么。这有助于保持命名空间的整洁。</p></li>
<li><p>你有一个巨大的代码块,最好把它分成单独的函数。这使得思考和调试更加容易,并且可能有助于以后重用代码。当然,这是一个玩具问题,你不会再使用它——但是做练习的全部目的是培养好习惯,这样分解代码绝对是一个好习惯!一般的经验法则是,如果一个函数包含超过十几行代码,您应该考虑进一步拆分它。</p></li>
<li><p>这个练习要求您在获取输入点的同时,跟踪x、y、xx和xy的运行和。我认为这是一个坏主意,或者至少比Python更具C语言风格,因为它迫使你同时完成两个不同的任务(获取点数并对它们进行数学运算)。我的建议是:如果你得到了分数,就得分数;如果你在做数学,就做数学;不要尝试同时做这两个。</p></li>
<li><p>类似地,我不喜欢你用回归计算来担心窗口的边在哪里。它为什么要知道或关心windows?希望您喜欢我的解决方案;-)</p></li>
</ul>
<p>以下是我对您代码的重构版本:</p>
<pre><code>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()
</code></pre>