Перейти к содержанию

KTB-06 Реализовать функционал статистики

📝 Описание

Необходимо определить формат и содержание отображаемой статистики в приложении, основываясь на требованиях ТЗ. Статистика должна включать следующие показатели:

  • Общее количество слов в словаре.
  • Количество выученных слов, где слово считается выученным, если значение свойства correctAnswersCount больше или равно 3.
  • Процентное соотношение выученных слов к общему количеству слов.

Формат отображения статистики должен соответствовать следующему примеру:

Выучено 4 из 6 слов | 66%

В блоке when для пункта меню "2" необходимо добавить функционал, который будет выполнять следующие действия:

  1. Использование функции-расширения filter для списка словаря dictionary, чтобы получить список слов, у которых correctAnswersCount больше или равно 3.
  2. Вычисление статистических показателей (общее количество слов в словаре, количество выученных слов, процент выученных слов).
  3. Вывод статистики (сформировать строку с подстановкой вычисленных значений в соответствии с требуемым форматом и вывести в консоль).
  4. Перезапуск цикла для повторного отображения меню.

🗒 Задание

  1. При выборе пункта меню "2" выполнить следующие действия:
    • Вычислить и отобразить общее количество слов в словаре (totalCount).
    • Вычислить и отобразить количество выученных слов, где correctAnswersCount ≥ 3 (learnedCount).
    • Рассчитать и отобразить процентное соотношение выученных слов к общему количеству (percent).
  2. Обеспечить формат вывода, соответствующий примеру.
  3. После вывода статистики – через пустую строку снова выводить меню консольного приложения.

❌ Ошибки

✏️ Комментарии

Иногда подсчет статистики делают в неправильном месте. Либо за циклом и тогда:

Если ты будешь считать статистику тут, то она не будет меняться позже в процессе изучения слов. Ведь на протяжении работы программы мы не будем выходить из цикла

Либо внутри цикла, но не в самой ветке

Считать статистику заранее не нужно. Может пользователь никогда и не зайдет в это меню, а ты уже нагрузил ему процессор.
Калькуляцию лучше делать внутри ветки `when`, иначе значения не будут пересчитываться при повторном входе в меню 2.
Давай просто в ветке по подсчету статистики в `when` считать невыученные слова в переменную.
Теперь ты дважды делаешь `filter` для списка слов, для расчета статистики. Если это будет список из 100 000 слов, получается 200к итераций цикла для фильтрации значений. Давай рассчитывать переменную и использовать ее.
Вообще можно объединить инициализацию и присваивание: `val learnedWordsCount = dictionary.filter { it.correctAnswersCount >= 3 }.count()`.
Всегда если можно используй `val` вместо `var`.
Обрати внимание, фильтрация повторяется дважды. Во-первых, нарушается принцип DRY (don't repeat yourself). Во-вторых, операция фильтрации по своей сути не дешевая. Ведь производится перечисление всех элементов из исходного списка, а также создается новый список.
Метод лучше назвать `printStatistic()`, ведь `get_` звучит как будто метод что-то возвращает. А еще лучше и правда возвращать строку, а печатать ее там где используешь. Так чуть универсальнее (на случай, например, если захотим писать статистику в файл или отправлять в телеграм бота).
Эту переменную лучше сделать локальной, так как ее область видимости имеет смысл только внутри `when -> "2"` для подсчета статистики. В ином случае она может оказаться проинициализированной неактуальным значением.
Для изучаемого слова можно использовать отдельную переменную, а не считать, что первый элемент списка — это изученное слово.

⌨️ Решение

"2" -> {
    val totalCount = dictionary.size
    val learnedCount = dictionary.filter { it.correctAnswersCount >= 3 }.size
    val percent = learnedCount * 100 / totalCount
    println("Выучено $learnedCount из $totalCount слов | ${percent}%\n")
    continue
}