#!/usr/bin/python
# -*- coding: utf-8 -*-

from mls import*
from math import sqrt,ceil
from Tkinter import *
from tkMessageBox import *

class Mnk:
    def __init__(self):
        self.window = Tk()
        self.window.title("Комитет сельских дел")
        self.window.resizable(0, 0)
        self.workspace =  Frame(self.window,width=300,height=500, relief=FLAT)
        self.workspace.grid(row=0, column=0)
        lab = Label(self.workspace, text="МНК-аппроксимация экспериментальных данных", font="Courier 12 bold")
        lab.grid(row=0, column=0, sticky="ewns")
        lab = Label(self.workspace, text="Абциссы и ординаты точек вводятся в поля X и Y через пробел", font="Courier 10 bold")
        lab.grid(row=1, column=0, sticky="ewns")
        self.workspace1 =  Frame(self.window,width=300,height=470, relief=FLAT)
        self.workspace1.grid(row=2, column=0)
        lab = Label(self.workspace1, text="X=")
        lab.grid(row=0, column=0, sticky="ewns")
        self.ex = Entry(self.workspace1, width=100)
	self.ex.insert(END,'-2 -1 0 1 2')
        self.ex.grid(row=0, column=1, columnspan=2, sticky="ewns")
        lab = Label(self.workspace1, text=" ")
        lab.grid(row=1, column=0, sticky="ewns")
        lab = Label(self.workspace1, text="Y=")
        lab.grid(row=2, column=0, sticky="ewns")
        self.ey = Entry(self.workspace1, width=100)
	self.ey.insert(END,'-2 23 5 -17 31')
        self.ey.grid(row=2, column=1, columnspan=2, sticky="ewns")
        lab = Label(self.workspace1, text=" ")
        lab.grid(row=3, column=0, sticky="ewns")
        self.btnr = Button(self.workspace1, text="run")
        self.btnr["command"] = self.run
        self.btnr.grid(row=4, column=1)
        self.btnv = Button(self.workspace1, text="graph")
        self.btnv["command"] = self.vid
        self.btnv.grid(row=4, column=2)
        lab = Label(self.workspace1, text="  ")
        lab.grid(row=6, column=0, sticky="ewns")
        self.window.mainloop()

    def sum(self,lst):
        s=0
        for x in lst: s+=float(x)
        return s
    def mx(self,lst):
        t=0;l=map(abs,lst)
        for k in l:t=max(k,t)
        return t	

    def calc(self):
        try:
            self.lx=map(eval,str(self.ex.get()).split())
            self.ly=map(eval,str(self.ey.get()).split())
        except :
            showerror('Комиссия построения','Неверно введены данные ')
            return 
        n=min(len(self.lx),len(self.ly))
        if n==0:
            showerror('Комиссия построения','Нет данных для обработки ')
            return 
        a=M([[0. for i in [0,1]] for j in [0,1]])
        b=M([0. for j in [0,1]])
        A=M([[0. for i in [0,1,2]] for j in [0,1,2]])
        B=M([0. for j in [0,1,2]])
        a[0][0]=A[0][0]=1.
        a[0][1]=a[1][0]=self.sum(self.lx)/n
        A[0][1]=A[1][0]=self.sum(self.lx)/n
        tmp=[self.lx[j]**2  for j in range(n)]
        a[1][1]=A[1][1]=self.sum( tmp)/n
        A[2][0]=A[0][2]=self.sum( tmp)/n
        tmp=[self.lx[j]**3 for j in range(n)]
        A[1][2]=A[2][1]=self.sum(tmp)/n
        tmp=[self.lx[j]**4 for j in range(n)]
        A[2][2]=self.sum(tmp)/n
        tmp=[self.ly[j] for j in range(n)] 
        b[0]=B[0]=self.sum(tmp)/n 
        tmp= [self.ly[j]*self.lx[j] for j in range(n)]
        b[1]=B[1]=self.sum(tmp)/n 
        tmp= [self.ly[j]*self.lx[j]**2 for j in range(n) ]
        B[2]=self.sum(tmp)/n
        return solver(a,b)[0],solver(A,B)[0]  

    def run(self):
        s=0
        self.w=Toplevel(self.window,bg='blue')
        self.w.title("Депо земледельческих орудий")
        self.w.maxsize(width=500,height=300)
        lab = Label(self.w, text="МНК- аппроксимация экспериментальных данных", font="Courier 12 bold")
        lab.grid(row=0, column=0, sticky="ewns")
        txt="Линейная аппроксимация\n "
        lst=self.calc() 
        lstl=lst [0]
        lstp=lst [1]
        txt+="y="+str(lstl[0])
        if lstl[1]>=0: txt+="+"+str(lstl[1])+"x \n"
        else : txt+=str(lstl[1])+"x \n"
        n=min(len(self.lx),len(self.ly))
        for j in range(n) :
          s+=(self.ly[j]-lstl[0]-lstl[1]*self.lx[j])**2
        txt+='Среднеквадратическое отклонение\n'
        txt+=str(sqrt(s/n))+'\n'
        txt+="Квадратическая аппроксимация\n "
        txt+="y="+str(lstp[0])
        if lstp[1]>=0:
            txt+="+"+str(lstp[1])+"x"
        else : txt+=str(lstp[1])+"x"
        if lstp[2]>=0:
            txt+="+"+str(lstp[2])+"x*x \n"
        else : txt+=str(lstp[2])+"x*x \n"
        s=0
        for j in range(n) :
          s+=(self.ly[j]-lstp[0]-lstp[1]*self.lx[j]-lstp[2]*self.lx[j]**2)**2
        txt+='Среднеквадратическое отклонение\n'
        txt+=str(sqrt(s/n))+'\n'
        lab = Label(self.w, text=txt, font="Courier 10 bold")
        lab.grid(row=1, column=0, sticky="ewns")
      
    def vid(self):
        self.w1=Toplevel(self.window,bg='red')
        self.w1.title("Комиссия построения ")
        self.w1.minsize(width=500,height=500)
        self.G = Canvas(self.w1, borderwidth=2, relief=GROOVE)
        self.G.grid(row=0, column=0)
        self.G.config(width=500, height=500, background="green")
        lst=self.calc() 
        lstl=lst [0] ; lstp=lst [1]
        n=min(len(self.lx),len(self.ly))
        x=ceil(self.mx(self.lx))+1
        y=ceil(self.mx(self.ly))+1
        fl=lambda x:lstl[0]+lstl[1]*x
        fp=lambda x:lstp[0]+lstp[1]*x+lstp[2]*x*x
        ix=250./x;iy=250./y
        self.G.create_line(250,0,250,500,fill="blue")
        self.G.create_line(0,250,500,250,fill="blue")
        for t in range(1,int(x)):
            self.G.create_line(250+ix*t,0,250+ix*t,500,fill='grey') 
            self.G.create_text(250+ix*t,255,text=str(t))
            self.G.create_line(250-ix*t,0,250-ix*t,500,fill='grey')
            self.G.create_text(250-ix*t,255,text='-'+str(t))
        for t in range(5,int(y),5):
            self.G.create_line(0,250+iy*t,500,250+iy*t,fill='grey') 
            self.G.create_text(245,250+iy*t,text='-'+str(t))
            self.G.create_line(0,250-iy*t,500,250-iy*t,fill='grey')
            self.G.create_text(245,250-iy*t,text=str(t))
        for t in range(n) :
            self.G.create_oval(245+ix*self.lx[t],245-iy*self.ly[t],255+ix*self.lx[t],255-iy*self.ly[t],fill='red')
        for t in range(n-1):
            self.G.create_line(250 +ix*self.lx[t],250-iy*fl(self.lx[t]),250 +ix*self.lx[t+1],250-iy*fl(self.lx[t+1]),fill='yellow')
            self.G.create_line(250 +ix*self.lx[t],250-iy*fp(self.lx[t]),250 +ix*self.lx[t+1],250-iy*fp(self.lx[t+1]),fill='brown') 	
   

Mnk()
