FAQ: Code Challenge: String Methods - Every Other Letter

My answer was quite same as yours, but i used .find()
The problem here is .index and .find can only point out the first occurrence.

“Hello” contains 2 “ll” which makes our answer went wrong.

Hello Community!

Why does this code give every other letter for the first word but not for the second word? It will also give me even numbers when I feed in a string of numbers. Why am I getting Hlloworld for the second call?

Thanks!

# Write your every_other_letter function here:

def every_other_letter(word):

  odd_letters = []

  for i in word:

    if word.index(i) % 2 == 0:

      odd_letters.append(i)

      odd_letters_joined = ''.join(odd_letters)

  return odd_letters_joined

# Uncomment these function calls to test your function:

print(every_other_letter("Codecademy"))

# should print Cdcdm

print(every_other_letter("0123456789"))

print(every_other_letter("Hello world!"))

# should print Hlowrd

print(every_other_letter(""))

print(every_other_letter("0123456789"))

# should print

Output:
Cdcdm
02468
Hlloworld
Traceback (most recent call last):
File “script.py”, line 16, in
print(every_other_letter(""))
File “script.py”, line 8, in every_other_letter
return odd_letters_joined
UnboundLocalError: local variable ‘odd_letters_joined’ referenced before assignment

there are several problems, first of using .index() isn’t a good idea. .index() will give you the first match. So if a letter of number occurs multiple times, that is a problem

use the loop to determine if the index is even

also, if word is an empty string, the loop doesn’t make any iteration, so odd_letters_joined isn’t named/defined, which is why you get an UnboundLocalError

Thanks stetim94,

I pulled the solution, and I see that my solution isn’t the one provided as a solution. This is one of my first attempts where anything at all worked where I didn’t use the supports provided. Thanks for your explanation of the unbound local error. That was helpful.

I thought I was using a loop to determine if the index was even. Is that what you are telling me, that using a loop to determine if the index is even is a bad idea? I see that it isn’t working, but I don’t understand why it isn’t. What’s going on?

Here’s another example:

print(every_other_letter(“eoeoeoeoeoeoeoeo”) outputs a string like this oooooooooo.

Thanks for your consideration.

you are not, you are using the .index() method. You should check the documentation on this method.

no, using the loop to determine an index is even is a very good idea. But that is not what you are currently doing

What would using a loop to determine an index look like? I’d like to compare the two in order to understand the differences. Thanks!

you could use range() to get the indexes/indices. Hasn’t this been covered? Seems like an important concept to know, or something you can check in the documentation/using google.

1 Like

stetim94,

  1. Learners need up to six interactions with a new concept/vocabulary word before they really understand it and grasp it. So, while the idea you’re telling me about may have been covered, this forum is supposed to be a place ask questions.
  2. You’re not answering the question. It seems like you got stuck on the idea that my solution was different than the best one, and you didn’t hear my question, "Why did my code seem to work on “Codecademy” but not on “Hello World!” If you don’t know, that’s ok.

As long as one knows it is nobody connected with the courseware who will attempt to answer.

The best thing about this post.


Just know, these forums don’t owe anybody.

2 Likes

@mtf nails it, like usual :slight_smile:

but I told you what you need, you need range(). which means you can consult documentation. A huge part of programming is figuring things out.

I did answer this. You think I don’t know? Take a look at my activity and the massive amount of people I have helped. Like mtf said: the best thing about this post

1 Like

I did answer this. You think I don’t know? Take a look at my activity and the massive amount of people I have helped. Like mtf said: the best thing about this post

You must have answered in a way that I did not understand because I think that I was using a loop in the code although it seems you disagree. Have you heard the phrase, “The Curse of Knowledge?” If you don’t know what that is, I’d ask you to check the documentation on that.

yes, you use a loop. But you don’t use the loop to determine if the index is even or odd.

you use the .index() method, which simple will give you the first index it can find (so under the hood, .index() very likely uses a loop)

but if that is the case, why not take the part of my answer that you struggle with, and ask further questions about it? Or give your thought process so I can see where you go wrong?

yes, you use a loop. I don’t disagree with the fact that you use a loop. But then you use a method (.index()) which you don’t seem to (fully) understand.

I think you have the idea that .index() will give you the index of the current value, which is not the case.

you will need to change the loop to get the indexes.

1 Like

So with proper understanding of how they came up with the solution (after the fact) would this route be acceptable?

def every_other_letter(word):
return word[ 0 : -1 : 2 ]

It never hurts to take our ideas to the interactive shell…

>>> word = "diction"
>>> word[ 0 : -1 : 2 ]
'dci'
>>> 

Now let’s test this outcome against our expected outcome based upon the criteria of the problem.

  • every other letter: does our poll begin on the first or the second letter (what is given in the criteria)?
  • regardless which, is the outcome complete or irregular?

To answer the second point, it is irregular. -1 as the upper bound excludes the last letter of the word.

I understand. Is the default position for the upper bound (if left blank) always be the last index?

If left blank, yes, but then 0 is also not needed.

word[ 0 : -1 : 2 ]

translates to,

word[ 0 : len(word)-1 : 2 ]

Think in terms of the behavior of range().

Ok I see. Thank you!

1 Like

You’re welcome. BTW, what is the selection criteria? Does it include the first letter, or the second, as the first one selected and then go from there every other one?

word[::2]
# vs.
word[1::2]

Update

Create a function named every_other_letter that takes a string named word as a parameter. The function should return a string containing every other letter in word .

The starting letter is not specified so we must toss a coin. Heads we start with the first, tails we start with the second. Heads it is.

word[::2]

I finally figured out what about the index method doesn’t work and how range fixes it.

The idea here is to not loop through the letters of the word (because index comes with the problems described above) but to loop through the position of the letter in the word. The range() gives me just a workbench to determine at which position in the word I am. That’s why I need to combine range() with len() in this excercise.

Not like in the index method, I do not append the letter itself to the output but I append the letter at the specific position in the word.

I hope this explanation helps in understanding (it helped me to simply formulate this reply). Thanks for all the help from this forum. What helped me understand this excercise was the code by yoliins in other thread Aren't strings immutable? - #3 by danthecoder123

Easier, I guess :slight_smile: :

def every_other_letter(word):

  return word[0:len(word):2]