Off-Platform Project Coded Correspondence: Conditional For + Try/Except Loop Output Stuck on First Iteration

Project URL: https://www.codecademy.com/courses/learn-python-3/informationals/python3-coded-communication
Current Code:

alphabet = "abcdefghijklmnopqrstuvwxyz"

encoded_message = "xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!"
offset = 10

def caesar_cypher(encoded_message, offset):
	decoded_message = ""
	in_alphabet = 0
	remainder_alphabet = 0
	for i in encoded_message:
		if (i in alphabet) == True:
			try:
				in_alphabet += alphabet.find(i)
				decoded_message += alphabet[in_alphabet + offset]
				in_alphabet = 0
			except IndexError:
				in_alphabet += alphabet.find(i)
				remainder_alphabet = ((len(alphabet) % offset) + 1)	
				decoded_message += alphabet[remainder_alphabet]
				remainder_alphabet = 0
				in_alphabet = 0
		else:
			decoded_message += i
	return decoded_message

print(caesar_cypher(encoded_message, 10))

Current Output:
hhy thhrh! thhs hs hn hxhmplh oh h hhhshr hhphhr. whrh you hhlh to hhhohh ht? h hoph so! shnh mh h mhsshhh hhhk whth thh shmh ohhsht!

Question:
First & foremost, please excuse what I have no doubt is likely poorly formatted, redundant code, as I am still quite new at this.

That said, as is relatively obvious, it appears as though the Except portion of my code, despite outputting the correct decoded letter the first time through, is getting stuck on said letter & re-applying it to any/all future instances when the Except portion proves relevant.

Most specifically, why does including a reset of the remainder_alphabet variable to zero not result in the correct decoded letter being applied following the first instance?

I’m sure the answer is relatively straightforward, however, after attempting to debug my code myself for an extended period of time, I’d greatly appreciate any insight any of you may be able to provide. Thanks in advance!

The problem I suspect is with this line of code:

remainder_alphabet = ((len(alphabet) % offset) + 1)	

This is a fixed variable that will never change it’s value, as len(alphabet) is always 26 and offset is always 10, so this variable will always take the value of 7, which is the index for ‘h’ which would explain why there’s so many 'h’s in your output.
The way to think about this is to think on what’s actually happening here. Your code is trying to see if the index is ‘in’ 0:25, and if not (i.e. if there’s an IndexError) then it’s running the exception code. So the exception code will only run if the index in_alphabet + offset is bigger than 25. So you want to take this index, and then take the modulo of it with len(alphabet). Then for example, if the index is 26, it will execute 26 % 26 = 0, and so take the letter at position 0 which is ‘a’.

The next problem you’ll likely encounter is that the try block exits as soon as the error is found, which means that in any situations where there’s an IndexError, in_alphabet will end up having alphabet.find(i) added to it twice and thus give you the wrong letter. I would recommend doing away with the += for the indexes, and just using in_alphabet = alphabet.find(i) and then resetting it to 0 will not matter.

1 Like

Thanks so much, @adamgaffney96!

In hindsight, as with most things, this presents as embarrassingly apparent, however, in the moment it was not so. Your explanation did an excellent job of breaking down the rationale underlying my error, & I greatly appreciate your foresight in also assisting me with the subsequent problem bound to present itself.

This being my first (admittedly wary) attempt of receiving assistance via Codecademy’s forums, I’m elated to have been met with such chivalrous assistance. Thank you again!

1 Like

On the off chance that it might help another individual who finds themselves on this post, below I’ve included the corrected code per @adamgaffney96’s instructions.


alphabet = "abcdefghijklmnopqrstuvwxyz"

encoded_message = "xuo jxuhu! jxyi yi qd unqcfbu ev q squiqh syfxuh. muhu oek qrbu je tusetu yj? y xefu ie! iudt cu q cuiiqwu rqsa myjx jxu iqcu evviuj!"
offset = 10

def caesar_cypher(encoded_message, offset):
	decoded_message = ""
	in_alphabet = 0
	remainder_alphabet = 0
	for i in encoded_message:
		if (i in alphabet) == True:
			try:
				in_alphabet = alphabet.find(i)
				decoded_message += alphabet[in_alphabet + offset]
				in_alphabet = 0
			except IndexError:
				in_alphabet = alphabet.find(i)
				remainder_alphabet = ((in_alphabet + offset) % len(alphabet))
				decoded_message += alphabet[remainder_alphabet]
				remainder_alphabet = 0
				in_alphabet = 0
		else:
			decoded_message += i
	return decoded_message

print(caesar_cypher(encoded_message, 10))