2

I'm writing some simple script to translate text to and from rot13. So inside the appriopriate class I have this:

def post(self): 
dict = string.maketrans("ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz", "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm")

code = self.request.get("text")
code = string.translate(code, dict)

It gets the parameter "text" fine but at the .translate it blows up with internal server error:

      File "<mypath>\main.py", line 46, in post
    code = string.translate(code, dict)
  File "C:\Python27\lib\string.py", line 498, in translate
    return s.translate(table + s[:0])
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 128: ordinal not in range(128)

What's wrong with my code?

Straightfw
  • 2,103
  • 3
  • 25
  • 38
  • 2
    This is purely a Python problem - nothing to do with App Engine. Also, `dict` is a very bad name for a variable, since it's also the name of a built in type. – Nick Johnson May 29 '12 at 01:09

1 Answers1

2
a = "This is a string".encode("rot13")
b = a.decode("rot13")
print b

Its python ;D it does exactly what you want.

The Unicode version of translate requires a mapping from Unicode ordinals (which you can retrieve for a single character with ord) to Unicode ordinals. If you want to delete characters, you map to None.

I changed your function to build a dict mapping the ordinal of every character to the ordinal of what you want to translate to:

def translate_non_alphanumerics(to_translate, translate_to=u'_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    translate_table = dict((ord(char), translate_to) for char in not_letters_or_digits)
    return to_translate.translate(translate_table)

>>> translate_non_alphanumerics(u'<foo>!') u'_foo__'

edit: It turns out that the translation mapping must map from the Unicode ordinal (via ord) to either another Unicode ordinal, a Unicode string, or None (to delete). I have thus changed the default value for translate_to to be a Unicode literal. For example:

>>> translate_non_alphanumerics(u'<foo>!', u'bad') u'badfoobadbad'
Jakob Bowyer
  • 32,237
  • 8
  • 73
  • 89
  • Haha, thank you, that's why I love learning Python, soon it will be able to wash the dishes :D However, I'm curious why my code above doesn't work, seems fine to me. – Straightfw May 28 '12 at 10:33
  • 1
    @Straightfw Be careful of str and unicode strings with translate function: http://stackoverflow.com/a/1324114/624829 – Zeugma May 28 '12 at 10:35
  • Don't you worry, I always do :) – Straightfw May 28 '12 at 11:09
  • As far as I know, this will not work with python 3. Is there a better way to do it than this? – lpapp Sep 09 '13 at 16:53
  • Fwiw, 'repr' fixed my very same issue without an external function, etc. That might be simpler a nicer. ;-) – lpapp Sep 09 '13 at 18:23