0

I'm trying to implement Rot-13 function, but stuck with, I assume, new lines.

Here's my code:

import cgi, string
def convert():
    lower = string.ascii_lowercase
    upper = string.ascii_uppercase
    punctuation = string.punctuation + ' '      
    with open('data.txt', 'r') as myfile:
        s = myfile.read()
    s = '%(pre_b)s%(s)s%(pre_e)s' % {'pre_b': '<pre>', 's': s, 'pre_e': '</pre>'}
    s = ''.join(map(lambda x: shift(x, lower, upper, punctuation), s[5:-6]))
    return cgi.escape(s, quote= True)

def shift(x, lower, upper, punctuation):
    if x in punctuation:
        return x
    elif x.istitle():
        return upper[(upper.index(x) + 13) % 26]
    try:
        return lower[(lower.index(x) + 13) % 26]
    except:
        print x
print convert()

One-line sentences are being processed OK, but when input contains new line, python says TypeError: expected string, NoneType found

Contents of the data.txt file is following:

test

test test

Please help.

mr_bulrathi
  • 514
  • 7
  • 23
  • The error is more than that, it will usually give you a line as well to help narrow it down. –  Apr 04 '16 at 04:49
  • 2
    Also, give examples of what fails. Because I managed to run your code without error, but I also managed to get an exception that is different than what you are stating in your question with another input. – idjaw Apr 04 '16 at 04:50
  • On further inspection, your code is a hot mess. –  Apr 04 '16 at 05:09
  • 1
    Lego Stormtroopr: your comments regarding ugliness of my code (but not containing any clues) are highly valuable – mr_bulrathi Apr 04 '16 at 05:15
  • I'm sure it could be made more constructive, but when asking for help, it would be useful to remove the warts which are not central to your problem. Straightening out what this code is supposed to do is a challenge, which reduces the chance that anybody will actually be able to help you. For some vague hints, see http://stackoverflow.com/help/mcve for a start. – tripleee Apr 04 '16 at 05:34
  • Here is a cute implementation: https://gist.github.com/gpiancastelli/806851 – Marichyasana Apr 04 '16 at 05:36
  • Unless this is homework or something, then this is related: http://stackoverflow.com/questions/3269686/short-rot13-function – OneCricketeer Apr 04 '16 at 05:46

1 Answers1

1

Your error is related to newlines, but not restricted only to them. Basically, for any character in punctuation, lower and upper, your shift() function returns something back. For everything else, it ends up here

except:
    print x

where the function returns nothing, i.e., the value None. And when you try to join a list where some elements aren't strings, you get the error you got.

>>> ''.join(['a', 'b', None])

Traceback (most recent call last):
  File "<pyshell#19>", line 1, in <module>
    ''.join(['a', 'b', None])
TypeError: sequence item 2: expected string, NoneType found

In summary, you need to return something even for characters not in your punctuation, lower and upper sets. Pseudocode for returning x:

if x in lower
    return something
elif x in upper
    return something else
else
    return x

And pseudocode for returning ''.

if x in lower
    return something
elif x in upper
    return something else
elif x in punctuation
    return x
else
    return ''
Reti43
  • 9,656
  • 3
  • 28
  • 44