# -*- coding: utf-8 -*-
"""
Created on Tue May 21 13:57:06 2019

@author: Stéphane Pasquet
"""
import numpy as np
import matplotlib.pyplot as plt
from sympy import *
x = Symbol('x')

def definite_function():
    fonction = input("Entrez l'expression de la fonction : ")
    # convertit la chaîne de caractères en 'fonction'
    f = lambdify(x,fonction,'math') # on utilise le module 'math' ici plutôt que 'numpy' car plus pratique
    fonction_latex = input('Syntaxe LaTeX : ')
    return f,fonction_latex

def window():
    xmin = float(input('xmin = '))
    xmax = float(input('xmax = '))
    ymin = float(input('ymin = '))
    ymax = float(input('ymax = '))
    return xmin,xmax,ymin,ymax

def definite_first_term():
    u = float(input("Entrez le premier terme : "))
    return u

def definite_nb_terms():
    n = int(input('Nombre de termes à construire : '))
    return n

def definite_name():
    name = input("Entrez le nom de l'image à sauvegarder (appuyez sur [Entrée] si vous ne voulez pas sauvegarder l'image) : ")
    return name

def construct_graph(xmin,xmax,ymin,ymax,f,fonction,u,n,name):
    """
    fig = plt.gcf()
    # tracé du repère et de la grille
    ax = plt.axes([xmin,ymin,xmax,ymax])
    ax.set_xlim(xmin,xmax)
    ax.set_ylim(ymin,ymax)
    ax.xaxis.set_major_locator(plt.MultipleLocator(1.0))
    ax.xaxis.set_minor_locator(plt.MultipleLocator(0.1))
    ax.yaxis.set_major_locator(plt.MultipleLocator(1.0))
    ax.yaxis.set_minor_locator(plt.MultipleLocator(0.1))
    ax.grid(which='minor', axis='x', linewidth=0.25, linestyle='--', color='0.75')
    ax.grid(which='minor', axis='y', linewidth=0.25, linestyle='--', color='0.75')
    """
    fig = plt.figure()
    ax = fig.add_subplot(111, aspect='equal')
    ax.grid()
    ax.spines['bottom'].set_position('zero')
    ax.spines['left'].set_position('zero')
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)

    # tracé des courbes
    x = np.linspace(xmin, xmax, 201)
    y = [f(x) for x in [xmin+i*(xmax-xmin)/200 for i in range(201)]]
    plt.plot(x,y,color='green')
    plt.plot(x,x,color='red')

    # 1er terme
    x = [u,u]
    y = [0,f(u)]
    plt.plot(x,y,linestyle='--',color='blue',linewidth=0.5)
    # construction des termes
    for i in range(0,n):
        x = [u,u]
        y = [u,f(u)]
        plt.plot(x,y,linestyle='--',color='blue',linewidth=0.5)
        x = [u,f(u)]
        y = [f(u),f(u)]
        plt.plot(x,y,linestyle='--',color='blue',linewidth=0.5)
        if i != n-1:
            x = [f(u),f(u)]
            y = [f(u),0]
            plt.plot(x,y,linestyle='--',color='orange',linewidth=0.5)
        if i%2 == 0:
            yunder=-0.05
        else:
            yunder = -0.1
        plt.text(u-0.02,yunder,np.around(u,2))
        u = f(u)

    params = {'mathtext.default': 'regular' }
    plt.rcParams.update(params)
    plt.rc('text', usetex = True)
    #plt.rc('font', family = 'serif')
    title = "Construction des "+str(n)+" premiers termes de la suite définie par\n$u_{n+1}=f(u_n)$ avec $f(x)="+fonction+"$"
    plt.title(title)
    if name != '':
        fig.savefig(name+'.png',dpi=100,bbox_inches='tight')
    plt.show()

if __name__ == '__main__':
    f,fonction = definite_function()
    u = definite_first_term()
    xmin,xmax,ymin,ymax = window()
    n = definite_nb_terms()
    name = definite_name()
    construct_graph(xmin,xmax,ymin,ymax,f,fonction,u,n,name)