0

I have some python code, the translate_string method returns the correct value nevmban but then after it prints "None".

def secret_translate(letter):
    code = ord(letter)-ord('a')
    code = (code+13)%26
    newCode = chr(code+ord('a'))
    return newCode

def translate_string(string):

    newMsg = ''
    i = 0
    while i < (len(string)):

        print(secret_translate(string[i]),end='')
        i= i+1 

print(translate_string("arizona"))

The program prints:

nevmbanNone

I expect it to print nevmban Where is the "None" coming from?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
anon_nerd
  • 1,251
  • 1
  • 10
  • 16
  • You need to post some more code.. And what does your `secret` variable contains?? – Rohit Jain Sep 27 '12 at 06:00
  • 1
    That's not the output .. you have infinite recursion here. – wim Sep 27 '12 at 06:03
  • You can replace `i = i+1` with `i += 1`, unrelated to your issue. – TankorSmash Sep 27 '12 at 06:05
  • @RohitJain sorry... print(underground_code("arizona")) should translate to nevmban but its transating to nevmbanNone PS. underground_code is a function before this block of code. That function has the translating algorithm, it works it is tested, but i am annoyed very much by None printing at the end when printed. I am sorry if the code was badly written, I am a nooob – anon_nerd Sep 27 '12 at 06:16
  • Where do you have your print?? Inside while or outside it?? If it is inside.. Then why are you calling the same function from inside.. for doing different task?? ** POST your Complete code ** – Rohit Jain Sep 27 '12 at 06:16
  • @RohitJain disregard the other BS look at my new code that I edited. Hope that helps. – anon_nerd Sep 27 '12 at 06:29
  • @anon_nerd.. Replace your `print(translate_string("arizona"))` with `translate_string("arizona")`.. This method doesn't return anything... That's why you are getting `None` – Rohit Jain Sep 27 '12 at 06:32
  • Thanks so much! Sorry for the hassle. Can you briefly explain why it was doing the none though?? – anon_nerd Sep 27 '12 at 06:34
  • @anon_nerd see my answer for an explanation of why None is added. – Paul Hiemstra Sep 27 '12 at 06:38
  • @anon_nerd I also added an alternative version of your translate routine to my answer. – Paul Hiemstra Sep 27 '12 at 06:46
  • `str.translate`...in older versions of Python, I'd just use `.encode('rot_13')` – nneonneo Sep 27 '12 at 06:47

4 Answers4

4

You are printing the result of your translate_string function, which is None, as there is no explicit return statement.

Janne Karila
  • 24,266
  • 6
  • 53
  • 94
1

When you call the print method like this:

print(underground_code(secret[i]),end='')

You are passing just one character in the function instead of the whole string. It will keep on checking the first character in your while loop:

while i < (len(secret)):

The above while will run only once. And the next function call your len(secret) will be 1.

*Of course, ignore what I said if this is what you want.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
1

Note that if you have the translation table, you really don't need to implement translation mechanisms. You have them built in string:

import string

fromlist="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
tolist = "cdefghijklmnopqrstuvwxyzab"
transtable = string.maketrans(fromlist, tolist)

mycypertext="FCJJM UMPJB"
print string.translate(mycyphertext, transtable) #will print hello world
oz123
  • 27,559
  • 27
  • 125
  • 187
  • +1 nice and compact solution, probably also performs quite well for really large strings – Paul Hiemstra Sep 27 '12 at 06:48
  • @PaulHiemstra, thanks! I have taken a weird challenge to read all the Python STL documentation. You would be surprised how many goodies Python has ! – oz123 Sep 27 '12 at 06:50
  • @PaulHiemstra, yes, a great goodie. However, from my little experience with teaching Python for newbies, I find that their syntax is harder to get compared to `for x in somelist: do something ...` – oz123 Sep 27 '12 at 06:53
0

You print the letters of the translated word as you go, I would recommend returning the translated word from the function instead. The fact that you see None printed behind your translated word is because inside the function you print the word, and outside the function you print the result of the function. The function has no result (no return statement) and the default is None. Printing this leads to the None being appended at the end of the string that was already printed inside the function.

I would recommend a restructuring of translate_string like this:

def translate_string(string):
  translated_letters = [secret_translate(letter) for letter in string]
  return("".join(translated_letters))

trans_string = translate_string("arizona")
print(trans_string)
'nevmban'

This solution uses a list comprehension to loop over the letters of the input string, no need for an explicit loop with a counter. List comprehensions are very nice, they do need some getting used to. In addition, the function now returns the string instead of printing it inside the function. The None is gone, and you can use the translated string further along in your program, e.g. as input to another function.

Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149