Python

Les Fonctions
A temps perdu...

Login / Mot de passe

L'utilisateur entre son nom et son prénom. Dans l'exemple d'affichage ci-dessous, l'utilisateur a entré bernard puis alain après les messages incitatifs :

Quel est votre nom ? bernard
Quel est votre prénom ? alain
Votre login est : a.bernard
Votre nom masqué est : b***d

Le programme doit utiliser une fonction login() qui prend pour variables deux chaînes de caractères et qui renvoie la 1ère lettre de la 1ère chaîne et la 2nde chaîne complète, séparées par un point (cf. l'affichage ci-dessus).

Le programme doit aussi utiliser une fonction masquer() qui prend pour variable une chaîne de caractères et qui renvoie la 1ère et la dernière lettre de cette chaîne de caractères, séparées par trois étoiles : ***.

  • Une piste ?
  • Un schéma ?
  • Une analyse ?
  • Solution

La fonction login() nécessite deux paramètres qui sont des chaînes de caractères. On peut les nommer ch1 et ch2 par exemple.

Dans la fonction login(ch1, ch2),

  • on extrait le 1er caractère avec ch1[0] ;
  • puis on renvoie une concaténation des caractères grâce à l'opérateur «+».
C'est la même idée qui permet de définir la fonction masquer().
##-----Définition des Fonctions-----##
def login(texte1, texte2):
    """Cette fonction renvoie la 1ère lettre de texte1 et texte2 complet,
       séparés par un point."""
    chaine = texte1[0] + '.' + texte2
    return chaine

def remplacer(texte):
    """Cette fonction renvoie la 1ère lettre et la dernière lettre de
       texte, séparées par trois étoiles '***'."""
    long = len(texte)-1        			# Indice du dernier caractère de la chaîne
    chaine = texte[0] + '***' + texte[long]
    return chaine

##-----Programme principal-----##
nom = input('Quel est votre nom ? ')
prenom = input('Quel est votre prénom ? ')
print('Votre login est :', login(prenom, nom))
print('Votre nom masqué est :', masquer(nom))

Suite de Robinson **

Quelle est la logique de passage d'une ligne à l'autre dans ce qui suit ?

0
10
1110
3110
132110
13123110
23124110
1413223110
1423224110
2413323110
  1. En première ligne, on commence par la chaîne '0'.
  2. En seconde ligne, on écrit ce qu'on voit en première ligne : un '0', ce qui donne '10'.
  3. En troisième ligne, on lit ce que l'on voit dans la ligne précédente : trois '1' et un '0', ce qui donne '1110'.
  4. ...et ainsi de suite en indiquant au même endroit le nombre total d'occurrences d'un chiffre donné dans la chaîne.

Les chiffres sont écris dans l'ordre décroissant et on n'indique pas l'effectif d'un chiffre absent.

Écrire un programme qui demande un entier n > 0 à l'utilisateur puis que affiche n lignes du triangle ci-dessus. Ce programme devra être décomposé en deux fonctions :

  • compteCarac() : fonction prenant en entrée une chaîne de caractères ch et un caractère car et retournant le nombre d'occurrences de car dans ch.
  • ligneSuivante() : fonction prenant en entrée une chaîne de caractères ch (constituée de chiffres) et retournant la ligne constituant le terme suivant dans la suite de Robinson.
  • Une piste ?
  • Un schéma ?
  • Une analyse ?
  • Solution
Le principe de la fonction compteCarac() a déjà été étudié dans d'autres exercices.

On compte le nombre de '9' puis le nombre de '8' et ainsi de suite jusqu'au nombre de '0' dans la ligne précédente pour obtenir la nouvelle ligne.

Bien évidemment, on n'affiche rien s'il n'y a pas d'occurence du chiffre étudié à la ligne précédente.

L'algorithme à appliquer semble clair
##----- Définition des Fonctions -----##
def compteCarac(texte, car):
    """texte est une chaîne de caractères, car est un caractère.
		Cette fonction renvoie le nombre entier d'occurences du
		caractère car dans le texte."""
	n = 0
	for lettre in texte :
		if lettre == car :
			n += 1
	return n

def ligneSuivante(texte):
    """texte est une chaîne de caractères constituée de chiffres.
		Cette fonction renvoie la ligne suivante dans le triangle de Robinson."""
    ligne = ''							# On part d'une chaîne vide
    for chiffre in '9876543210':
		if chiffre in texte:
			ligne += str(compteCarac(texte, chiffre)) + chiffre
	return ligne


##----- Programme principal -----##
while True:								# On contraint l'utilisateur
    try:
        n = int(input('Entrer un entier strictement positif : '))
        if n > 0 :                      # Strictement positif ?
            break                       # On sort de la boucle infinie
    except:
        print('Respecte les consignes, merci !')

ligne = '0'
for i in range(n):
	print(ligne)
	ligne = ligneSuivante(ligne)

Suite de Conway **

Quelle est la logique de passage d'une ligne à l'autre dans ce qui suit ?

1
11
21
1211
111221
312211
13112221
1113213211
  1. En première ligne, on commence par la chaîne '1'.
  2. En seconde ligne, on écrit ce qu'on voit en première ligne : un '1', ce qui donne '11'.
  3. En troisième ligne, on lit ce que l'on voit dans la ligne précédente : deux '1', ce qui donne '21'.
  4. Sur la ligne suivante, on écrit de même ce que l'on voit : un '2' et un '1', ce qui donne '1211'.
  5. ...et ainsi de suite...

Écrire un programme qui demande un entier n > 0 à l'utilisateur puis qui affiche n lignes du triangle ci-dessus.

  • Une piste ?
  • Un schéma ?
  • Une analyse ?
  • Solution
  • Variante

Trois fonctions sont nécessaires dans ce programme :

Prenons par exemple la chaîne de caractères 'aaaabccd'. Selon le principe de la suite de Conway, la ligne suivante devrait être '4a1b2c1d'. Comment y arriver ?

  1. On mémorise le 1er caractère de la chaîne :
  2. On le «compte» (il y en a un...).
  3. On passe au caractère suivant.
  4. Tant que ce caractère est le même que le 1er caractère pointé, on passe au suivant et on ajoute 1 au décompte.
  5. Lorsque le caractère suivant est différent du caractère pointé, on enregistre le décompte précédent puis on mémorise le nouveau caractère.
  6. Puis on recommence (pointage, ajout au décompte si caractère identique, passage au caractère suivant) jusqu'à pointer le dernier caractère de la chaîne...

Parcourir l'ensemble des caractères avec une boucle for ne paraît pas judicieux. Imbriquer deux boucles while testant sur l'indice du caractère pointé dans la chaîne semble être une meilleure option.

##----- Définition des Fonctions -----##
def ligneSuivante(texte):
    """texte est une chaîne de caractères constituée de chiffres.
		Cette fonction renvoie la ligne suivante dans le triangle de Conway."""
    ligne = ''							# On part d'une chaîne vide
	p = 0								# On pointe sur le 1er caractère
    while p < len(texte):
		car = texte[p]
		d = 1 							# On commence le décompte
		p += 1
		while p < len(texte) and texte[p] == car:
			d += 1
			p += 1
		ligne += str(d) + car
	return ligne


##----- Programme principal -----##
while True:								# On contraint l'utilisateur
    try:
        n = int(input('Entrer un entier strictement positif : '))
        if n > 0 :                      # Strictement positif ?
            break                       # On sort de la boucle infinie
    except:
        print('Respecte les consignes, merci !')

ligne = '1'
for i in range(n):
	print(ligne)
	ligne = ligneSuivante(ligne)

Une autre version, avec un autre raisonnement et utilisant davantage de fonctions. Celles-ci peuvent plus facilement être ré-utilisées dans d'autres programmes.

##----- Définition des Fonctions -----##
def CompteCaracSuite(texte) :
    """La fonction retourne le nombre de caractères successifs identiques au début du texte.
		CompteCaracSuite('aaaabccd') renvoie 4 et CompteCaracSuite('') doit renvoyer 0."""
    
    if len(texte) == 0 : 
        return 0						# chaine vide, on renvoie 0

    car = texte[0]
    d = 0								# compteur de caractères identiques

    for lettre in texte :
        if lettre == car :
			d += 1
        else :
			break						# On sort de la boucle for
    return d 


def EnleveDebut(texte):
    """ La fonction retourne la chaîne de caractères "texte" tronquée des
	premiers caractères identiques. EnleveDebut('aaaabccd') renvoie 'bccd'."""

    n = CompteCaracSuite(texte)			# nombre de caractères identiques au début
    return texte[n:]					# on tronque grâce aux tranches
                   
    
def ligneSuivante(texte):
    """texte est une chaîne de caractères constituée de chiffres.
		Cette fonction renvoie la ligne suivante dans le triangle de Conway."""
    ligne = ''							# On part d'une chaîne vide
	while texte != '':
		ligne += str(CompteCaracSuite(texte)) + texte [0]
		texte = EnleveDebut(texte)
	return ligne


##----- Programme principal -----##
while True:								# On contraint l'utilisateur
    try:
        n = int(input('Entrer un entier strictement positif : '))
        if n > 0 :                      # Strictement positif ?
            break                       # On sort de la boucle infinie
    except:
        print('Respecte les consignes, merci !')

ligne = '1'
for i in range(n):
	print(ligne)
	ligne = ligneSuivante(ligne)