Aller au contenu

Miroir

Miroir

Définition

On appelle miroir d'un mot, le mot écrit à contre-sens.

Exemples:

  • le miroir de "soleil" est "lielos".
  • le miroir de "ados" est "soda".
  • le miroir de "épater" est "retapé".
  • le miroir de "repas" est "saper".

Note

Lorsque un mot et un miroir ont tous deux une signification, on parle d'anacyclique.

Programmation

Écrire un code possible pour la fonction:

def miroir(mot):
    """
    mot -- chaîne de caractères

    renvoie la chaîne miroir de mot.

    >>> miroir('soleil')
    'lielos'
    """
Un code
def miroir(mot):
    """
    mot -- chaîne de caractères

    renvoie la chaîne miroir de mot.

    >>> miroir('soleil')
    'lielos'
    """
    ch = ''
    for lettre in mot:
        ch = lettre + ch
    return ch

Pour bien comprendre ce qui est fait ici, réfléchissez à ce que l'on obtiendrait en écrivant ch = ch + lettre à la place de ch = lettre + ch.

Palindrome

Définition

On appelle palindrome un mot qui est égal à son miroir.

Exemples:

  • radar, rotor, kayak, été, ici, tôt, ressasser
  • "engagelejeuquejelegagne"
  • "karineallaenirak"

Programmation

Écrire un code possible pour la fonction:

def est_palindrome(mot):
    """
    mot -- chaîne de caractères
    renvoie True si mot est égal à son miroir, False sinon.

    >>> est_palindrome('été')
    True
    >>> est_palindrome('hiver')
    False
    """
  • Écrire une version utilisant la fonction miroir de l'exercice précédent.
  • Écrire une version n'utilisant pas la fonction miroir de l'exercice précédent.
Un code avec miroir.

On utilise la fonction miroir précédente.

def est_palindrome(mot):
    """
    mot -- chaîne de caractères
    renvoie True si mot est égal à son miroir, False sinon.

    >>> est_palindrome('été')
    True
    >>> est_palindrome('hiver')
    False
    """
    return mot == miroir(mot)
Un code sans miroir.

Le principe:

  • si la première lettre n'est pas égale à la dernière, ce n'est pas un palindrome.
  • Sinon, si la seconde lettre n'est pas égale à l'avant-dernière, ce n'est pas un palindrome.
  • Sinon, ...

Et on peut arrêter les tests en arrivant à la moitié du mot...

def est_palindrome(mot):
    """
    mot -- chaîne de caractères
    renvoie True si mot est égal à son miroir, False sinon.

    >>> est_palindrome('été')
    True
    >>> est_palindrome('hiver')
    False
    """
    for k in range(0,len(mot)//2+1):
        if mot[k] != mot[len(mot)-1-k]:
            return False
    return True

La zorglangue

Dans "Z comme Zorglub", Zorglub parle à ses zorglhommes en zorglangue.

zorglangue

Remarque

Dans la dernière cellule de cet extrait de Spirou, Zorglub commet l'erreur classique que vous ne devez pas faire: ne testez que peu de cas ! Cela le ménera dans la suite de l'histoire à l'échec de ses projets !

La fonction miroir définie précédemment permet donc déjà de transformer un mot de la langue usuelle en un mot de la zorglangue.

Il nous reste à écrire une fonction prenant en ertèmarap une phrase (c'est à dire des mots séparés par des blancs) et renvoyant en eitros cette phrase en zorglangue.

Exercice

Écrire un corps possible pour la fonction suivante:

def indice_prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie l'indice du prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la longueur de chaîne s'il n'y pas de séparateur d'indice >= ind.
    """
Solution
def indice_prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie l'indice du prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la longueur de chaîne s'il n'y pas de séparateur d'indice >= ind.
    """
    separateurs = "?. ';,!"  
    for j in range(ind, len(chaine)):
        if chaine[j] in separateurs: return j
    return len(chaine)

Exercice

Écrire un corps possible pour la fonction suivante:

def prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie le prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la chaîne vide s'il n'y pas de séparateur d'indice >= ind.
    """
Solution
def prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie le prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la chaîne vide s'il n'y pas de séparateur d'indice >= ind.
    """
    separateurs = "?. ';,!"  
    for j in range(ind, len(chaine)):
        if chaine[j] in separateurs: return chaine[j]
    return ''

Exercice

Écrire une fonction prenant en ertèmarap une phrase (c'est à dire des mots séparés par des blancs, des caractères de ponctuation, des apostrophes) et renvoyant en eitros cette phrase en zorglangue.

nu edoc elbissop
def miroir(mot):
    """
    mot -- chaîne de caractères

    renvoie la chaîne miroir de mot.

    >>> miroir('zorglub')
    'bulgroz'
    """
    ch = ''
    for lettre in mot:
        ch = lettre + ch
    return ch


def indice_prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie l'indice du prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la longueur de chaîne s'il n'y pas de séparateur d'indice >= ind.
    """
    separateurs = "?. ';,!"  
    for j in range(ind, len(chaine)):
        if chaine[j] in separateurs: return j
    return len(chaine)



def prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie le prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la chaîne vide s'il n'y pas de séparateur d'indice >= ind.
    """
    separateurs = "?. ';,!"  
    for j in range(ind, len(chaine)):
        if chaine[j] in separateurs: return chaine[j]
    return ''


def zorglangue(phrase):
    """
    phrase -- chaîne de caractères, phrase en français.
    renvoie phrase en zorglangue
    """
    indice = 0
    esarhp = ''
    while indice < len(phrase):
        mot = ''
        prochain_sep = prochain_separateur(phrase, indice)
        indice_prochain_sep = indice_prochain_separateur(phrase, indice)
        for j in range(indice,  indice_prochain_sep):
            mot = mot + phrase[j]
        indice =  indice_prochain_sep+1
        esarhp = esarhp + miroir(mot) + prochain_sep
    return esarhp

Un essai (à double-sens: le traducteur du français vers la zorglangue fonctionne aussi en sens inverse!):

>>> zorglangue("J'écris en zorglangue. Eviv Bulgroz!")
"J'sircé ne eugnalgroz. vivE zorgluB!"
>>> zorglangue("J'sircé ne eugnalgroz. vivE zorgluB!")
"J'écris en zorglangue. Eviv Bulgroz!"

Exercice

Vous avez sans doute constaté que les fonctions prochain_separateur et indice_prochain_separateur font deux fois le même travail. Le programme pourrait gagner du temps à l'exécution en ne faisant qu'une seule fois ce travail. Nous verrons par la suite, avec la notion de tuple, qu'une fonction peut renvoyer deux valeurs (ou plutôt un couple de valeurs). Sans en dire plus sur la notion de tuple, voici un exemple de fonction renvoyant deux valeurs:

def jerenvoiedeuxvaleurs():
    return 2, 3

Une utilisation:

>>> a, b = jerenvoiedeuxvaleurs()
>>> a
2
>>> b
3

Reprenez le code de la solution précédente et faites en sorte que le travail de prochain_separateur et indice_prochain_separateur soit fait une seule fois à l'aide d'une fonction renvoyant un couple de valeurs.

Solution
def miroir(mot):
    """
    mot -- chaîne de caractères

    renvoie la chaîne miroir de mot.

    >>> miroir('zorglub')
    'bulgroz'
    """
    ch = ''
    for lettre in mot:
        ch = lettre + ch
    return ch


def prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie l'indice et le caractère du prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la longueur de chaîne et la chaîne vide s'il n'y pas de séparateur d'indice >= ind.
    """
    separateurs = "?. ';,!-"  
    for j in range(ind, len(chaine)):
        if chaine[j] in separateurs: return j, chaine[j]
    return len(chaine), ''


def zorglangue(phrase):
    """
    phrase -- chaîne de caractères, phrase en français.
    renvoie phrase en zorglangue
    """
    indice = 0
    esarhp = ''
    while indice < len(phrase):
        mot = ''
        indice_prochain_sep, prochain_sep = prochain_separateur(phrase, indice)
        for j in range(indice,  indice_prochain_sep):
            mot = mot + phrase[j]
        indice =  indice_prochain_sep+1
        esarhp = esarhp + miroir(mot) + prochain_sep
    return esarhp

Exercice

Zorglub est respectueux des règles usuelles... Il préférerait qu'à la place d'une majuscule soit toujours écrit une majuscule et qu'à la place d'une minuscule soit toujours écrit une minuscule.
Par exemple "Bonjour." deviendrait "Ruojnob.".

A vous d'écrire des modifications du code précédent pour satisfaire cette demande.

Aide

Pour simplifier les transformations du code, une fois n'est pas coutume, on se permettra d'utiliser des fonctions python prédéfinies non citées dans le cours.

>>> 'a'.upper()
'A'
>>> 'B'.lower()
'b'
>>> 'b'.lower()
'b'
>>> '.'.lower()
'.'
>>> '?'.upper()
'?'
Solution

Un code possible.

Les modifications sont effectuées au niveau du code de la fonction miroir (rien ne change dans les fonctions qui suivent la fonction miroir).

def est_majuscule(lettre):
    """
    lettre -- un caractère
    renvoie True si lettre est une majuscule, False sinon.

    On ne traite pas le cas de majuscule accentuée.
    """
    return lettre in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"


def position_maj(phrase):
    """
    phrase -- chaîne de caractère.
    renvoie une chaîne de M et m où les M
    marquent la présence des majuscules.

    >>> position_maj("Coucou Laura.")
    'MmmmmmmMmmmmm'
    """
    resultat = ''
    for caractere in phrase:
        if est_majuscule(caractere): 
            resultat += 'M'
        else:
            resultat += 'm'
    return resultat

def miroir(mot):
    """
    mot -- chaîne de caractères

    renvoie la chaîne miroir de mot.

    >>> miroir('zorglub')
    'bulgroz'
    >>> miroir('Zorglub')
    'Bulgroz'
    """
    positions_majuscules = position_maj(mot)
    ch = ''
    for caractere in mot:
            ch = caractere.lower() + ch
    resultat = ''
    for indice, caractere in enumerate(ch):
        if  positions_majuscules[indice] == 'M':
            resultat = resultat + caractere.upper()
        else:
            resultat = resultat + caractere
    return resultat


def prochain_separateur(chaine, ind):
    """
    chaine -- chaine de caractères
    ind -- entier, un indice possible dans chaine
    renvoie l'indice et le caractère du prochain caractère séparateur avec indice >= ind.
    On appelle ici séparateur: caractère espace, point, point d'interrogation...
    renvoie la longueur de chaîne et la chaîne vide s'il n'y pas de séparateur d'indice >= ind.
    """
    separateurs = "?. ';,!-"  
    for j in range(ind, len(chaine)):
        if chaine[j] in separateurs: return j, chaine[j]
    return len(chaine), ''


def zorglangue(phrase):
    """
    phrase -- chaîne de caractères, phrase en français.
    renvoie phrase en zorglangue
    """
    indice = 0
    esarhp = ''
    while indice < len(phrase):
        mot = ''
        indice_prochain_sep, prochain_sep = prochain_separateur(phrase, indice)
        for j in range(indice,  indice_prochain_sep):
            mot = mot + phrase[j]
        indice =  indice_prochain_sep+1
        esarhp = esarhp + miroir(mot) + prochain_sep
    return esarhp