Posts: 5
Threads: 2
Joined: Mar 2024
Mar-31-2024, 09:40 AM
(This post was last modified: Mar-31-2024, 04:45 PM by ForsakenDusk.)
Hello everyone,
I am currently doing procedural programming exercices, and there are a lot of extra outputs I want to understand before switching to OOP exercises, I still already checked some OOP concepts to see if It could help me understanding such outputs but currently I'm in a dead end.
The goal of the current exercise is to take each letter of the sentence to code and to forward it 4 rows further into the alphabet, not saving spaces.
Example : "Ave caesar" -> "ezigeiwev"
I succeed with concatenating str, but when I try adding space, I fail.
I fail too with using str.replace()
Here's my code :
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
GAP = 4
chain_to_code = "ave caesar"
concatenated_chain = ""
for character in range(len(chain_to_code)):
for letter in range(len(ALPHABET)):
if chain_to_code[character] == ALPHABET[letter]:
concatenated_chain += ALPHABET[(letter + GAP) % len(ALPHABET)]
copied_and_coded_chain = chain_to_code
for character in range(len(copied_and_coded_chain)):
for letter in range(len(ALPHABET)):
if copied_and_coded_chain[character] == ALPHABET[letter]:
copied_and_coded_chain = copied_and_coded_chain.replace(copied_and_coded_chain[character], ALPHABET[(letter + GAP) % len(ALPHABET)], 1)
break
concatenated_chain_with_spaces = ""
for character in range(len(chain_to_code)):
for letter in range(len(ALPHABET)):
if chain_to_code[character] == ALPHABET[letter]:
concatenated_chain_with_spaces += ALPHABET[(letter + GAP) % len(ALPHABET)]
elif chain_to_code[character] == " ":
concatenated_chain_with_spaces += " "
print(f"chain to code : {chain_to_code}")
print(f"method 1, concatenaded chain : {concatenated_chain}")
print(f"method 2, with str.replace and spaces : {copied_and_coded_chain}")
print(f"method 3, concatenaded chain with spaces : {concatenated_chain_with_spaces}") Here's the output :
Output: chain to code : ave caesar
method 1, concatenaded chain : ezigeiwev
method 2, copied and coded chain : eve ceeser
method 3, concatenaded chain with spaces : ezi geiwev
I tried understanding results of method 2 & 3, but I failed.
Any help would be appreciated.
I use Win10 x64 - Python 3.10 - IDE Wing Personal 10.0.3.0
edit : for method 3 there are 26 spaces (which is len(ALPHABET)) between both words but it's showing only 1 I don't know why.
Posts: 7,312
Threads: 123
Joined: Sep 2016
Some tips and as example print both with and without spaces.
Also range(len(chain_to_code)) is not good here,just remember that range(len(sequence)) is almost always a bad way.
So just iterate over the string,no adding on is needed.
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
GAP = 4
chain_to_code = "ave caesar"
encoded_without_spaces = ""
encoded_with_spaces = ""
for character in chain_to_code:
#print(repr(character)) # Tips to see all
if character in ALPHABET:
encoded_char = ALPHABET[(ALPHABET.index(character) + GAP) % len(ALPHABET)]
encoded_without_spaces += encoded_char
encoded_with_spaces += encoded_char
# Handle spaces
elif character == " ":
encoded_with_spaces += " "
print(f"Encoded without spaces: {encoded_without_spaces}")
print(f"Encoded with spaces: {encoded_with_spaces}") Output: Encoded without spaces: ezigeiwev
Encoded with spaces: ezi geiwev
But just need this as it will handle inputs string with or without space correct.
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
GAP = 4
chain_to_code = "ave caesar"
concatenated_chain = ""
concatenated_chain_with_spaces = ""
for character in chain_to_code:
if character in ALPHABET:
concatenated_chain += ALPHABET[(ALPHABET.index(character) + GAP) % len(ALPHABET)]
else:
concatenated_chain += character
print(f"Encoded: {concatenated_chain}") Output: Encoded: ezi geiwev
Posts: 5
Threads: 2
Joined: Mar 2024
Mar-31-2024, 04:45 PM
(This post was last modified: Mar-31-2024, 04:45 PM by ForsakenDusk.)
Thanks for your string iteration hint.
I looked at your code and then I improved mine.
I tried again working with str.replace() but I think it's bad for this exercise :
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
GAP = 4
chain_to_code = "ave caesar"
concatenated_chain = ""
concatenated_chain_with_spaces = ""
for character in chain_to_code:
if character in ALPHABET:
encoded_character = ALPHABET[(ALPHABET.index(character) + GAP) % len(ALPHABET)]
concatenated_chain += encoded_character
concatenated_chain_with_spaces += encoded_character
elif character == " ":
concatenated_chain_with_spaces += " "
chain_with_str_replace = chain_to_code
character_count = 0
for character in chain_with_str_replace:
if character in ALPHABET:
encoded_character = ALPHABET[(ALPHABET.index(character) + GAP) % len(ALPHABET)]
chain_with_str_replace = chain_with_str_replace.replace(chain_with_str_replace[character_count], encoded_character, 1)
character_count += 1
print(f"chain to code : {chain_to_code}")
print(f"method 1, concatenaded chain : {concatenated_chain}")
print(f"method 2, concatenaded chain with spaces : {concatenated_chain_with_spaces}")
print(f"method 3, with str.replace and spaces : {chain_with_str_replace}") Output: chain to code : ave caesar
method 1, concatenaded chain : ezigeiwev
method 2, concatenaded chain with spaces : ezi geiwev
method 3, with str.replace and spaces : izi geewev
So what str.replace() does for the 3 first letters :
1. replaces "a" per "e"
2. replaces "v" per "z"
3. replaces new "e" (first letter) per "i" instead of replacing third letter "e" per "i"
I tried to fix this as you can see in my code, but then I discovered with my IDE documentation that str.replace(arg1, arg2, 1) look always for first occurrence of arg1.
So I guess it's impossible using str.replace() for this exercise, unless using 2D lists with first dimension being the character and second dimension being boolean - already replaced or not, I'll try later.
Posts: 6,779
Threads: 20
Joined: Feb 2020
Mar-31-2024, 10:31 PM
(This post was last modified: Apr-02-2024, 02:22 PM by deanhystad.)
str.replace() is a poor choice for this problem. Even if replace() replaced all occurrences it would still be a poor choice. After replacing all 'a' with 'e' you try to replace 'e' with 'i' resulting in replacing all a's and 'e's with i's.
def cipher(string, shift=4):
alphabet = "abcdefghijklmnopqrstuvwxyz"
def replace(string, a, b):
"""Replace all a's in string with b."""
return "".join(b if c == a else c for c in string)
encoder = dict(zip(alphabet, alphabet[shift:] + alphabet[:shift]))
for letter in string:
string = replace(string, letter, encoder.get(letter, ""))
return string
print(cipher("abcdefghijklmnopqrstuvwxyz", 1)) Output: aaaaaaaaaaaaaaaaaaaaaaaaaa
The source string must be left intact while you build a new string. I like defining the cipher using a dictionary. This one passes unrecognized characters through.
def cipher(string, shift=4):
alphabet = "abcdefghijklmnopqrstuvwxyz"
shift = shift % len(alphabet)
encoder = dict(zip(alphabet, alphabet[shift:] + alphabet[:shift]))
return "".join(encoder.get(c, c) for c in string)
x = cipher("Ave Caesar!", 2)
print(x)
print(cipher(x, -2)) Output: Axg Ccguct!
Ave Caesar!
If you want to limit the passed characters, add them to the dictionary and default dictionary.get() to return an empty string.
def cipher(string, shift=4):
alphabet = "abcdefghijklmnopqrstuvwxyz"
passed = " .,!?"
shift = shift % len(alphabet)
encoder = dict(zip(alphabet, alphabet[shift:] + alphabet[:shift]))
encoder.update({x: x for x in passed})
return "".join(encoder.get(c, "") for c in string)
x = cipher("Ave Caesar!", 2)
print(x)
print(cipher(x, -2)) Output: xg cguct!
ve aesar!
Posts: 5
Threads: 2
Joined: Mar 2024
Thanks, I discovered because of you new ways to use dictionaries. I read some IDE documentation about them.
I updated your code so it can work with capital letters :
def cipher(string, shift=4):
alphabet = "abcdefghijklmnopqrstuvwxyz"
alphabet_caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
passed = " .,!?"
shift = shift % len(alphabet)
encoder = dict(zip(alphabet, alphabet[shift:] + alphabet[:shift]))
encoder.update({x: x for x in passed})
encoder_caps = dict(zip(alphabet_caps, alphabet_caps[shift:] + alphabet_caps[:shift]))
encoder.update(encoder_caps)
return "".join(encoder.get(c, "") for c in string)
x = cipher("Ave Caesar!", 2)
print(x)
print(cipher(x, -2)) Output: Cxg Ecguct!
Ave Caesar!
Posts: 1,090
Threads: 143
Joined: Jul 2017
Apr-07-2024, 04:30 PM
(This post was last modified: Apr-07-2024, 04:30 PM by Pedroski55.)
I learned this whilst working for MI5! (Top secret, don't tell anyone!)
from string import ascii_lowercase, ascii_uppercase, digits, punctuation, whitespace
alpha = ascii_uppercase + ascii_lowercase + digits + punctuation
len(alpha) # 94
# Thank you Franz Schubert!
text = '''Ave Maria
Gratia plena
Maria, gratia plena
Maria, gratia plena
Ave, ave dominus
Dominus tecum
Benedicta tu in mulieribus
Et benedictus
Et benedictus fructus ventris
Ventris tuae, Jesus.
Ave Maria'''
def cyberSecurity(text):
text_list = [t for t in text]
for i in range(len(text_list)):
if text_list[i] in alpha:
index = alpha.index(text_list[i])
# go back to the beginning if index > len(alpha) - 4
if index > len(alpha) - 5:
index = 4 - (len(alpha) - index )
text_list[i] = alpha[index]
else:
text_list[i] = alpha[index+4]
coded = ''.join(text_list)
return coded
print(cyberSecurity(text)) Unbreakable code, but hard to sing!
Output: Ezi Qevme
Kvexme tpire
Qevme: kvexme tpire
Qevme: kvexme tpire
Ezi: ezi hsqmryw
Hsqmryw xigyq
Firihmgxe xy mr qypmivmfyw
Ix firihmgxyw
Ix firihmgxyw jvygxyw zirxvmw
Zirxvmw xyei: Niwyw<
Ezi Qevme
|