Потоки данных и коллекции в Kotlin

Потоки данных и коллекции в Kotlin #

Входные и выходные потоки данных #

Презентацию по теме можно посмотреть по ссылке

Видео-запись: Rutube

Работа с null-значениями #

Презентацию по теме можно посмотреть по ссылке

Видео-запись: Rutube

Коллекции в Kotlin #

Презентацию по теме можно посмотреть по ссылке

Видео-запись: Rutube

Задание № 1: Работа с коллекциями #

В рамках данной практической работы реализуйте небольшое консольное приложение на языке Kotlin, решающее следующую задачу.

Пользователь вводит в приложение коэффициенты многочлена произвольной степени n. Многочлен степени n имеет форму \( a_n * x^n + a_{n−1} *x^{n−1} + · · · + a_1 * x + a_0 \) .

Вычислите значение многочлена в точке x, указанной пользователем. Вычислите значение производной многочлена в той же точке.

Предлагается следующий подход к решению задачи.

  1. Реализуйте функцию для получения одного целого числа от пользователя со стандартного потока ввода. Данная функция может иметь следующую сигнатуру:
    fun readInt(prompt: String) : Int { /**/ }
    1. Аргумент prompt должен содержать строку-приглашение, например "Введите целое число> ", которое должно показываться пользователю перед вводом числа. Приглашение должно показываться перед вводом числа, без переноса строки. Используйте метод print.
    2. Для считывания рекомендуется использовать метод readLnOrNull.
    3. null-значение может быть получен в случае, например, в случае окончания потока ввода. В рамках данной программы будем считать, что поток ввода не завершён, и будем пытаться считывать данные со стандартного потока ввода ещё раз в случае получения null-значения.
    4. Метод должен получать строку от пользователя и пытаться преобразовать её к целому числу. Для преобразования строки к числу можно использовать метод toInt. Обратите внимание, что в случае ошибки преобразования будет выброшено исключение NumberFormatException. Процесс обработки исключений описан в документации.
      1. Если преобразование выполнено успешно, то его результат надо возвратить в качестве результата работы функции.
      2. Если преобразование не было успешно, то функция должна повторить запрос на ввод данных от пользователя. Пользователю необходимо сообщить о возникшей проблеме, чтобы он не повторил свою ошибку ещё раз. В качестве альтернативы можно воспользоваться функцией toIntOrNull. Но необходимо обязательно обработать ошибочную ситуацию.
  2. Реализуйте функцию для получения коэффициентов многочлена. Данная функция может иметь следующую сигнатуру:
    fun readCoefficients() : List<Int> { /**/ }
    1. Данная функция должна запрашивать степень коэффициента многочлена, N, с помощью метода readInt. Если было получено отрицательное число, то необходимо запросить ввод данных ещё раз.
    2. Затем функция должна получить N+1 коэффициентов многочлена. Для этого можно использовать метод readInt с сохранением результата в изменяемом списке целых чисел.
      1. Для создания динамического списка для хранения чисел используйте функцию mutableListOf().
      2. Для добавления элемента используйте метод add().
    3. Сформированный список коэффициентов многочлена метод должен вернуть в качестве своего значения.
    4. Созданный изменяемый список, объект интерфейса MutableList, может быть возвращён клиентам как объект неизменяемого списка List, т.к. интерфейс MutableList унаследован от List:
      interface MutableList<E> : List<E>, MutableCollection<E>
      Клиентам данного метода нет необходимости получать изменяемый список, т.к. пользователь уже завершил ввод своих данных.
    5. Удобным форматом для хранения коэффициентов является формат, когда на первом месте в массиве хранится коэффициент многочлена нулевой степени, на втором — первой степени и т.д. Для считывания удобно спрашивать у пользователя коэффициенты, начиная со старшего члена. Перед возвращением списка коэффициентов пользователю его необходимо развернуть с помощью метода reversed.
  3. Используйте функцию readInt для считывания точки x, в которой необходимо произвести вычисление значения многочлена.
  4. Реализуйте функцию для вычисления коэффициентов производной многочлена. Данная функция может иметь следующую сигнатуру:
    fun calcDerivative(coefs: List<Int>) : List <Int> { /**/ }
    1. Для вычисления производной удобно расположить коэффициенты многочлена по возрастающей. Т.е. коэффициент многочлена степени 0 должен быть первым, степени 1 - вторым и так далее.
    2. Производной будет многочлен, у которого:
      • Значение новых элементов вычисляется как значение коэффициента оригинального многочлена, умноженного на порядковый номер многочлена.
      • Первый элемент отсутствует, т.к. степень производной многочлена меньше степени многочлена на 1.
    3. Для вычисления производной по индексам можно воспользоваться диапазонами от 1 до размера оригинального массива:
       
      for (index in 1 until coefs.size) { coefs[index] } 
  5. Реализовать функцию вычисления значения многочлена в точке. Данная функция может иметь следующую сигнатуру:
    fun polynomValue(coefs: List<Int>, point: Int) : Int { /**/ }
    1. Для вычисления значения числа в указанной степени можно воспользоваться методом pow.
    2. Для преобразования целого числа в вещественное можно использовать метод toFloat.
    3. Для преобразования вещественного числа в целое можно использовать метод toInt.
  6. Используя полученные функции выполнить вычисление значения многочлена и его производной в точке x.
  7. Выведите информацию о многочлене, его производной и их значении в указанной точке с помощью строковых шаблонов.

Задание № 2. Получение данных из аргументов #

Решите предыдущую задачу, только входными данными для приложения должно получать не со стандартного потока данных, а через аргументы приложения.

Предлагается следующая последовательность аргументов:

КОЛИЧЕСТОВО-КОЭФФИЦИЕНТОВ 1-Й-КОЭФФИЦИЕНТ .... N-Й-КОЭФФИЦИЕНТ ТОЧКА

Пример:

3 1 2 -5 -10

  1. Добавьте в стартовую функцию main возможность принимать массив строк, аргументы приложения.

  2. Настройте передачу аргументов при запуске задачи run в IDEA. В список аргументов Gradle после команды run добавьте аргументы, которые необходимо передать приложению. Например: run --args="3 1 2 -5 -10".

  3. Создайте новую функцию для получения списка чисел из аргументов. Данная функция может иметь следующую сигнатуру:

    fun argumentsToIntsOrNull(arguments: Array<String>): List<Int>? { ... }

    Она должна возвращать:

    • Либо список целых чисел, если все аргументы содержали строковое представление целых чисел.
    • Либо null-значение, если какой-либо элемент содержал не число.
  4. Полученный список должен быть обработан в функции main:

    • Необходимо проверить на наличие null-значения. В случае проблем с проверкой данных приложение должно завершить работу с ошибочным кодом.
    • Если количество переданных коэффициентов не соответствует ожиданиям, то надо сообщить об этом пользователю и завершить работу с ошибочным кодом.
    • Во всех остальных случаях можно сформировать коллекцию коэффициентов и значение точки для проверки. Рекомендуются к использованию функции: slice, drop, take, dropLast, takeLast.
  5. Передайте полученные данные в существующие функции, чтобы получить нужный результат.

© A. M. Васильев, 2024, CC BY-SA 4.0, andrey@crafted.su