# -*- coding: utf-8 -*-
"""
tp1.py

TP 1


"""

# Import 

import numpy as np
import matplotlib.pyplot as plt

# Fonctions communes



# %% Partie 3

def Somme(L):
    """ Calcule la somme des éléments de la liste numérique L """
    S=0 #Accumulateur pour la somme
    for i in range(len(L)): #indices pour L
        S=S+L[i] #ou S+=L[i]
    #A ce point S= la somme des éléments de L
    return S

def Denombrement(L,mini=1,maxi=5):
    """ Compte le nbre d'éléments de L compris stric. entre mini et maxi """
    cpt=0 #Accumulateur pour compter
    for i in range(len(L)): #indices pour L
        if L[i]>mini and L[i]<maxi:
            cpt+=1
    return cpt

def SommeFiltree(L,mini=1,maxi=5):
    """ Somme les éléments de L compris stric. entre mini et maxi """
    S=0 #Accumulateur pour sommer
    for i in range(len(L)): #indices pour L
        if L[i]>mini and L[i]<maxi:
            S+=L[i]
    return S

def Produit(L):
    """ Calcule le produit des éléments de la liste numérique L """
    P=1 #Accumulateur pour le produit
    for i in range(len(L)): #indices pour L
        P=P*L[i] 
    return P

def Minimum(L):
    """ Calcule le minimum des éléments de la liste numérique L """
    m=L[0] #Accumulateur pour le min
    for i in range(len(L)): #indices pour L
        if m > L[i]:
            m=L[i] 
    return m

def Maximum(L):
    """ Calcule le maximum des éléments de la liste numérique L """
    m=L[0] #Accumulateur pour le max
    for i in range(len(L)): #indices pour L
        if m<= L[i]:
            m=L[i] 
    return m


def IndiceMinimum(L):
    """ Calcule le premier indice d'un element minimal de la liste numérique L """
    m=L[0] #Accumulateur pour le min
    imin=0 #position du minimum
    for i in range(len(L)): #indices pour L
        if m > L[i]:
            m=L[i]
            imin=i
    return imin

def IndiceMaximum(L):
    """ Calcule le dernier indice d'un element maximal de la liste numérique L """
    m=L[0] #Accumulateur pour le max
    imax=0 #position du max
    for i in range(len(L)): #indices pour L
        if m<= L[i]:
            m=L[i]
            imax=i
    return imax


liste_entiers=[2,1,4,3,6,7,5]
print("Test Somme de",liste_entiers,"=",Somme(liste_entiers))
print("Test Denombrement entre 1 et 5 de",liste_entiers,"=",Denombrement(liste_entiers))
print("Test SommeFiltree entre 1 et 5 de",liste_entiers,"=",SommeFiltree(liste_entiers))
print("Test Produit de",liste_entiers,"=",Produit(liste_entiers))
print("Test Minimum de",liste_entiers,"=",Minimum(liste_entiers))
print("Test Maximum de",liste_entiers,"=",Maximum(liste_entiers))
print("Test IndiceMinimum de",liste_entiers,"=",IndiceMinimum(liste_entiers))
print("Test IndiceMaximum de",liste_entiers,"=",IndiceMaximum(liste_entiers))



# %% Partie 4 - Suites récurrentes
def f(x):
    """ fonction f
    """
    return (x-1)**2

def fof(x):
    """ fonction fof
    """
    return f(f(x))



def suite(n,u0):
    """ 
    Entrées : un entier n et u0
    Sortie : la liste [u0,...,un] des termes de la suite
    """
    L=[u0]
    for k in range(n):
        L.append(f(L[-1]))
    return L
# %% Question 1 et 2


X = np.linspace(0,3,100)  #vecteur de 100 points régulièrement espacés entre 0 et 3
Y = f(X)  #vecteur des images des éléments de X
plt.plot(X,X)  # graphe de X en fonction de X
plt.plot(X,Y)  # graphe de Y en fonction de X
plt.show()     # commande d'affichage

# %% Question 3

def dicho(eps):
    m = 0
    M = 1
    c = (m+M)/2
    while np.abs(m-M)>eps:
        if f(c)-c > 0:
            m = c
            c = (m+M)/2
        else :
            M = c
            c = (m+M)/2
    return c

#%% Question 4

N = range(10)     # liste [0,...,9]
U = suite(9,3.0)  # liste [u0,...,u9]
U = [np.log(u) for u in U]  # lites [ln(u0),...,ln(u9)]
plt.plot(N,U,'o')
plt.show()

#%% Question 5

N = range(100)   # liste [0,...,99]
U = suite(99,2.61) # liste [u0,...,u99]
plt.plot(N,U,'o')
plt.show()

#%% Question 6

X = np.linspace(0,3,100)
Y = f(X)
Y2=fof(X)
plt.plot(X,X)
plt.plot(X,Y2)
plt.plot(X,Y)
plt.show()