2014-10-02 3 views
-5

Я пытаюсь написать функцию rot(c,n), которая вращает один символ c вперед на n точек в алфавите.Сумасшедшая задача: вращающиеся буквы в функции шифрования Python

def rot(c,n): 
""" rotate c forward by n characters, 
    wrapping as needed; only letters change 
""" 

if 'a' <= c <= 'z':   # lower-case 
    new_ord = ord(c) + n 
    if new_ord > ord('z'): 
     new_ord = new_ord - (2*n) 
elif 'A' <= c <= 'Z':  # upper-case 
    new_ord = ord(c) + n 
    if new_ord > ord('Z'): 
     new_ord = new_ord - (2*n) 

else:      # non-alpha 
    new_ord = ord(c) 
return chr(new_ord) 

Однако мои желаемые результаты могут быть следующие:

>>> rot('a', 2) 
'c' 
>>> rot('y', 2) 
'a' 
>>> rot('A', 3) 
'D' 
>>> rot('Y', 3) 
'B' 
>>> rot('!', 4) 
'!' 

я получаю неправильные выводы. Может ли кто-нибудь сказать мне, что я делаю неправильно?

+2

подсказка: 'new_ord = new_ord - (2 * п)'. – isedev

+0

что вы подразумеваете под этим точно. –

+0

Он означает, что эта строка неверна. – Kevin

ответ

2

Ваша проблема здесь:

new_ord = new_ord - (2*n) 

Идея заключается в том, что, когда вы идете мимо г, вы должны удалить точно весь алфавит, а не удалить вдвое больше, чем вы только что добавили.

Try:

new_ord = new_ord - 26 
+3

Что делать, если я делаю «гниль ('a', 100)'? – Kevin

+0

спасибо. Вы были очень полезны –

+0

хороший звонок, @ Кевин - исправлено это и в моем ответе – TML

0

Эта версия также поддерживает "негативный поворот"; Я также переключил условные нам .isupper() и .islower(), потому что я считаю их немного более удобными для чтения (и в меньшей степени подвержены кремовой чередой ошибок):

def rot(c,n): 
    """ rotate c forward by n characters, 
     wrapping as needed; only letters change 
    """ 
    new_ord = ord(c) + (n % 26) 
    if c.isupper(): 
     if new_ord > ord('Z'): 
      new_ord -= 26 
     elif new_ord < ord('A'): 
      new_ord += 26 
     return chr(new_ord) 
    elif c.islower(): 
     if new_ord > ord('z'): 
      new_ord -= 26 
     elif new_ord < ord('a'): 
      new_ord += 26 
     return chr(new_ord) 
    return c 
1

Два лайнер: (Не пытайтесь повторить это дома)

def rot(c, n): 
    start = 97 if c.islower() else 65 if c.isupper() else False  
    return chr((ord(c)-start+n)%26 + start) if start else c 
0

Alternativly:

import string 
from itertools import cycle 

def make_rotation_tables(n):  
    uc, lc = map(cycle, (string.uppercase, string.lowercase)) 
    nchar = len(string.uppercase) 
    part = slice(n, n + nchar) 
    rotate = lambda n, it: ''.join(
     [next(it) for i in xrange(26+nchar)][part]) 
    rot_letters = ''.join(map(lambda x: rotate(n, x), [uc, lc]))  
    return string.maketrans(string.letters, rot_letters) 

rottbl = make_rotation_tables(1) 
print 'Caesar dixit: "Veni, vidi, vici!"'.translate(rottbl) 
>>> Dbftbs ejyju: "Wfoj, wjej, wjdj!"