Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Операции, производимые с данными (Типы структур данных и предметная область)

Содержание:

ВВЕДЕНИЕ

Технология программирования представляет собой совокупность средств и методов, необходимых для разработки программного обеспечения. Решающее значение для специалиста в области информационных технологий и программирования имеет выбор парадигмы программирования, определяющей успешность реализации программного продукта, и соответствующего ей языка программирования [11.]. За последние 50 лет появились сотни языков, поддерживающих различные парадигмы, причем некоторые из них используют несколько парадигм (такие языки называют мультипарадигменными). Однако, несмотря на большое количество языков программирования, существует несколько действительно важных концепций программирования, и не так много языков, которые были бы актуальны на протяжении более десяти лет. Именно парадигмы программирования определяют общий способ проектирования прикладных программ [3.]. Парадигмой программирования называют используемый различными языками подход к программированию, то есть, проще говоря, набор идей и понятий, определяющих стиль написания программ. Среди основных парадигм программирования выделяют объектно-ориентированную, императивную, декларативную, структурную, функциональную и логическую. Большинство языков программирования, активно используемых в современной разработке прикладных программ, являются мультипарадигменными [4.].

Одной из разновидностей прикладных программ являются информационно-справочные системы, которые позволяют эффективно хранить необходимую пользователю информацию и осуществлять быструю навигацию по накопленному в базе материалу. В связи с постоянно возрастающим объемом хранимой информации проектирование прикладных программ для хранения и упорядочивания накопленной информации является актуальной задачей.

Целью данной курсовой работы является изучение операций, применяемых к данным, а также структур для их хранения. Итогом выполнения работы должна стать разработка программного приложения, реализующего информационно-справочную систему на основе одной из структур данных в соответствии с выбранной предметной областью, которая сможет выводить информацию, а также осуществлять поиск в базе данных по заданным параметрам. Для достижения цели в курсовой работе были поставлены следующие задачи:

  • получить представление об основных операциях с данными;
  • выбрать структуру данных, которая позволяет осуществлять чтение, запись, поиск информации;
  • выявить ключевые особенности проектирования программ, позволяющие вводить информацию, хранить ее в файле, а также осуществлять модификацию данных;
  • реализовать информационно-справочную системы с использованием выбранной структуры данных на одном из языков программирования, а также провести ее тестирование и отладку.

Для достижения обозначенных целей были выбраны следующие методы исследования: систематизация специальной литературы и мировых информационных ресурсов по проблеме исследования.

1. Теоретические сведения

1.1 Типы структур данных и предметная область

Структуры данных играют довольно важную роль в разработке программного обеспечения [12.]. По сути, они представляют собой всего лишь специальные форматы для организации и хранения данных.

Структура данных – это контейнер, который хранит данные в определенном макете [1.]. Этот «макет» позволяет структуре данных быть эффективной в некоторых операциях и неэффективной в других.

Структуры данных активно используются в различных областях знаний, находя широкое применение в многочисленных научных и практических приложениях [10.]. Структуру данных можно считать некоторой совокупностью однотипных и/или логически связанных данных, которую можно хранить и обрабатывать как единое целое. Для добавления, поиска, изменения и удаления данных структура данных предоставляет некоторый набор функций, составляющих её интерфейс.

Существует множество различных структур данных [2.]: массив (каждому элементу данных присваивается индекс, который соответствует позиции элемента в массиве), список (массив, в котором каждый элемент является отдельным объектом и состоит из двух элементов: данных и ссылки на следующий узел), очередь, стек, граф (набор вершин, которые соединены друг с другом в виде сети дугами), дерево (иерархическая структура данных, состоящая из вершин и дуг), словарь (структура данных, предназначенная для хранения произвольных объектов с доступом по ключу).

В простейших контейнерах акцент сделан на самих значениях. Например, органайзер, представляющий собой список запланированных событий, используется для хранения набора элементов – предстоящих событий. Можно добавить новое значение в список, проверить, найдено ли значение в списке и удалить значение из списка. В словаре, с другой стороны, данные разделены на две части. Каждый элемент, хранящийся в словаре, представлен парой ключ / значение. Ключ используется для доступа к элементу. С помощью ключа можно получить доступ к значению, которое обычно содержит больше информации [5.].

В качестве предметной области в данной работе рассмотрен учет банковских вкладов. В настоящее время разработано большое количество программных продуктов, включающих в себя все необходимые функции и возможности для выполнения роли информационно-справочной системы (ИСС) с информацией о вкладах. Каждый объект (вклад) имеет следующий набор атрибутов: название банка, название тарифа, дата открытия вклада, валюта, срок (лет), процентная ставка, условия вклада.

В ходе работы были поставлены и решены следующие задачи:

  1. Определен функционал ИСС «Банковские вклады»;
  2. Обоснован выбор структур данных, оптимальных для разработки приложения;
  3. Спроектирована модульная структура приложения;
  4. Разработаны алгоритмы работы модулей;
  5. Выполнена реализация и тестирование программного приложения средствами языка Python версии 3.7.

Практически каждый человек пользовался услугами банка, многие открывали вклады с заранее известными условиями. В большинстве банков в наше время сделать это довольно просто, для этого достаточно иметь доступ к Интернету.

Актуальность данной работы обусловлена удобством использования электронных ресурсов для хранения данных. Пользователь программного приложения без особого труда может добавлять или удалять записи из общей базы данных, а также выполнять поиск по ней. Программное приложение довольно простое в освоении и позволяет сделать работу с банковскими вкладами простой и быстрой.

Для выполнения поставленной в работе задачи была выбрана такая структура данных, как «линейный односвязный список» (ЛОС), позволяющая хранить информацию о банковских вкладах.

Взаимодействие с пользователем осуществляется при помощи графического интерфейса.

1.2 Линейный односвязный список

Односвязный список – структура данных, в которой каждый элемент является отдельным объектом и состоит из двух элементов: данных и ссылки на следующий узел (рисунок 1). 

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

«Голова» списка (head) – это первый элемент списка; «хвостом» списка называют оставшуюся часть списка без «головы».

Рисунок 1 – Организация данных в односвязном списке

Базовые операции, которые можно выполнять со списками [13.]:

  1. Добавление узла в список.

Функция добавления узла в список принимает два аргумента:

  • указатель на узел, после которого происходит добавление;
  • данные для добавляемого узла.

Добавление узла в список включает в себя следующие этапы:

  • создание добавляемого узла и заполнение его поля данных;
  • переустановка указателя узла, предшествующего добавляемому, на добавляемый узел;
  • установка указателя добавляемого узла на следующий узел (тот, на который указывал предшествующий узел).

Процедуру добавления узла можно отобразить схемой, представленной на рисунке 2.

Рисунок 2 – Добавление узла в список

  1. Удаление узла из списка.

В качестве аргументов функции удаления элемента списка передаются указатель на удаляемый узел, а также указатель на корень списка.
Функция возвращает указатель на узел, следующий за удаляемым.

Удаление узла из списка включает в себя следующие этапы [14.]:

  • установка указателя предыдущего узла на узел, следующий за удаляемым;
  • освобождение памяти удаляемого узла.

Процедуру удаления узла можно отобразить схемой, представленной на рисунке 3.

Рисунок 3 – Удаление узла из списка

  1. Получение длины списка.

Происходит проход по списку до конца с увеличением длины после каждого просмотренного элемента. Функция возвращает подсчитанную длину списка.

  1. Поиск элемента в списке.

Речь идет о поиске значения, сравнимого с заданным значением при помощи некоторой функции. Функция поиска принимает два параметра: заданное значение и функция, при помощи которой можно сравнить заданное значение с искомым. Если при проходе по списку сравнение было успешным, в результате возвращается найденный элемент.

Линейный поиск [7.] – очень простой и понятный алгоритм поиска в структуре данных. Нужный элемент ищется путем обхода списка от начала до конца до тех пор, пока не будет найден. Заданный элемент для поиска сравнивается со всеми элементами, присутствующими в списке, и при успешном сопоставлении (когда значения равны) возвращается номер текущего элемента в списке или число -1.

На рисунке 4 проиллюстрировано начало работы алгоритма линейного поиска в предположении, что ищется число 3,8. Поиск начинается с первого элемента – при первом сравнении 1,5 не равно 3,8, поэтому выполняется переход к следующему элементу.

Рисунок 4 – Начало работы алгоритма линейного поиска

Следующее сравнение представлено на рисунке 5. Число 2,7 также не равно 3,8, поэтому алгоритм выполняет переход к следующему элементу.

Рисунок 5 – Второй шаг алгоритма линейного поиска

На третьем шаге алгоритма выполняется еще одно сравнение (рисунок 6), которое позволяет сделать вывод о том, что искомый элемент найден. Алгоритм возвращает позицию этого элемента (индекс 2 при индексировании с нуля).

Рисунок 6 – Последний шаг алгоритма линейного поиска

При поиске в этом списке из 4 элементов алгоритму пришлось использовать всего 3 сравнения. Сколько сравнений нужно выполнить, зависит от общей длины, а также от того, находится ли искомый элемент в начале или в конце списка. В худшем случае, если заданный элемент является последним элементом, то необходимо будет выполнить поиск по всему списку, чтобы найти его.

Процедура поиска отражена на рисунке 7 в виде блок-схемы.

Для реализации приложения учета банковских вкладов наиболее удобно использовать односвязный список, поскольку каждая заявка (с информацией о вкладе) может быть представлена как конкретный элемент списка. Заявку можно удалить из списка, или же можно добавить в список новую заявку. Также списки обеспечивают эффективное (за константное время) добавление и удаление элементов [8., 9.].

Рисунок 7 – Поиск элемента в списке

1.3 Алгоритмы для производимых операций

Программное приложение, или АИС «Банковские вклады» содержит информацию по заявкам на вклады (включая уже открытые вклады; понятия «заявка на вклад» и «вклад» далее используются взаимозаменяемо) и поддерживает следующие функции:

  1. Добавление вклада. Пользователю предлагается ввести данные для добавления заявки на вклад в список (рисунок 8).
  2. Удаление вклада. Пользователь имеет возможность выбрать конкретный вклад и удалить его; при этом высвечивается сообщение об ошибке, если пользователь не выбрал ни один вклад, но вызвал функцию удаления (рисунок 9).

Рисунок 8 – Блок-схема алгоритма процесса добавления заявки на вклад в список

Рисунок 9 – Блок-схема алгоритма процесса удаления заявки на вклад из списка

  1. Получение информации о данных. Предполагается, что все вклады содержатся в файле текстового формата. Вся подробная информация о данных находится в этом файле. При вызове данной функции пользователь имеет возможность ознакомиться с количеством добавленных вкладов (а в случае наличия большого числа вкладов эта функция довольно удобна). Блок-схема приведена на рисунке 10.
  2. Сохранение данных в файл. После произведения некоторых манипуляций в приложении пользователь может сохранить результат своей работы в файл и в дальнейшем считать сохраненные данные из этого файла для возобновления и продолжения работы (рисунок 11).

Рисунок 10 – Блок-схема алгоритма процесса получения информации о данных

Рисунок 11 – Блок-схема алгоритма процесса сохранения заявок на вклады в файл

  1. Считывание данных из файла. При вызове данной функции информация из файла, содержащего вклады, выводится непосредственно в окне приложения (рисунок 12).
  2. Поиск вкладов по заданному критерию. Поиск может быть осуществлен по двум критериям: по дате открытия вклада и названию тарифа. Пользователь может выбрать любой из этих двух критериев. Далее пользователь задает данные для поиска, происходит вызов функции поиска, после чего появляется окно с найденными вкладами по заданному критерию. Если поиск неудачен, в окне указывается сообщение о том, что нет найденных вкладов (рисунок 13).

Рисунок 12 – Блок-схема алгоритма процесса считывания заявок на вклады из файла

Рисунок 13 – Блок-схема алгоритма процесса поиска заявок на вклады по заданному критерию.

2. Программная реализация информационно-справочной системы для работы с данными

2.1 Инструменты для разработки

Для программной реализации был выбран высокоуровневый язык программирования общего назначения Python; версия языка – 3.7.

Python был создан Гвидом Ван Россумом в конце 80-х годов и остается одним из самых простых и эффективных языков программирования на сегодняшний день [15., 20.]. Он может использоваться как для начальных шагов в программировании, так и для решения серьезных научных задач. Python является интерпретируемым и объектно-ориентированным языком, поддерживающим при этом несколько парадигм программирования, в том числе функциональную и императивную [16.]. Основными архитектурными чертами языка можно назвать автоматическое управление памятью, динамическую типизацию и удобные высокоуровневые структуры данных (такие, как кортежи, множества, словари и списки) [18., 19.]. В Python имеются встроенные типы: булевый, строка, Unicode-строка, целое число произвольной точности, число с плавающей запятой, комплексное число и многие другие [22.]. Код в Python организовывается в функции и классы, которые могут объединяться в модули (они в свою очередь могут быть объединены в пакеты). Все значения, в том числе встроенные коллекции и типы данных, функции, методы, модули, классы являются объектами [21.].

Для создания графического интерфейса приложения используется библиотека Python 3 Tkinter.

Tkinter – это пакет для Python, предназначенный для работы с библиотекой Tk [22.]. Библиотека Tk содержит компоненты графического интерфейса пользователя (graphical user interface – GUI), написанные на языке программирования Tcl.

Под графическим интерфейсом пользователя (GUI) подразумеваются все те окна, кнопки, текстовые поля для ввода, скроллеры, списки, радиокнопки, флажки и др., которые можно увидеть на экране, открывая то или иное приложение. Через них происходит взаимодействие с программой и управление ею. Все эти элементы интерфейса называются виджетами (widgets).

Модуль Tkinter включает следующие классы:

  1. Button (кнопка);
  2. Radiobutton (радиокнопка)
  3. Checkbutton (флажок);
  4. Entry (однострочное поле для ввода);
  5. Text (многострочное поле для ввода);
  6. Label (метка);
  7. Scale (ползунок);
  8. Scrollbar (полоса прокрутки);
  9. Frame (виджет для группировки других виджетов);
  10. LabelFrame (аналог Frame, только с заголовком);
  11. Listbox (список);
  12. Canvas (поле для рисования);
  13. PanedWindow (элемент разделения окна);
  14. Menu (главное меню);
  15. Tk (главное единственное окно);
  16. Toplevel (дочернее окно).

Существует множество библиотек для GUI. Tk далеко не самая популярная, хотя с ее использованием написано немало проектов. Тем не менее, данная библиотека является наиболее простой и удобной, поэтому для создания графического интерфейса в программе была использована именно эта библиотека.

Программное приложение состоит из одного главного окна (которое можно закрыть/свернуть/развернуть). В левой части окна на панели выводится список вкладов, в правой части представлен функционал приложения: текстовые поля для введения данных и создания заявок по вкладам; кнопки для выполнения функций приложения. Для вывода сообщений об ошибках используются дополнительные миниатюрные окна, появляющиеся на экране пользователя.

Для хранения и обработки данных можно также использовать файлы. В языке Python можно взаимодействовать с файлами, выполняя их чтение или запись [17.]. Файл – это именованная область диска, предназначенная для длительного хранения данных в постоянной памяти (например, на жёстком диске).

Чтобы прочитать или записать данные в файл, сначала нужно его открыть. После окончания работы файл необходимо закрыть, чтобы освободить связанные с ним ресурсы. Поэтому в Python операции с файлами выполняются в следующем порядке: открытие файла, чтение или запись файла, закрытие файла.

Для работы с файлами в Python существует несколько режимов [21.]: ′r′ – открытия файла для чтения, ′w′ – открытие файла для записи и т. д.

В разрабатываемом приложении файл будет использован в качестве базы данных, в которой будут содержаться все заявки. Пользователь имеет возможность считать данные из файла, сохранить данные в файл или же удалить какую-либо заявку из базы данных.

2.2 Разработка приложения

Программное приложение состоит из одного главного окна (которое можно закрыть/свернуть/развернуть). В левой части окна на панели выводится список вкладов, в правой части представлен функционал приложения: текстовые поля для введения данных и создания вкладов; кнопки для выполнения функций приложения. Для вывода сообщений об ошибке используются дополнительные миниатюрные окна, появляющиеся на экране пользователя.

В главном окне приложения отражены все необходимые функции (рисунок 14). Пользователь может ввести в соответствующее текстовое поле название банка, название тарифа, дату открытия вклада, валюту, срок (количество лет, на которое выдается вклад), процентную ставку, условия вклада.

Рисунок 14 Главное окно программы

Диаграмма классов приведена на рисунке 15. Имеется четыре класса: ListNode, LinkedList, Deposit и Bank. Помимо классов, в программе также реализован ряд функций, обеспечивающих функционал приложения.

Классы ListNode и LinkedList отвечают за реализацию структуры данных линейный односвязный список (узел и список, соответственно). В них реализованы основные методы работы со списком:

  • append(self, item) – метод добавления в конец списка;
  • append_asc_order(self, item) – метод добавления в конец списка с сохранением упорядоченности (в лексикографическом порядке по названию банка);
  • length(self) – метод, возвращающий длину списка;
  • search(self, equal, x) – метод поиска значения, сравнимого с x при помощи функции equal;
  • delete(self, item_id) – метод удаления элемента из списка по номеру.

Рисунок 15 – Диаграмма классов приложения

Класс Deposit описывает банковский вклад. Он имеет атрибуты bank_name (название банка), tariff_name (название тарифа), currency (валюта), deposit_date (дата открытия вклада; по умолчанию 01.01.2019), time (срок – количество лет хранения вклада), percent (процентная ставка), conditions (условия вклада). Также в классе имеется набор методов: метод show (self) предназначен для вывода на список формы, метод tar_eq (self, num) является функцией для проверки соответствия названия тарифа переданному значению, метод date_eq (self, date) работает по аналогии с предыдущим для проверки соответствия даты открытия вклада переданному значению.

Класс Bank описывает информацию о вкладах. Его атрибутами являются список вкладов catalogue и имя файла filename, в котором содержится информация о вкладах. Метод show (self, filename) выводит данные в файл; метод getDepositsOf (self, a) предназначен для нахождения вкладов по названию тарифа или дате открытия вклада.

Исходный код проекта расположен в двух файлах.

        1. LinkedList.py – файл для хранения классов ListNode и LinkedList, предназначенных для описания узла односвязного списка и непосредственно самого односвязного списка;
        2. main.py – файл для хранения классов Bank и Deposit, а также для построения графического интерфейса приложения; главный модуль программы.

2.3 Руководство пользователя и тестирование программы

Для запуска программы пользователю необходимо иметь набор средств, описанных в подразделе 2.1, а именно – интерпретатор языка Python версии 3.1.x или старше, а также библиотеку Tkinter, установленную в качестве пакета для Python для более ранних версий языка (начиная с 3.0.x). Простую загрузку и установку любой общедоступной библиотеки Python можно выполнить с помощью менеджера пакетов pip. Он представляет собой инструмент для управления библиотеками Python. Непосредственный процесс загрузки и установки выполняется при помощи команды pip3 install <название библиотеки>.

Если код главной программы находится в файле с расширением *.py на рабочем столе пользователя (рисунок 16), то для запуска программы достаточно открыть ее в стандартной среде разработки языка IDLE, после чего выбрать пункт меню Run и далее Run Module (рисунок 17).

Рисунок 16 – Файл программы на рабочем столе пользователя

Рисунок 17 – Запуск программы из среды разработки языка

Запуск программы может быть осуществлен способом, описанным в предыдущем абзаце, однако есть и другой способ, без демонстрации пользователю программного кода. Через командную строку необходимо перейти в директорию с файлом (выполнив команду cd <путь к файлу>), после чего ввести команду python code.py (где code.py – имя файла программы).

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

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

Для добавления информации о вкладе необходимо заполнить все поля и нажать на кнопку «Добавить вклад». После этого текстовые поля сразу же очищаются, а вклад с соответствующими ему атрибутами появляется в левой части окна (рисунок 18).

Данные при добавлении в список сортируются по названию банка.

Рисунок 18 – Окно программы после добавления вклада

Чтобы удалить вклад, необходимо выбрать нужный вклад в списке слева, выделив его левой кнопкой мыши, а после этого нажать на кнопку «Удалить вклад». После выполненного действия удаленный вклад пропадает из списка. В случае, когда пользователь нажимает на кнопку «Удалить вклад», не выбрав сам вклад, появляется сообщение об ошибке (рисунок 19).

Рисунок 19 – Окно с ошибкой в случае попытки удаления невыбранного вклада

Приложение позволяет выполнять поиск среди вкладов по названию тарифа или дате открытия вклада. Чтобы выполнить поиск, необходимо отметить желаемый способ поиска, ввести название тарифа или дату открытия вклада, по которым нужно выполнить поиск и нажать на кнопку «Поиск», после чего появляется окно с информацией о найденных вкладах (рисунки 20, 21).

Если по условиям поиска не было найдено ни одного вклада, появляется окно с соответствующим сообщением (рисунок 22).

Рисунок 20 – Окно программы после поиска вклада по названию тарифа

Рисунок 21 – Окно программы после поиска вклада по дате открытия

Рисунок 22 – Информационное окно после неудачного поиска

При нажатии на кнопку «Считать данные из файла» в левой части окна выводятся все сохраненные в файле вклады (рисунок 23). Предварительно все добавленные вклады должны быть сохранены в файле. Сохранение происходит после нажатия на кнопку «Сохранить в файл». Вид файла с вкладами приведен на рисунке 24.

Рисунок 23 – Чтение вкладов из файла

Рисунок 24 – Файл «Вклады.txt», содержащий информацию о считываемых вкладах

Пользователь имеет возможность получить все данные, содержащиеся в системе. Для этого необходимо нажать на кнопку «Получить информацию о данных». Подробные данные находятся в файле «Вклады.txt»; пользователь, считав данные из этого файла (кнопка «Считать данные из файла») и нажав на кнопку «Получить информацию о данных», может узнать количество добавленных вкладов (рисунок 25).

Таким образом, был разработан удобный и интуитивно понятный для пользователя интерфейс.

Рисунок 25 – Окно программы с информацией о данных

ЗАКЛЮЧЕНИЕ

В ходе выполнения курсовой работы была изучена и проанализирована учебно-методическая документация, учебная литература и интернет по выбранной теме.

Были найдены всевозможные способы достижения поставленной цели, анализ которых позволил выбрать наиболее оптимальный способ, для достижения которого был разработан необходимый набор универсальных функций.

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

В практической части работы выполнено проектирование приложения, предназначенного для автоматизации решения задач по хранению, обработке и выдачи информации о банковских вкладах. На основании результатов проектирования разработано приложение, обладающее заданной функциональностью. Проведено тестирование приложения, по результатам которого в приложении устранены выявленные ошибки. Разработаны контрольные примеры, которые можно использовать как для освоения приемов работы с приложением, так и для контроля работоспособности приложения при его установке. Применение структур данных (в частности, линейных односвязных списков) и широкие возможности языка Python позволяет создавать программы, имеющие требуемую функциональность.

Программа имеет понятный графический интерфейс, выводит все необходимые пояснения и подсказки, является законченной и удобной для использования. Таким образом, цель курсовой работы достигнута в полном объеме.

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1. Лутц М. Изучаем Python, 4-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2011. – 1280 с.
  2. Златопольский Д.М. Основы программирования на языке Python. – М.: ДМК Пресс, 2017. – 284 с.
  3. Лутц М. Программирование на Python, том I, 4-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2011. – 992 с.
  4. Лутц М. Программирование на Python, том II, 4-е издание. – Пер. с англ. – СПб.: Символ-Плюс, 2011. – 992 с.
  5. Гэддис Т. Начинаем программировать на Python. – 4-е изд.: Пер. с англ. – СПб.: БХВ-Петербург, 2019. – 768 с.
  6. Лучано Рамальо Python. К вершинам мастерства. – М.: ДМК Пресс, 2016. – 768 с.
  7. Свейгарт, Эл. Автоматизация рутиных задач с помощью Python: практическое руководство для начинающих. Пер. с англ. – М.: Вильямc, 2016. – 592 с.
  8. Рейтц К., Шлюссер Т. Автостопом по Python. – СПб.: Питер, 2017. – 336 с.: ил. – (Серия «Бестселлеры O’Reilly»).
  9. Любанович Билл Простой Python. Современный стиль программирования. – СПб.: Питер, 2016. – 480 с.: – (Серия «Бестсепперы O’Reilly»).
  10. Федоров, Д. Ю. Программирование на языке высокого уровня Python : учебное пособие для прикладного бакалавриата / Д. Ю. Федоров. – 2-е изд., перераб. и доп. – Москва : Издательство Юрайт, 2019. – 161 с. – (Бакалавр. Прикладной курс). – ISBN 978-5-534-10971-9. – Текст: электронный // ЭБС Юрайт [сайт]. – URL: https://urait.ru/bcode/437489 (дата обращения: 13.06.2020).
  11. Шелудько, В. М. Основы программирования на языке высокого уровня Python: учебное пособие / В. М. Шелудько. – Ростов-на-Дону, Таганрог: Издательство Южного федерального университета, 2017. – 146 c. – ISBN 978-5-9275-2649-9. – Текст: электронный // Электронно-библиотечная система IPR BOOKS: [сайт]. – URL: http://www.iprbookshop.ru/87461.html (дата обращения: 13.06.2020). – Режим доступа: для авторизир. пользователей
  12. Шелудько, В. М. Язык программирования высокого уровня Python. Функции, структуры данных, дополнительные модули: учебное пособие / В. М. Шелудько. – Ростов-на-Дону, Таганрог: Издательство Южного федерального университета, 2017. – 107 c. – ISBN 978-5-9275-2648-2. – Текст: электронный // Электронно-библиотечная система IPR BOOKS: [сайт]. – URL: http://www.iprbookshop.ru/87530.html (дата обращения: 13.06.2020). – Режим доступа: для авторизир. пользователей
  13. Доусон М. Программируем на Python. – СПб.: Питер, 2014. – 416 с.
  14. Прохоренок Н.А. Python 3 и PyQt. Разработка приложений. – СПб.: БХВ-Петербург, 2012. – 704 с.
  15. Пилгрим Марк. Погружение в Python 3 (Dive into Python 3 на русском)
  16. Прохоренок Н.А. Самое необходимое. – СПб.: БХВ-Петербург, 2011. – 416 с.
  17. Основные структуры данных [Электронный ресурс] / URL: https://habr.com/ru/post/422259 (Дата обращения: 20.06.2020)
  18. Словари [Электронный ресурс] / URL: https://devpractice.ru/python-lesson-9-dict Словари (Дата обращения: 22.06.2020)
  19. Списки, кортежи и словари [Электронный ресурс] / URL: https://pythonru.com/osnovy/2-python-dlja-data-science-struktury-dannyh Списки, кортежи и словари (Дата обращения: 24.06.2020)
  20. Стиль кода в языке Python [Электронный ресурс] / URL: https://pep8.ru/doc/pep8 (Дата обращения: 27.06.2020)
  21. Our Documentation | Python.org [Электронный ресурс] / URL: https://www.python.org/doc/ (Дата обращения: 25.06.2020)
  22. The Python Tutorial [Электронный ресурс] / URL: https://docs.python.org/3/tutorial/ (Дата обращения: 26.06.2020)

ПРИЛОЖЕНИЯ

ИСХОДНЫЙ КОД ПРОГРАММЫ

LinkedList.py

class ListNode: # класс для узла односвязного списка

def __init__(self, data): # конструктор класса

self.data = data # хранимые данные

self.next = None # указатель на следующий элемент

return

def has_value(self, value): # метод для сравнения переданного значения с хранимыми данными

if self.data == value:

return True

else:

return False

def show(self): # метод для вывода данных в строковом виде

return str(self.data)

class LinkedList: # класс односвязного списка

def __init__(self): # конструктор класса

self.head = None # голова списка (верхний элемент)

self.tail = None # хвост списка (оставшаяся часть списка)

return

def append(self, data): # метод добавления в конец списка

if not isinstance(data, ListNode): # если тип добавляемого элемента не соответствует узлу списка

data = ListNode(data) # создать новый узел на основе этого элемента

if self.head is None: # если список пуст

self.head = data # добавить элемент как голову списка

else:

self.tail.next = data # иначе добавить его следующим за последним элементом хвоста

self.tail = data

#print(self.head.data)

return

def append_asc_order(self, data): # метод добавления в конец списка (с упорядочиванием по возрастанию)

new_node = ListNode(data) # новый узел с переданными данными

if self.head is None: # если список пуст, то добавить в голову

self.head = new_node

return

temp = self.head # взять голову списка как текущий узел

if temp.data > data: # если элемент текущего узла больше переданного

# разместить переданный узел в голову списка

new_node.next = temp

self.head = new_node

return

# пока не достигнут конец списка

while temp.next:

if temp.next.data > data: # если элемент следующего узла больше переданного, прервать цикл

break

temp = temp.next # двигаться далее по списку

# поменять местами добавленный узел с последним просмотренным для упорядочения

new_node.next = temp.next

temp.next = new_node

def length(self): # метод, возвращающий длину списка

count = 0

current_node = self.head

while current_node is not None: # проход по списку до конца с увеличением длины после каждого просмотренного элемента

count = count + 1

current_node = current_node.next

return count

def __iter__(self): # реализация итератора списка (для обхода в цикле for)

current = self.head

while current is not None:

yield current # возврат генератора при обходе списка

current = current.next

def search(self, equal, x): # метод поиска значения, сравнимого с x при помощи функции equal

info = '' # строка, содержащая представления всех найденных значений

current = self.head

while current != None:

if equal(current.data, x):

info += str(current.data) + '\n'

current = current.next

return info

def delete(self, data_id): # метод удаления элемента из списка по номеру

current_id = 0 # текущий номер узла

current_node = self.head # текущий узел

previous_node = None # предыдущий узел

while current_node is not None:

if current_id == data_id: # если найден узел с заданным номером

if previous_node is not None: # и это не первый узел (голова)

previous_node.next = current_node.next # переназначить ссылку на следующий элемент за текущим предыдущему

else:

self.head = current_node.next # иначе удалить голову (переназначить ссылку на следующий элемент за текущим голове)

return

# следующая итерация:

previous_node = current_node # сделать предыдущим текущий

current_node = current_node.next # текущим - следующим

current_id = current_id + 1 # увеличить номер узла

return

main.py

from tkinter import *

from tkinter import messagebox

import datetime as d

from LinkedList import *

# класс, описывающий банковский вклад

class Deposit:

bank_name = '' # название банка

tariff_name = '' # название тарифа

currency = '' # валюта

deposit_date = d.date(2019, 1, 1) # дата открытия вклада по умолчанию - 01.01.2019

time = 0 # срок вклада

percent = 0 # процентная ставка

conditions = '' # условия вклада

def __init__(self, n, a, cur, y, t, p, c): # параметризованный конструктор класса, присваивает полям переданные значения аргументов

self.bank_name = n

self.tariff_name = a

self.currency = cur

self.deposit_date = y

self.time = t

self.percent = p

self.conditions = c

def __str__(self): # строковое представление класса

return '{0}; {1}; {2}; {3}; {4}; {5}; {6}\

'.format(self.bank_name,self.tariff_name,self.currency,self.deposit_date,self.time,self.percent,self.conditions)

def show(self): # метод для вывода на список формы

return 'Название банка: {0}, название тарифа: {1}, валюта: {2}, дата открытия \

вклада: {3}, срок вклада: {4} г., процентная ставка: {5}%, условия вклада: {6}\

'.format(self.bank_name,self.tariff_name,self.currency,self.deposit_date,self.time,self.percent,self.conditions)

def tar_eq(self, n): # функция для проверки соответствия названия тарифа переданному значению

return self.tariff_name == n

def date_eq(self, date): # функция для проверки соответствия даты открытия вклада переданному значению

return self.deposit_date == date

# функции для сравнения вкладов (по названию банка):

def __lt__(self, fl):

return self.bank_name < fl.bank_name

def __gt__(self, fl):

return self.bank_name > fl.bank_name

# класс, описывающий информацию о вкладах

class Bank:

catalogue = LinkedList() # список вкладов

filename = 'Вклады.txt' # имя файла

# конструктор класса - создает односвязный список вкладов

def __init__(self):

catalogue = LinkedList()

# метод, который формирует строку, содержащую информацию о данных

def __str__(self):

return 'Данные расположены в файле {0}. Всего добавлено {1} вкладов'.format(self.filename, self.catalogue.length())

# метод, который выводит данные в новый файл

def show(self, filename):

with open(filename, 'w', encoding = 'utf-8') as f:

for b in self.catalogue:

f.writelines(b.show() + '\n')

f.close()

# метод для нахождения вкладов по названию тарифа или дате открытия

def getDepositsOf(self, a):

info = '' # строка с информацией обо всех найденных вкладах

if var.get() == 1: # если выбран пункт "по дате открытия"

numberstr = ''.join(a.split('.')) # сконвертировать введенную строку с датой в формате ДД.ММ.ГГГГ в строку с датой в формате ДДММГГГ

deposit_date = d.datetime.strptime(numberstr, "%d%m%Y").date() # конвертация строки с датой в тип даты

Deposits = self.catalogue.search(Deposit.date_eq, deposit_date) # поиск по дате в каталоге

elif var.get() == 0: # если выбран пункт "по названию тарифа"

Deposits = self.catalogue.search(Deposit.tar_eq, a) # поиск по названию тарифа в каталоге

if Deposits is not None: # если вклады были найдены

info += Deposits + '\n' # дописать их в конец строки с результатом

else:

info = '' # иначе строка с результатом пуста

return info

# создание объекта класса базы вкладов

Bank = Bank()

# функция добавления в список

def addItem():

# получение параметров из списка элементов:

bank_name = ents['Название банка']

tariff_name = ents['Название тарифа']

currency = ents['Валюта']

deposit_date = d.date(int(ents['Год открытия вклада'].get()), int(ents['Месяц'].get()), int(ents['День'].get()))

time = int(ents['Срок вклада'].get())

percent = int(ents['Процентная ставка'].get())

conditions = ents['Условия вклада']

# создание и добавление объекта класса для вклада в односвязный список:

b = Deposit(bank_name.get(), tariff_name.get(), currency.get(), deposit_date, time, percent, conditions.get())

#Bank.catalogue.append(b)

Bank.catalogue.append_asc_order(b)

# вставка элементов односвязного списка в список на форме:

lbox.delete(0, END)

for b in Bank.catalogue:

lbox.insert(END, b.show())

# очистка полей ввода:

bank_name.delete(0, END)

tariff_name.delete(0, END)

currency.delete(0, END)

conditions.delete(0, END)

# функция удаления из списка

def deleteItem():

select = list(lbox.curselection()) # получить выделенный элемент

if select: # если было что-то выделено, то удалить все выделенные элементы из односвязного списка и из списка на форме

select.reverse()

for i in select:

print('Удален элемент списка с индексом ', i)

lbox.delete(i)

Bank.catalogue.delete(i)

else: # иначе сообщить об ошибке

messagebox.showinfo('Ошибка!', 'Выберите вклад из списка!')

# функция вывода информации о данных

def printInfo():

messagebox.showinfo('Информация о данных', Bank)

# функция вывода информации о вкладах по введенным данным

def printDepositsByInput():

catalogue = Bank.getDepositsOf(ent.get())

if catalogue.strip() != '':

messagebox.showinfo('Найденные вклады: ', Bank.getDepositsOf(ent.get()))

else:

messagebox.showinfo('Ошибка!', 'Вкладов не найдено!')

# функция сохранения в файл

def saveInFile():

f = open('Вклады.txt', 'w', encoding = 'utf-8') # открыть файл на запись

info = '' # вклады из списка

for a in Bank.catalogue:

info += a.show() + '\n'

f.writelines(info) # записать все вклады из списка

f.close() # закрыть файл

# функция чтения из файла

def openFile(filename):

with open(filename, 'r', encoding = 'utf-8') as f: # открыть файл на чтение (в режиме автоматического закрытия)

bbank = [line.strip() for line in f if line.strip()] # получить список строк из файла

for fli in bbank: # для каждой строки из этого списка

params = fli.strip().split(';') # получить список параметров строки по разделителю ';'

date_obj = d.datetime.strptime(params[3].strip(), '%Y-%m-%d').date() # получить дату из четвертого параметра

dep = Deposit(params[0].strip(), params[1].strip(), params[2].strip(), date_obj,

int(params[4].strip()), int(params[5].strip()), params[6].strip()) # создать объект вклада

Bank.catalogue.append(dep) # добавить его в односвязный список

lbox.delete(0, END)

for dep in Bank.catalogue:

lbox.insert(END, dep.show())

b1['state'] = 'disabled'

# список названий элементов-полей

fields = ['Название банка', 'Название тарифа', 'Валюта', 'Условия вклада']

# словарь для формирования числовых полей

# (ключ - параметр [год, месяц, день, срок, процент], значение - пара чисел [макс. значение параметра, мин. значение параметра])

numbers = {'Год открытия вклада':(2019, 2022), 'Месяц':(1, 12), 'День':(1, 31), 'Срок вклада':(1, 5), 'Процентная ставка':(5, 15)}

# функция добавления элементов на форму (возвращает словарь элементов)

def makeForm(root, fields):

entries = {} # словарь элементов-значений с ключами-названиями полей

for field in fields: # для каждого названия поля:

row = Frame(root) # создать рамку (фрейм)

lab = Label(row, width=22, text=field+': ', anchor='w') # создать текстовую метку шириной 22, растянуть налево

ent = Entry(row) # создать поле ввода

ent.insert(0, 'Введите ' + field) # вставить текст в поле ввода

row.pack(side=TOP, fill=X, padx=5, pady=5) # сделать рамку видимой, расположив сверху и растянув по форме, с отступами от границ по 5

lab.pack(side=LEFT) # сделать метку видимой, расположив слева

ent.pack(side=RIGHT, expand=YES, fill=X) # сделать поле ввода видимым, расположив справа и растянув по форме

entries[field] = ent # добавить поле ввода в словарь в соответствие с его названием

for num in numbers.items(): # для каждого значения:

row = Frame(root) # создать рамку (фрейм)

lab = Label(row, width=22, text=num[0]+': ', anchor='w') # создать текстовую метку шириной 22, растянуть налево

ent = Spinbox(row, from_=num[1][0], to=num[1][1]) # создать регулятор типа вверх-вниз для значений даты (установить макс. и мин. параметры регулятора в зависимости от выбранного ключа)

ent.insert(0, '')

row.pack(side=TOP, fill=X, padx=5, pady=5)

lab.pack(side=LEFT)

ent.pack(side=RIGHT, expand=YES, fill=X)

entries[num[0]] = ent # добавить параметр даты в словарь в соответствие с его названием

return entries

root = Tk() # создать окно

lbox = Listbox(width=120, height=30, selectmode=SINGLE) # расположить на форме список

lbox.pack(side=LEFT) # сместить его влево и сделать видимым

scroll = Scrollbar(command=lbox.yview) # установить полосу прокрутки (на случай большого количества значений)

scroll.pack(side=LEFT, fill=Y) # также сделать ее видимой

lbox.config(yscrollcommand=scroll.set)

f = Frame()

f.pack(side=LEFT, padx=10)

ents = makeForm(f, fields) # получить элементы

# создать кнопку для каждого действия с заданным текстом и вызовом соответствующей функции при нажатии:

b1 = Button(f, text='Считать данные из файла', command=(lambda:openFile('Вклады.txt')))

b1.pack(fill=X, padx=5, pady=5)

b2 = Button(f, text='Добавить вклад', command=addItem)

b2.pack(fill=X, padx=5, pady=5)

b3 = Button(f, text='Удалить вклад', command=deleteItem)

b3.pack(fill=X, padx=5, pady=5)

b4 = Button(f, text='Сохранить в файл', command=saveInFile)

b4.pack(fill=X, padx=5, pady=5)

b5 = Button(f, text='Получить информацию о данных', command=printInfo)

b5.pack(fill=X, padx=5, pady=5)

var = IntVar() # номер выбранной радиокнопки для поиска

var.set(0) # установить по умолчанию 'по названию банка'

nf = Radiobutton(f, text='по названию тарифа', variable=var, value=0) # радиокнопка для поиска по названию банка

da = Radiobutton(f, text='по дате открытия', variable=var, value=1) # радиокнопка для поиска по дате открытия вклада

ent = Entry(f) # добавить текстовое поле для ввода

ent.insert(0, '01.01.2019') # вставить текст в поле ввода

b6 = Button(f, text='Поиск', command=printDepositsByInput) # добавить кнопку поиска

# расположить ее и радиокнопки слева:

b6.pack(side=LEFT, padx=15, pady=15)

nf.pack(side=LEFT)

da.pack(side=LEFT)

# добавить текстовую метку и расположить ее чуть правее:

lab = Label(f, width=22, text='Параметр поиска: ')

lab.pack(side=LEFT)

# расположить кнопку для поиска справа:

ent.pack(side=RIGHT)

root.mainloop()