def somme_iterative(n):
    resultat = 0
    for i in range(1, n+1):
        resultat = resultat + i
    return resultat
    
def somme_formule(n):
    return n*(n+1)//2   # l'opérateur // retourne le quotient de la division euclidienne, donc le résulat est forcément entier
    
def somme_recursive(n):
    if n == 0:          # Condition d'arret de la récursion
        return 0
    else:
        return n + somme_recursive(n-1)     # On décrémente n lors du nouvelle appel à somme_recursive
    
def somme_recursive_avec_appels(n):
    print("---"*(5-n) + f" début - somme_recursive_avec_appels({n})")
    if n == 0:
        print("---"*(5-n) + f" fin - somme_recursive_avec_appels({n})")
        return 0
    else:
        s = somme_recursive_avec_appels(n-1)
        print("---"*(5-n) + f" fin - somme_recursive_avec_appels({n})")
        return n + s

"""
récursion terminale, non pris en charge par python ou alors compliqué
https://stackoverflow.com/questions/13591970/does-python-optimize-tail-recursion
"""
def somme_recursive_terminale(n,s):
    if n == 0:
        return s
    else:
        return somme_recursive_terminale(n-1, s+n)

a = 5
print (somme_iterative(a))
print (somme_formule(a))
print (somme_recursive(a))
print (somme_recursive_avec_appels(a))
print (somme_recursive_terminale(a,0))