KTB-04 Спарсить файл словаря и распечатать содержимое¶
📝 Описание¶
Необходимо реализовать функциональность, позволяющую отслеживать количество правильных ответов пользователя на каждое слово в тренажёре. Это соответствует 4 пункту требований к тренажёру.
Добавление свойства в класс Word
Следует использовать ранее созданный класс Word и добавить в него новое свойство correctAnswersCount со значением по умолчанию 0. Это свойство будет хранить количество правильных ответов для каждого слова, что позволит отслеживать уровень освоения пользователем каждого термина.
Хранение данных в файле
Для сохранения этой информации между сессиями необходимо хранить количество правильных ответов в файле со словами. Данные следует добавлять в ту же строку, где уже находятся слово и его перевод, используя дополнительный разделитель — вертикальную черту |.
На данном этапе необходимо вручную добавить эти значения в файл, дополнив строки новым разделителем и числом в конце каждой строки. Обеспечиваем единый формат данных.
Обработка отсутствующих данных
При чтении данных из файла возможно отсутствие информации о количестве правильных ответов в некоторых строках (особенно если поле было добавлено недавно). Поэтому при прохождении по строкам файла в цикле необходимо добавить проверку на null. Для этого рекомендуется использовать элвис-оператор.
Таким образом, при отсутствии данных свойству correctAnswersCount будет присвоено значение 0, что обеспечит корректную работу приложения.
Инициализация словаря и вывод данных
После добавления нового свойства и настройки чтения данных из файла – требуется инициализировать пустой изменяемый список dictionary, который будет содержать объекты типа Word.
На каждой итерации цикла по строкам файла необходимо создавать новый объект Word и добавлять его в dictionary.
🗒 Задание¶
- Добавить новое свойство в класс для хранения слов.
- Вручную добавить разделитель с 0 значением, при отсутствии числа правильных ответов в файле – использовать значение по умолчанию.
- Инициализировать пустой изменяемый список для словаря
dictionaryс типом объектовWord. - На каждой итерации прохода по строкам файла создавать объект типа
Wordи добавлять его вdictionary. - Распечатать содержимое
dictionaryв консоль.
❌ Ошибки¶
- не используют
toIntOrNull()для обработки отсутствующего значения в файле
✏️ Комментарии¶
Если создают файл в коде и записывают туда слова:
В целом, будет гибче если мы будем считывать словарь из файла. Это дает возможность менять словарь без пересборки приложения. На крайний случай можно проверять, существует ли файл: `if(!wordsFile.exists()) { createStartWords() }`
Если просто вычитывают значение correctAnswersCount, не проверяя его наличие и Null
Оператор `[2]` можно заменить вызовом метода `get()` - это будет эквивалентная операция.
А можно использовать `getOrNull()` - которая в случае ошибки обращения по индексу возвратит `null`: `val correctAnswers: Int = line.getOrNull(2)?.toIntOrNull() ?: 0`.
Сейчас мы делаем основу для нашего консольного тренажера слов, который будем в дальнейшем апгрейдить до Телеграм-бота. На текущем этапе наша задача написать код, который грузит из файла словарь. Словарь, в нашем случае, список `Word`'ов. Логика такая - если файла нет, создаем его и заполняем словами. Если есть - ничего не делаем, ведь словарь предоставлен извне.
Давай удалим выше строку: `wordsFile.writeText("")`. Она по сути затирает все содержимое словаря, и тогда мы вынуждены всегда заполнять словарь заново.
Слово у нас представляется английским значением, переводом, а также давай добавим поле, которое обозначает - сколько раз пользователь правильно его ответил. При определенном пороге правильных ответов, считаем что слово выучено.
А теперь давай подумаем, если не указано количество, или указано не корректно, может просто будем проставлять 0? Чтобы не работать внутри приложения с нулябельными полями.
Попробуй в `words.txt` добавить `good|хорошо|` (строка заканчивается вертикальной чертой). Приложение упадет. Надо починить.
Стоит всегда стараться избегать нулябельных полей. Тем более обработки нулябельных полей оператором `!!`. Этот оператор означает "я не хочу заморачиваться над нулябельностью в этом поле".
Мы используем `correctAnswersCount` для хранения количества ответов пользователей. И значение его всегда определено – либо пользователь еще не отвечал, либо отвечал какое-то количество раз правильно.
⌨️ Решение¶
data class Word(
val original: String,
val translate: String,
val correctAnswersCount: Int = 0,
)
fun main() {
val wordsFile = File("words.txt")
val dictionary = mutableListOf<Word>()
for (string in wordsFile.readLines()) {
val split = string.split("|")
val word = Word(
original = split[0],
translate = split[1],
correctAnswersCount = split[2].toIntOrNull() ?: 0
)
dictionary.add(word)
}
println(dictionary)
}