Search code examples
pythonstringgoogle-app-enginewebapp2

What is wrong with this webapp2 code?


I am writing a webapp in python to convert a string by rot13 such as rot13(a)=n , rot13(b)=o and so on. But the code is only working for letters after m. From letters a to m there is no change. What am I doing wrong, here is my code:

import webapp2
import cgi

form = """<form method="post">
    Type a string to convert:
    <br>
    <textarea name="text">%(text)s</textarea>
    <br>
    <input type="submit">
</form> """

class MainHandler(webapp2.RequestHandler):
    def write_form(self, text=""):
        self.response.out.write(form % {"text": cgi.escape(text)})

    def get(self):
        self.write_form()

    def post(self):
        new_text = self.request.get('text')
        text = ""
        for x in range(len(new_text)):
            text += convert(new_text[x])
        self.write_form(text)

def convert(t):
    for (i, o) in (('a', 'n'),
                   ('b', 'o'),
                   ('c', 'p'),
                   ('d', 'q'),
                   ('e', 'r'),
                   ('f', 's'),
                   ('g', 't'),
                   ('h', 'u'),
                   ('i', 'v'),
                   ('j', 'w'),
                   ('k', 'x'),
                   ('l', 'y'),
                   ('m', 'z'),
                   ('n', 'a'),
                   ('o', 'b'),
                   ('p', 'c'),
                   ('q', 'd'),
                   ('r', 'e'),
                   ('s', 'f'),
                   ('t', 'g'),
                   ('u', 'h'),
                   ('v', 'i'),
                   ('w', 'j'),
                   ('x', 'k'),
                   ('y', 'l'),
                   ('z', 'm')):
        t = t.replace(i, o) 
    return t


app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

When i place the letters n to z above a, then a to m are giving correct result.


Solution

  • The issue is in the convert() method, Lets take a simple Example to understand this.

    Lets take example of string 'an' and try to convert it.

    First we get a from the tuple of tuple and we replace it with n in the string, so it becomes - 'nn' . Now after lots of misses, we get to n in the tuple of tuples and we again do replace on the whole string, and this time we get - 'aa' . As you can see we are again replacing complete string, not just the remaining of the not converted string. This is the basic issue in your code (atleast the issue you mention).

    To fix this, Python already provides a str.translate() (with str.maketrans) function to do what you are trying to do, you should use that instead. Example -

    Python 2.x -

    def convert(t):
        from string import maketrans
        tt = maketrans('abcdefghijklmnopqrstuvwxyz','nopqrstuvwxyzabcdefghijklm')
        t = t.translate(tt)
        return t
    

    For Python 3.x , you should use str.maketrans() instead of string.maketrans() .