Help with exercise(8-13) for Python Programming by John Zelle
The program seems to work, however the linear regression line created does not seem to really be the line of best fit.
I think the problem is the implementation of the equation. I'm not sure if i'm interpreting it right, also I am unsure if I am doing what should be done in regards to the last paragraph of the exercise.
here is the graphics library: http://mcsp.wartburg.edu/zelle/python/ppics1/code/graphics.py
if you want to try it out.
here is the the exercise:
Write a program that graphically plots a regression line, that is, the line with the best fit through acollection of points. First ask the user to specify the data points by clicking on them in a graphicswindow. To find the end of input, place a small rectangle labelled “Done" in the lower left corner ofthe window; the program will stop gathering points when the user clicks inside that rectangle.The regression line is the line with the following equation:
here is the equation: http://i.stack.i开发者_运维百科mgur.com/xj2uu.jpg I can't post pictures
x is the mean of the x-values and .y is the mean of the y-values.As the user clicks on points, the program should draw them in the graphics window and keep track ofthe count of input values and the running sum of x, y, x2 and xy values. When the user clicks inside the“Done" rectangle, the program then computes value of y (using the equations above) correponding tothe x values at the left and right edges of the window to compute the endpoints of the regression linespanning the window. After the line is drawn, the program will pause for another mouse click beforeclosing the window and quitting.
I can't seem to get the code formatted right so I included this http://pastebin.com/JsQ0eM2R
# 8-13-LOB.py
from graphics import *
def listMulti(list1,list2):
tempAcc = 0
for i in range(len(list1)):
tempAcc += list1[i] * list2[i]
print tempAcc
return tempAcc
def squareList(iterable):
itSum = 0
for i in iterable:
itSum += i**2
return itSum
def listMean(iterable):
return sum(iterable)/len(iterable)
def regression(xList,yList,win):
xBar = listMean(xList)
yBar = listMean(yList)
xListSq = squareList(xList)
xListXyList = listMulti(xList,yList)
m = ((xListXyList) - ((len(xList)*xBar*yBar)))/\
((xListSq) - (len(xList)* (xBar**2)))
y1 = yBar + m*(-50.0 - xBar)
y2 = yBar + m*(50.0 - xBar)
Line(Point(-50.0,y1),Point(50.0,y2)).draw(win)
return "ybar: %f\txBar: %f\tm: %f\ty1: %f\ty2: %f" %(yBar,xBar,m,y1,y2)
def windraw():
win = GraphWin("Line of Best Fit",500,500)
win.setCoords(-50.0,-50.0,50.0,50.0)
doneBox = Rectangle(Point(-50,-50),Point(-40,-45))
doneBox.setWidth(3)
doneBoxTxt = Text(Point(-45,-47.5),"DONE")
doneBox.draw(win)
doneBoxTxt.draw(win)
return win
def pointBuild(xList,yList,win):
tempPoint = Point(25,25) # prime tempPoint for sentinel loop
# tests if given point is past rectangle created for doneBox
while (tempPoint.getX() - (Point(-40,-45)).getX() == abs(tempPoint.getX() - (Point(-40,-45)).getX())) or\
(tempPoint.getY() - (Point(-40,-45)).getY() == abs(tempPoint.getY() - (Point(-40,-45)).getY())):
tempPoint = win.getMouse()
tempPoint.draw(win)
xList.append(tempPoint.getX()); yList.append(tempPoint.getY())
def main():
xList,yList = [],[]
win = windraw()
pointBuild(xList,yList,win)
print regression(xList,yList,win)
# Test out coordinate lists accumulation from pointBuild
for i in range(len(xList)-1):
print "Point(%2.2f,%2.2f)" % (xList[i],yList[i])
win.getMouse()
win.close()
main()
I think the problem is that your pointBuild routine adds the point where the user clicks in the "DONE" box to the regression list, so every dataset has a point in the lower left. You can confirm this by adding "print xList, yList" before pointBuild returns. I would modify the routine to:
while True: # (a common python idiom for "do forever until we break")
tempPoint = win.getMouse()
if (tempPoint is in the DONE rectangle):
# get out, we're done: don't forget to handle the case where
# there are no points in xList/yList!
break
else:
# draw the point
# add it to xList, yList
I think you might also want to look at the "is in the DONE rectangle" logic. IIUC, you simply want to know if tempPoint.getX() is between -50 and -40 and .getY() is between -50 and -45.
Good luck!
精彩评论