2016-08-19 1 views
2

Je suis très novice en programmation (6 semaines, autodidacte sur le net avec "codecademy" et "python the hard way"). J'ai décidé qu'il était temps que j'expérimente l'écriture de code sans direction et que je frappe un mur avec mon second projet. J'essaye de faire un "codeur secret" qui prend une chaîne de raw_input et remplace chaque lettre dedans avec la prochaine dans l'alphabet. Avec mes connaissances très limitées, j'ai pensé qu'un dictionnaire devrait être la voie à suivre. Avec un « petit » aide googler, je l'ai écrit ceci:python 2.7 remplacer une chaîne raw_input par une valeur tirée d'un dictionnaire

alpha = {"a" : "b", "b" : "c", "c" : "d", "d" : "e", "e" : "f", "f" : "g","g" : "h" 
     , "h" : "i", "i" : "j", "j" : "k", "k" : "l", "l" : "m","m" : "n", "n" : "o" 
     , "o" : "p", "p" : "q", "q" : "r", "r" : "s","s" : "t", "t" : "u", "u" : "v" 
     , "v" : "w", "w" : "x", "x" : "y", "y" : "z", "z" : "a"} 

entry = raw_input("Please write a sentence you want to encode: ") 

def encode(entry, letters): 
    for k, v in letters.iteritems(): 
     if k in alpha: 
      entry = entry.replace(k, v) 
    return entry 
print encode(entry, alpha) 

Le problème que j'ai est que seulement la moitié des lettres dans ma chaîne sont remplacées par les valeurs correctes du dictionnaire. "a" et "b" seront tous les deux imprimés comme "c" quand "a" devrait être imprimé comme "b" et "b" devrait être imprimé comme "c" et ainsi de suite.

illustration

Là où je me complètement perdu est que, quand je l'ai remplacé chaque valeur dans mon dictionnaire avec des chiffres, il a parfaitement fonctionné.

illustration bis

Voilà l'essentiel de, je ne comprends vraiment pas ce qui ne va pas avec mon code.

Merci d'avance pour votre aide. PS: C'était mon premier article sur stackoverflow, j'espère que j'ai fait tout ce que je devrais faire.

EDIT: Puisque je ne peux pas encore donner de réputation, je vais simplement vous remercier tous pour vos réponses utiles. Je peux voir un peu plus clair maintenant où est mon erreur et je prendrai l'information fournie ici pour réparer mon code et travailler pour le comprendre correctement. Aussi, je peux voir qu'il existe des approches beaucoup plus logiques et directes pour résoudre ce genre de problème. Les fonctions sont encore un peu floues pour moi mais je suppose que c'est normal si tôt.

+0

vous devez faire une boucle à l'entrée, pas de lettres, et se joindre à chaque ombles de retour avec « » – YOU

+1

Imaginez ce scénario ... vous avez un 'dans votre chaîne a', et vous boucle et changer tout le' a '' s ​​à 'b's, mais alors, vous bouclez et changez tous les' b's '' c' (qui peuvent inclure les 'a's que vous avez changé en' b's etc ... –

+0

: D Mec je t'aime enthousiasme. Python est pratique mais puissant, donc un exercice similaire serait de crypter vos messages en utilisant des solutions crypto réelles - voyez par vous-même à quel point cela devient simple avec Python http://stackoverflow.com/questions/30056762/rsa-encryption-and-decryption-in -python :) –

Répondre

0
def encode(entry, letters): 
    for k, v in letters.iteritems(): 
     if k in alpha: 
      entry = entry.replace(k, v) 
    return entry 
print encode(entry, alpha) 

Appel encode(entry, alpha) dans la fonction d'impression, vous passez la fonction encode() le dictionnaire alpha être la variable letters dans la fonction. Ensuite, vous utilisez l'itérateur pour parcourir la variable letters (qui est le dictionnaire alpha). Ensuite, votre instruction if vérifie si ce k (que vous venez de recevoir de la variable letters, qui est le alpha dictionnaire) est dans le dictionnaire alpha, ce qui bien sûr l'est.

Vous aurez besoin de faire quelque chose comme ceci:

for k, v in letters.iteritems(): 
    if k in entry: 
     entry = entry.replace(k, v) 
1

Le problème est que puisque vous itérer sur le dictionnaire au lieu de la chaîne que vous pourriez remplacer caractère original plusieurs fois. Par exemple avec une entrée donnée de 'ab' le premier remplacement se traduira par 'bb' et la seconde à 'cc' dans le cas où iteritems retourne les clés dans l'ordre a, b. Notez que puisque le dictionnaire est une collection non ordonnée, l'ordre des éléments retournés est aléatoire.

Vous pouvez résoudre le problème en utilisant generator expression itérer sur la chaîne source et join pour créer le résultat:

def encode(entry, letters): 
    return ''.join(letters.get(c, c) for c in entry) 

L'exemple ci-dessus appelle get au lieu d'utiliser l'opérateur d'index pour traiter les cas où alpha doesn Ne contient pas une lettre dans la chaîne source. La différence entre get et l'opérateur d'index est que get prend le deuxième argument qui est la valeur par défaut qui sera retournée dans le cas où cette clé n'existe pas. Dans l'exemple ci-dessus, la valeur par défaut est le caractère lui-même.

+0

Solution assez propre (je l'ai upvoted) puisque l'OP est un débutant, il serait cool de fournir une explication plus large. Comme la méthode get() et la façon dont elle choisit la valeur des lettres ou utilise la clé fournie par défaut au cas où l'élément ne serait pas trouvé. –

+0

@ monchitos82 Bon point, ajouté une explication un peu plus longue. – niemmi

0

Les dictionnaires ne sont pas commandés, vous remplacez donc certaines lettres ('a' -> 'b') et d'autres sont ignorés.

Pour votre édification, ce que vous faites s'appelle rot (rotation). Le plus connu est rot13.

Écrire des choses vous-même est utile lorsque vous démarrez pour la première fois, mais il existe une fonction de bibliothèque standard assez cool appelée string.maketrans qui fera exactement cela!

1

Xetnus est correct, vous devez faire défiler la variable d'entrée au lieu des lettres. peut-être quelque chose comme ceci

def encode(entry, letters): 
    new_entry = '' 
    for letter in entry: 
     if letter in letters: 
      new_entry += letters[letter] 
    return new_entry 
print encode(entry, alpha) 
0

D'autres ont souligné comment faire correctement cela en utilisant un dictionnaire comme recherche. Cependant, vous pouvez également utiliser la méthode str.translate qui évite d'avoir à chercher et reconstruire une chaîne.

import string 

trans = string.maketrans(
    'abcdefghijklmnopqrstuvwxyz', # from... 
    'bcdefghijklmnopqrstuvwxyza' # to 
) 

print raw_input('Please enter something to encode: ').translate(trans) 
+0

C'est une manière très élégante et simple de faire ce que je voulais faire et je vais certainement l'utiliser car je vois déjà comment je peux faire en sorte que mon code fasse des manipulations plus complexes des chaînes avec. Je vais travailler sur faire de ma fonction ce que je veux avec l'aide fournie dans d'autres réponses, puis, une fois que je serai capable de le coder correctement, je passerai à l'utilisation de la méthode str.translate en raison de sa simplicité. Merci de l'avoir suggéré. – Gorian