0

I am attempting to learn Python and am working on an assignment for fun that involves translating "encrypted" messages (it's just the alphabet in reverse). My function is supposed to be able to read in an encoded string and then print out its decoded string equivalent. However, as I am new to Python, I find myself continually running into a type error with trying to use the indices of my lists to give the values. If anyone has any pointers on a better approach or if there is something that I just plain missed, that would be awesome.

def answer(s):
'''
All lowercase letters [a-z] have been swapped with their corresponding values
(e.g. a=z, b=y, c=x, etc.) Uppercase and punctuation characters are unchanged.

Write a program that can take in encrypted input and give the decrypted output
correctly.
'''
    word = ""

    capsETC = 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\
          'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\
          ' ', '?', '\'', '\"', '@', '!', '#', '$', '%', '&', '*', '(', \
          ') ', '-', '_', '+', '=', '<', '>', '/', '\\'

    alphF = 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'

    alphB = 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm',\
        'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'

    for i in s:
        if i in capsETC:  # if letter is uppercase or punctuation
            word = word + i  # do nothing
        elif i in alphB:  # else, do check
            for x in alphB: # for each index in alphB
                if i == alphB[x]: # if i and index are equal (same letter)
                    if alphB[x] == alphF[x]:  # if indices are equal
                        newLetter = alphF[x]  # new letter equals alpf at index x
            str(newLetter) # convert to str?
            word = word + newLetter # add to word

print(word)
s = "Yvzs!"

answer(s)
pault
  • 41,343
  • 15
  • 107
  • 149
McBraunie
  • 107
  • 1
  • 12
  • 5
    `for x in alphB:` does not get you the index in `alphB`, it gives you the actual object. You can use `for i, x in enumerate(alphB)` to get the index `i` and the item `x` OR you can use `for x in range(len(alphB)):` to get only the indices. – pault Apr 20 '18 at 20:05

2 Answers2

2

Your current issue is that you are trying to use letters as indices. To fix your current approach, you could use enumerate while looping through each of your strings.

If you want a much simpler approach, you can make use of str.maketrans and str.translate. These two builtin functions help easily solve this problem:

import string
unenc = string.ascii_lowercase # abcdefghijklmnopqrstuvwxyz
decd = unenc[::-1] # zyxwvutsrqponmlkjihgfedcba

secrets = str.maketrans(unenc, decd)
s = "Yvzs!"
print(s.translate(secrets))

Output:

Yeah!

If you want a looping approach, you can use try and except along with string.index() to achieve a much simpler loop:

import string
unenc = string.ascii_lowercase # abcdefghijklmnopqrstuvwxyz
decd = unenc[::-1] # zyxwvutsrqponmlkjihgfedcba

s = "Yvzs!"
word = ''
for i in s:
  try:
    idx = unenc.index(i)
  except:
    idx = -1
  word += decd[idx] if idx != -1 else i

print(word)

Output:

Yeah!
user3483203
  • 50,081
  • 9
  • 65
  • 94
  • 1
    Ha I was just about to comment this linking to your answer [here](https://stackoverflow.com/a/49820919/5858851). The one comment I would make is that you can use `unenc=string.lowercase` and `decd = ''.join(list(reversed(unenc)))` instead of enumerating all of the letters. – pault Apr 20 '18 at 20:13
  • Thank you all for contributing to this question! I am bookmarking this because I think it is definitely important for me to learn to solve problems more efficiently like this in the future. Thank you! – McBraunie Apr 20 '18 at 21:30
2

your code is fine, just a few changes (left your old lines as comments)

def answer(s):

    word = ""

    capsETC = 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',\
          'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\
          ' ', '?', '\'', '\"', '@', '!', '#', '$', '%', '&', '*', '(', \
          ') ', '-', '_', '+', '=', '<', '>', '/', '\\'

    alphF = 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'

    alphB = 'z', 'y', 'x', 'w', 'v', 'u', 't', 's', 'r', 'q', 'p', 'o', 'n', 'm',\
        'l', 'k', 'j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a'

    for i in s:

        if i in capsETC:  # if letter is uppercase or punctuation

            word = word + i  # do nothing

        elif i in alphB:  # else, do check

            for x in range(len(alphB)): # for each index in alphB

                if i == alphB[x]: # if i and index are equal (same letter)

                    # if alphB[x] == alphF[x]:  # if indices are equal

                        newLetter = alphF[x]  # new letter equals alpf at index x

                       # str(newLetter) # convert to str?
                        word = word + newLetter # add to word

    return word


s = "Yvzs!"
print(s)
print(answer(s))

ouput

Yvzs!
Yeah!

of course you can make it a lot simple and python's way... but wanted to change your code as little as possible

shahaf
  • 4,750
  • 2
  • 29
  • 32
  • This is great! Thank you. I am still trying to grasp the whole "Pythonic" way of thinking and doing things, so I get that my route was not that way. I like the shorter versions, for sure but this is as far as I could envision solving at this point. Thank you for taking the time to work on this! – McBraunie Apr 20 '18 at 21:28