#!/usr/bin/env python
# coding: utf
'''
Написать программу, рисующую какой-нибудь график
'''

from math import *
import pygame

SFun="sin(x)"
A,B=-1,4
NDots=200
SSize=(800,600)
Border=(6,3)

def scale(x,d,D):
    '''Преобразует число m из диапазона d в диапазон D'''
    return D[0]+(float(x)-d[0])*(D[1]-D[0])/(d[1]-d[0])

def scaledot(m,v,V):
    '''Преобразует координаты точки m в прямоугольнике v
    в координаты в прямоугольнике V.'''
    return [scale(x,d,D) for x,d,D in zip(m,zip(*v),zip(*V))]

# Выполнять функцию, хранящуюся в строке SFun
def fun(x, s=SFun): return eval(SFun)

def calculate(A,B,SFun,Rect):
    '''Вычисльить график функции SFun от точки A до точки B.
    График встроить в прямоугольник Rect'''
    # Вычислим абсциссы точек
    abss=[scale(i,(0,NDots),(A,B)) for i in xrange(NDots+1)]
    # Вычислим ординаты точек
    ords=[fun(x) for x in abss]
    # Вычислим область значений функции
    Min,Max=min(ords),max(ords)
    # Границы графика — номинальные и на экране
    v,V=((A,Min), (B,Max)), (Rect.bottomright, Rect.topleft)
    return [scaledot(m, v, V) for m in zip(abss,ords)]

pygame.init()
screen=pygame.display.set_mode(SSize)

CanExit,NeedRecalc=False,True
while not CanExit:
    ev=pygame.event.wait()
    if ev.type == pygame.QUIT:
        CanExit=True
    elif ev.type == pygame.KEYDOWN:
        if ev.key == 27:
            CanExit=True
        elif ev.key == 13:
            SFun=raw_input("Введите функцию от x: ")
            NeedRecalc=True
    elif ev.type == pygame.MOUSEMOTION:
        if ev.buttons[0]:
            d=scale(ev.rel[0],(0,SSize[0]),(0,B-A))
            A+=d
            B+=d
            NeedRecalc=True
        elif ev.buttons[2]:
            d=scale(-ev.rel[0],(0,SSize[0]),(0,B-A))
            A-=d
            B+=d
            NeedRecalc=True
    if NeedRecalc:
        Frame=pygame.Rect(Border,(SSize[0]-2*Border[0],SSize[1]-2*Border[1]))
        Graph=calculate(A,B,SFun,Frame)
        NeedRecalc=False
    screen.fill(pygame.Color("Black"))
    pygame.draw.lines(screen, pygame.Color("white"), False, Graph)
    pygame.display.flip()
