Storing several location values from list into another list in python
Question:
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.
Answers:
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)
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()
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.
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)
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()