#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
Проект "Построение графика", версия 3
Построение графика произвольной функции
в произвольно диапазоне на текстовом экране произвольных размеров
горизонтальная ориентация картинки
'''
#  name: scale
#  @param x, X0, X1, Z0, Z1
#  @return z
def scale(x, X0, X1, Z0, Z1):
  'Преобразует координату x в диапазоне [X0, X1] в координату z в диапазоне [Z0, Z1]'
  return Z0+(Z1-Z0)*(x-X0)/float(X1-X0)

#  name: round
#  @param x
#  @return x, округлённое до ближайшего целого
def round(x):
  return int(floor(x+0.5))

#  name: fun
#  @param x -- параметр, eq -- строковая формула
#  @return вычисленная формула от x
def fun(x, eq):
  return eval(eq)

#  name: grafun
#  @param X0, X1, count, formulae
#  @return список длиной count вида [(x, formulae(x)),..], х из диапазона [X0, X1]
def grafun(X0, X1, count, formulae):
  ret=[]
  for i in range(count):
    x=scale(i, 0, count-1, X0, X1)
    y=fun(x, formulae)
    ret.append((x,y))
  return ret

#  name: dot
#  @param scr, x, y[, char]
#  @return none
def dot(scr, x, y, char="*"):
  'Поставить точку (по умолчанию "*") на виртуальный экран scr'
  scr[round(y)][round(x)]=char

#  name: printscreen
#  @param scr
#  @return none
def printscreen(scr):
  'Выводит виртуальный экран scr на текстовый экран'
  print ""
  for l in range(len(scr)-1,-1,-1):
    print "".join(scr[l])

from math import *
fml=raw_input("Введите функцию в виде формулы от x (например, sin(x)*x ): ")
X0, X1, W, H = input("Введите начало диапазона, конец диапазона, ширину и высоту экрана: ")
X0, X1 = float(X0), float(X1)

gr=grafun(X0, X1, W, fml)
# Найдём минимум и максимум функции в этих точках
Y0, Y1 = min([e[1] for e in gr]), max([e[1] for e in gr])

screen=[[" "]*W for i in range(H)]  # "виртуальный экран WxH"
# нарисуем график
for e in gr:
  dot(screen, scale(e[0],X0, X1, 0, W-1), scale(e[1],Y0, Y1, 0, H-1))
# выведем получившееся
printscreen(screen)
