# Créé par Fab Cap2, le 27/05/2026 en Python 3.7
import numpy as np
import matplotlib.pyplot as plt

# =========================================
# 1. VALEURS EXPÉRIMENTALES À SAISIR
# =========================================

# Valeurs de a en m dont une manquante
a = np.array([
    0.20e-3,
    0.30e-3,
    ...,
    0.40e-3,
    0.50e-3
])

# Valeurs de i en m dont une manquante
i = np.array([
    4.75e-3,
    3.17e-3,
    ...,
    2.38e-3,
    1.90e-3
])

# =========================================
# 2. CHOIX DE LA COURBE
# =========================================

print("=================================")
print("CHOIX DE LA COURBE")
print("=================================")
print("1 : i = f(a)")
print("2 : i = f(1/a)")

choix_courbe = input("Votre choix : ")

if choix_courbe == "1":
    x = a
    nom_x = "a"
    xlabel = "a (m)"

elif choix_courbe == "2":
    x = 1 / a
    nom_x = "1/a"
    xlabel = "1/a (m⁻¹)"

else:
    raise ValueError("Choix de courbe invalide.")

# =========================================
# 3. CHOIX DU MODÈLE
# =========================================

print("\n=================================")
print("CHOIX DU MODÈLE")
print("=================================")
print("1 : Linéaire")
print("2 : Exponentiel")
print("3 : Logarithmique")

choix_modele = input("Votre choix : ")

# Domaine lisse pour le tracé
x_modele = np.linspace(min(x), max(x), 500)

# =========================================
# MODÈLE LINÉAIRE
# =========================================

if choix_modele == "1":

    print("\nLa droite passe-t-elle par l'origine ?")
    print("1 : Oui")
    print("2 : Non")

    choix_origine = input("Votre choix : ")

    # -------------------------------------
    # DROITE PASSANT PAR L'ORIGINE
    # -------------------------------------

    if choix_origine == "1":

        k = np.sum(x * i) / np.sum(x**2)

        i_modele = k * x_modele

        if choix_courbe == "1":
            equation = f"i = {k:.3e} × a"

        else:
            equation = f"i = {k:.3e} × 1/a"

    # -------------------------------------
    # DROITE GÉNÉRALE
    # -------------------------------------

    elif choix_origine == "2":

        k, b = np.polyfit(x, i, 1)

        i_modele = k * x_modele + b

        if choix_courbe == "1":
            equation = f"i = {k:.3e} × a + {b:.3e}"

        else:
            equation = f"i = {k:.3e} × 1/a + {b:.3e}"

    else:
        raise ValueError("Choix invalide.")

# =========================================
# MODÈLE EXPONENTIEL
# =========================================

elif choix_modele == "2":

    if np.any(i <= 0):
        raise ValueError(
            "Le modèle exponentiel nécessite des valeurs positives."
        )

    B, lnA = np.polyfit(x, np.log(i), 1)

    A = np.exp(lnA)

    i_modele = A * np.exp(B * x_modele)

    equation = f"i = {A:.3e} × exp({B:.3e} × {nom_x})"

# =========================================
# MODÈLE LOGARITHMIQUE
# =========================================

elif choix_modele == "3":

    if np.any(x <= 0):
        raise ValueError(
            "Le modèle logarithmique nécessite des valeurs positives."
        )

    k, b = np.polyfit(np.log(x), i, 1)

    i_modele = k * np.log(x_modele) + b

    equation = f"i = {k:.3e} × ln({nom_x}) + {b:.3e}"

else:
    raise ValueError("Choix de modèle invalide.")

# =========================================
# 4. AFFICHAGE DU GRAPHE
# =========================================

plt.figure(figsize=(9, 5))

# Points expérimentaux
plt.scatter(
    x,
    i,
    label="Mesures expérimentales"
)

# Courbe du modèle
plt.plot(
    x_modele,
    i_modele,
    label="Modélisation"
)

# Axes
plt.xlabel(xlabel)
plt.ylabel("i (m)")

# Titre
plt.title("Étude de l'interfrange")

# Grille
plt.grid()

# Légende
plt.legend()

# Affichage de l'équation
plt.text(
    0.05,
    0.95,
    equation,
    transform=plt.gca().transAxes,
    verticalalignment="top",
    bbox=dict(
        boxstyle="round",
        facecolor="white"
    )
)

# Affichage final
plt.show()