Programmer en Python en 2nde

Sortie anticipée de boucle ou de fonction

Plus tard ! Cette page peut être travaillée en seconde lecture.

Plusieurs return dans une fonction

On aimerait écrire une fonction spécifiée ainsi :

Paramètre Une liste de nombres
Valeur renvoyée True si la liste contient un 0, False sinon.

On peut procéder ainsi :


 
def contient_0(liste):
    presence_d_un_zero = False
    for x in liste:
        if x == 0:
            presence_d_un_zero = True
    return presence_d_un_zero
	
	
L = [1, 1, 1, 0, 1]
M = [1, 1, 1]

print(contient_0(L))
print(contient_0(M))

L'inconvénient de cette méthode est que la liste est entièrement parcourue, même si un 0 est trouvé dès le début de liste. Dans le cas de listes très longues, cela induit des pertes de temps.

Nous proposons ci-dessous trois façons de stopper le parcours de la liste dès qu'un 0 est obtenu.

  • Boucle while
  • Sortir avec break
  • Sortir avec return
  • Compléments Python

L'utilisation d'une boucle while est ici naturelle puisqu'on ne sait pas a priori à quel moment on pourra stopper la boucle.

On est toutefois obligé d'alourdir le code avec une variable servant d'indice afin de contrôler que l'on ne dépasse pas la longueur de la liste (ce qui provoquerait une erreur) :


def contient_0(liste):
    # indice pour parcourir la liste :
    i = 0 
    # initialisation de la variable presence_d_un_zero :
    presence_d_un_zero = (liste[i] == 0)	# de type booléen
	
    # boucle de parcours de la liste
    # arrêtée dès qu'un 0 est trouvé :
    while not(presence_d_un_zero) and (i < len(liste)-1) :
        i += 1								# on incrémente d'une unité
        presence_d_un_zero = (liste[i] == 0)
    return presence_d_un_zero
	
	
L = [1, 1, 1, 0, 1]
M = [1, 1, 1]

print(contient_0(L))
print(contient_0(M))

Nous avons une boucle :

  • a priori bornée (par la longueur de liste), ce qui appelle plutôt une boucle for,
  • mais pouvant être stoppée plus tôt, ce qui demanderait plutôt l'usage d'une boucle while.

Pour éviter d'alourdir le code comme dans la première solution (avec un indice de parcours et une condition d'arrêt double), le langage Python offre la possibilité de stopper une boucle for avant son terme en utilisant l'instruction break.

On obtient le code suivant, un peu plus facile à lire :


def contient_0(liste):
    presence_d_un_zero = False
	
    for x in liste :
        if x == 0 :
            presence_d_un_zero = True
            break 						# arrêt de la boucle for
			
    return presence_d_un_zero
	
	
L = [1, 1, 1, 0, 1]
M = [1, 1, 1]

print(contient_0(L))
print(contient_0(M))

Remarque importante

Tous les programmeurs s'accordent aujourd'hui pour proscrire l'usage de goto dans les programmes ( «programmation spaghetti»). L'usage de break est parfois proscrite pour les mêmes raisons : il permet de sauter d'une partie de programme à une autre en ne respectant pas les structures de programmation usuelles.

Il est possible d'allèger encore ce code en utilisant une propriété du mot-clé return : dès qu'il est rencontré, le programme sort de la fonction. Les instructions qui suivent l'exécution d'un return ne sont tout simplement pas lues.

On en déduit le code ci-dessous :


def contient_0(liste):
    for x in liste :		# Parcours de chaque valeur de la liste
        if x == 0 :
            return True
 
    return False			# Aucun 0 n'a été rencontré
	
	
L = [1, 1, 1, 0, 1]
M = [1, 1, 1]

print(contient_0(L))
print(contient_0(M))

La fonction est stoppée et renvoie True dès qu'un 0 est rencontré.

Si on ne rencontre pas de 0 dans la boucle, l'instruction return de la boucle n'est jamais vue/lue. Python exécute dans ce cas la ligne inscrite après la boucle et la fonction renvoie False.

Pour la question particulière posée ici, on peut utiliser le mot-clef in de Python :


			
			

Présence d'un zéro dans les chiffres d'un entier

Écrire une fonction en Python qui respecte la spécification suivante :

Paramètres un entier naturel n non nul
Valeur renvoyée True si l'un des chiffres de n est 0 (en base 10) et False sinon.

Compléter le programme par un test sur quelques nombres et l'affichage correspondant à l'écran.

  • while
  • break
  • for
  • return
  • in

def a_chiffre_nul(n):
    """ n : entier naturel non nul. """
    un_chiffre_nul = False
	
    while n > 0 and not(un_chiffre_nul):
        if n%10 == 0 : 
            un_chiffre_nul = True
        n = n//10
		
    return un_chiffre_nul


def affiche_resultat(n):
    chiffre_nul = a_chiffre_nul(n)
    if chiffre_nul :
        print("Au moins un chiffre de {} est nul.".format(n))
    else :
        print("Aucun chiffre de {} n'est nul.".format(n))
		
 
affiche_resultat(2)
affiche_resultat(102)

L'instruction break peut également stopper une boucle while :


def a_chiffre_nul(n):
    """ n : entier naturel non nul. """
    un_chiffre_nul = False
	
    while n > 0 :
        if n%10 == 0 : 
            un_chiffre_nul = True
            break
        n = n//10
		
	return un_chiffre_nul
	
def affiche_resultat(n):
    chiffre_nul = a_chiffre_nul(n)
    if chiffre_nul :
        print("Au moins un chiffre de {} est nul.".format(n))
    else :
        print("Aucun chiffre de {} n'est nul.".format(n))
		
 
affiche_resultat(2)
affiche_resultat(102)  

Avec une boucle for et len(str())

Notons K le nombre de chiffres de l'entier n (écriture usuelle en base 10). Ce nombre K peut s'obtenir en Python avec le code len(str(n)) car str(n) transforme l'entier n en chaîne de caractères.

Par exemple, l'entier 12 devient la chaîne "12". Et len() renvoyant le nombre de caractères d'une chaîne, l'instruction len(str(12)) renverra la valeur 2.

La boucle s'exécutant a priori au plus K fois, on peut utiliser len(str(n)) :


def a_chiffre_nul(n):
    """ n : entier naturel non nul. """
    un_chiffre_nul = False

    for _ in range(len(str(n))) :
        if n%10 == 0 :
            un_chiffre_nul = True
            break
        n = n//10

    return un_chiffre_nul

def affiche_resultat(n):
    chiffre_nul = a_chiffre_nul(n)
    if chiffre_nul :
        print("Au moins un chiffre de {} est nul.".format(n))
    else :
        print("Aucun chiffre de {} n'est nul.".format(n))


affiche_resultat(2)
affiche_resultat(102)
affiche_resultat(9920)

Avec une boucle for et un peu d'arithmétique



def nombre_chiffres(n):
    if n==0 : return 1
    compteur = 0
    while n != 0:
        n = n//10
        compteur += 1
    return compteur
	
	

def a_chiffre_nul(n):
    """ n : entier naturel non nul. """
    un_chiffre_nul = False

    for _ in range(nombre_chiffres(n)) :
        if n%10 == 0 :
            un_chiffre_nul = True
            break
        n = n//10

    return un_chiffre_nul
	
	

def affiche_resultat(n):
    chiffre_nul = a_chiffre_nul(n)
    if chiffre_nul :
        print("Au moins un chiffre de {} est nul.".format(n))
    else :
        print("Aucun chiffre de {} n'est nul.".format(n))


affiche_resultat(2)
affiche_resultat(102)
affiche_resultat(9920)

On retrouve ci-dessous un code similaire à celui de la solution utilisant une boucle while et l'instruction break :


def a_chiffre_nul(n):
    """ n : entier naturel non nul. """
    while n > 0 :
        if n%10 == 0 :
            return True
        n = n//10
		
	return False
	
def affiche_resultat(n):
    chiffre_nul = a_chiffre_nul(n)
    if chiffre_nul :
        print("Au moins un chiffre de {} est nul.".format(n))
    else :
        print("Aucun chiffre de {} n'est nul.".format(n))
		
 
affiche_resultat(2)
affiche_resultat(102)

Avec le mot-clé in et la transformation de l'entier en chaîne de caractères, le code est plus bref (mais l'objectif étant de faire des mathématiques, on ne choisira pas a priori cette option de facilité).


def a_chiffre_nul(n):
    """ n : entier naturel non nul. """
    return '0' in str(n)
	
def affiche_resultat(n):
    chiffre_nul = a_chiffre_nul(n)
    if chiffre_nul :
        print("Au moins un chiffre de {} est nul.".format(n))
    else :
        print("Aucun chiffre de {} n'est nul.".format(n))
		
 
affiche_resultat(2)
affiche_resultat(102)

Nombre premier

Écrire une fonction en Python qui respecte la spécification suivante :

Paramètres un entier naturel n > 1
Valeur renvoyée True si n est premier, False sinon

Compléter le programme par un test sur quelques nombres et l'affichage correspondant à l'écran.

  • Solution utilisant while
  • Solution utilisant break
  • Solution utilisant return

from math import floor, sqrt

def est_premier(n):
    """ n entier naturel au moins égal à 2. """
    premier = True
    d = 2
    while premier and d <= floor(sqrt(n)) :
        if n%d == 0 :
            premier = False			# Sortie de la boucle while
        d += 1
		
    return premier
	
for k in range(2, 20):
    print("{} est premier : {}.".format(k, est_premier(k)))

Avec une boucle for :


from math import floor, sqrt

def est_premier(n):
    """ n entier naturel au moins égal à 2. """
    premier = True
    for d in range(2, floor(sqrt(n)) + 1 ) :
        if n%d == 0 :
            premier = False
            break
        d += 1

    return premier

for k in range(2, 20):
    print("{} est premier : {}.".format(k, est_premier(k)))

Ou avec un while :


from math import floor, sqrt

def est_premier(n):
    """ n entier naturel au moins égal à 2. """
    premier = True
    d = 2
    while d <= floor(sqrt(n)) :
        if n%d == 0 : 
            premier = False
            break
        d += 1
		
    return premier
	
for k in range(2, 20):
    print("{} est premier : {}.".format(k, est_premier(k)))

from math import sqrt

def est_premier(n):
    """ n entier naturel au moins égal à 2. """
    d = 2
    while d <= sqrt(n)  :
        if n%d == 0 :
            return False
        d += 1
		
    return True
	
for k in range(2, 20):
    print("{} est premier : {}.".format(k, est_premier(k)))

Pour éviter l'appel à la racine carrée sqrt() (qui fait "sortir" des entiers), on peut effectuer la modification suivante :


def est_premier(n):
    """ n entier naturel au moins égal à 2. """
    d = 2
    while d*d <= n  :
        if n%d == 0 :
            return False
        d += 1
		
    return True
	
for k in range(2, 20):
    print("{} est premier : {}.".format(k, est_premier(k)))

Palindrome

Écrire une fonction en Python qui respecte le cahier des charges suivant :

Paramètres une chaîne de caractères ch
Valeur renvoyée True si ch est un palindrome, False sinon

On rappelle qu'un palidrome est une chaîne de caractères qui peut se lire à l'identique dans les deux sens :

  • radar
  • sos
  • ressasser

Compléter le programme par un test sur quelques chaînes et l'affichage correspondant à l'écran.

  • Solution utilisant while
  • Solution utilisant break
  • Solution utilisant return

def est_palindrome(mot) :
    palin = True							# Booléen qui permet d'arrêter le parcours
    i = 0
    while palin and i <= len(mot)//2 :	# Parcours de la moitié de la chaîne
        if  mot[i] != mot[-i-1] : 
            palin = False
        i += 1
    return palin
	
	
	
print(est_palindrome("karineallaenirak"))
print(est_palindrome("sos"))
print(est_palindrome("soos"))
print(est_palindrome("soso"))
print(est_palindrome("radar"))
print(est_palindrome("radars"))

def est_palindrome(mot) :
    palin = True
 
    for i in range(0, len(mot)//2+1 ) :  
        if  mot[i] != mot[-i-1] : 
            palin = False
            break
		 
    return palin
	
	
	
print(est_palindrome("karineallaenirak"))
print(est_palindrome("sos"))
print(est_palindrome("soos"))
print(est_palindrome("soso"))
print(est_palindrome("radar"))
print(est_palindrome("radars"))

def est_palindrome(mot) :
	 
    for i in range(0, len(mot)//2+1 ) :  
        if  mot[i] != mot[-i-1] :
            return False
		 
    return True
	
	
	
print(est_palindrome("karineallaenirak"))
print(est_palindrome("sos"))
print(est_palindrome("soos"))
print(est_palindrome("soso"))
print(est_palindrome("radar"))
print(est_palindrome("radars"))