%reset
global MyVariable
globals()

"""
Explanation: Devoir à mi-parcours
Exigeant d'avoir abordé les notions de : 
- Genéricité 
- Portée d'une Variable
- Structures de Contrôle (Bases)
- Types de base
- Recursivité
1) Rapels de cours, sur les declarations de contrôle
(Control Statements)
1.1) Nom de variable et valeur
Quel est/quels sont le ou les cas en python où l’on peut déclarer une variable (donc un nom) en python sans lui assigner directement une valeur ? Comment s’appelle ce type de variable spécifiquement ?
End of explanation
"""


for it in range(10):
    print(it)

it=0
while it < 10:
    print(it)
    it +=1

"""
Explanation: 1.2) Boucles en python
Expliquez brièvement le fonctionnement des deux principales boucles en python (for et while) en précisant notamment : 


qu’est ce qui change à chaque itération
quand est-ce que le boucle s’arrête
End of explanation
"""


def Ajoute_dix(inputData):
    if isinstance(inputData, int):
        return inputData + 10
    elif isinstance(inputData, str):
        return int(inputData) + 10
    else:
        return 10

# applications avec un INT
a=15
print("Le type de a est : {}".format(type(a)))
b=Ajoute_dix(a)
print("En applicant la fonction Ajoute_dix à (a) on obtient : {}".format(b))
print("Qui est de type : {}".format(type(b)))
# applications avec un STR
a='15'
print("Le type de a est : {}".format(type(a)))
b=Ajoute_dix(a)
print("En applicant la fonction Ajoute_dix à (a) on obtient : {}".format(b))
print("Qui est de type : {}".format(type(b)))


"""
Explanation: 1.3) Concept informatique
Qu’est ce qu’est la généricité (le fait qu’un code soit générique) ?
End of explanation
"""


a=5%2
print('a=5%2 is a {} of type {}'.format(a,type(a)))

a=[1]+3
print('a=[1]+3 is a {} of type {}'.format(a,type(a)))

a=[1]*3
print('a=a=[1]*3 is a {} of type {}'.format(a,type(a)))

a=9.0*9
print('a=9.0*9 is a {} of type {}'.format(a,type(a)))

a=9*"9"
print("a=9*“9” is a {} of type {}".format(a,type(a)))

a = 4 == "4"
print("a=4=“4” is a {}".format(a,type(a)))

a=4="4"
print("a=4=“4” is a {}".format(a)))

"""
Explanation: 2)  Partie 2 : Operateurs Arithmétiques
End of explanation
"""


x=3
y=5
z=11

a = True
b = False

(x < y ) and (a or b)

(x < y < z) != (a != b)

(a and (not b) and ( -y <= -z ) )

(not (a and b)) or ((y**2 < z**2))

"""
Explanation: 2.2)  Question 2
End of explanation
"""


liste1 = ["a", "b", "c", "d", "e"]

"""
Explanation: 2.3 Question 3
End of explanation
"""


liste1[ len(liste1) ]

liste1[ - len(liste1) ]

"""
Explanation: 2.3.1 Question 3.1
End of explanation
"""


a=2
while a <= 7:
    a = a*a + a + 1
print(a)

"""
Explanation: 2.4 Question 4
End of explanation
"""


a=1
for it in range(5):
    a = a + it
print(a)

"""
Explanation: 2.5 Question 5
End of explanation
"""


liste1 = [1,2,3]
liste2 = liste1
liste2.append(4)
print(liste1)

"""
Explanation: 2.6 Question 6
End of explanation
"""


x=8
liste1 = [ ]
for it in range(x//2):
    liste1.append( x - it )
print( liste1 )

"""
Explanation: 2.7 Question 7
End of explanation
"""


def cube_si_abs_plus_grande_que_un( x ):
    if abs( x*x*x >= 1.0 :
        print("Erreur")
        return
    return x*x*x

def cube_si_abs_plus_grande_que_un( x ):
    if abs( x*x*x <= 1.0 ) : ## Condition mal formeé
        print("Erreur")
        return
    return x*x*x

print(cube_si_abs_plus_grande_que_un(3))

"""
Explanation: 3) Debogage de code
Dans cette partie les codes fournis ne fonctionnent pas, soit parce qu’ils provoquent une erreur, soit parce qu’ils ne produisent pas les résultats attendus.
Le but est de les corriger.
3.1 Exercice 1 : Syntax error
3.1.1 Exercice 1.1
End of explanation
"""


def factorielle( int( n ) ):
    res = 1
    for it in range(1,n+1):
        res = res*it
return res

print( factorielle( 10 ) )

def factorielle( n ):
    res = 1
    for it in range(1,n+1):
        res = res*it
    return res

print( factorielle( 10 ) )

"""
Explanation: 3.1.2 Exercice 1.2
End of explanation
"""


def somme_carre( n ):
    res = 0
i=0
while i < n:
i += 1
        res += i*i
      return res

def somme_carre( n ):
    res = 0
    i=0
    while i < n:
        i += 1
        res += i*i
    return res

somme_carre(10)

"""
Explanation: 3.1.3 Exercice 1.3
End of explanation
"""


from math import srqt #Faute de frape
def somme_sqrt( n ):
res = 0 i=0 while i < n #On ne declare pas les vaiables sur la m ligne
i += 1#Faute d'indentation
        res += sqrt(i)
    return res

from math import sqrt #Faute de frape
def somme_sqrt( n ):
    res = 0 
    i=0 
    while (i < n):
        i += 1
        res += sqrt(i)
    return res

somme_sqrt(5)

"""
Explanation: 3.1.4) Exercice 1.4
End of explanation
"""


def somme_racine_cubique( n ):
    res = 0
    for it in range(n):
        res += it**(1/3)
    return res

somme_racine_cubique(8)

def somme_racine_cubique( n ):
    res = 0
    for it in range(n+1):
        res += it**(1/3)
    return res

somme_racine_cubique(8)

"""
Explanation: 3.2 Exercice 3
End of explanation
"""


def f(liste):
    for i in range(len(liste)):
        for j in range(i):
            if liste[i][j] != 0: 
                return False
    return True

a = f( [[1,1,1],
        [0,1,1],
        [0,0,1]] )
print('Est ce que la matrice contient des 0 sous la diagonale ? {}'.format(a))

a = f( [[1,0,0],
        [0,1,0],
        [0,0,1]] )
print(a)

b = f( [[1,1,1],
        [0,1,1],
        [0,0,1]] )
print(b)

c = f( [[1,0,0],
        [1,1,0],
        [1,1,1]] )
print(c)

d = f( [[1,1,1],
        [1,1,1],
        [1,1,1]] )
print(d)

"""
Explanation: 4) Analyse de code
Dans cette partie les codes fonctionnent, le but étant de comprendre leur effet, ou d’être capable de les simplifier.
4.1 Exercice 1
End of explanation
"""


def f( n ):
    if n == 0:
        return False
    return not f( n - 1 )

a = f(12)
b = f(8)
c = f(13)
print(a,b,c)

for it in range(50):
    print('le nombre {0} est il impair ? {1}'.format(it,f(it)))

"""
Explanation: 4.2 Exercice 2
End of explanation
"""


def f( n ):
    res = 0
    for it in range(n):
        if it % 5 == 1:
            res = res + it
        if it % 7 == 1:
            res = res + it
        if it % 9 == 1:
            res = res + it
    return res

for it in range(50):
    print('Si on applique à {} la fonction on obtient {} '.format(it,f(it)))

def f( n ):
    res=0
    for it in range(n):
        if (it % 5 == 1): res += it
        if (it % 7 == 1): res += it
        if (it % 9 == 1): res += it          
    return res

def f (n ):
    l=range(n)
    liste1=[it for it in l if it % 5 == 1]
    liste2=[it for it in l if it % 7 == 1]
    liste3=[it for it in l if it % 9 == 1]
    return (sum(liste1)+sum(liste2)+sum(liste3))

for it in range(50):
    print('Si on applique à {} la fonction on obtient {} '.format(it,f(it)))

"""
Explanation: 4.3 Exercice 3
End of explanation
"""


from time import clock
def duree(fonction, n=10):
    debut = clock()
    fonction(n)
    fin = clock()
    return fin - debut

def somme_n_entiers1(n):
    ref=0
    l=range(n+1)
    for it in l:
        if it % 2 == 0:
            ref += it
    return ref

def somme_n_entiers2(n):
    it=0
    ref=0
    l=range(n+1)
    while (it < len(l)):
        if (l[it] % 2 == 0):
            ref += it
        it += 1
    return ref

def SumRec(n):
    if n  == 0:
        return(0)
    elif n % 2 != 0:
        return(n-1 + SumRec(n-3))
    else :
        return(n + SumRec(n-2))

def SommePair(n):
    return sum(range(0,n+1,2))

print('{:>25}> {:f} s'.format('utilisation de la fonction for ',duree(somme_n_entiers1) ))
print('{:>25}> {:f} s'.format('utilisation de la fonction while ',duree(somme_n_entiers2) ))
print('{:>25}> {:f} s'.format('utilisation la plus simple ',duree(SommePair) ))
print('{:>25}> {:f} s'.format('utilisation la recursivité ',duree(SumRec) ))

"""
Explanation: 5) Codage
5.1 Exercice 1 : somme de multiples pairs
et evaluation de leur performance...
End of explanation
"""


def Test_11(My_Liste):
    for it in My_Liste:
        if it % 11 == 0: 
            return True
            break
    return False

Test_11([1, 2, 3, 22])


"""
Explanation: 5.2 Exercice 2 : recherche de multiple de 11
End of explanation
"""


def div_euclidiene(a,b):
    q,r=0,a
    while r>=b:
        q,r=q+1,r-b
    return(q,r)


a=546
b=34
quotient, reste = div_euclidiene(a,b)
print("La Division euclidienne peut s'ecrire \n {0} = {1} x {2} + {3}".format(a,b,quotient,reste))

"""
Explanation: 6  Algorithme des différences successives
End of explanation
"""


