Substitution de deux lettres a UNE autre lettre.

Fermé
Kerbi666 Messages postés 338 Date d'inscription mercredi 6 janvier 2010 Statut Membre Dernière intervention 4 janvier 2015 - 28 déc. 2012 à 00:21
Kerbi666 Messages postés 338 Date d'inscription mercredi 6 janvier 2010 Statut Membre Dernière intervention 4 janvier 2015 - 10 janv. 2013 à 20:56
Bonjour,
je commence a programmer en python et je cherche a faire un programme qui transforme une lettre par une autre. J'ai trouvé ma joie grâce a ce code :

message=input("test:")
def traduire(message):
intab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
outtab = "n'importe quoi"
return (message.translate(dict((ord(x), y) for (x, y) in zip(intab, outtab))))

Mais enfaite je suis pas si joyeux que ça, car je cherche a substituer deux(ou plusieurs) caractères a un seul autre caractère. c'est a dire remplacer "^^" par "a", "aea" par "a"...
Mais comment faire comprendre cela a python?

Autre question plus complexe : Si je veut crypter un texte, et que je veut que mon gentil python remplace la lettre a de façon aléatoire par "5" ou "b" ou "v", je m'y prend comment?

Merci d'avance pour vos réponses !

PS : quelqu'un peut m'expliquer la dernière ligne de mon programme? ca marche, mais j'aimerais savoir la signification et l'utilité de "dict","zip"... par simple curiosité.





A voir également:

8 réponses

heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 28/12/2012 à 01:46
Bonsoir,

Pour la première question:

ss = 'Althaea corbaeas'  
print ss  
print ss.replace("aea",'i')  
print ss.replace("aea",'i').replace('corb','Elv')

affiche

Althaea corbaeas  
Althi corbis  
Althi Elvis


Mais quand il s'agit de remplacer plusieurs suites de caractères, replace() est moins pratique puisqu'il faut autant de replace() que de suites à rmplacer. Il faut alors recourir aux expressions régulières:

import re  

pat = '(\^\^|aea)'  
RE = re.compile(pat)  
ss = 'Althaea corb^^s'  
print ss  
print RE.sub('M',ss)

affiche

Althaea corb^^s  
AlthM corbMs
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
28 déc. 2012 à 02:00
Pour la deuxième question:

import re
from random import choice

def remplace(mat):
    return choice(('5','b','v'))

RE = re.compile('a')

ss = 'patatras, patate, anagramme, arabica'
print ss
print RE.sub(remplace,ss)
print RE.sub(remplace,ss)
print RE.sub(remplace,ss)

affiche

patatras, patate, anagramme, arabica
pbtvtr5s, pbtvte, bnvgrbmme, brbbicb
p5tvtrbs, pvt5te, vnvgr5mme, vrbbicb
pbt5trvs, pvtbte, 5nbgrvmme, vrvbicb


Mais pour un cas simple comme celui-ci, on peut se passer des expressions régulières:

from random import choice

ss = 'patatras, patate, anagramme, arabica'
print ss

print ''.join(choice(('5','b','v')) if x=='a' else x for x in ss)
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 28/12/2012 à 02:17
Pour la dernière question


print zip('abcdef',[10,20,30,40,50,60])
affiche

[('a', 10), ('b', 20), ('c', 30), ('d', 40), ('e', 50), ('f', 60)]


Ceci montre bien ce que fait zip().
J'ai fait exprès de prendre une chaîne et une liste, pour montrer que zip() prend des séquences comme arguments, quelles que soient ces séquences, càd qu'elles n'ont pas besoin d'être de même nature.

zip(a,b) s'arrête d'associer les éléments des séquences a et b quand elle a atteint la fin de la plus courte des deux séquences.

Pour l'expression finale, tu dois regarder les fonction ord, dicr, translate dans la doc officielle, c'est inutile que je répète ce qui se trouve déjà expliqué ailleurs.
0
Kerbi666 Messages postés 338 Date d'inscription mercredi 6 janvier 2010 Statut Membre Dernière intervention 4 janvier 2015 40
28 déc. 2012 à 05:56
Re, j'ai essayer des trucs mais j'ai un problème : Si jveut transformer "/\" en a, ben ya pas moyen, et ça va me refaire le même truc avec tout les / et \ a mon avis. J'arrive pas a faire comprendre a python que /\ doit être considéré comme chaîne de caractère a remplacé par une autre. soit j'ai une erreur, soit ca remplace pas, ou mal ^^'. J'ai tenté des bidouilles a la con du genre rajouté des " et ' fin.. c'est des actions désespérés.

import re

pat = '(\^\^|/\)' <---- /\, lui, il veut pas hein, pas moyen.
RE = re.compile(pat)
ss = 'Althaea corb^^/\s'
print(ss)
print(RE.sub('M',ss))

----------------------------------------------------------------------------------------

message = input("Entre ton message :")
message1=list(message)
i=0
for i in range(0,len(message1)):
if message1[i]=="4" or message1[i]=="/\": <-- What is wrong with you?!!
message1[i]="a"
print(message1)

Si tu as une solution hésite pas... Merci encore ! ^^
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 28/12/2012 à 11:53
L'antislash est le caractère utilisé en Python pour échapper certains caractères dans les chaînes
Regarde ici:
https://docs.python.org/2/reference/lexical_analysis.html#string-literals

'/\' ne marche pas car l'antislash échappe le caractère ' qui est censé marquer la terminaison de la chaîne.
Donc il faut échapper l'antislash, et ça se fait avec ... un antislash:
'/\\'


Ceci dit ton dernier code ne marchera pas pour modifier les séquences de deux caractères consécutifs /\ parce que message1[i] représente un seul caractère

Soit dit en passant, la ligne
 i=0
n'est pas nécessaire



Maintenant pour ce qui est de l'utilisation du module re, il y a une difficulté supplémentaire.
Lis ceci si tu arrives à y comprendre quelque chose:
https://docs.python.org/2.7/howto/regex.html#the-backslash-plague
Je pense que ce passage de la doc n'est pas une très bonne explication du problème mais je n'ai pas le temps d'en dire plus.
Le fait est que les codes suivants avec le module re marchent:

import re 

pat = '(\^\^|/\\\\)'  
RE = re.compile(pat)   
ss = 'Althaea corb^^/\s'   
print(ss)   
print(RE.sub('M',ss))   

print '-----------------------------------'  

pat = r'(\^\^|/\\)'  
RE = re.compile(pat)   
ss = 'Althaea corb^^/\s'   
print(ss)   
print(RE.sub('M',ss)) 


NB La présence de l'antislash devant les caractères ^ est nécessaire car '^' dans un pattern de regex a une signification particulière, cf la doc
0
Kerbi666 Messages postés 338 Date d'inscription mercredi 6 janvier 2010 Statut Membre Dernière intervention 4 janvier 2015 40
Modifié par Kerbi666 le 28/12/2012 à 15:23
Merci. Merci. et Merci encore.
Jvais continuer sur ma lancée et tenter de comprendre ces liens.
Tu m'as vraiment beaucoup aider, encore merci.

Arf ><, le séparateur étant | , je fait comprendre comment a python que |-\ doit être remplacé par M? ><

import re

a = r'(4|/\\|@|\^|aye|?|/-\\||-\\|q)'
RE = re.compile(a)
ss = "|-\\"
print(ss)
print(RE.sub('M',ss))

résultat :
|-\
M|M-M\M

même quand a = r'()' , ben ca affiche le même truc.

Ta une idée? :)
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 28/12/2012 à 16:16
M'étonnerait que tu obtiennes ce résultat avec le code que tu donnes, parce que '?' dans un pattern de regex a une signification spéciale, c'est un quantificateur.
Pour annuler cette spécialité de '?' dans un pattern de regex , il faut l'échapper.


Pour ce qui est de la réponse à ta question:
perso je n'arrive pas à travailler avec les raw strings précédée de r ou R. J'ai pris l'habitude de travailler avec des chaînes normales, je pige mieux ce que je fais.
Donc la réponse à ta question:

import re 

a = '(4|/\\\\|@|\^|aye|\?|/-\\\\|\|-\\\\|q)' 
print 'a ==',a 
print 'repr(a) ==',repr(a) 
print 
RE = re.compile(a)  
ss = "a 4 b /\ c @ d ^ e aye f ? g /-\ h |-\ i q j"  
print(ss)  
print(RE.sub('-',ss))  

print '\n---------------------------------\n' 


b = r'(4|/\\|@|\^|aye|\?|/-\\|\|-\\|q)' 
print 'b ==',b 
print 'repr(b) ==',repr(b) 
print 'a==b  est ',a==b 
print 
RE = re.compile(a)  
ss = "a 4 b /\ c @ d ^ e aye f ? g /-\ h |-\ i q j"  
print(ss)  
print(RE.sub('-',ss)) 



Je te conseille de lire la doc sur le module re si tu veux l'utiliser pour éviter de bidouiller des trucs sans piger.

'|' dans un pattern de regex n'est pas un séparateur, ça a pour signification OU , c'est à dire que ça sert à construire une alternative comportant plusieurs options.
0
Kerbi666 Messages postés 338 Date d'inscription mercredi 6 janvier 2010 Statut Membre Dernière intervention 4 janvier 2015 40
Modifié par Kerbi666 le 28/12/2012 à 18:31
En fait le caractère n'est pas ? mais delta minuscule. D'ailleurs ça me fait aussi une erreur quand je remplace \? par delta minuscule. Une idée?
(visiblement CCM ne comprend pas ce caractère. ca le remplace par ?)
D'ailleurs je viens d'essayer avec d'autres caractères du même style ( €,?,?) et ca fait aussi une erreur du coup je suppose que ça va le faire avec tous. Et comme je doit les utiliser... :/
Erreur :
a == Traceback (most recent call last):
File "parcquejmangeduvomi.py", line 4, in <module>
print ('a ==',a)
File "C:\Python32\lib\encodings\cp850.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2202' in position
17: character maps to <undefined>
Appuyez sur une touche pour continuer...
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 3/01/2013 à 00:03
Resalut

J'ai installé Python 3.2 de façon à pouvoir tester les programmes dans la même version de Python que toi.

J'obtiens l'erreur que tu rapportes, mais uniquement dans une console:

- dans la console C:\WINDOWS\System32\cmd.exe (ouverte par Démarrage / Exécuter / cmd), en lançant le script enregistré.

- dans la console Python (command line) (mais pas dans IDLE en mode Shell), en entrant les instructions
>>> a = 'f|' + chr(8706) 
>>> print(a)

8706 est la valeur en décimal du point de code Unicode U+2202
Python note ce point de code '\u2202', c'est cette notation qui est indiquée dans le message d'erreur

Soit dit en passant le caractère de point de code U+2202 n'est pas la lettre delta minuscule du grec (qui a pour coode point U+03B4) mais le 'signe de différentielle partielle'
cf https://www.utf8-chartable.de/unicode-utf8-table.pl

Le problème vient apparemment du fait que Python va chercher l'encoding CP850 dans le dossier Lib \ encodings, alors que cet encoding ne code pas le caractère désigné.
CP signifie "code page", c'est à dire un mapping caractère <-> octet unique pour un ensemble de caractères donné.
Les code pages sont de vieux encodings créés par IBM et utilisés par Windows il y a longtemps. D'après Wikipedia, la CP850 "est encore utilisée dans les fenêtres de type console ou invite de commandes sur les systèmes Microsoft Windows en Europe occidentale."

Le problème semble être lié à l'intervention de print()

En effet, dans une console, le code suivant
>>> a = 'f|' + chr(8706) 
>>> print(a)
produit une erreur à cause de CP850,
tandis que celui-ci
>>> a = 'f|' + chr(8706) 
>>> a
affiche '\u2202'

Parallèlement, les erreurs qui se produisent quand on lance un script à partir d'une console disparaissent si on élimine les instructions print() du script.
Et quand on lance un script dans IDLE (que ce soit en mode Edit ou en mode Shell), print(chr(8706)) affiche le signe de dérivation partielle et non pas '\u2202' , contrairement à une console.



Ceci dit, si on ne place pas d'instruction print() devant afficher un caractère exotique dans le script, on parvient à faire tourner en console un programme avec un résultat correct.
C'est ce que j'ai obtenu avec le script suivant, dans lequel les seules print() [car il faut bien faire apparaître queqlue chose dans la console] ne doivent afficher que des chaînes dans lesquelles le signe de dérivation partielle a été remplacé par un '-'.
MAIS ATTENTION il faut remplacer dans le code ci-dessous le point d'interrogation ? par le signe de dérivation partielle: il suffit d'aller le copier dans un répertoire de caractères Unicode et de le coller dans le script.
CCM n'est pas foutu d'afficher les caractères unicode. Le site doit être codé en PHP, je parie.

import re 

ss = 'c:?:e:f:g' 
for a in ( 'f|\u2202', 
           'f|\U00002202', 
           'f|\N{PARTIAL DIFFERENTIAL}', 
           'f|?', 
           'f|' + chr(8706), 
           b'f|\xe2\x88\x82'.decode() ): 
  
    RA = re.compile(a) 
    print(  "\nRA.sub('-',ss) == ",RA.sub('-',ss), 
            '\n================================' ) 

print('###########################################') 

ss = 'c:\u2202:e:f:g' 
for a in ( 'f|\u2202', 
           'f|\U00002202', 
           'f|\N{PARTIAL DIFFERENTIAL}', 
           'f|?', 
           'f|' + chr(8706), 
           b'f|\xe2\x88\x82'.decode() ): 

    RA = re.compile(a) 
    print( "\nRA.sub('-',ss) == ",RA.sub('-',ss), 
           '\n================================' )


Le résultat est

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================
###########################################

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================

RA.sub('-',ss) ==  c:-:e:-:g 
================================


Les éléments parcourus par les boucles sont les différentes manières d'introduire un caractère unicode dans une chaîne.

L'erreur due à CP850 n'est pas liée à la présence du signe de dérivation partielle dans le script puisqu'il se trouve dans le script (après remplacement de ? par ce signe). Donc, au niveau de l'exécution, ce n'est pas sa présence qui pose problème, c'est bien uniquement au moment où il s'agit que quelque chose soit affiché que ça ne marche plus.
Donc, premièrement CP850 n'intervient que pour l'affichage,
et deuxièmement il semble bien qu'on ne puisse pas afficher de caractère exotiques dans une console alors qu'on le peut dans IDLE.
0
heyquem Messages postés 759 Date d'inscription mercredi 17 juin 2009 Statut Membre Dernière intervention 29 décembre 2013 130
Modifié par heyquem le 3/01/2013 à 23:06
En creusant le sujet sur internet, j'ai vu que le problème de l'affichage de caractères exotiques et peu communs dans la console Windows est en effet connu.
J'ai vu diverses propositions pour remédier à ce problème, je ne les ai pas toutes comprises à fond mais je retiens qu'il faut cliquer droit sur la barre en haut d'une fenêtre de console Windows, puis sur Propriétés pour accéder à la possibilité de faire des modifications. Il faut alors:
- changer la police utilisée par la console pour Lucida Console, qui est TrueType, alors que le réglage par défaut est raster
- changer l'encoding utilisé par la console en faisant par exemple
chcp 1252
pour basculer sur un encoding CP1252.
Le problème c'est qu'il faudrait trouver pour tous les caractères exotiques rencontrés dans les chaînes traitées l'encoding qui les codent tous , et ceci n'est certainement pas possibles pour tous les types de caractères utilisables ensemble dans un texte. Par exemple si on veut afficher à la fois les caractères cyrilliques et les grecs il faudrait ISO 8859-5 et ISO 8859-7 en même temps, ce qui n'est pas possible, enfin je crois....




Mais j'ai trouvé une autre solution, plus satisfaisante parce qu'il n'est pas nécessaire de se priver de faire print() de chaînes contenant des caractères non supportés par l'encoding de la console ou de se compliquer la vie à modifier les paramètres de la console.

Il suffit d'enregistrer les résultats dans un fichier et d'utiliser startfile() dans le programme pour ouvrir ce fichier.
Même en déclenchant le programme à partir d'une console Windows, il y aura ouverture de ce fichier de résultats en dehors de la console et cela affichera correctement tous les caractères Unicode si le sytème d'exploitation le gère, ce qui est le cas pour Windows depuis longtemps.
Mais pour que ça marche bien, il faut utiliser la fonction open() du module codecs avec un encoding égal à 'utf-8'

import re      
from codecs import open      
from os import startfile,remove      
from time import sleep      

ss = 'c:?:e:f:g'      

with open('recoit.txt','w','utf-8') as f:      
                  
    for a in ( 'f|\u2202',      
               'f|\U00002202',      
               'f|\N{PARTIAL DIFFERENTIAL}',      
               'f|?',      
               'f|' + chr(8706),      
               b'f|\xe2\x88\x82'.decode() ):      
              
        f.write( '   a == ' + a + '      ss  == ' + ss      
                 + "\r\nre.sub('"+a+"','-',ss) == " + re.sub(a,'-',ss)      
                 + '\r\n=================================\r\n' )      


x = startfile('recoit.txt')      
sleep(0.5)      
remove('I:\\potoh\\encods\\recoit.txt')


A exécuter dans la console Windows

Et évidemment, il faut remplacer le point d'interrogation dans ce code par le symbole voulu qu'on ira copier dans
https://www.utf8-chartable.de/unicode-utf8-table.pl
parce que CCM n'affiche pas correctement les caractères Unicode

Dans ce code, la présence de sleep(0.5) donne le temps au sytème d'exploitation d'ouvrir le fichier avant qu'il soit effacé poar la ligne suivante. Sans ce sleep(0.5) on n'obtient rien
0
Kerbi666 Messages postés 338 Date d'inscription mercredi 6 janvier 2010 Statut Membre Dernière intervention 4 janvier 2015 40
10 janv. 2013 à 20:56
Excuse moi du temps de réponse, j'étais coupé d'internet.
Incroyable, vraiment.
Tu as toute ma gratitude ! Je vais regarder tout ça de plus près, chercher un moyen de l'intégrer a mon programme, et je reviendrais dire ce qu'il en est !
Merci milles fois !
0