Логика кода подсчета гласных в строке

На канале у одного блогера увидел код - программу для подсчета гласных букв в тексте:

user_input = input('Enter something: ')

vowels = 'eyuioa'
vowels_count = 0
index = 0

while index < len(user_input):

    if user_input[index] in vowels:
        vowels_count += 1
    index += 1

print(vowels_count)

Код работает правильно. Как я понимаю, когда пользователь вводит данные с клавиатуры, происходят следующие процессы:

  1. Данные попадают в переменную user_input.
  2. Цикл while считывает данные и проверяет, чтобы длина текста была больше, чем длина переменной index. Если условие соблюдается, то программа запускает блок while.
  3. И вот тут происходит нестыковка. Я думал, что if по порядку должен проверять каждый символ переменной user_input и сличать с нашим списком гласных (переменная vowels); дальше добавлять каждый символ в счетчик count и, если найдет гласную, в счетчик vowels_count.

Но, почему-то, автор после оператора if указывает, что переменная user_input обращается сразу к счетчику count, у которого по логике значение равно 0.

Если есть возможность, очень прошу сообщество объяснить данный феномен. Заранее благодарю за содействие.


Ответы (2 шт):

Автор решения: Faraday

У вас есть строка, состоящая из гласных букв

vowels = 'eyuioa'

А так же счётчик их количества

vowels_count = 0

У вас есть условие цикла

while index < len(user_input)

Это значит, что цикл будет работать, пока index не достигнет длинны слова.

Внутри цикла мы берём текущий i-й символ из строки ввода и проверяем его, есть ли в vowels i-й символ из строки ввода? Если такой есть, мы увеличиваем количество найденных букв на 1

vowels_count += 1

Блока else тут нет. Это значит, что в любом случае у нас выполняется увеличение index на единицу

index += 1

index выступает в качестве счётчика. За каждый проход цикла он увеличивается на 1. На каждой итерации цикла вы будете проверять i-й символ из строки ввода


Но почему-то автор после оператора "if" указывает, что переменная "user_input" обращается сразу к счетчику "count", у которого по логике значение = 0?

ИНДЕКСАЦИЯ МАССИВОВ НАЧИВАЕТСЯ С НУЛЯ

user_input[0] -> Ok
user_input[1] -> Ok
user_input[-1] -> Error

UPD Строки считаются массивом символов.

str = 'hello world'
str[0] -> 'h'
str[1] -> 'e'
str[2] -> 'l'
str[3] -> 'l'
str[4] -> 'o'
...

UPD2:

Не понятно как одна переменная index получает из переменной user_input буквенные значения для сравнения с символами из переменной vowels, а в другой строке та же самая переменная index оперирует цифровыми значениями в качестве счетчика?

Доступ к массиву осуществляется по числовому значению, продублирую фрагмент:

str = 'hello world'
str[0] -> 'h'
str[1] -> 'e'
str[2] -> 'l'
str[3] -> 'l'
str[4] -> 'o'
...

Как сделать так, что бы значение задавалось не хард кодом? Вы можете, к примеру, сначала использовать числовую переменную:

str = 'hello world'
index = 4
str[4] -> 'o'
str[index] -> 'o'

Как видите, разницы между результатами не будет, потому что используется числовое значение для доступа к конкретному элементу массива по индексу, а индекса массива, напомню, имеет числовое значение и начинается с нуля.

Что бы получить следующий символ, вы можете увеличить значение переменно индексатора на единицу

index += 1 -> 5

Тогда следующая попытка получить символ из строки будет уже выполнять доступ к 5-му элементу

str[index] -> ' ' (пробел)

Для понимания

Для работы с массивом вам нужно понимать три вещи

  • Массив - набор однотипных последовательных элементов
  • Индекса элемента - его порядковый номер, который начинается с нуля
  • Значение массива - то, что хранится под i-м порядковым номером

В вашем случае user_input это массив (к примеру, пусть там будет строка Hello world). index - это переменная, которая хранит порядковый номер. Она нужно только для потому, что она постоянно изменяется при каждом прохождении цикла. При выполнении user_input[index] вы обращаетесь к какому-то конкретному элементу (букве).

Для упрощения, ваш код мог бы выглядеть вот так:

while index < len(user_input):
    c = user_input[index]
    if c in vowels:
        vowels_count += 1
    index += 1

Обратите внимание, что я добавил строку

c = user_input[index]

На этом этапе вы получаете конкретную букву из user_input и проверяете, есть ли она в vowels. Тут c это конкретная буква (символ) полученный из user_input (строки, массива символов) по порядковому номеру index (который является числовым)

→ Ссылка
Автор решения: CrazyElf

Так, чисто в дополнение. Весь ваш подсчёт можно сократить до одной строки:

vowels_count = sum(ch in vowels for ch in user_input)

Т.е. весь код целиком:

user_input = input('Enter something: ')
vowels = 'eyuioa'
vowels_count = sum(ch in vowels for ch in user_input)
print(vowels_count)

Причём, и читается то такой код гораздо понятнее, чем все эти индексы с инкрементами.

Буквально:

код как читать
sum посчитай число
ch in vowels гласных букв
for ch среди букв
in user_input пользовательского ввода

"Перевод кода" целиком:

# посчитай число гласных букв среди букв пользовательского ввода
vowels_count = sum(ch in vowels for ch in user_input)

Всё просто и понятно. Никаких индексов, длин строк и прочих низкоуровневых понятий.

P.S. При желании, можно и из всего кода сделать однострочник:

print(sum(ch in 'eyuioa' for ch in input('Enter something: ')))
→ Ссылка