Greystone
Greystone

Reputation: 13

Storing several location values from list into another list in python

I'm trying to get the location of all the letters of an input "text" from a list "alphabet". <- Thats the part I'm having trouble with.

For some context: after those letters are stored, the list aplphabet will shift a given number of places. Then our stored locations can be retrieved and we can print out an encoded message.

alphabet = ['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']

direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
text = input("Type your message:\n").lower()
shift = int(input("Type the shift number:\n"))


text_len = len(text)
i = text_len
text_catch = []
while text_len != 0:
  while i != 0:
    print(alphabet.index(text[i - 1]))
    for i in text:
      text_catch.append(alphabet.index(text[i-1]))
    i -= 1
text_len -= 1

I am using the word hello as an imput. When I remove

    for i in text:
          text_catch.append(alphabet.index(text[i-1]))

I get each location of the letters hello printed out. I'm having trouble storing those locations to another list. (type error: unsupported opperand type(s) for -: 'str' and 'int'

I tried

    for i in text:
          text_catch.append(alphabet.index(text[i-1]))

so that every time it looped, it would add the location alphabet.index(text[i-1] to list text_catch. I got a type error. Very new to this and honestly, still way over my head.

Upvotes: 1

Views: 53

Answers (3)

Greystone
Greystone

Reputation: 13

Don't get caught up in coding a certain way. I was making life way harder and had to step back. Here isn't technically a solution to my problem above but it's a much better way of doing it.

alphabet = ['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', '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']


def starting_cypher():
    direction = input("\nType 'encode' to encrypt, type 'decode' to decrypt:\n")
    text = input("Type your message:\n").lower()
    shift = int(input("Type the shift number:\n"))
    if direction == "encode":
        encrypt(plain_text=text, shift_amount=shift)
    elif direction == "decode":
        decrypt(coded_text=text, shift_amount=shift)
    else:
        print("That's not an option. ")
        exit()


def encrypt(plain_text, shift_amount):
    cipher_text = ""
    for letter in plain_text:
        position = alphabet.index(letter)
        new_position = position + shift_amount
        cipher_text += alphabet[new_position]
    print(f"The encoded text is {cipher_text}")
    print("\n")
    continue_cypher = input("Would you like to try again? y/n: \n")
    if continue_cypher == "y":
        starting_cypher()
    elif continue_cypher == "n":
        exit()
    else:
        print("That is not an accepted response.")
        exit()


def decrypt(coded_text, shift_amount):
    decoded_text = ""
    for letter in coded_text:
        position = alphabet.index(letter)
        new_position = position + 26 - shift_amount
        decoded_text += alphabet[new_position]
    print(f"The decoded text is {decoded_text}")
    print("\n")
    continue_cypher = input("Would you like to try again? y/n: \n")
    if continue_cypher == "y":
        starting_cypher()
    elif continue_cypher == "n":
        exit()
    else:
        print("That is not an accepted response.")
        exit()


starting_cypher()

Upvotes: 0

ahmadjanan
ahmadjanan

Reputation: 445

Instead of using nested loops, you could try out a simpler approach to encode/decode text based on the user's input.

For instance, you could try something like:

alphabets = ['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']

direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
text = input("Type your message:\n").lower()
shift = int(input("Type the shift number:\n"))

processed_text = ''
for character in text:
    idx = alphabets.index(character)
    
    # choose the operation
    if direction == 'encode':
        shifted_idx = idx + shift
    else:
        shifted_idx = idx - shift
    
    # wrap-around indexes which are greater than 25 to make sure you get an alphabet from the start of the alphabets instead
    shifted_idx %= 26
    
    # append alphabet to your output string
    processed_text += alphabets[shifted_idx]

print(processed_text)

Upvotes: 0

Swifty
Swifty

Reputation: 3419

The type error comes from using i as an index integer (i = len(text)) and as a string (for i in text); here's a fixed version of your code:

i =  len(text)
text_catch = []
while i != 0:
    print(alphabet.index(text[i - 1]))
    text_catch.append(alphabet.index(text[i-1]))
    i -= 1

Note that you don't need indexes, nor do you need to loop through text in reverse; you can simply do:

for letter in text:
    print(alphabet.index(letter))
    text_catch.append(alphabet.index(letter))

And there actually are far quicker methods to do the same (look at the ord and chr functions). For example:

def encode(text, shift):
    return ''.join([chr(((ord(letter)-97) + shift)%26 + 97) for letter in text])

def decode(text, shift):
    return encode(text,-shift)

Upvotes: 0

Related Questions