You are on page 1of 905

І.В.

Мельник

Основи програмування на мові Python.


Комплексний навчальний посібник з курсів
«Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі»
для студентів-бакалаврів напряму підготовки
171 «Електронні пристрої та системи».
Том 1. Базові принципи побудови мови програмування Python та її
головні синтаксичні конструкції

Київ
Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»

2019
Рекомендовано до друку
Методичною радою Національного технічного університету України „Київський
політехнічний інститут імені Ігоря Сікорського”, протокол № ___ від ___ грудня
2019 р.
Рецензенти:
В.Т. Лазурік, доктор технічних наук, професор, декан факультету
математики та інформатики Харківського національного
університету ім. В.Н. Каразіна
С.С. Забара, доктор технічних наук, професор, завідуючий ка-
федрою інформаційних технологій та програмування Інституту
комп’ютерних технологій Відкритого міжнародного університету
розвитку людини „Україна”, лауреат Державної премії СРСР,
лауреат Державної премії України

Мельник І.В.
Основи програмування на мові Python. Комплексний навчальний
посібник з курсів «Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі» для студентів-бакалаврів
напряму підготовки 171 «Електронні пристрої та системи». Том 1.
Базові принципи побудови мови програмування Python та головні
синтаксичні конструкції – 372 с.

Посібник містить великий обсяг теоретичного та практичного


матеріалу щодо програмування на мові Python, яка сьогодні вважається
однією із самих розвинених мов програмування, призначених для
вирішення завдань моделювання. У першому томі посібника розглянуті
загальні основи об’єктно-орієнтованого програмування, базові принципи
мови програмування Python та її головні синтаксичні конструкції.
Особлива увага приділяється оператору присвоєння, способам роботи з
функціями та бібліотеками, особливостям використання математичних
функцій, роботі з рядками, спискам, умовному оператору та операторам
циклу. Окремо розглянуті засоби об’єктно-орієнтованого програмування
мови Python та ускладнені структури даних, якто множини, кортежі та
словники. Посібник призначений для студентів-бакалаврів, які навчаються
за напрямом «Електронні пристрої та системи», може бути корисним для
студентів інших напрямів.
© Мельник І.В., 2019

2
ЗМІСТ
Відомості про автора............................................................................................. 13
ВСТУП ................................................................................................................... 15
Розділ 1. Історія розвитку об’єктно-орієнтованого програмування та його
головні принципи .................................................................................................. 23
1.1 Історія розвитку засобів програмування ...........................................................23
1.2 Поняття про об’єкти та базові принципи об’єктно-орієнтованого
програмування ..................................................................................................................26
1.3 Ієрархія класів з точки зору теорії скінченних автоматів та узагальнений
алгоритм формування запитів про властивості об’єкта......................................41
1.4 Історія створення мови програмування Python та її головні особливості.......45
1.5 Філософія мови програмування Python .............................................................53
Контрольні питання та завдання до розділу 1........................................................57
Розділ 2. Базові принципи мови програмування Python та способи
розв’язування простих обчислювальних задач .................................................. 63
2.1 Встановлення та запуск інтерпретатора мови Python на персональному
комп’ютері .........................................................................................................................63
2.2 Початок роботи з інтерпретатором Python та прості арифметичні
розрахунки .........................................................................................................................71
2.3 Змінні та типи змінних............................................................................................77
2.4 Математична бібліотека Python та математичні функції.............................84
2.4.1 Бібліотека математичних функцій мови Python та доступ до неї.......84
2.4.2 Константи та базові функції для роботи з цілими та дійсними
числами ............................................................................................................................84
2.4.3 Функції перетворення типів числових даних............................................87
2.4.4 Експоненціальна, логарифмічна та степенева функції .........................89
2.4.5 Тригонометричні та зворотні тригонометричні функції .......................93
2.4.6 Гіперболічні та зворотні гіперболічні функції .........................................96
2.4.7 Робота з комплексними числами в інтерпретаторі мови Python.......100
2.4.8 Функції як аргументи інших функцій........................................................103
2.5 Створення функцій користувача та робота з ними в інтерпретаторі мови
3
Python..................................................................................................................................108
2.5.1 Опції налаштування оболонки IDLE для системи програмування
Python 3 ..........................................................................................................................108
2.5.2 Створення власних функцій користувача та головні принципи
роботи з ними...............................................................................................................115
2.5.3 Способи роботи з функціями та визначення їхніх параметрів та
змінних через простір імен ......................................................................................123
2.5.4 Програмні модулі та способи роботи з ними ..........................................132
2.5.5 Робота у командному вікні інтерпретатора в діалоговому режимі та
тестування програмних модулів ............................................................................142
2.5.6 Приклади створення функцій, призначених для автоматичного
перерахунку значень фізичних величин..............................................................145
2.6 Операції з рядковими даними та функції мови програмування Python
для роботи з ними..........................................................................................................158
2.6.1 Базові операції мови програмування Python для роботи із рядковими
даними.............................................................................................................................158
2.6.2 Функції перетворення рядкових даних до числових та числових до
рядкових.........................................................................................................................162
2.6.3 Спеціальні символи мови програмування Python для роботи з
рядками...........................................................................................................................165
2.6.4 Особливості введення та відображення рядкових змінних на екрані з
використанням системних функцій input() та print() ......................................166
2.6.5 Запис текстової інформації до файлів .......................................................170
2.6.6 Головні функції мови програмування Python для роботи з рядками .......173
2.6.7 Формування тексту допомоги до власних функцій користувача з
використанням рядкових даних .............................................................................178
2.6.8 Індексація елементів рядків ..........................................................................179
Контрольні питання та завдання до розділу 2......................................................185
Розділ 3 Розгалуження, структуровані дані та цикли у мові програмування
Python.................................................................................................................... 197
3.1 Базові операції порівняння даних у мові програмування Python............197

4
3.2 Логічні вирази ..........................................................................................................200
3.3 Арифметико-логічні вирази ................................................................................211
3.4 Синтаксис умовного оператора та відповідні лінгвістичні конструкції
мови програмування Python .......................................................................................215
3.5 Приклади розв’язування деяких прикладних завдань фізичної
електроніки з використанням умовного оператора............................................220
3.6 Списки у мові програмування Python та способи роботи з ними...........226
3.6.1 Визначення списків та базові функції мови програмування Python
для роботи з ними .......................................................................................................226
3.6.2 Створення матриць з використанням списків.........................................240
3.7 Оператори циклу із заданою кількістю повторень та заданою умовою......244
3.7.1 Оператор циклу із заданою кількістю повторень та його
використання для формування списків ...............................................................244
3.7.2 Способи обробки списків з використанням оператора циклу ...........247
3.7.3 Вкладені цикли та їх використання для формування матриць..........254
3.7.4 Розрахунок значень функцій, матриць та числових послідовностей з
використанням циклічних структур .....................................................................263
3.7.5 Розрахунок спектрів випромінювання за формулою Рідберга з
використанням циклічних структур .....................................................................274
3.7.6 Оператор циклу із заданою умовою та можливості його
використання для розв’язування прикладних завдань програмування ....280
3.7.7 Примусове переривання та продовження циклів...................................286
3.7.8 Анонімна лямбда-функція та генератори .................................................292
3.7.9 Обробка виключних та помилкових ситуацій у мові програмування
Python...............................................................................................................................297
Контрольні питання та завдання до розділу 3......................................................303
Розділ 4 Способи роботи з об’єктами та структурованими даними в мові
програмування алгоритма .................................................................................. 310
4.1 Об’єкти та класи в мові програмування Python............................................310
4.1.1 Створення та використання класів .............................................................310

5
4.1.2 Приклад формування методів класу та посилань на них через
створені об’єкти ..........................................................................................................318
4.1.3 Конструктори та визначення властивостей об’єктів ............................320
4.1.4 Інкапсуляція та приватні методи класу.....................................................329
4.1.5 Успадкування класів у мові програмування Python та формування
списків із об’єктів визначеного класу..................................................................334
4.1.6 Написання програми для визначення типу матеріалу за його
електропровідністю з використанням методів об’єктно-орієнтованого
програмування .............................................................................................................342
4.1.7 Загальний перелік правил об’єктно-орієнтованого програмування
мови Python...................................................................................................................348
4.1.8 Порівняльний аналіз можливостей використання об’єктів та модулів у
мові програмування Python.........................................................................................350
4.2 Множини у мові програмування Python..........................................................351
4.2.1 Визначення множин та головні правила роботи з ними......................351
4.2.2 Операції над множинами у мові Python ....................................................355
4.3 Кортежі як структуровані дані та способи роботи з ними ........................361
4.3.1 Поняття про кортежі та загальні правила їхнього формування та
роботи з ними...............................................................................................................361
4.3.2 Іменовані кортежі .............................................................................................365
4.3.3 Приклади використання класів та кортежів для роботи з
геометричними об’єктами........................................................................................367
4.4 Словники у мові програмування Python та особливості роботи з ними .....373
Контрольні питання та завдання до розділу 4......................................................380

6
ЗМІСТ
Розділ 5 Створення програм із віконними графічними інтерфейсами.............. 3
5.1 Узагальнена структура програм із консольним та віконним
інтерфейсами .......................................................................................................................3
5.2 Створення та розташування компонентів віконного інтерфейсу з
використанням засобів програмування мови Python .............................................6
5.2.1 Створення головного вікна для розташування елементів віконного
інтерфейсу та способи їхнього розташування.......................................................6
5.2.2 Класифікація елементів віконного інтерфейсу...........................................8
5.2.3 Способи формування простих текстових вікон........................................10
5.2.4 Узагальнена схема відображення компонентів віконного інтерфейсу
Модель – Вигляд – Контролер .....................................................................................17
5.2.5 Розташування кнопок як елементів віконного інтерфейсу та способи
аналізу події натиснення на кнопку...........................................................................21
5.2.5.1 Методи розташування кнопок та визначення їхніх властивостей.........21
5.2.5.2 Методи аналізу події натиснення на кнопку..........................................31
5.2.5.3 Описання методів для роботи з елементами віконного інтерфейсу з
точки зору теорії подійного моделювання ................................................................37
5.2.6 Створення та розташування інших елементів віконного інтерфейсу ........38
5.2.6.1 Головні елементи віконного інтерфейсу .................................................38
5.2.6.2 Кнопка вибору..................................................................................................39
5.2.6.3 Селекторна кнопка..........................................................................................43
5.2.6.4 Список як елемент віконного інтерфейсу ...............................................49
5.2.6.5 Нумерований список......................................................................................55
5.2.6.6 Лінійка з повзунцем .......................................................................................58
5.2.6.7 Формування інформаційного рядка про успішність студента через
заповнення елементів інтерфейсного вікна .............................................................61
5.3 Приклади закінчених програм із віконним інтерфейсом ............................64
5.3.1 Однобічний лічильник ......................................................................................64
5.3.2 Двобічний лічильник.........................................................................................67

7
5.3.3 Реакція на події із затримкою та приклад створення
багатофункціонального годинника із секундоміром та звуковим сигналом .....69
5.3.4 Створення стандартних елементів віконного меню текстового
редактора .........................................................................................................................78
5.3.5 Програми для простого та інженерного калькулятора ..........................89
5.3.5.1 Простий калькулятор .....................................................................................89
5.3.5.2 Інженерний калькулятор.............................................................................110
5.3.6 Створення віконного інтерфейсу для конвертору фізичних величин......113
5.3.7 Створення віконного інтерфейсу для програми, призначеної для
визначення матеріалів за їхніми електрофізичними параметрами.............118
5.4 Розміщення графічних елементів у віконному інтерфейсі .......................122
5.4.1 Об’єкти векторної графіки модуля tkinter та способи їхньої побудови та
розташування.................................................................................................................122
5.4.2 Можливості зміни властивостей графічних об’єктів, розташованих
на полотні, для створення анімаційних фрагментів ........................................132
5.4.3 Можливості побудови графіків математичних функцій з
використанням графічних об’єктів модуля tkinter...........................................142
5.4.3.1 Вкладенки як додатковий елемент віконного інтерфейсу...............142
5.4.3.2 Спосіб побудови графіків математичних функцій з використанням
прямих ліній як елементарних графічних об’єктів..........................................145
5.5 Розширені бібліотеки елементів віконного інтерфейсу в інтерпретаторі
мови програмування Python .......................................................................................155
Контрольні питання та завдання до розділу 5......................................................162
Розділ 6 Розширені можливості мови Python для розв’язування прикладних
завдань програмування та складних інженерних та наукових завдань......... 176
6.1 Можливості використання пакету Anaconda для розв’язування завдань
математичного моделювання та наукових завдань ............................................176
6.1.1 Описання головних можливостей пакету Anaconda, призначених для
розв’язування інженерних та наукових завдань.....................................................176
6.1.2 Масиви та операції з ними в системі програмування Anaconda .......180
6.1.2.1 Визначення масивів та основні правила роботи з ними...................180

8
6.1.2.2 Головні атрибути масивів та методи для роботи з ними .................183
6.1.2.3 Реалізація матричних макрооперацій та інших алгебраїчних
операцій над масивами та окремими їхніми елементами..............................191
6.1.2.4 Використання математичних функцій для роботи з масивами .....202
6.1.2.5 Функції для виконання операцій лінійної алгебри ............................210
6.1.3 Графічні можливості системи Anaconda...................................................214
6.1.3.1 Засоби для побудови двовимірної графіки...........................................214
6.1.3.2 Засоби для побудови тривимірної графіки...........................................242
6.1.3.3 Засоби для створення анімаційних ефектів..........................................248
6.1.3.4 Можливості інтеграції графічних об’єктів модуля matplotlib
системи програмування Anaconda із об’єктами графічного інтерфейсу
модуля tkinter................................................................................................................256
6.1.4 Символьні обчислення в системі програмування Anaconda ..............262
6.1.4.1 Загальні основи символьних обчислень ................................................262
6.1.4.2 Аналітичні функції алгебраїчних перетворень ...................................269
6.1.4.3 Функції для аналітичного розв’язування алгебраїчних рівнянь та їх
систем..............................................................................................................................277
6.1.4.4 Аналітичні функції матричної алгебри..................................................282
6.1.4.5 Аналітичні функції математичного аналізу .........................................285
6.1.5 Приклади розв’язування прикладних завдань математичного
моделювання з використанням системи програмування Anaconda ...........292
6.1.5.1 Чисельне обчислення інтегралів ..............................................................292
6.1.5.2 Чисельне розв’язування диференціальних рівнянь ...........................298
6.2 Функції інтерпретатора мови Python для програмування мережних
програмних додатків та приклади створення мережного програмного
забезпечення....................................................................................................................307
6.2.1 Базові принципи програмування мережних додатків з
використанням функцій інтерпретатора мови Python ....................................307
6.2.2 Приклад створення простої мережної бази даних на основі клієнт-
серверної технології...................................................................................................311

9
6.2.3 Приклад створення простої мережної обчислювальної програми на
основі клієнт-серверної технології .......................................................................328
6.3 Можливості використання інтерпретатора мови Python для програмування
мікроконтролерів .............................................................................................................333
Контрольні питання та завдання до розділу 6 ...........................................................342
Розділ 7 Практичні заняття................................................................................................379
7.1 Заняття 1. Головні принципи об’єктно-орієнтованого програмування.........379
Індивідуальні завдання для виконання практичного заняття 1.......................379
Контрольні питання до практичного заняття 1......................................................381
7.2 Заняття 2. Основи роботи з інтерпретатором мови Python...............................382
Індивідуальні завдання для виконання практичного заняття 2.......................382
Контрольні питання до практичного заняття 2......................................................384
7.3 Заняття 3. Написання програми, призначеної для переведення фізичних та
інформаційних величин із однієї системи вимірювання до іншої ........................386
Індивідуальні завдання для виконання практичного заняття 3...........................386
Контрольні питання до практичного заняття 3......................................................388
7.4 Заняття 4. Автоматичне визначення типу транзистора за його
маркуванням ....................................................................................................................389
7.4.1 Загальна постановка завдання визначення типу приладу за його
маркуванням та спосіб його розв’язування............................................................389
7.4.2 Система маркування транзисторів .................................................................390
7.4.3 Індивідуальні завдання для виконання практичного заняття 4...............394
Контрольні питання до практичного заняття 4......................................................395
7.5 Заняття 5. Кусково-лінійна інтерполяція та лінійна апроксимація таблично
заданих функцій ...............................................................................................................396
7.5.1 Основи теорії лінійної інтерполяції ...............................................................396
7.5.2 Основи теорії лінійної апроксимації ...............................................................398
7.5.3 Індивідуальні завдання для виконання практичного заняття 5...............399
Контрольні питання до практичного заняття 5 .........................................................401
7.6 Заняття 6. Чисельне розв’язування нелінійних рівнянь методом січних.........403
7.6.1 Метод січних як спосіб розв’язування нелінійних рівнянь......................403

10
7.6.2 Індивідуальні завдання для виконання практичного заняття 6...............404
Контрольні питання до практичного заняття 6......................................................406
7.7 Заняття 7. Чисельне інтегрування функцій на заданому числовому інтервалі
методом трапецій.............................................................................................................407
7.7.1 Чисельне інтегрування та метод трапецій......................................................407
7.7.2 Індивідуальні завдання для виконання практичного заняття 7...............409
Контрольні питання до практичного заняття 7 ......................................................410
7.8 Заняття 8. Розв’язування систем лінійних рівнянь методом Крамера.........412
7.8.1 Визначник матриці та спосіб розв’язування систем лінійних рівнянь
методом Крамера..........................................................................................................412
7.8.2 Приклади розв’язування систем лінійних рівнянь з використанням
метода Крамера.............................................................................................................413
7.8.3 Індивідуальні завдання для виконання практичного заняття 8...............415
Контрольні питання до практичного заняття 8 ......................................................416
7.9 Заняття 9. Створення програмних засобів для подійного моделювання
фізичних процесів............................................................................................................417
7.9.1 Основи теорії подійного моделювання...........................................................417
7.9.2 Індивідуальні завдання для виконання практичного заняття 9...............418
Контрольні питання та завдання до практичного заняття 9 ................................420
7.10 Заняття 10. Розв’язування диференціальних рівнянь з використанням
засобів програмування системи Anaconda .................................................................421
Індивідуальні завдання для виконання практичного заняття 10 ........................421
Контрольні питання до практичного заняття 10 ....................................................423
7.11 Заняття 11. Створення програмного забезпечення для мережної
обчислювальної системи................................................................................................424
Індивідуальні завдання для виконання практичного заняття 11 ........................424
Контрольні питання до практичного заняття 11 ....................................................426
7.12 Заняття 12. Створення програмного забезпечення для програмування
мікроконтролерів .............................................................................................................428
Індивідуальні завдання для виконання практичного заняття 12 ........................428
Контрольні питання до практичного заняття 12 ....................................................430

11
8. Загальний перелік питань та завдань для самоконтролю знань ............................432
8.1 Загальні положення................................................................................................432
8.2 Базовий рівень знань..............................................................................................433
8.3 Середній рівень знань............................................................................................434
8.4 Високий рівень знань.............................................................................................434
Додаток А. Програма для формування рядка з відомостями про студента для
прикладу 5.19........................................................................................................................438
Додаток Б. Програма багатофункціонального годинника із звуковим сигналом та
секундоміром для прикладу 5.24......................................................................................443
Додаток В. Програма текстового редактора для прикладу 5.25 ................................452
Додаток Г. Програма простого калькулятора з реалізацією головних математичних
функцій та з десятьми комірками пам’яті для прикладу 5.26............................................455
Додаток Д. Конвертор фізичних величин із віконним інтерфейсом для прикладу
5.28 ..........................................................................................................................................487
Додаток E. Програма для визначення матеріалу за його електрофізичними
параметрами для прикладу 5.29........................................................................................492
Додаток Є. Програма для побудови графіків математичних функцій в
інтерфейсному вікні для прикладу 5.36 .....................................................................496
Додаток Ж. Програма для побудови графіків математичних функцій засобами
бібліотеки matplotlib в інтерфейсному вікні модуля tkinter для прикладу 6.55 ........498
Додаток З. Програма клієнта для виведення інформації про успішність студента у
діалогове інтерфейсне вікно, написана з використанням мережних технологій для
прикладу 6.84.........................................................................................................................501
Додаток І. Програми клієнта та сервера для проведення розрахунків значень
математичних функцій з використанням клієнт-серверних технологій для
прикладу 6.85 ......................................................................................................................505
Література .............................................................................................................................511

12
Відомості про автора
Мельник Ігор Віталійович

Доктор технічних наук, професор кафедри


електронних приладів та пристроїв факультету
електроніки Національного технічного
університету України «Київський політехнічний
інститут ім. І. Сікорського». Народився у 1966 р.
у м. Києві. У 1983 р. закінчив середню школу та поступив до Київського політех-
нічного інституту, який закінчив у 1989 р. за фахом «інженер електронної тех-
ніки». З 1989 року по поточний час працює у Національному технічному
університеті України «Київський політехнічний інститут» на посадах аспіранта,
асистента, старшого викладача, доцента, докторанта та професора. Після
закінчення аспірантури у 1994 р. захистив кандидатську дисертацію. Розробив
ряд спеціалізованих курсів, зокрема: «Електронні пристрої обчислювальної
техніки», «Обчислювальні системи та мережі», «Проектування інформаційних
електронних систем», «Променеві інформаційно-технологічні системи»,
«Імовірнісні основи обробки даних». З 2005 по 2008 рік навчався у докторантурі
Національного технічного університету України «КПІ». З 2004 р. – за
сумісництвом доцент кафедри комп’ютерної інженерії Відкритого міжнародного
університету розвитку людини «Україна», де викладає курси «Архітектура
комп’ютерних мереж» та «Дослідження та проектування комп’ютерних мереж».
У 2009 р. захистив докторську дисертацію. Був науковим керівником аспіранта,
який захистив кандидатську дисертацію з вакуумної та плазмової електроніки. З
2016 р. професор кафедри електронних приладів та пристроїв.
Як науковець зробив внесок у розвиток теорії високовольтного
тліючого розряду, розробив методи комп’ютерного розрахунку та
проектування технологічних газорозрядних електронних гармат.
Має понад 240 наукових праць, серед яких більше 50 опубліковано за
кордоном, зокрема, 10 авторських свідоцтв, 5 патентів України та 8

13
навчальних посібників. Опубліковані навчальні посібники: «Інформаційні
комп’ютерні мережі» (2006), «Комп’ютерні мережі та телекомунікації»
(2007), «Система науково-технічних розрахунків MatLab та її використання
для розв'язання задач із електроніки», у двох томах (2009), «Проектування та
дослідження комп’ютерних мереж» (2010), «Основи проектування
безпроводових комп’ютерних мереж» (2011), «Planung und Optimierung von
Rechnernetzen» (2011, німецькою мовою), «Основы построения
компьютерных сетей» (2013, видана російською мовою в Азербайджані),
«Кодування сигналів в електронних системах. Частина 1. Параметри сигналів
та каналів зв’язку та методи їхнього оцінювання» (2016), «Кодування
сигналів в електронних системах. Частина 2. Математичні основи теорії
кодування», у трьох томах (2018). Брав участь у роботі багатьох
національних та міжнародних конференцій. Член організаційних комітетів
міжнародних конференцій «Elnano» та «UkrMiCo». Член редакційної колегії
журналу «Прикладні проблеми математичного моделювання». Член
спеціалізованої вченої ради з захисту кандидатських та докторських
дисертацій.
Коло наукових інтересів: комп’ютерне моделювання фізичних процесів
та явищ в газорозрядних електронних приладах, комп’ютерне моделювання
технологічних процесів, комп’ютерні мережі та INTERNET, дискретна
математика, об’єктно-орієнтоване програмування.

14
ВСТУП
Комплексний навчальний посібник, який пропонується, спрямований
на вивчення методів та засобів програмування мови Python для студентами-
бакалаврами другого курсу, які навчаються за напрямом «Електронні
пристрої та системи» на факультеті електроніки Національного технічного
університету України «КПІ імені Ігоря Сікорського».
Оскільки сьогодні вся сучасна промислова та побутова електронна
апаратура є програмованою, вивчення майбутніми фахівцями в галузі
електроніки основ програмування та відповідних алгоритмічних мов має
вкрай важливе значення. Крім цього, проектувальникам електронної
апаратури вельми важливо знати наявні комп’ютерні засоби, призначені для
моделювання електронних схем та систем з метою підвищення ефективності
їхнього проектування.
На кафедрі електронних приладів та пристроїв факультету електроніки
Національного технічного університету України «Київський політехнічний
інститут імені Ігоря Сікорського» приділяється велика увага вивченню
програмного забезпечення та алгоритмічних мов. В курсі «Обчислювальні
системи та мережі» викладаються основи програмування мовою Асемблер,
яка має вкрай важливе значення для організації ефективної роботи
електронної апаратури за заданими алгоритмами [1]. Також особлива велика
увага приділяється вивченню основ дискретної математики та теорії
скінченних автоматів [2]. З самого початку навчання, в курсі
«Програмування та алгоритмічні мови», студенти вивчають мову
програмування С, яка вже протягом майже п’ятдесяти років є загальним
світовим стандартом для системного програмування та для реалізації
ефективних алгоритмів функціонування програмованих цифрових
електронних пристроїв та апаратів [3 – 5]. В ході вивчення курсу
«Обчислювальні системи та мережі» студенти також знайомляться з
основами програмування в системі науково-технічних розрахунків MalLab,
яка сьогодні вважається одним із найефективніших засобів моделювання для

15
вирішення складних інженерних та наукових завдань [6, 7]. Для надання
відповідних знань з сучасних технологій об’єктно-орієнтовного
програмування студентам в курсі «Програмування та алгоритмічні мови»
викладаються основи мови програмування С++ [8 – 11].
Проте низка питань, пов’язаних із вивченням студентами прогресивних
сучасних технологій програмування цифрової електронної апаратури, в
процесі навчання бакалаврів напряму «Електронні пристрої та системи» досі
залишається неохопленою. Недостатньо вивчаються сучасні технології
створення розподілених програмних додатків [12 – 14] та можливості
використання для цього засобів об’єктно-орієнтованого та системного
програмування [12 – 19], майже не приділяється увага створенню
програмного забезпечення для організації роботи розвинених комп’ютерних
мереж та для синхронізації роботи мережних електронних пристроїв [20 –
22]. У зв’язку з цим, для надання студентам цих необхідних знань, до плану
навчання введено додатковий курс «Об’єктно-орієнтоване програмування».
Сьогодні найбільш ефективними мовами об’єктно-орієнтованого
програмування для створення мережного програмного забезпечення та
розподілених програмних додатків вважаються мови Java [23] та Python [24 –
38]. Проте, якщо мова Java сьогодні насамперед орієнтована на використання
об’єктно-орієнтованого підходу до створення мережних додатків на основі
розподілених баз даних [12 – 14, 23], мова Python, створена в дев’яностих
роках ХХ століття, вважається значно більш універсальною та
багатофункціональною [24 – 38]. Залежно від бібліотек, які встановлюються
та підключаються, вона може бути ефективним інструментом і для
розв’язування завдань моделювання та проведення складних інженерних та
наукових розрахунків, і для роботи з базами даних, і для створення
розподілених мережних додатків, і для програмування цифрової електронної
апаратури [24 – 29]. Бурхливий розвиток мови програмування Python дав
величезний поштовх для подальшого розвитку нових, сучасних технологій
програмування, серед яких слід відзначити інтерактивний Python,

16
впроваджений у системі програмування Anaconda [26], та ефективні сучасні
технології машинного навчання [26, 28, 29]. Про популярність цієї мови
програмування серед програмістів та студентів свідчить також велика
кількість навчальної літератури, опублікованої протягом останніх років [24 –
29]. Підвищенню популярності мови програмування Python сприяли також її
простота, універсальність та багатофункціональність. Вивчаючи Python,
можна послідовно переходити від створення та відлагодження простих
фрагментів програм до написання складних програмних комплексів,
призначених для вирішення серйозних інженерних та наукових завдань. Така
багатофункціональність та ефективність мови програмування Python
пов’язана також з тим, що розробники мови не лише реалізували необхідні
засоби програмування, але й сформулювали відповідні принципи роботи з
ними, які називаються філософією мови Python [24 – 26]. Тобто, можна
сказати, що сучасний Python – це органічне поєднання теорії алгоритмів,
різних розділів математики та філософії інженерного мислення [24 – 29].
У зв’язку з цим навчальний посібник, якій пропонується, орієнтований
на вивчення студентами-бакалаврами напряму «Електронні пристрої та
системи» основ мови програмування Python. Посібник є комплексним. Перші
п’ять розділів вивчаються в курсі «Об’єктно-орієнтоване програмування», а
шостий – в курсі «Обчислювальні системи та мережі». Вивчення засобів
програмування системи Anaconda в курсі «Обчислювальні системи та
мережі» є дуже ефективним з методичної точки зору та дозволяє легко
перейти до вивчення засобів програмування системи науково-технічних
розрахунків MatLab.
Відмінною рисою навчального посібника, який пропонується, є велика
кількість наведених прикладів та їх орієнтація на розв’язування практичних
завдань, зокрема завдань з пошуку інформації та формування звітів та
завдань з моделювання фізичних процесів та явищ в електронних пристроях.
Велика увага приділяється створенню закінчених програмних продуктів з
віконним інтерфейсом користувача. Окремо розглянутий зв’язок існуючих

17
засобів програмування мови Python з теорією алгоритмів, для великої
кількості прикладів, які розглядаються, наведені блок-схеми алгоритму, що
відповідають завданням, які розв’язуються. Оскільки коди деяких програм,
особливо програм із віконним інтерфейсом, є досить об’ємними, ці коди
перенесені до додатків.
Іншою важливою відмінною рисою посібника є комплексний підхід до
розгляду величезної кількості засобів програмування мови Python. У
другому, третьому та четвертому розділах розглядаються елементарні засоби
програмування мови Python, які є стандартними та призначені для
ефективного розв’язування простих завдань. У п’ятому розділі
розглядаються способи створення закінчених програмних продуктів з
віконними інтерфейсами. У шостому розділі розглядаються розвинені засоби
програмування мови Python, призначені для розв’язування складних завдань
математичного моделювання, а також засоби для створення мережного
програмного забезпечення та для програмування цифрової електронної
апаратури, зокрема мікроконтролерів. Перші п’ять розділів містять
теоретичний матеріал, який викладається в курсі «Об’єктно-орієнтоване
програмування», а матеріал шостого розділу викладається в курсі
«Обчислювальні системи та мережі». Також передбачається, що студенти
будуть використовувати матеріал, викладений у посібнику, в процесі
подальшого навчання та під час написання дипломних робіт. Вивчення
студентами засобів програмування системи Anaconda дає важливе
теоретичне підґрунтя для подальшого вивчення більш розвинених
програмних засобів, реалізованих в системі науково-технічних розрахунків
MalLab [6, 7].
Загальна структура посібника має наступний вигляд.
У першому розділі викладаються основи теорії структурного та
об’єктно-орієнтованого програмування. Описана історія розвитку засобів
програмування та наведений зв’язок поняття об’єкту із дискретною
математикою та теорією скінченних автоматів [2]. Сформульовані головні

18
визначення та правила, пов’язані із загальною концепцією об’єктно-
орієнтованого програмування [8 – 11, 15 – 19]. Описана історія розвитку
мови програмування Python, розглянуті головні її переваги та недоліки, а
також наведені філософські принципи програмування, які пропонують
розробники цієї мови.
У другому розділі розглядаються загальні основи роботи з оболонкою
інтерпретатора мови програмування Python третьої версії, засоби
налаштування цієї оболонки, синтаксичні конструкції мови та структура
бібліотек та модулів. Окремо розглянуті засоби роботи з числовими даними,
з функціями математичних бібліотек та з рядковими даними. Особлива увага
приділяється створенню власних функцій користувача та програмним
засобам для роботи з ними. Цей матеріал складає теоретичне підґрунтя для
реалізації сучасних методів структурного та модульного програмування та
для написання фрагментів простих програм.
У третьому розділі розглядаються більш розвинені засоби структурного
програмування, зокрема, умовні оператори, списки як індексовані структури
даних, а також цикли із заданою кількістю повторень та із виходом за
заданою умовою. Окремо розглянуті такі нестандартні засоби програмування
мови Python, як анонімні лямбда-функції та оператор обробки виключних
ситуацій [24 – 26].
Теоретичний матеріал, наведений у другому та третьому розділах,
супроводжується великою кількістю прикладів закінчених програм, серед
яких слід окремо відзначити програми, призначені для обробки інформації
про фізичні величини та для моделювання явищ та процесів фізичної
електроніки. Наприклад, у підрозділі 2.5.6 розглянутий простий конвертор
фізичних величин, у підрозділі 3.5 наведена програма для визначення типів
матеріалів за значенням їхньої електропровідності або діелектричної
проникності, а у підрозділі 3.7.5 розглянута та проаналізована програма для
розрахунку спектрів випромінювання газів за формулою Рідберга. Деякі
наведені приклади пов’язані також із курсом «Обчислювальна математика».

19
У підрозділі 3.7.4 наведені приклади використання списків та циклів із
заданою кількістю повторень для транспортування матриці та для множення
двох матриць, а у підрозділі 3.7.6 – приклад чисельного розв’язування
нелінійного рівняння методом Стеффенсона. Розглядаються також
способи розв’язування деяких задач дискретної математики та теорії
чисел [2, 5, 7]. Тобто, комплексність навчального посібника полягає ще
й у тому, що матеріал, наведений в ньому, може бути використаний для
вивчення інших дисциплін та для виконання відповідних
розрахункових завдань.
У четвертому розділі описані способи роботи з об’єктами та
розглянуті приклади використання загальних принципів об’єктно-
орієнтованого програмування, розглянутих у розділі 1, в мові
програмування Python. Деякі з програм, наведених у другому та
третьому розділах, переписані з використанням засобів об’єктно-
орієнтованого програмування та проведений порівняльний аналіз
різних способів реалізації програмного коду. Також у четвертому
розділі окремо розглянуті такі нестандартні структури даних мови
програмування Python, як множини, кортежі та словники. Способи
використання цих нестандартних структур даних у закінчених
функціональних програмах розглядаються у п’ятому та шостому
розділах.
У п’ятому розділі розглянуті засоби програмування мови Python,
призначені для створення функціональних програмах із графічним
інтерфейсом користувача. Головні елементи сучасного віконного
інтерфейсу та засоби їх створення розглянуті у підрозділах 5.1 та 5.2, а
у підрозділі 5.3 наведені та проаналізовані коди закінчених,
функціональних програм. Особливо цікавою серед них є програма
простого калькулятора, наведена у підрозділі 5.3.5.1. Функціональність
цієї програми та можливість роботи калькулятора з різними комірками
пам’яті дозволяє використовувати її для вивчення основ роботи

20
гіпотетичного процесора на практичних заняттях з курсу
«Обчислювальні системи та мережі». Коди програм конвертора фізичних
величин та визначення типу матеріалів за їхніми електрофізичними
властивостями, наведені у другому та третьому розділах, переписані з
формуванням віконниого інтерфейсу. Проведений порівняльний аналіз кодів
цих програм. У підрозділі 5.4 окремо розглянуті засоби інтерактивної
графіки та анімації, а також наведений та проаналізований код закінченої
функціональної програми із віконним інтерфейсом, призначеної для
побудови графіків математичних функцій.
У шостому розділі розглядаються ускладнені розвинені засоби мови
програмування Python, які призначені для розв’язування більш складних
прикладних інженерних та наукових завдань. У підрозділі 6.1 розглянуті
засоби програмування мови IPython та системи Anaconda [26]. Зокрема,
приділяється окрема увага масивам як структурованим числовим даним та
способам роботи з ними, засобам для роботи з двовимірною та тривимірною
науковою графікою, засобам для створення анімаційних ефектів,
символьному процесору, засобам для обчислення інтегралів та засобам для
розв’язування звичайних диференціальних рівнянь. У підрозділі 6.2
розглядаються функції інтерпретатора мови Python, призначені для
створення мережних програм з використанням технологій передавання
даних клієнт-сервер, а у підрозділі 6.3 – функції, призначені для
програмування мікроконктролерів.
У сьомому розділі наведені плани практичних занять та завдання, які
повинні виконати студенти. Вказані критерії оцінок за кожне виконане
завдання. Заняття 1 – 8 відповідають плану курсу «Об’єктно-орієнтоване
програмування», а заняття 9 – 12 – плану курсу «Обчислювальні системи та
мережі».
Всі розділи, з першого по шостий, закінчуються контрольними
питаннями та завданнями, а до кожного практичного заняття контрольні
питання наведені окремо. У восьмому розділі наведений перелік питань,

21
завдань та практичних занять, які відповідають базовому, середньому та
високому рівню знань студентів, що надає студентам можливість самостійно
оцінити свої знання та уникнути серйозних конфліктів з викладачем щодо
оцінювання рівня своїх знань. Для підтвердження високого рівня знань
студент повинен написати реферат та виступити за темою реферату на
семінарському занятті. Можливі теми рефератів наведені у підрозділі 8.3.

22
Розділ 1. Історія розвитку об’єктно-орієнтованого
програмування та його головні принципи
У цьому розділі розглядаються базові принципи об’єктно-орієнтованого
програмування та історія його розвитку. Надані визначення об’єкту, класу,
розглядаються поняття інкапсуляції, успадкування, поліморфізму, полів класу,
методів, властивостей об’єкта та абстрагування даних та методів.
Показаний зв’язок загальних принципів об’єктно-орієнтованого програмування
із теорією регулярних мов та скінченних автоматів. Розглядаються базові
принципи побудови мови Python як мови об’єктно-орієнтованого
програмування та головні її переваги. Введено поняття філософії мови
програмування та розглянуті філософськи принципи мови Python.

1.1 Історія розвитку засобів програмування

Історія розвитку мов програмування безпосередньо пов’язана із


історією розвитку обчислювальної техніки. Перші мови програмування, які
називались мнемокодами, були розроблені на початку п’ятдесятих років
минулого століття для перших обчислювальних машин. Загалом у цих мовах
програмування і для запису чисел, і для запису виконуваних команд
використовувались двійкові коди. Така організація обчислювального процесу
цілком відповідала архітектурі машини Фон-Неймана, проте користуватися
такими мовами без спеціальної професійної підготовки було дуже важко. Ці
мови програмування історики обчислювальної техніки називають мовами
першого покоління.
Ситуація почала змінюватись у середині п’ятдесятих років минулого
століття, коли для кожної марки обчислювальних машин відповідного
виробника стали розробляти транслятори з мови програмування асемблер, у
якій вводилось поняття змінної та типу змінних. У мові асемблер коди
команд починають відділяти від змінних, які вони обробляють. Числові дані
окремо систематизуються та зберігаються в окремих комірках пам’яті. Мова
асемблер є досить ефективною та дозволяє писати програмний код, який
швидко обробляється електронно-обчислювальними пристроями. Такі мови

23
програмування історики обчислювальної техніки називають мовами другого
покоління. Різні варіанти мови асемблер є популярними і сьогодні. Їх
використовують для написання драйверів периферійних пристроїв та для
програмування мікроконтролерів з метою керування швидкодіючими
об’єктами. Наприклад, досить популярною сьогодні є мова програмування
асемблер для мікропроцесорів сімейства Intel 80x86 [1]. Недоліком мов
програмування другого покоління є їх орієнтація на професіональних
програмістів та відсутність єдиного стандарту для всіх типів обчислювальних
систем.
Ситуація ретельно змінилась у 1955 році, коли видатний математик та
програміст Джон Бекус запропонував фірмі IBM створити нову, ефективну
мову програмування для проведення науково-технічних та економічних
розрахунків. В результаті робіт Д. Бекуса була створена мова програмування
FORTRAN, яку вважають першою високорівневою мовою програмування,
або мовою програмування третього покоління. Практичні результати,
отримані Д. Бекусом під час створення мови FORTRAN, були обґрунтовані з
точки зору теорії регулярних мов [2] та удосконалені Петером Науром. До
мов програмування третього покоління відносять також мови PL1, Algol,
Cobol, Pascal, Ada, C. Доречи, до кінця дев’яностих років минулого століття
мова програмування FORTRAN досить ефективно використовувалась для
проведення складних математичних розрахунків.

Джон Бекус Петер Наур


(1924 – 2007) (1928 – 2016)

24
Окремо слід відзначити мову програмування С, на основі якої
американськими програмістами К. Томпсоном та Д. Рітчі на початку
сімдесятих років минулого століття була створена операційна система UNIX
[3 – 5]. Саме С на довгі роки стала основною мовою системного
програмування, яка згодом у значній мірі замінила асемблер. Це було
пов’язано з тим, що на мову С був розроблений єдиний міжнародний
стандарт і вона стала апаратно-незалежною.

Денніс Мак-Алістер Рітчі (1941 — 2011), праворуч, та


Кеннет Лейн Томпсон (нар. 1943), ліворуч

Розвиток мов програмування третього покоління також призвів до


появи нової теоретичної концепції структурного програмування, яка
ґрунтується на доведеній італійськими математиками Бьомом та Якопіні
теоремі про те, що міжадресні переходи в межах програми можна замінити
комплексними умовними операторами та циклічними структурами [6, 7].
Подальшому розвитку методів структурного програмування сприяли також
роботи з математичної логіки, дискретної математики, теорії регулярних мов
та теорії предикатів, найбільший розвиток у теорію програмування в цей
період її розвитку внесли Е.В. Дайкстра та В.М. Глушков.

Едсгер Вібе Дайкстра Віктор Михайлович Глушков


(1930 – 2002) (1923 – 1982)

25
У 1961 році К.Ю. Айверсон розробляє мову програмування APL, у якій
було вперше запропоновано та використано безпосередня адресація не окремих
даних, а їх структур, зокрема векторів та матриць. Також в APL вперше була
реалізована можливість виконання алгебраїчних операцій над структурованими
даними. Зараз така концепція називається матричним програмуванням. Сьогодні
засоби матричного програмування у найбільш повній формі реалізовані у системі
науково-технічних розрахунків MatLab [6, 7] та у мові програмування Python.

Кеннет Юджин Айверсон


(1920 – 2004)

1.2 Поняття про об’єкти та базові принципи об’єктно-


орієнтованого програмування

Тоді ж, ще у шістдесяті роки ХХ століття, починають з’являтися і перші


мови з реалізацією концепції об’єктно-орієнтованого програмування (ООП).
Спочатку ООП виникло як результат розвитку методів та засобів структурного
програмування. Але недоліком структурних програм розробники програмного
забезпечення стали вважати те, що дані та процедури, які їх обробляють, не
пов’язані між собою. Саме через це з’являється поняття об’єкта, яке дозволяє
встановити безпосередній зв’язок між процедурами та даними, які в них
обробляються. Надамо відповідне визначення [8 – 11].
Визначення 1.1 Об’єкт – це віртуальна субстанція, до якої можна
надсилати повідомлення, а об’єкт реагує на них через аналіз даних, які
зберігаються в його пам’яті.

26
Слід відзначити, що, з точки зору теорії програмування, об’єкт є
скінченним автоматом із відповідною організацією пам’яті [2].
Для подальшого розвитку ООП було введене поняття події та подійно-
орієнтованого програмування. Надамо відповідне визначення [8 – 11].
Визначення 1.2 Подією називається запит на обробку даних, який
аналізується через пам’ять об’єкта.
Взаємодія між об’єктами здійснюється через надсилання повідомлень.
Надамо відповідне визначення [8 – 11].
Визначення 1.3 Повідомленням називається надсилання запиту до
об’єкта через виклик відповідної функції.
Сьогодні, як результат подальшого розвитку концепції ООП, розглядають
також поняття агента. У разі розглядання такої концепції агентами вважаються
незалежні частини програмного коду на рівні виконання програми. Тоді
вважається, що взаємодія об’єктів здійснюється на рівні зміни середовища, у
якому вони розміщуються. Терміни «агент» та «середовище» більше
притаманний соціальним моделям, і тому ця термінологія частіше застосовується
для програмного забезпечення, яке використовується для аналізу соціальних
процесів і пов’язане із поширенням сучасних інформаційних технологій до сфери
соціальних знань [11 – 14]. Ці терміни також широко використовуються для
аналізу поведінки та моделювання біологічних об’єктів та систем, але у технічній
сфері та в області інформаційних технологій вони поки не є такими, які загально
вживаються [12 – 14].
Більш важливим для розуміння загальних принципів ООП є поняття класу.
Надамо відповідні визначення [8 – 11].
Визначення 1.4 Полем називається сукупність змінних, які
характеризують відповідну властивість об’єкта.
Визначення 1.5 Методами називаються відповідні функції для роботи із
полями об’єкта.
Визначення 1.6 Класом називається універсальний, комплексний,
інтегрований тип даних, який складається із набора полів, заданих відповідними
змінними, та визначеними методами для роботи із цими полями.

27
Для всіх об’єктів в ООП визначається відповідний клас, а через запити
аналізуються властивості об’єкта. Зазвичай базовими операціями із класами в
ООП є функції читання та зміни полів, якими визначаються властивості об’єкта.
Властивості майже співпадають із полями та зазвичай ототожнюються з ними,
хоча, для спрощення розуміння програмного коду, вони описуються окремо.
У теорії ООП вважається, що клас має інтерфейсну природу, оскільки
звичайне звернення до нього відповідає аналізу властивостей, а не самих
змінних. Інтерфейсна природа класу проявляється також у тому, що зазвичай у
разі копіювання відповідної змінної копіюється лише властивість, а не самі дані,
тому іноді клас також розглядають як тип даних із посиланнями. Найчастіше
класи розробляються таким чином, щоб забезпечити цільність даних про
природу об’єкта для узагальненої задачі, яка розв’язується [8 – 11].
Для цього розглядаються чотири головні концепції ООП, а саме:
абстрагування даних, інкапсуляція, наслідування та поліморфізм. Надамо
відповідні визначення [8 – 11].
Визначення 1.7 Абстрагування даних, як один із принципів ООП,
означає виділення головної інформації про властивості об’єкта та виключення із
розгляду другорядної інформації.
Визначення 1.8 Інкапсуляцією називається властивість системи, яка
дозволяє об’єднати всі дані, які стосуються об’єкта, та методи для роботи з ними
в одному класі.
Проте слід відзначити, що загальної тотожності між інкапсуляцією та
визначенням властивостей об’єкту не існує. В деяких мовах програмування ці
поняття ототожнюються, а в інших – розрізняються [8, 9].
Визначення 1.9 Успадкуванням називається властивість системи, яка
дозволяє описати властивості об’єктів нового класу на основі того класу, який
вже існує [8, 9].
Визначення 1.10 Клас, від якого здійснюється успадкування,
називається базовим класом, батьківським класом або суперкласом [8, 9].
Визначення 1.11 Новий клас, який створюється, називається нащадком,
спадкоємцем, дочірнім класом або похідним класом [8, 9].

28
Визначення 1.12 Поліморфізмом називається властивість системи, яка
дозволяє використовувати об’єкти із однаковим інтерфейсом без додаткових
знань про їхню внутрішню структуру [8, 9].
Також іноді в теорії ООП використовують поняття про параметричний
поліморфізм, якому відповідає концепція узагальненого програмування [8 – 11].
В теорії ООП також виділяють поняття аспектів. Надамо відповідне
визначення.
Визначення 1.13 Аспектами в теорії ООП називають мовні конструкції,
які безпосередньо до об’єктів не відносяться, але використовуються для
безпечної роботи з ними та для обробки виключних ситуацій.
Першими мовами програмування, які були розроблені в шістдесяті роки
минулого століття та використовували концепцію ООП, стали Simula-67,
Smalltalk та LISP, проте на той час як мови ООП вони не розглядалися. Доречи,
мова LISP і зараз використовується для систематизації та оформлення
конструкторської документації в САПР AutoCAD [8]. Проте справжніми
творцями концепції ООП вважають Б. Страуструпа, який розробив мову С++
[15], та Г. Буча, розробника мови UML та автора низки книг, присвячених
загальній ідеології ООП [8 – 10]. Фундаментальні роботи цих авторів, які були
опубліковані у вісімдесятих-дев’яностих роках ХХ століття, мали вкрай важливе
значення для розвитку та поширення загальної концепції ООП і для її
практичного використання в задачах моделювання та проектування
різноманітних технічних систем.

Бьярн Страуструп Граді Буч


(нар. 1950) (нар. 1955)

29
Сьогодні кількість мов програмування, які реалізують парадигму ООП, є
найбільшою порівняно із іншими парадигмами, зокрема із мовами,
орієнтованими на структурне, логічне, функціональне та матричне
програмування. Зрозуміло, що насамперед це пов’язано із тим, що концепція
ООП тісно пов’язана із моделями сучасної теорії скінченних автоматів, яка є
загальнотеоретичним підґрунтям всіх концепцій програмування [2]. Сьогодні
найбільш популярними серед мов ООП стали мова С++, система програмування
Delphi, а також мови C#, Java та Python.
Четверте покоління мов програмування пов’язане із створенням мов,
призначених для реалізації величезних проектів та проблемно-орієнтованих
мов програмування, призначених для описання конкретних понять вузької
галузі. Прикладами таких мов є SQL, HTML, XML, Prolog [12 – 14].
Щоправда ряд мов, які відносять до четвертого покоління, не є мовами
програмування у повному значенні цього слова. Наприклад, SQL є мовою
формування запитів до баз даних, а HTML – мовою розмітки гіпертексту та
формування гіперпосилань. Тому ці мови не є повноцінними мовами
програмування, скоріше вони виступають своєрідними спеціалізованими
доповненнями до мов програмування. Теж саме стосується XML. Основною
відмінною рисою мов програмування четвертого покоління є наближення до
людської мови. З точки зору теорії регулярних мов такі мови називають
декларативними [2, 8, 9, 12 – 14].

1.3 Приклади формування ієрархії класів


Головну концепцію ООП, пов’язану із інкапсуляцією, наслідуванням та
поліморфізмом, можна зрозуміти із наступних жартівливих діалогів, наведених у
прикладах.
Приклад 1.1
– Кішка є птахом?
30
– Ні, кішка – це тварина.
– А кішка – це травоїдна тварина?
– Ні, кішка – це хижак.
– А півень – це птах?
– Так.
– А чому півень – це птах, а кішка – тварина?
– Тому що півень має крила.
– А птахи літають?
– Так, більшість птахів вміють літати.
– А птахи дихають?
– Так, всі птахи дихають.
– А чому птахи дихають?
– Тому, що вони – живі істоти.
– А кішки дихають?
– Так, кішки теж дихають.
– А півень літає?
– Ні, хоча півень – це птах, він не вміє гарно літати. Це виключна ситуація.
– А летуча миша літає?
– Так, літає.
– А летуча миша – це птах?
– Ні, хоча летуча миша вміє літати, це тварина, а не птах. Це виключна
ситуація.
Узагальнена діаграма, на якій показано успадкування класів, об’єкти, які
належать цим класам, а також ознаки, або властивості цих об’єктів для
наведеного вище діалогу, представлені на рис. 1.1.
Наведемо тепер інший діалог, який стосується визначення та аналізу
деяких фізичних властивостей електронних приладів.

31
Батьківський клас
Об’єкти, Живі
екземпляри істоти
класів
Пінгвін
Птахи Тварини Класи –
спадкоємці
Страус

Горобець Орел Травоїдні Хижаки

Півень Корова Кішка

Заяць Летуча
миша
Їдять
Дихають Літають траву

Їдять Їдять Їдять


Ознаки тварин комах рибу

Рис. 1.1 Класифікація об’єктів, які належать до класу живих істот, та їхні ознаки

Приклад 1.2

– Діод – це напівпровідниковий прилад?

– Ні, не завжди. Бувають також вакуумні діоди.

– А тріод?

– Тріодами зазвичай називають вакуумні електронні лампи.

Напівпровідникові прилади із трьома електродами частіше називають

транзисторами.

– А транзистор – це надвисокочастотний прилад?

– Ні, не завжди. Бувають також низькочастотні транзистори.

– А транзистор – це сильнострумний прилад?

32
– Ні, існують також транзистори із низьким значенням струму.

– А чим відрізняється діод від тріода?

– Діод має два контакти, а тріод – три. В вакуумних пристроях ці контакти

підводяться до електродів, а в напівпровідникових – до напівпровідникового

кристалу.

– А чи існують пристрої, які мають чотири електроди?

– Так. Вакуумні пристрої із чотирма електродами називаються тетродами,

а напівпровідникові – тиристорами.

Класифікація електронних пристроїв за типом фізичного середовища, яке в

них використовується, а також та за кількістю електродів, наведена на рис. 1.2.

Ознаки класифікації електронних приладів


Тип фізичного Кількісь
середовища електродів

Класи
Вакуумні Напівпровідникові Два Три Чотири
прилади прилади

Тріоди Транзистори Тиристори Діоди Тетроди


Об’єкти

Рис. 1.2 Класифікація електронних приладів за різними ознаками

На рис. 1.3 головні положення концепції ООП, сформульовані у

визначеннях 1.1 – 1.13, представлені у вигляді жартівливих ілюстрацій, які

наведені у фундаментальному підручнику з ООП одного із засновників цієї

концепції та методології програмування, автора мови UML Г. Буча [8].

33
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]

34
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]
(продовження)

35
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]
(продовження)
36
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]
(продовження)
37
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]
(продовження)
38
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]
(продовження)

39
Рис. 1.3 Наочна ілюстрація головних принципів ООП в жартівливій формі [8]
(закінчення)

40
1.3 Ієрархія класів з точки зору теорії скінченних автоматів та
узагальнений алгоритм формування запитів про властивості об’єкта

Припустимо, що об’єкт, як екземпляр дочірнього класу, має ієрархію


наслідування із трьох батьківських класів, та до цього об’єкта, з іншого
програмного модуля, робиться запит щодо його властивості. Тоді алгоритм
пошуку та аналізу цієї властивості через ієрархію класів є наступним.
1. Проаналізувати змінні дочірнього класу. Якщо дана властивість у
дочірньому класі не визначена, слід звернутися до першого батьківського
класу.
2. Якщо дана властивість у першому батьківському класі також не
визначена, слід звернутися до другого батьківського класу.
3. Якщо дана властивість у другому батьківському класі також не
визначена, слід звернутися до третього батьківського класу.
4. Якщо дана властивість у третьому батьківському класі також не
визначена, слід вважати сформований запит до об’єкту таким, на який в ієрархії
класів немає відповіді.
Слід відзначити, що, з точки зору структури системи наслідування,
ієрархія класів може бути паралельною або послідовною. Так, ієрархічна
структура, наведена на рис. 1.1, яка відображує ієрархію класів живих істот, є
послідовною, а структура, наведена на рис. 1.2, яка відображує ієрархію
класів електронних приладів – паралельною. Послідовність успадкування
класів полягає в тому, що якщо об’єкт належить до відповідного класу, він
також належить до батьківського класу. Наприклад, якщо кішка є хижаком,
вона також є твариною та живою істотою. Проте кішка не може бути птахом,
оскільки ці класи є паралельними і жодна з живих істот не належить обом
паралельним класам. Так саме, якщо корова є травоїдною, вона не може бути
хижаком. Навпаки, якщо прилад є вакуумним, він може мати три електроди,
це, згідно із рис. 1.3, буде вакуумний тріод. У цьому і полягає принцип
паралельного наслідування, тобто, об’єкти із паралельним наслідуванням
можуть належати відразу до кількох класів однієї ієрархії.

41
З точки зору передавання запиту та аналізу властивостей системи
паралельність означає, що структуру даних різних класів можна обробляти
одночасно, а для послідовної ієрархії класів така обробка може проводитись
лише послідовно, із переходами від одного батьківського класу до іншого. На
рис. 1.4 наведена схема послідовного та паралельного скінченного автомату
для розглянутого прикладу із трьома батьківськими класами, а на рис. 1.5 –
блок-схема алгоритму аналізу властивості об’єкта за сформованим запитом.
Слід відзначити, що якщо схема скінченного автомату для паралельної та
послідовної ієрархії об’єктів є різною, то алгоритм пошуку властивості –
однаковим. Це пов’язано з тим, що схема скінченного автомату є більш
універсальною і теорія скінченних автоматів дає відповідь на питання про те,
які події автомат може обробляти паралельно. Пошук таких подій
називається розбиттям автомату [2].

Передавання
Запит запиту
О ДК БК1 БК2 БК3
Відповідь
Передавання
відповіді

а)

БК1
Передавання
запиту
Запит
О ДК БК2
Відповідь
Передавання
відповіді
БК3

б)
Рис. 1.4 Схеми скінченних автоматів, які відображують послідовне (а) та
паралельне (б) наслідування класів об’єкта

42
Початок

Прийняття
1 запиту

2
Дочірній клас ДК має
відповідь на запит? 7

Ні
3
Батьківський клас БК1
має відповідь на запит? 7

Ні
4
Батьківський клас БК2
має відповідь на запит? 7

Ні
5
Батьківський клас БК3
має відповідь на запит? 7

Ні 2 3 4 5

Відповідь
6 не знайдена Формування
7 відповіді

Кінець
Кінець

Рис. 1.5 Блок-схема алгоритму аналізу запиту про властивість об’єкта

43
Розглянемо блок-схему обробки конкретних запитів. Для ієрархії об’єктів,

показаної на рис. 1.1, проаналізуємо запит «Чи вміє кішка літати?», а для ієрархії

об’єктів, показаної на рис. 1.2 – запит «Чи є транзистор вакуумним приладом?».

Відповідні блок-схеми алгоритмів наведені на рис. 1.6 та 1.7.

Початок

Чи вміє кішка
1 літати?

Кішка – це птах?
2

Ні, тварина.
3

Більшість тварин
не літає. Кішка є
4 виключенням?

5 Ні.

Відповідь: кішка
не літає.
6

Кінець

Рис. 1.6 Блок-схема алгоритму пошуку відповіді на питання «Чи вміє кішка

літати» згідно із діаграмою успадкування об’єктів, наведеною на рис. 1.1

44
Початок

Транзистор –
це вакуумний
1 прилад?

Ні, напівпро-
2 відниковий.

Кінець

Рис. 1.7 Блок-схема алгоритму пошуку відповіді на питання «Чи є транзистор


вакуумним приладом?» згідно із діаграмою успадкування об’єктів, наведеною на
рис. 1.2

Для закріплення теоретичних знань, отриманих у цьому розділі з теорії


ООП, необхідно виконати практичне заняття №1, яке наведене у розділі 7.

1.4 Історія створення мови програмування Python та її головні


особливості

Python відноситься до мов програмування четвертого покоління. Розвиток


цих мов програмування був обумовлений двома факторами – створенням у
вісімдесяті-дев’яності роки ХХ століття концепції ООП, розглянутої у попередніх
підрозділах, та бурхливим розвитком глобальних комп’ютерних мереж та Інтернет
наприкінці ХХ століття. Із розвитком Інтернет виникла потреба написання
комп’ютерних програм, які могли б запускатися і правильно виконуватися на
різних апаратних платформах та в різних операційних системах. Це насамперед
вимагало створення єдиних стандартів на мережне програмне забезпечення,
згодом такі стандарти були створені, і сьогодні, у зв’язку із бурхливим розвитком
хмарних обчислень, саме вони стають найбільш популярними [12 – 14].

45
Обчислення у комп’ютерних мережах насамперед пов’язані із використанням
клієнт-серверних технологій. Надамо відповідні визначення [20 – 22].
Визначення 1.14 Клієнтом у теорії комп’ютерних мереж називається

комп’ютер, який надсилає запит.

Визначення 1.15 Сервером у теорії комп’ютерних мереж називається

комп’ютер, який приймає та обробляє запит.

Слід відзначити, що визначення 1.14 та 1.15 трішки відрізняються від


загальноприйнятих понять про серверні та клієнтські комп’ютери. Пересічені та
недосвідчені користувачі комп’ютерних мереж зазвичай вважають, що
комп’ютер клієнта – це комп’ютер користувача у мережі, а сервер – це
віддалений потужний комп’ютер, який надає клієнтові інформацію. Найчастіше
це буває саме так, але зворотній інформаційних потік у двосторонньому діалозі
між джерелом та приймачем інформації також є цілком можливим [20 – 22].
Першою мовою програмування для клієнт-серверних технологій стала
мова Java [23]. Розроблена на основі С++, ця мова швидко стала популярною
серед програмістів-професіоналів. Її відмінними рисами є можливість роботи
програм, написаних на Java, на різних комп’ютерах під різними
операційними системами, а також дуже висока надійність програмних
додатків, яка полягає у тому, що на Java можна за короткий термін писати
величезні програмні проекти без ризику пошкодити будь-які компоненти
операційної системи. На деякий час, наприкінці дев’яностих років ХХ
століття, саме Java фактично стає єдиним стандартом для написання клієнт-
серверних програмних додатків. Ця мова програмування широко
використовується і сьогодні, насамперед для роботи із базами даних великого
об’єму, проте її популярність, у зв’язку із розвитком інших мов
програмування, стала дещо меншою [20 – 22].
Із поширенням мережі Інтернет з’являється потреба створювати
динамічні сайти, і для вирішення цієї проблеми програмування була створена
мова програмування РНР [12 – 14]. Надалі, на початку ХХІ століття, у

46
розвитку наукових та технологічних розробок починають переважати
тенденції об’єднання високих технологій у програмуванні навколо крупних
корпорацій. Результатом такого розвитку стала розробка мови С# на
платформі .NET [12 – 14].
Із розвитком Інтернет та клієнт-серверних технологій програмування,
разом із мовою Java, розробляється та починає бурхливо розвиватися нова мова
програмування Python [24 – 29]. За основу для розробки цієї мови була взята
модель ООП мови Smalltalk, яка була розроблена однією із перших та завдяки
своїй простоті стала досить популярною серед широкого кола програмістів [8, 9].
Python з’явився на початку дев’яностих років минулого століття майже
одночасно із мовою програмування Java, а його розробником був відомий
голландський математик та програміст Гвідо ван Россум.

Гвідо ван Россум


(нар. 1956)

Закінчивши університет в Амстердамі, Россум досить довго розробляв


мову програмування ABC, яка, на його думку, мала бути простою для
навчання студентів основам програмування. Через деякий час Россум
починає розуміти, що необхідно змінити концепцію програмування і
розробити систему, яка була б зручною для запису алгоритмів та, з іншого
боку, дозволяла б ефективно створювати графічні програмні оболонки.
Створення саме такої мови програмування цікавило всіх колег Россума, і він
починає серйозно займатися цим завданням. Але, попре все, нова мова
зберігає головні особливості ABC як мови для навчання студентів та

47
програмістів-початківців. Потім виявилось, що розроблена Россумом мова
програмування Python є не лише простою та ефективною, але й може бути
легко вбудованою у програмні додатки. А з іншого боку, простота Python
сприяла тому, що його почали вводити до навчальних програм не лише в
університетах, але й у школах та коледжах [24, 30].
Так, поступово, Python стає найбільш популярною мовою
програмування для написання програмних додатків для клієнт-серверних
технологій [20 – 22]. Сьогодні публікується велика кількість літератури з мови
програмування Python [24 – 29], і вся вона є свіжою, актуальною, та
відслідковує найновітніші тенденції розвитку цієї мови багатоцільового
призначення. Багато інформації можна знайти також в Інтернеті [31 – 38].
Серед деяких програмістів існує думка про те, що простота мови Python не
дозволяє використовувати її для розв’язування складних наукових задач та
для проведення науково-технічних досліджень. Проте сьогодні ситуація
ретельно змінюється, з’являється все більша кількість бібліотек для Python,
функції яких призначені саме для розв’язування серйозних наукових завдань,
як на локальних комп’ютерах, так і з використанням клієнт-серверних
технологій [26].
У підручнику [26] представлена діаграма Венна, яка характеризує
організацію методів пошуку нової інформації та формування наукових знань на
сучасному рівні. Ця діаграма наведена на рис. 1.8. Згідно із висновками сучасних
аналітиків, наука про дані охоплює три окремих галузі знань, які не
перетинаються.
1. Навички фахівців у галузі математичної статистики, які вміють
розглядати набори даних та робити з цього розгляду відповідні висновки.
2. Навички фахівців у галузі комп’ютерних наук, які вміють створювати та
реалізовувати алгоритми для ефективного зберігання, обробки та візуалізації
даних.
3. Експертні знання предметної галузі.
З цієї точки зору сучасні засоби програмування мови Python, орієнтовані
на машинне навчання та статистичну обробку даних, призначені саме для
розв’язування складних наукових завдань [26].

48
Пристрасть до
наукових

Машинне
навчання
досліджень Знання методів
або до статистичної
написання обробки даних
комп’ютерних
програм
Наука
про дані
Традиційні
Небезпечна дослідження
зона

Експертні знання предметної


галузі

Рис. 1.8 Наука про дані та її місто у системі сучасних міждисциплінарних


наукових досліджень, наочно показане з використанням діаграми Венна

Це насамперед такі бібліотеки, як NumPy, Pandas, Matplotlib [26]. Тут


найбільш цікавою є концепція машинного навчання, яка полягає у тому, що
обчислювальні та алгоритмічні можливості науки про дані об’єднуються із
статистичною обробкою, за рахунок чого створюються підходи до дослідження
структур даних, пов’язаних із ефективністю обчислень. Найбільш популярною
версією середовища програмування Python серед академічної та наукової
спільноти вважається IPython [26, 32].
Також слід відзначити, що деякі обчислювальні засоби мови програмування
Python, зокрема графічні засоби візуалізації бібліотеки Matplotlib,
безпосередньо пов’язані із засобами програмування та візуалізації системи
науково-технічних розрахунків MatLab [6, 7, 26]. З іншого боку, використання
об’єктно-орієнтованого підходу робить мову Python легкою для вивчення та

49
простою для розуміння. Зараз базові конструкції цієї мови вивчаються навіть
у школах та коледжах.
Крім цього, сьогодні мова Python ефективно використовується для
програмування програмованих мікроелектронних пристроїв та систем.
Зокрема, транслятори мови Python мають мікрокомп’ютери Raspberry та
Auderino. Через послідовний порт передавання даних USB відлагоджені
програми, написані мовою Python, передаються на мікрокомп’ютери та
використовуються для керування складною електронною апаратурою [27].
Також важливим фактором щодо привабливості використання мови
програмування Python у системі освіти та у наукових закладах є те, що
транслятори Python є безкоштовними та вільно поширюються через мережу
Internet. Python належить не до комерційного програмного забезпечення, а до
безкоштовного проекту вільних програм, який називається GNU [5]. Саме у
зв’язку з цим мова програмування Python є апаратно-незалежною та
кросплатформною системою. Зокрема, існують версії Python для
програмування під операційними системами Windows, UNIX, Linux та
MacOS [26]. Засновником та головним ідеологом концепції вільного
програмного забезпечення GNU вважається видатний американський
програміст Річард Столмен.

Річард Столмен
(нар. 1953)

Проте не завжди використання мови програмування Python є доречним,


ефективним та правильним як з технічної, так і з комерційної точки зору. Нижче
наведені найважливіші переваги та недоліки цієї мови програмування.

50
Серед переваг мови програмування Python над іншими мовами ООП,
призначеними для роботи з використанням клієнт-серверних технологій, фахівці
вважають наступні [25].
1. Головною перевагою мови програмування Python є її простота, яка
дозволяє легко розуміти та аналізувати програмний код.
2. Багатофункціональність мови Python, яка проявляється в тому, що
будь-яка програма пишеться один раз, а звертатися до неї можна багаторазово.
3. Лаконізм мови Python, який проявляється в тому, що програми, написані
на Python, зазвичай є коротшими, ніж програми, написані іншими мовами
програмування. Це дозволяє у значній мірі підвищити ефективність роботи
програмістів, оскільки, за статистикою, кількість рядків, які програміст пише за
один день, визначається його професійною кваліфікацією та рівнем зайнятості та
не залежить від мови програмування, яка використовується [26].
4. Мову Python можна вивчати послідовно, починаючи від простих занять
в школі [24, 25] до створення наукових проектів з моделювання складних
процесів, статистичного аналізу даних та машинного навчання [26].
5. Мова Python є крос-платформною, тобто, програми, написані цією
мовою, можуть використовуватись на будь-яких комп’ютерах, від
однокристальних мікрокомп’ютерів до величезних обчислювальних комплексів,
без зміни програмного коду.
6. Всі інтерпретатори мови Python є безкоштовними, що, у значний мірі,
знижує вартість програмних комплексів, які створюються з її використанням.
Серед недоліків мови програмування Python слід враховувати наступні її
особливості [25].
1. В більшості сучасних операційних систем, зокрема у системі Windows,
мова Python не встановлена за замовченням. У багатьох випадках для
встановлення або оновлення інтерпретатора мови Python слід використовувати
ресурси Інтернет [31, 32].
2. Якщо у програмі проводиться велика кількість обчислень,
інтерпретатори мови програмування Python можуть генерувати не настільки

51
швидкодійний код, як транслятори мов С, С++ та Java. Хоча, для більшості
програмних додатків, швидкодія програм, написаних мовою Python, є досить
високою.
Також слід мати на увазі, що у багатьох випадках ефективні рішення
задач програмування на Python є більш швидкодійними, ніж неефективні
рішення на більш складних мовах, таких як С, С++ або Java. З іншого боку,
ефективність програм, написаних низькорівневою мовою асемблер, є
високою лише за умови, що в них немає зайвих команд, а, враховуючи
складність цієї мови, писати такі ефективні програми вкрай важко [1]. А
асемблерний код у разі переходу з однієї апаратної платформи на іншу
частіше за все зазвичай необхідно ретельно аналізувати та переписувати, що
також ускладнює широке використання таких програм.
В цілому, менша ефективність програм, написаних на Python, пов’язана
лише з тим, що, для спрощення написання коду, більшість обчислень
переносяться в процедури. Доречи, саме таким чином побудована мова
програмування системи науково-технічних розрахунків MatLab [6,7], у цьому ці
дві системи програмування є дещо схожими. І тут слід мати на увазі, що
стандартні інтерпретатори мови Python написані відкритим кодом на мові
програмування С, що дозволяє професіональним програмістам підвищувати
швидкодію створених програм через зміну коду інтерпретатора та написання
власних додаткових процедур. Проте таку оптимізацію коду програми слід
робити дуже акуратно. Зазвичай не дуже висока ефективність коду пов’язана із
додатковими перевірками, які, з іншого боку, підвищують надійність роботи
програмних засобів.
Слід також відмітити, що Python – досить молода мова програмування, і
якість інтерпретаторів та ефективність машинного коду, який вони генерують,
постійно підвищується. На початковому етапі свого розвитку мова Java
вважалась вкрай повільною [23], а сьогодні, навпаки, інтерпретатори цієї мови
створюють дуже швидкодійні коди [12 – 14].
У будь-якому разі, простота мови Python та висока ефективність написання

52
програм на ній, а також орієнтація на кліент-серверні технології, незалежність від
апаратного та програмного забезпечення та безкоштовність компіляторів,
роблять цю мову все більш популярною серед програмістів. Нею із задоволенням
користуються як початківці, що лише починають освоювати ази програмування,
так і професіонали.
Як і для будь-яких програмних продуктів, існують різні версії
інтерпретаторів мови Python. Сьогодні для всіх користувачів стоїть вибір між
версіями Python 2 та Python 3 [25]. Python 2 – це класичний варіант мови, який
майже не змінюється та підтримує варіанти старого апаратного, системного та
програмного забезпечення. Якщо Вас задовольняє такий варіант – Вам треба
використовувати саме цю версію. Доречи, Python 2 завжди встановлювався на
комп’ютерах з операційною системою Linux [25]. Тобто, можна сказати, що це
правильне рішення для тих, хто програмує традиційними засобами та не
використовує новітні технології програмування. Відмінні риси цього
програмного продукту – висока надійність та підтримка старих інформаційних
технологій. Свого часу здавалося, що Python 2 – це дуже гарна мова та вона не
потребує суттєвих змін. Проте, зрозуміло, що ця мова не була ідеальною, згодом
в ній були знайдені помилки. Деякі з цих помилок були виправлені відразу без
значних зусиль, а деякі потребували суттєвих змін програмного коду. І тут
виявилося, що простіше переписати інтерпретатор цілком, ніж виправляти такі
складні помилки, з урахуванням того, що виправлення однієї помилки може
привести до появи іншої. Тому після версії 2.7 був створений зовсім новий
інтерпретатор Python 3. Тобто, без перебільшення можна сказати, що якщо
Python 2 – це історія та сьогодення, то Python 3 – це майбутнє у технологіях
програмування. Проте слід мати на увазі, що на застарілій техніці та із
застарілими програмними продуктами Python 3 може не працювати. Так що, у
будь-якому разі, рішення за вами, обирайте самі між традиційними та новітніми
технологіями програмування.

1.5 Філософія мови програмування Python


Мова програмування Python, як і будь яка інша мова програмування, має
свій характерний стиль та, можна сказати, свою парадигму, або, навіть точніше,
свою філософію. Доречи, це у деякій мірі притаманно із звичайним мовам,
53
зокрема, українській, англійській, німецькій, французькій та іншим. Слід
відзначити, що письменники та поети вважають, що часто сама мова, саме слово
спіткає людей на відповідний стиль спілкування та відповідну філософію
мислення. Замислюєшся над текстом, шукаєш потрібні слова – і ось, непомітно
для тебе, сама твоя думка стає глибшою та яскравішою. Як математика часто
спіткає вчених та інженерів на видатні відкриття, так філософія мови надає
натхнення письменникам та поетам та спіткає їх на подальший творчій пошук,
надає їм творчої наснаги.
А у програмуванні необхідно розв’язувати як точні, так і нестандартні
завдання, для яких поки не існує точних рішень. Сьогодні загальною концепцією
філософії програмування можна вважати теорію регулярних мов та теорію
скінченних автоматів, які базуються на основі дискретної математики та теорії
ймовірностей, але містять в собі значно більше, ніж строгі математичні
доведення [2]. Як вже було відмічено, концепція об’єктно-орієнтованого
програмування також базується на теорії скінченних автоматів.
Проте розробники мови Python пішли далі у цьому напрямку, зважаючи на
те, що сьогодні програмне забезпечення – це не лише реалізація вдало записаних
алгоритмів, але й засіб для створення красивих речей, зокрема витворів
мистецтва. Адже ж, за допомогою комп’ютерних програм композитори пишуть
музику, аранжувальники створюють цікаві музикальні композиції, а художники
малюють картини. Щодо письменників та поетів, то для них комп’ютер вже
давно став головним інструментом для набирання текстів. Тобто, можна без
перебільшення сказати, що сьогодні саме комп’ютер став найголовнішим
інструментом майже для всіх творчих особистостей. І головним принципом
інженерів, науковців та митців, які працюють із комп’ютером як з універсальним
інструментом, є не зміна окремих деталей проекту, а робота з об’єктами через
технології копіювання та вставлення. Творча людина відмічає об’єкт, змінює
його властивостей та, у разі необхідності, переміщує його в інше місце
загального проекту. Слід відзначити, що проектом у даному разі називають не
заплановані дії в бізнесі, а реалізацію нових ідей через творчу активність
особистості або колективу розробників.
Саме тому розробники мови програмування Python не лише створили

54
відповідні лінгвістичні конструкції з використанням методів та засобів теорії
ООП, але й сформулювали головні філософські принципи, яких бажано
дотримуватись, працюючи із цією системою. Будь-який інтерпретатор мови
Python завжди має файл під назвою this, який містить в собі головні принципи,
за якими формується філософія програмування цієї мови. Вони прості, лаконічні,
трішки жартівливі, проте їх легко зрозуміти. Сформулюємо їх наприкінці цього
підрозділу та будемо намагатися дотримуватися їх під час написання програм на
Python. Щоб прочитати ці принципи англійською мовою, достатньо в
інтерпретаторі набрати просту команду: import this. Команда import
пов’язана із завантаженням бібліотек та модульним програмуванням [6, 7].
Основи роботи з інтерпретатором мови Python розглядатимуться у підрозділах
2.1 та 2.2, а основи роботи із бібліотечними файлами та модулями – у підрозділі
2.5.4. У таблиці 1.1 наведені ці шістнадцять головних філософських принципів
мови програмування Python, англійською мовою, в оригіналі, та в українському
перекладі [24, 25].

Таблиця 1.1 – Головні філософські принципи мови програмування Python,


записані авторами у файлі this.py

№ Англійське речення Український переклад


1. Beautiful is better than ugly Красиве є кращим, ніж виродливе
2. Explicit is better than implicit Явне є кращим, ніж побічне
3. Simple is better, than complex Просте є кращим, ніж складне
Складне є кращим, ніж
4. Complex is better, than complicated
ускладнене
Однорівневе є кращим, ніж
5. Flat is better, than nested
вкладене
6. Spares is better, than dense Розряджене є кращим, ніж щільне
7. Readability count Читаність має значення
Особливі випадки є не настільки
Special cases aren’t special enough
8. особливими, щоб порушувати
to break the rules
загальні правила

55
Таблиця 1.1 – Головні філософські принципи мови програмування Python,
записані авторами у файлі this.py (продовження)

№ Англійське речення Український переклад


Практичність є важливішою за
9. Although practicality beat purity
бездоганність
Про помилки ніколи не можна
Errors should never pass silently.
10. замовчувати, якщо вони не
Unless explicitly silenced
замовчуються явно
Якщо Ви зустріли двозначність, не
In the face of ambiguity, refuse the
11. варто спокушати себе, що Ви
temptation to guess
вгадаєте вірне значення
There should be one – and Має існувати один – і бажано
preferable only one – obvious way лише один – очевидний спосіб
12. to do it. Although that way may not щось зробити, хоча спочатку він
be obvious at first unless you are для Вас може бути не очевидним,
Dutch якщо Ви не голландець
Краще зараз, ніж ніколи, хоча
Now is better than never. Although
13. ніколи іноді буває краще, ніж
never is often better than right now
відразу зараз
If the implementation is hard to Якщо реалізацію складно
14.
explain, it’s a bad idea пояснити, така ідея є поганою
If the implementation is easy to Якщо реалізацію легко пояснити,
15.
explain, it may be a good idea така ідея, можливо, є гарною
Простори імен – це дуже гарна
Namespaces are one honking great
16. ідея, тому варто створювати їх
idea – let’s do more of those!
побільше

У наступних розділах цього підручника ми побачимо, як ці філософські


принципи реалізуються на практиці під час написання програм мовою Python.

56
Контрольні питання та завдання до розділу 1

1. Які покоління мов програмування Вам відомі і як вони пов’язані із


історію розвитку обчислювальної техніки та засобів програмування? Наведіть
приклади мов програмування різних поколінь.
2. У чому полягає базова концепція ідеології структурного програмування
та на яких теоретичних засадах вона ґрунтується?
3. Як теорія структурного програмування пов’язана із теорією предикатів?
Свою відповідь обґрунтуйте.
4. Як теорія структурного програмування пов’язана із теорією регулярних
мов та скінченних автоматів? Свою відповідь обґрунтуйте.
5. У чому полягає велике практичне значення мови програмування С та
чому, починаючи з сімдесятих років ХХ століття, ця мова стає все більш
популярною?
6. На яких базових концепціях програмування побудована ідеологія
операційної системи UNIX?
7. У чому полягає базова концепція об’єктно-орієнтованого програмування
та на яких теоретичних засадах вона ґрунтується? Які мови об’єктно-
орієнтованого програмування Вам відомі?
8. Як базова концепція об’єктно-орієнтованого програмування пов’язана із
теорією регулярних мов та скінченних автоматів? Свою відповідь обґрунтуйте.
9. Що являє собою поняття об’єкту в теорії об’єктно-орієнтованого
програмування? Свою відповідь обґрунтуйте та наведіть приклади об’єктів.
Поясніть визначення 1.1.
10. Що являє собою поняття події в теорії об’єктно-орієнтованого
програмування? Свою відповідь обґрунтуйте та наведіть приклади подій.
Поясніть визначення 1.2.
11. Що являє собою поняття повідомлення в теорії об’єктно-орієнтованого
програмування? Свою відповідь обґрунтуйте та наведіть приклади повідомлень.
Поясніть визначення 1.3.
12. Що являє собою поняття агента в теорії об’єктно-орієнтованого
57
програмування? Чому цей термін рідко використовується в технічній галузі.
13. Що являє собою поняття середовища в теорії об’єктно-орієнтованого
програмування? Чому цей термін рідко використовується в технічній галузі.
14. Що являє собою поняття поля в теорії об’єктно-орієнтованого
програмування? Свою відповідь обґрунтуйте та наведіть приклади полів.
Поясніть визначення 1.4.
15. Що являє собою поняття метода в теорії об’єктно-орієнтованого
програмування? Свою відповідь обґрунтуйте та наведіть приклади методів.
Поясніть визначення 1.5.
16. Що являє собою поняття класу в теорії об’єктно-орієнтованого
програмування? Свою відповідь обґрунтуйте та наведіть приклади класів.
Поясніть визначення 1.6.
17. Які операції із класами вважаються базовими в теорії об’єктно-
орієнтованого програмування? Свою відповідь обґрунтуйте та наведіть приклади
таких операцій.
18. Чому в теорії об’єктно-орієнтованого програмування вважається, що
клас має інтерфейсну природу?
19. Що являє собою абстрагування даних у теорії об’єктно-орієнтованого
програмування? Поясніть визначення 1.7.
20. Що являє собою інкапсуляція в теорії об’єктно-орієнтованого
програмування? Поясніть визначення 1.8.
21. Що являє собою успадкування в теорії об’єктно-орієнтованого
програмування? Поясніть визначення 1.9.
22. Що являє собою батьківський клас у теорії об’єктно-орієнтованого
програмування? Поясніть визначення 1.10.
23. Що являє собою дочірній клас у теорії об’єктно-орієнтованого
програмування? Поясніть визначення 1.11.
24. Що являє собою поліморфізм у теорії об’єктно-орієнтованого
програмування? Поясніть визначення 1.12.
25. Що являє собою поняття аспектів у теорії об’єктно-орієнтованого

58
програмування? Поясніть визначення 1.13.
26. Що являють собою мови програмування четвертого покоління? Які
мови програмування четвертого покоління Вам відомі?
27. Як головні принципи об’єктно-орієнтованого програмування можна
пояснити через формулювання питань та відповіді на них? Наведіть власні
приклади таких діалогів.
28. Поясніть приклад 1.1 та діаграму, яка наведена на рис. 1.1.
29. Як теорія об’єктно-орієнтованого програмування пов’язана із
класифікацією електронних приладів? Поясніть приклад 1.2 та діаграму, яка
наведена на рис. 1.2.
30. Наведіть приклади класифікації електронних приладів за іншими

ознаками, не пов’язаними із класифікацією, наведеною на рис. 1.2.

31. Поясніть, як Ви розумієте жартівливі ілюстрації, які наведені на


рис. 1.3, та підписи на цих ілюстраціях. Як ці принципи можуть бути використані
під час написання складних програмних комплексів?
32. Що являє собою ієрархія класів та спосіб формування запитів про
властивості об’єкту з точки зору теорії скінченних автоматів? Наведіть власні
приклади формування запиту через ієрархію класів та нарисуйте відповідну
схему скінченного автомата.
33. Чим відрізняється послідовна та паралельна ієрархія класів з точки
зору способу формування запиту? Свою відповідь обґрунтуйте та наведіть
доречні приклади формування запитів у системах із послідовою та паралельною
ієрархією класів?
34. У якому випадку, послідовної чи паралельної ієрархії, можна вважати,
що об’єкт належить двом незалежним класам? Свою відповідь обґрунтуйте та
наведіть доречні приклади такого успадкування властивостей об’єкта.
35. У якому випадку, послідовної чи паралельної ієрархії, можна вважати,
що об’єкт належить двом залежним класам? Свою відповідь обґрунтуйте та
наведіть доречні приклади такого успадкування властивостей об’єкта.

59
36. Чим відрізняється спосіб передавання запиту про властивості об’єкта
для послідовної та паралельної ієрархії класів? Свою відповідь обґрунтуйте та
наведіть доречні приклади передавання запитів для обох випадків.
37. Поясніть схеми скінчених автоматів, наведені на рис. 1.4.
38. Поясніть блок-схему алгоритму, наведену на рис. 1.5.
39. Поясніть блок-схеми алгоритмів пошуку інформації за запитом,
наведені на рис. 1.6 та 1.7.
40. Що являє собою поняття клієнта у теорії комп’ютерних мереж?
Поясніть визначення 1.14.
41. Що являє собою поняття сервера у теорії комп’ютерних мереж?
Поясніть визначення 1.15.
42. Що являють собою клієнт-серверні технології у сучасній теорії
програмування, з урахуванням розвитку мережі Інтернет? Наведіть власні
приклади алгоритмів роботи програм, які використовують клієнт-серверні
технології.
43. Які мови програмування, в яких використовуються клієнт-серверні
технології, Вам відомі?
44. Які базові концепції програмування були закладені розробниками в
мову програмування Python?
45. Чому мова програмування Python вважається простою і легкою для
вивчення, незважаючи на те, що на ній можна писати досить складні
програмні проекти?
46. Назвіть голові переваги мови програмування Python, через які вона
сьогодні стає все більш популярною?
47. У чому полягає кросплатформність мови програмування Python?
48. У чому полягає багатофункціональність мови програмування Python?
50. У чому полягає лаконізм мови програмування Python?
51. До якого класу програмного забезпечення, коштовного чи
безкоштовного, належать інтерпретатори мови програмування Python?
52. Назвіть голові недоліки мови програмування Python, та вкажіть, для

60
якого програмного забезпечення цю мову не варто використовувати?
53. Чому сьогодні вважається, що інтерпретатори мови програмування
Python створюють не дуже швидкодійний програмний код?
54. Проведіть порівняльний аналіз мов програмування Python, С++ та
асемблер. Для яких програмних проектів варто використовувати кожну із цих
мов? Свою відповідь обґрунтуйте.
55. Проведіть порівняльний аналіз мови програмування Python та мови
програмування системи науково-технічних розрахунків MatLab. Для яких
програмних проектів варто використовувати кожну із цих мов? Свою
відповідь обґрунтуйте.
56. Що являє собою закритий та відкритий програмний код? Наведіть
приклади операційних систем та комп’ютерних програм, написаних з
використанням закритого та відкритого програмного коду.
57. Яким програмним кодом, закритим чи відкритим, написані
інтерпретатори мови програмування Python?
58. Проведіть порівняльний аналіз другої та третьої версії мови
програмування Python. У яких випадках бажано використовувати другу, а у
яких – третю версію цієї мови програмування?
59. Як Ви розумієте таке поняття, як «філософія мови»?
60. Чи можна вважати теорію скінченних автоматів основою філософії
мов структурного програмування? Свою відповідь обґрунтуйте.
61. Чи можна вважати теорію скінченних автоматів основою філософії
мов об’єктно-орієнтованого програмування? Свою відповідь обґрунтуйте.
62. Чи існує філософія людських мов, наприклад, української,
англійської, німецької, французької, іспанської або арабської мови? У чому,
на ваш погляд, полягає філософія української мови?
63. Чи може бути передана філософія людської мови через вірші або
через прозаїчні твори? Наведіть приклади літературних творів, які, на Ваш
погляд, вірно та досконало передають філософію української мови?

61
64. У якому випадку для створення програмного забезпечення достатньо
знати теорію скінченних автоматів, а коли важливішими є більш глибокі
філософські принципи? Свою відповідь обґрунтуйте.
65. Чому сьогодні персональний комп’ютер стає ефективним інструментом
не лише для математиків та інженерів, але й для творчих особистостей, які
працюють в гуманітарній галузі, зокрема поетів, музикантів, художників? Свою
відповідь обґрунтуйте. Які програмні продукти для створення картин, анімацій,
кінофільмів або музикальних творів Вам відомі?
66. Поясніть філософські принципи мови програмування Python, наведені
у підрозділі 1.5. Які з цих принципів, на Ваш погляд, є суперечливими або
невірними? Наведіть власні приклади з Вашого життя, коли ці принципи
виконувались, або навпаки, не виконувались.
67. Зіграйте з одногрупниками у ділову гру. Один студент висловлює
один із шістнадцяти філософських принципів мови Python англійською
мовою, а другий дає його український переклад. Якщо студент, який
перекладав, дав вірну відповідь, тоді його черга висловлювати інший
принцип англійською мовою, а якщо він переклав неточно – тоді перший
студент висловлює один із інших шістнадцяти принципів. Перемагає той
студент, який дасть більше вірних відповідей.
68. Організуйте диспут, завданням якого є обсудити філософські
принципи мови програмування Python, наведені у підрозділі 1.5. Для
проведення диспуту розділіть групу на дві рівних команди. Представники
першої команди протягом диспуту повинні відстоювати ці філософськи
принципи, а представники другої команди – їх заперечувати. На обговорення
кожного із положень цих принципів дається не більше п’яти хвилин.

62
Розділ 2. Базові принципи мови програмування Python та способи
розв’язування простих обчислювальних задач
У цьому розділі розглядаються основи роботи з інтерпретатором мови
Python, зокрема,способи формування арифметичних виразів, математична
бібліотека,способи описання функцій користувача, формування власних
файлів та модулів, а також функції мови Python для роботи із рядковими
даними. Розглянуті основи роботи з інтерпретатором через систему
команд та засоби створення власних функцій з використанням графічної
оболонки IDLE. Окрема увага приділяється операціям над рядками та
функціям, призначеним для роботи з ними. Як приклад написання
програмного модуля розглянуті конвертори фізичних та інформаційних
величин.

2.1 Встановлення та запуск інтерпретатора мови Python на


персональному комп’ютері

Зрозуміло, що версія інтерпретатора Python, яку Ви можете встановити


на своєму персональному комп’ютері, залежить від його апаратного та
системного забезпечення. Слід відзначити, що під операційними системами
OS X, Linux та UNIX зазвичай вже встановлений інтерпретатор Python 2, а
під операційною системою Windows в початковій її інсталяції інтерпретатора
Python взагалі немає, його необхідно встановлювати окремо. Тому
розглянемо послідовні кроки, які слід виконати для встановлення на
персональному комп’ютері інтерпретатора мови Python версії 3 [25].
1. Визначити, яка із версій Python вже встановлена на Вашому
комп’ютері. Якщо жодна із версій не встановлена, слід завантажити одну із
інсталяцій, розташованих на сайті [33].
2. Після завантаження сторінки офіційного сайту Python [33],
комп’ютер спробує визначити тип встановленої операційної системи та
підібрати версію Python, яка найбільше підходить для Вашого комп’ютера.
Якщо Ви шукаєте собі найкращу версію Python для ОС Windows, можна
спростити задачу пошуку, заходячи відразу на сторінку з інсталяціями
інтерпретаторів Python саме для цієї операційної системи [34]. На екрані
з’явиться Інтернет-сторінка, аналогічна тій, яка показана на рис. 2.1.
3. На цій сторінці, біля версії інтерпретатора мови Python, яку Ви
вважаєте за найкращу для себе, натисніть мишею на гіпертекстове посилання
«Download» (Завантажити).
4. Після переходу за цим посиланням Ви побачите сторінку, на якій
знайдете інформацію щодо деталей завантаження та встановлення відповідного
інтерпретатора, аналогічну наведеній на рис. 2.2. Прочитавши її до кінця, Ви
побачите посилання на завантаження відповідного файлу. Нижня частина
інформаційного вікна наведена на рис. 2.3.

63
Рис. 2.1. Інтернет-сторінка для з інформацією про останні версії Python [33]
(екранна копія)

Рис. 2.2 Інтернет-сторінка для завантаження обраної версії Python 3.7.1


(екранна копія)
64
Рис. 2.3 Нижня частина Інтернет-сторінки для завантаження версії Python
3.7.1, де можна обрати найкращу конфігурацію цього інтерпретатора для
Вашого комп’ютера (екранна копія)

У такий спосіб встановлюються базові функції та бібліотеки


інтерпретатора мови програмування Python для ОС Windows. Якщо ви
користуєтеся іншими операційними системами, наприклад, Unix або Linux,
інтерпретатор Python версії 2 має бути вже встановленим на вашому
комп’ютері. Відповідні інструкції щодо інсталяції мови програмування Python
версії 3 для цих операційних систем можна знайти в підручнику [25] або на
офіційному сайті розробників інтерпретаторів мови Python [33].
Для розробників програмних додатків для наукових досліджень бажано
також встановити розширені бібліотеки системи програмування Python, які
називаються Anaconda. Anaconda – це розширений інструментарій мови
програмування Python, призначений для рішення серйозних наукових задач.
Попередня версія Anaconda була орієнтована на Python 2, хоча й була
65
можливість встановити також інтерпретатор Python третьої версії. Оновлений
пакет Anaconda 2.0 орієнтований вже на останню версію інтерпретатора
Python [25]. Серед великої кількості бібліотек Anaconda, призначених для
проведення наукових розрахунків, найбільш важливими є наступні [26]:
NumPy – стандартні засоби описання структур даних, зокрема
одномірних та багатомірних масивів;
Pandas – розширені засоби програмування для роботи із
структурованими даними;
Matplotlib – засоби графічної візуалізації результатів обчислень;
Scikit-Learn – засоби машинного навчання, основані на методах
математичної статистики.
Існує дистрибутив системи програмування Anaconda в двох варіантах –
скорочений варіант Miniconda [32] та розширений варіант Anaconda, із
більшою кількістю стандартних функцій для проведення наукових
розрахунків [35]. Версія Python, яка використовується у системі
програмування Anaconda, дещо відрізняється від стандартної версії та
називається Ipython [26]. Інтернет-сторінки, на яких розташовані посилання
для завантаження пакетів Anaconda та Miniconda, показані на рис. 2.4 та 2.5.

Рис. 2.4 Інтернет-сторінка для завантаження системи Anaconda [35] (екранна


копія)

66
Рис. 2.5 Інтернет-сторінка для завантаження системи Miniconda [32] (екранна
копія)

Також слід відзначити, що інтерпретатор мови Ipython вже вбудований


в інсталяції системи Anaconda, тому вона не потребує встановлення базового
інтерпретатора мови Python, а ставиться на комп’ютер окремо. Оскільки
Python є крос-платформною мовою програмування, програми, написані на
мові Python останньої версії, можна запускати також у системі Anaconda.
Інсталяційні пакети системи Anaconda строї версії, орієнтованої на
Python 2, зазвичай називаються просто Anaconda, а пакети нової версії –
Anaconda3 [25].
Anaconda встановлюється на комп’ютері у власній папці з ім’ям
Anaconda, і це означає, що, по-перше, вона ніяк не пов’язана із іншими
версіями Python, встановленими на тому ж комп’ютері, а по-друге, що
користувач системи Anaconda не повинен мати прав адміністратора для

67
встановлення цієї системи та для роботи з нею. Документація до пакету
Anaconda міститься на сайті [36].
Для тих програмістів, які не бажають встановлювати Anaconda,
альтернативним рішенням є використання разом із Python пакетів
розширення pip та virtualenv [25, 37, 38]. Прочитати досконале описання
можливостей цих пакетів та знайти відповідні інсталяції можна на сайтах [37,
38]. Вікна Інтернет-сторінок [37, 38] показані на рис. 2.6 та 2.7.

Рис. 2.6 Інтернет-сторінка [37] з інформацією про пакети розширення pip та


virtualenv (екранна копія)

Після встановлення необхідної версії інтерпретатора для початку


роботи з ним достатньо набрати командний рядок python або натиснути на
іконку графічного інтерфейсу Windows, яка відповідає файлу python.exe [25].

68
Рис. 2.7 Інтернет-сторінка [38], яку можна використовувати для встановлення
пакету розширення pip (екранна копія)

Тоді на екрані з’являється наступний текст.


Python 3.4.0 (v3.4.0:04f714765c13, Mar 16 2014, 19:24:06)
[MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more
information.
>>>
Для версії Python 3 існує більш зручний інтерпретатор із графічною
оболонкою, який називається IDLE (абревіатура англійських слів Integrated
Development and Learning Environment – Інтегроване середовище для
розробки та навчання), призначений для написання власних програмних
модулів [24]. Структура віконного інтерфейсу цієї програми та основи роботи з
нею розглядатимуться у підрозділі 2.5.1.
Спосіб запуску інтерпретатора Python з командним рядком та графічної
оболонки IDLE через віконний інтерфейс ОС Windows показаний на рис. 2.8.

69
Рис. 2.8 Запуск інтерпретаторів Python із командним рядком та із оболонкою
редагування файлів через командне меню ОС Windows (екранна копія)

Слід відзначити, що робота з інтерпретатором мови програмування Python


дуже схожа на роботу з інтерпретатором команд системи науково-технічних
розрахунків MatLab [6, 7]. Основи роботи з інтерпретатором Python у режимі
командного рядка будуть розглянуті у наступному підрозділі цього
посібника.
Важливим є те, що інтерпретатор мови програмування Python працює
70
як віртуальна машина [24, 25]. З практичної точки зору це означає, що його
робота не залежить від особливостей операційної системи, тобто, Ваші
програми, написані на Python, без проблем будуть працювати на різних
апаратних платформах в різних операційних системах. У цьому і полягає
одна із важливих переваг відкритого коду програм та проекту вільного
програмного забезпечення GNU [5, 41].

2.2 Початок роботи з інтерпретатором Python та прості


арифметичні розрахунки
Як вже було відмічено, інтерпретатор мови програмування Python дуже
схожий на інтерпретатор мови науково-технічних розрахунків MatLab. Якщо не
вводити імен змінних, інтерпретатор Python можна використовувати як
звичайний калькулятор [24, 25]. Наведемо відповідні приклади такого
використання інтерпретатора Python.
Приклад 2.1
>>> 10 + 5
15
>>> 10.0 + 5
15.0
>>> res = 10.0 + 5
>>> res
15.0
>>> res + 10
25.0
>>> _ + 25
50.0
>>>
Розглянемо головні правила записування командних рядків в інтерпретаторі
мови програмування Python, які, дійсно, є схожими на командні рядки мови
програмування системи науково-технічних розрахунків MatLab [6, 7].

71
1. Командний рядок починається з запрошення до введення команди, яке в
інтерпретаторі Python позначається символом >>> (три знаки «більше»).
2. Якщо виразу не присвоєно ім’я змінної, значення цього виразу
виводиться у наступному рядку. У цьому випадку запрошення до введення
команди переноситься на рядок, який іде після виведення результату обчислень.
Слід відзначити, що, на відміну від системи науково-технічних розрахунків
MatLab [6, 7], за замовченням ім’я змінної ans обчисленому виразу не
присвоюється. Крім цього, в кінці командного рядка не ставиться крапка з
комою. Виведення результатів обчислень в інтерпретаторі мови
програмування Python здійснюється за замовченням наступним чином: якщо
виразу присвоєно ім’я змінної, результат обчислень виводиться на екран, а у
противному випадку – не виводиться. Правила формування імен змінних у
мові програмування Python розглядатимуться у наступному підрозділі.
3. В інтерпретаторі Python передбачене визначення типів числових
даних за замовченням, яке здійснюється наступним чином. Якщо у запису
числа не стоїть крапка, це число вважається цілим, а якщо стоїть – дійсним.
Проте формат виведення чисел на екран у мові програмування Python може
бути визначений окремо, відповідні функції інтерпретатора розглядатимуться
у підрозділі 2.5 цього підручника.
4. Для позначення останнього отриманого результату обчислень замість
ім’я змінної ans можна використовувати символ нижнього підкреслення _.
5. Робота з комплексними числами у мові програмування Python також
передбачена, відповідні оператори та функції розглядатимуться у підрозділі 2.4.7.
Головними арифметичними операціями, які визначені у мові
програмування Python, є наступні: + – додавання; – – віднімання; * –
множення; ** – піднесення до степені; / – ділення, результатом виконання цієї
операції завжди є дійсне число; // – ділення з округленням вниз, результатом
виконання цієї операції завжди є ціле число; % – остача від ділення. Також в
Python існує низка спеціальних арифметичних операцій над дійсними
числами, запозичених із мови програмування С. Це такі операції [24, 25]:

72
+= n – збільшення значення числа або змінної на величину n;
–= n – зменшення значення числа або змінної на величину n;
*= n – множення значення числа або змінної на величину n;
/= n – ділення значення числа або змінної на величину n;
//= n – ділення з округленням вниз значення числа або змінної на
величину n;
%= n – остача від ділення числа або змінної на величину n.
Розглянемо відповідний приклад, у якому використовуються такі операції:
Приклад 2.2
>>> a = 3
>>> a += 2
>>> a
5
>>> a –= 6
>>> a
>>> –1
>>> a += 10
>>> a
9
>>> a /= 3
>>> a
3.0
>>> a *= 5
>>> a
15.0
>>> a //= 3
>>> a
5
>>> a %= 3
>>> a

73
2
>>> a + 2
>>> _
4
>>> a
2
>>>
Із приклада 2.2 чітко зрозуміло, чим відрізняється арифметичний вираз
a + 2 від виразу a += 2. Якщо записаний вираз a + 2, значення змінної a
не змінюється, а результат обчислень можна подивитися через посилання за
змінну _ (нижнє підкреслення). На відміну від цього, вираз a += 2 змінює
значення змінної a. Зазвичай у різних мовах структурного програмування замість
виразу a += 2 пишуть a = a + 2, ці два вирази є еквівалентними. Вираз
a += 2 є трішки коротшим та відповідає стилю програмування мов С, Java та
Python, хоча запис a = a + 2 у цих мовах програмування також
допускається [3, 23, 25, 26, 37, 38]. Більш досконало способи визначення змінних
та роботи з ними будить розглянуті у наступному підрозділі.
Окремо у мові програмування Python розглядається обробка виключних
ситуацій, або помилки програмування. З точки зору теорії скінченних
автоматів такі ситуації відповідають невизначеному стану автомата та їх під
час написання програм слід обробляти окремо. У разі використання
розглянутих вище арифметичних операторів мови Python можливі наступні
виключні ситуації [24, 25].
1. Посилання на ім’я невизначеної змінної.
2. Ділення на нуль.
Зазвичай у такому разі інтерпретатор мови Python формує відповідне
повідомлення про помилку розрахунків:
Traceback (most recent call last):
File <stdin>, line 1, in <module>
Далі, в наступних рядках, іде описання відповідної помилки.

74
Можливі помилки програмування та повідомлення інтерпретатора, які їм
відповідають, наведені у наступному прикладі.
Приклад 2.3
>>> a = 3
>>> s
Traceback (most recent call last):
File <stdin>, line 1, in <module>
s
NameError: name “s” is not defined
>>> a / 0
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ZeroDivisionError: division by zero
>>> a % 0
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ZeroDivisionError: division by zero
>>> a // 0
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ZeroDivisionError: division by zero
a /= 0
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ZeroDivisionError: division by zero
Слід також відзначити, що, на відміну від стандартів відомих мов
структурного та об’єктно-орієнтованого програмування, зокрема мов С, С++ та
Java, у мові програмування Python передбачена можливість виклику функцій
через структуровані дані та присвоєння змінним значення структури через
виклик функції. Відповідні засоби роботи із функціями також запозичені у

75
Python із системи науково-технічних розрахунків MatLab [6, 7] та будуть
розглянуті у підрозділі 2.5 цього посібника. У теорії програмування
структури даних, які є результатом роботи функцій, називаються кортежами.
Визначення кортежів та способи роботи з ними через виклик функцій
розглядатимуться у підрозділі 4.3.
Як було показано у навчальних посібниках [6, 7], використання
структурованих даних для виклику функцій та для повернення результату їх
виконання вкрай спрощує методологію структурного програмування та
дозволяє уникнути використання поняття процедури, притаманного таким
мовам програмування, як С, FORTRAN та Pascal.
Розглянемо цікавий приклад, який наочно ілюструє ефективність
використання структурованих масивів числових даних під час проведення
арифметичних обчислень через виклик функції.
Приклад 2.4
>>> a = 11
>>> a //= 3
>>> a
3
>>> a %= 3
>>> a
2
>>> divmod(a,2)
(3,2)
З аналізу наведеного прикладу видно, що одна арифметична функція
divmod, яка викликається через структуровані числові дані та повертає іншу
впорядковану структуру, дозволяє замінити дві арифметичні операції, а саме,
цілочислене ділення та взяття остачі. Інший спосіб проведення таких обчислень,
без використання структур – це послідовне виконання дій ділення та взяття
остачі, що у значній мірі ускладнює програмний код.

76
2.3 Змінні та типи змінних
Важливою відмінністю мови Python від інших мов програмування є те,
що всі змінні, зокрема числові, у ній за замовченням визначаються як
відповідні об’єкти. Тобто, будь-яка змінна – це посилання на об’єкт.
Об’єкт у мові Python завжди має відповідний тип, який визначає, що
можна робити з цими даними. Тип даних можна описувати явно, але зазвичай
він правильно визначається за замовченням. Проте, якщо не вказувати тип
даних, а вважати, що він буде визначений за замовченням, необхідно
дотримуватись відповідних правил.
Повернемося до прикладів 2.1 та 2.2. Якщо проаналізувати їх більш
досконало з точки зору узгодження типів цілого та дійсного числа, можна
сформулювати наступні властивості типів, які притаманні мові програмування
Python. Ці властивості формуються на основі теорії регулярних мов та
відомих аксіом теорії чисел [2, 42].
Властивість 2.1 Якщо число складається лише із цифр, воно
вважається натуральним.
Властивість 2.2 Якщо перед числом стоїть знак «–», воно вважається
від’ємним. Сукупність натуральних та від’ємних чисел формує множину
цілих чисел, якій відповідає тип цілого числа int.
Властивість 2.3 Всі арифметичні дії над цілими числами, крім
операцій ділення та піднесення до степені, дають в результаті ціле число.
Властивість 2.4 Якщо у запису числа між цифрами стоїть крапка,
таке число вважається раціональним. Раціональним числам відповідає тип
даних float.
Властивість 2.5 Якщо під час проведення арифметичних операцій
над числами хоча б одне із них є раціональним, результатом виконання цієї
операції буде раціональне число.
Наприклад, 15 – ціле число, а 15.0 – раціональне число.
Властивість 2.6 Результатом ділення двох цілих чисел є раціональне
число.

77
Властивість 2.7 Якщо показник степені є натуральним числом,
результатом піднесення цілого числа до цієї степені завжди буде ціле число.
Властивість 2.8 Якщо показник степені є від’ємним цілим числом,
результатом піднесення цілого числа до цієї степені завжди буде раціональне
число.
Зрозуміло, що властивість 2.7 є наслідком властивості 2.3, а властивість
2.8 – наслідком властивості 2.6.
Властивість 2.9 Результатом цілочисленого ділення двох цілих чисел
завжди є ціле число.
Властивість 2.10 Результатом взяття остачі від ділення двох цілих
чисел завжди є ціле число.
Розглянемо наступний приклад, у якому більш досконало показані
можливості використання властивостей 2.1 – 2.10 під час програмування в
інтерпретаторі мови Python.
Приклад 2.5
>>> a = 3
>>> b = a + 2
>>> b
5
>>> c = b**3
>>> c
125
>>> d = b**(-3)
>>> d
0.008
>>> f = 1/c
>>> f
0.008
>>> e = c/5
>>> e
25.0
78
>>> g = c//5
>>> g
25
>>> h = g % 4
>>> h
1
>>>
Описання числових змінних у мові програмування Python як об’єктів із
відповідними властивостями має свої певні переваги [25]. Теоретичні
відомості, розглянуті у розділі 1, свідчать про те, що об’єкти та їхні класи
вводять до структури програми додаткову систематизацію. В принципі,
Python у технічній літературі розглядається як мова із строгою типізацією,
тобто, якщо змінюється значення змінної, тип об’єкта не змінюється. Проте
можуть існувати такі методи, які створюють новий об’єкт на основі
батьківського та змінюють його тип. Наприклад, для об’єктів типа int
такими методами є операції ділення та піднесення до степені. А значення
змінної розглядається як властивість об’єкта. Наприклад, якщо у прикладі 2.5
записаний вираз a = 3, це означає що об’єкту з ім’ям a присвоєно значення
3. Тут a – ім’я об’єкта, тип цього об’єкта – int, а значення 3 – його
властивість. Проте операції ділення або піднесення до від’ємної степені
можуть змінити тип нового об’єкта на float – дійсне число. Наприклад,
об’єкт з ім’ям b є результатом арифметичної операції додавання b = a + 2.
Тому цей об’єкт, згідно із ієрархією успадкування та властивістю 2.3, має тип
int, як і об’єкт a. Об’єкт c визначається як c = b**3. Оскільки об’єкт b
має тип int, а число 3 – натуральне, згідно із ієрархією успадкування та
властивістю 2.7 об’єкт c також має тип int. Тепер розглянемо об’єкт e, який
визначений арифметичним виразом e = c/5. З одного боку, результатом
виконання цієї операції ділення може бути ціле число. Дійсно,
c/5 = 125/5 = 25. Але оскільки у виразі e = c/5 стоїть операція
ділення, результатом виконання цієї операції, згідно із властивістю 2.6, буде
не ціле, а дійсне число типа float. Тобто, змінні, або об’єкти з іменами a, b
79
та c мають тип int, а успадкований від них об’єкт e – це вже об’єкт типа
float, який має значення 25.0.
Механізм наслідування об’єктів, яким відповідають ім’я змінних, у мові
Python є дуже простим та реалізований наступним чином. Коли вводиться
ім’я першої змінної, наприклад, a, інтерпретатором створюється відповідний
об’єкт з ім’ям id1, і через цей ідентифікатор робиться посилання на комірку
пам’яті, де розташований відповідний об’єкт. Згідно із властивостями 2.1 –
2.10 визначається тип цього об’єкту. Об’єкт, який описує просту числову
змінну, містить всього два поля: ім’я змінної та її значення. Значення змінної
характеризує властивість об’єкта. Якщо створюється інший об’єкт,
наприклад, змінна b, йому буде відповідати ідентифікатор id2, і так далі.
Наприклад, для розглянутих змінних a, b, c та e ієрархія успадкування
об’єктів, а також методи їх створення, тип та поля, показана у таблиці 2.1. У
даному, простому випадку, ієрархія об’єктів є стандартною та визначається
інтерпретатором автоматично: id1 → id2 → id3 → id4. Тобто, згідно із
властивостями 1.9 та 1.10, наведеними у підрозділі 1.2, об’єкт id1 належить
батьківському класу, об’єкт id2 – першому дочірньому класу, об’єкт id3 –
другому дочірньому класу, а об’єкт id4 – третьому дочірньому класу.
Ієрархія наслідування класів для цього випадку є послідовною.
Таблиця 2.1 – Ієрархія об’єктів, які відповідають іменам змінних,
визначених у прикладах 2.5 та 2.6
Поля об’єкта
Ім’я
Метод створення Тип Ім’я
об’єкту Значення
змінної
id1 a = 3 int a 3
id2 b = a + 2 int b 5
id3 c = b**3 int c 125
id4 e = c/5 float e 25.0
id5 a = 2 int a 2

80
Розглянемо тепер інший приклад, для якого ієрархія класів, що
відповідають іменам змінних є більш складною.
Приклад 2.6
>>> a = 3
>>> b = a + 2
>>> b
5
>>> c = b**3
>>> c
125
>>> e = c/5
>>> e
25.0
>>> a += 2
>>> a
5
>>> a = 2
>>> a
2
>>>
У розглянутому прикладі 2.6 значення змінної a спочатку, з
використанням арифметичного виразу a += 2 збільшується на 2. Тут іде
посилання на вже створений об’єкт id1 із зміною поля «Значення». Проте
наступний оператор присвоювання a = 2 не буде посилатися на ідентифікатор
об’єкта id1, він створить новий об’єкт id5. Відповідні зміни ієрархії об’єктів
також відображені у таблиці 2.1. Проте інтелектуальний інтерпретатор мови
Python відразу зрозуміє, що посилання на об’єкт з ім’ям id1 вже відсутнє,
видалить його поля та звільнить відповідні комірки оперативної пам’яті.
Зробити посилання на об’єкт, якому відповідає визначена змінна, в
інтерпретаторі мови програмування Python можна двома різними способами
[24, 25].
Найпростіший з них – це набрати команду інтерпретатора type(VN),

81
де VN – ім’я змінної, тип якої аналізується. У цьому випадку інтерпретатор
видає інформацію про тип змінної VN. Можна послатися на створений об’єкт
іншим чином, через команду id(VN). У цьому разі інтерпретатор видає
інформацію про номер комірки пам’яті, в якій розташований даний об’єкт.
Розглянемо приклади використання цих команд.
Приклад 2.7
>>> a = 3
>>> b = a + 2
type(a)
<class ‘int’>
type(b)
<class ‘int’>
>>> id(a)
194793612
>>> id(b)
1647398712
>>>
Проте слід відзначити, що навіть посилання на властивості об’єктів, не
кажучи вже про комірки оперативної пам’яті, в яких розташовані відповідні
змінні, в Python майже не використовуються. Тут працює важливе загальне
правило ООП про абстрагування даних та виключення із розгляду другорядної
інформації, яке було сформульоване у визначенні 1.7. Зазвичай користувачі
працюють із Python як із простою та лаконічною мовою та використовують
лише посилання на змінні через визначені імена. Властивості об’єктів, які
цим змінним відповідають, у цьому випадку вважаються скритими. А тоді
командні рядки, наведені у прикладах 2.1 – 2.6, майже нічим не
відрізняються від простих та зрозумілих команд мови програмування
MatLab [6, 7]. Саме тому сьогодні мова програмування Python стає
популярною не лише для роботи з базами даних та створення Інтернет-
додатків [12 – 14], але й для рішення складних задач моделювання та для
обробки статистичних даних [26].
У мові Python, як і в більшості інших мов програмування, існують

82
відповідні домовленості щодо можливостей використання імен змінних.
Загальні правила формування імені змінної є наступними [25].
1. Імена змінних повинні складатися лише з таких символів:
– латинські літери верхнього регістру (від «A» до «Z») та
нижнього регістру (від «a» до «z»), інтерпретатор Python
розрізняє великі та малі латинські літери;
– цифри, від 0 до 9;
– нижнє підкреслення.
2. Імена змінних не можуть починатися з цифри.
3. Інтерпретатор Python особливо обробляє імена, які починаються з
символу нижнього підкреслення, тому цей символ також не може стояти в
імені першим.
4. Як імена змінних не можна використовувати зарезервовані слова
мови Python. Список зарезервованих слів наведений у таблиці 2.2
Приклади коректних та некоректних імен змінних наведені у таблиці 2.3.
Таблиця 2.2 – Зарезервовані слова мови Python, розташовані за абеткою [24, 25]
and as assert break class continue
def del elif else except exec
finally for from global if import
in is lambda nonlocal not or
pass raise return try while with
yield True False None – –

Таблиця 2.3 – Коректні та некоректні імена змінних у мові Python

Коректні імена Некоректні імена


a 1_a
a1 q@
a_b_c_95 while
a_1 as

83
2.4 Математична бібліотека Python та математичні функції
2.4.1 Бібліотека математичних функцій мови Python та доступ до неї
Як було вже відмічено, за останні роки Python, разом із системою
науково-технічних розрахунків MatLab, а також C, Java та іншими мовами
програмування, стає однією із самих популярних систем в академічному
середовищі. Крім системи Anacoda, створеної на базі IPython, можливості
якої у підрозділі 6.3 розглядатимуться окремо, у базовій версії Python також
розроблена потужна стандартна бібліотека математичних функцій math.
Прочитати описання цих функцій в Інтернет можна на сторінці [43].
Для підключення цих бібліотек до інтерпретатора достатньо ввести
команду import math, а потім посилатися на ці функції із зазначенням
імені бібліотеки перед іменем функції, при цьому імена бібліотеки та функції
розділяються точкою. Таке звернення до бібліотек у мові Python є
стандартним.

2.4.2 Константи та базові функції для роботи з цілими та дійсними


числами
Головними математичними константами, визначеними у бібліотеці math
мови програмування Python, є значення е = 2.17... та π = 3.14... .
Розглянемо приклад, в якому ці константи використовуються для
проведення математичних обчислень.
Приклад 2.8
>>> import math
>>> math.pi
3.141592653579793
>>> math.e
2.718281828459045
>>> R = 5
>>> S = math.pi*R**2
>>> S
78.53981633974483
>>> T = math.e**2
>>> T
7.38905609893065
84
>>>
Слід відзначити, що необхідність визначення ім’я бібліотеки math
залежить від версії інтерпретатора. В деяких версіях, наприклад, в графічній
оболонці IDLE на базі версії Python 3, можна імпортувати не бібліотеки, а окремі
функції, у цьому разі слід просто вказувати ім’я функції [24]. Список інших
важливих базових функцій бібліотеки math для роботи з цілими та дійсними
числами наведений у таблиці 2.4 [24, 25]. Також необхідність посилання на ім’я
бібліотеки залежить від способу підключення функцій. Можливі засоби
підключення функцій та модулів розглядатимуться у підрозділі 2.5.4.
Розглянемо приклад використання математичних функцій.
Приклад 2.9
>>> import math
>>> с = abs(-4.7)
>>> с
4.7
>>> с = floor(-9.3)
–10
>>> с = ceil(7.6)
>>> с
8
>>> с = round(10.7)
>>> с
11
>>> с = round(1.3584,2)
1.36
>>> с = factorial(10)
>>> с
3628800
>>>
Слід відзначити, що якщо параметри функції та можливості її
використання Вам невідомі або Ви їх забули, особливості її використання можна
подивитися з використання системної команди help. Нижче наведений приклад
використання цієї команди [24, 25, 27].

85
Таблиця 2.4 – Базові математичні функції для роботи з цілими та
дійсними числами
Функція Що виконує Параметри Приклади
виклику використання
Обчислення модуля Ціле або дійсне abs(9)
abs() цілого або дійсного число, один abs(-4.7)
числа параметр
Округлення дійсного Дійсне число, floor(7.6)
floor() числа до цілого в один параметр floor(-9.3)
меншу сторону
Округлення дійсного Дійсне число, ceil(7.6)
ceil() числа до цілого в один параметр ceil(-9.3)
більшу сторону
Округлення дійсного Два параметри, ціле round(10.7)
числа до та дійсне число, round(-1.8)
найближчого цілого Перший параметр round(1.3584,2)
або до дійсного із задає число, яке
заданою кількістю треба округляти, а
знаків другий – кількість
round() знаків. За
замовченням другий
параметр дорівнює
0, що відповідає
округленню до
найближчого цілого
числа
Обчислення значення Один параметр, factorial(10)
factorial()
факторіала натуральне число factorial(0)

86
Приклад 2.10
>>> help (abs)
Help on built-in function abs in module builtins:
abs(x, /)
Return the absolute value of the argument
>>>

2.4.3 Функції перетворення типів числових даних


У підрозділі 2.3 розглядалися загальні правила програмування на мові
Python, які дозволяють визначати тип даних під час проведення обчислень за
замовченням. Ці правила для базових алгебраїчних операцій описуються
наведеними вище властивостями 2.1 – 2.10.
Слід відзначити, що такі правила існують і для інших математичних
функцій, які розглядаються в Python як методи обробки даних та будуть
описані у наступних підрозділах. Зазвичай результатом роботи цих функцій є
дійсні числа, навіть за умови, що аргументом функції є ціле число. Виключні
ситуації та помилки визначення аргументу також розглядаються окремо. На
відміну від системи науково-технічних розрахунків MatLab, де всі
обчислення проводяться в області комплексних чисел, у Python вважається,
що результатом роботи математичних функцій має бути дійсне число. Тому
вирази, аналогічні − 5 , log(–5) або arcsin(10) вважаються помилковими [25].
Але, не зважаючи на те, що система обробки виключних ситуацій та
визначення типів даних за замовченням з використанням принципів ООП у
мові Python дуже ретельно пропрацьована, розробниками також передбачена
можливість перетворення типів даних ручним способом з використанням
відповідних функцій. Взагалі таких функцій дві: функція int() перетворює
дійсне число на ціле, а функція float()– ціле число на дійсне. Окремо слід
відзначити, що аргументами функцій int()та float() можуть бути
рядкові дані. Способи роботи із рядками у мові Python розглядатимуться у
підрозділі 2.6. Можливість роботи із рядками відрізняє функції int() та

87
float() від розглянутих у попередньому підрозділі функцій округлення.
Результатом роботи функцій int() та float() без параметрів є нульове
значення.
Слід відзначити, що дійсне число у мові Python, як і в більшості інших
мов програмування, може бути записаним в експоненціальній формі, або у
формі із плаваючою комою. У комп’ютерних науках існує
загальноприйнятий стандарт для запису дійсних чисел в експоненціальній
формі: окремо записується характеристика та мантиса числа, а між ними
ставиться символ е. Наприклад запис 2е4 означає 2·104 = 20000 [6, 7]. Слід
відзначити, що функцію int() можна використовувати також для
перетворення дійсних чисел із плаваючою комою на ціле число.
Розглянемо приклад використання функцій int() та float().
Приклад 2.11
>>> с = int(-4.7)
>>> с
–4
>>> с = int(5.2)
>>> с
5
>>> int()
0
>>> с = float(3)
>>> с
3.0
>>> float()
0.0
>>> с = int(‘5’)
>>> с
5
>>> с = float(‘3.2’)
>>> с
88
3.2
>>> с = int(3e5)
>>> с
300000
>>>
Взагалі інтерпретатори Python 2 дозволяють, без зниження точності
обчислень, обробляти цілі числа в діапазоні від –231 до 231, а інтерпретатори
Python 3 – в діапазоні від –263 до 263. Тобто, у Python 3 була збільшена
кількість розрядів для запису одного числа від 32 до 64, що також є
безсумнівною перевагою нової версії цієї мови програмування [25].
Існує ще одна цікава, та важлива з точку зору технології
програмування, можливість використання функції int(), пов’язана із
переведенням значень булевих змінних до числової форми. Без такого
перетворення неможливо було б формувати арифметико-логічні вирази та
повноцінно використовувати можливості матричного стилю програмування.
Відповідні теоретичні відомості будуть наведені у підрозділі 3.3.

2.4.4 Експоненціальна, логарифмічна та степенева функції


Одними із найважливіших математичних функцій, які реалізовані майже у
всіх мовах програмування, є експоненціальна, логарифмічна та степенева функції
[3 – 7, 15 – 17, 39, 40]. Незважаючи на те, що у мові програмування Python існує
оператор піднесення до степені ** , описаний у підрозділі 2.3, існує також
степенева функція pow(y,x), яка обчислює значення p(y, x) = yx [24, 25]. Ця
функція, як і більшість інших математичних функцій, розташована в
бібліотеці math. Відмінність оператора піднесення до степені ** від функції
pow(y,x) насамперед полягає у тому, що, як було відмічено у підрозділі
2.3, у разі використання оператора піднесення цілого числа до степені
натурального числа результатом цієї операції є ціле число. Цьому правилу
узгодженості типів відповідає властивість 2.7. На відміну від оператора **
результатом роботи функції pow(y,x) бібліотеки math завжди є дійсне
89
число. Альтернативні можливості обчислення функції степені у мові Python
насамперед пов’язані з тим, що Python став розвиватися нещодавно та в
ньому запозичені багато вдалих рішень з інших мов програмування, до яких,
доречи, програмісти вже встигли звикнути. Наприклад, оператор ** був
запропонований у мові FORTRAN, а функція pow(y,x) – у мовах С та С++
[3 – 5, 10, 15, 17, 39, 40]. Розглянемо приклади використання оператора
піднесення до степені та степеневої функції.
Приклад 2.12
>>> import math
>>> q = math.pow(4,2)
>>> q
16.0
>>> q = 4**2
>>> q
16
>>> q = math.pow(4.8,2.6)
59.05099464259841
>>>
Крім можливості отримання результатів у вигляді цілого числа, в іншому
оператор ** та функція pow(y,x) дають однакові результати, і використання
того або іншого способу обчислення степені зазвичай залежить лише від того,
який стиль програмування, функціональний чи декларативний, більше
подобається програмісту. Доречи, багато альтернативних лінгвістичних
конструкцій існує також у системі науково-технічних розрахунків MatLab [6, 7].
Крім цього, в бібліотеці math існує також функція обчислення
квадратного кореня sqrt(), оскільки ця функція також часто
використовується програмістами для проведення математичних розрахунків і
вона реалізована майже у всіх мовах програмування. Слід відзначити, що у

90
системі програмування Python параметрами функції sqrt() бібліотеки
math можуть бути лише додатні числа. У разі, якщо як аргумент цієї
функції визначене від’ємне число, формується повідомлення про помилку.
Робота з комплексними числами в інтерпретаторі мови Python реалізована
через окрему бібліотеку, відповідні засоби програмування будуть розглянуті
у підрозділі 2.4.7. Розглянемо приклад використання функції sqrt()
бібліотеки math.
Приклад 2.13
>>> import math
>>> q = math.sqrt(121)
>>> q
11
>>> q = math.sqrt(–9)
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ValueError: math domain error
>>>
На основі функції взяття квадратного кореня та оператора обчислення
степені в бібліотеці math реалізована також нестандартна для інших мов
програмування функція обчислення гіпотенузи прямокутного трикутника
hypot(). Ця функція має два параметри hypot(x, y). Обчислення
проводяться за відомою із основ геометрії формулою [45]:

h( x, y ) = x 2 + y 2 . (2.1)

Наведемо приклад використання функції hypot.


Приклад 2.14
>>> import math
>>> c = math.hypot (3,4)
>>> c
5.0
91
>>> c = math.hypot (5,12)
>>> c
13.0
>>>
Проте функція hypot() може бути легко реалізована і на основі інших
математичних функцій, тому на практиці, крім окремих випадків розв’язування
складних завдань геометричного моделювання, вона використовується вкрай
рідко [24, 25].
Вкрай важливими для розв’язування складних завдань математичного
моделювання та прикладної фізики є експоненціальна та логарифмічна функції
[6, 7]. Тому, хоча, як було відмічено у підрозділі 2.4.1, число e для
інтерпретаторів мови Python є системною константою, а це означає, що
значення експоненціальної функції ex може бути знайдене через обчислення
степені числа e, експоненціальна функція exp(x) у бібліотеці math реалізована
окремо. Це також пов’язано із відповідними традиціями програмування, оскільки
функція обчислення значення експоненти реалізована майже у всіх сучасних
мовах програмування [3 – 5, 10, 15, 17, 39, 40]. Розглянемо простий приклад
обчислення значення експоненціальної функції.
>>> import math
>>> c = math.exp(2)
>>> c
7.38905609893065
>>>
Логарифмічна функція log(x, n) також реалізована у бібліотеці math.
Ця функція має два параметри – аргумент функції x та основу логарифму n. Така
особливість реалізації цієї функції є дуже зручною для програмістів, оскільки
вона дозволяє обчислювати логарифми без використання відомої формули
переходу до іншої основи [45]:
92
logc (a )
logb (a ) = . (2.2)
logc (b )

Якщо функція log(x), має лише один параметр x, за замовченням


вважається, що необхідно обчислити натуральний логарифм від аргументу x.
Розглянемо приклад обчислення значення логарифмічної функції.
Приклад 2.15
>>> import math
>>> c = math.log(math.e**2)
>>> c
2.00000000000000
>>> c = math.log(8,2)
>>> c =
3
>>>

2.4.5 Тригонометричні та зворотні тригонометричні функції


Також важливими для моделювання фізичних процесів, які протікають
в електронних приладах та системах, є тригонометричні функції. Ці функції,
зокрема, є важливими для описання коливальних процесів [6, 7]. У бібліотеці
math інтерпретатора мови Python реалізовані такі тригонометричні функції
[25, 44, 45].
1. Прямі тригонометричні функції:
– sin(x) – обчислення синуса від заданого аргументу x;
– cos(x) – обчислення косинуса від заданого аргументу x;
– tan(x) – обчислення тангенса від заданого аргументу x;
2. Зворотні тригонометричні функції:
– asin(x) – обчислення арксинуса від заданого аргументу x;
– acos(x) – обчислення арккосинуса від заданого аргументу x;
– atan(x) – обчислення арктангенса від заданого аргументу x;
– atan2(y,x) – додаткова функція, яка дозволяє шукати значення кута
за заданими координатами точки x та y у декартовій системі координат. Кут

93
обчислюється в радіанах. Тобто, насправді ця функція обчислює значення [45]:
 y
ϕ( x, y ) = arctg  . (2.3)
 x
З одного боку, функцію atan2(y,x) можна легко замінити функцією
atan(x), скориставшись формулою (2.3). Але, з іншого боку, вона може бути
дуже зручною для проведення арифметичних операцій із комплексними
числами, які розглядатимуться у підрозділі 2.4.7.
3. Функції для переведення значень кутів, заданих у радіанах, на градуси,
та кутів, заданих у градусах на радіани:
– degrees(x) – переведення значення кута x, заданого в радіанах, на
відповідне значення в градуса;
– radians(x) – переведення значення кута x, заданого в градусах, на
відповідне значення в радіанах.
Для здійснення цих простих перетворень використовуються відомі
геометричні співвідношення [45]:
π ⋅ ϕd 180 ⋅ ϕr
ϕr = ; ϕd = , (2.4)
180 π
де ϕd – кут, заданий у градусах, ϕr – той же самий кут, заданий в радіанах.
Розглянемо приклад використання тригонометричних, зворотних
тригонометричних функцій та функцій перетворення кутів.
Приклад 2.16
>>> import math
>>> deg = 30
>>> rad = math.radians(deg);
>>> rad
0.52359877559830
>>> s = math.sin(rad)
0.50000000000000
>>> c = math.cos(rad)
0.86602540378444
>>> t = math.tan(rad)
0.57735026918963
>>> a_s = math.asin(s)
>>> a_s

94
0.52359877559830
>>> a_c = math.acos(c)
>>> a_c
0.52359877559830
>>> a_t = math.atan(t)
>>> a_t
0.52359877559830
>>> deg_s = math.degrees(a_s)
>>> deg_s
29.99999999999999
>>> deg_c = math.degrees(a_c)
>>> deg_c
29.99999999999999
>>> deg_t = math.degrees(a_t)
>>> deg_t
29.99999999999999
>>> x = 7
>>> y = 5
>>> y_x = y/x
>>> y_x
0.71428571428571
>>> w1 = math.atan2(y,x)
>>> w1
0.62024948598282
>>> w2 = math.atan(y_x)
>>> w2
0.62024948598282
>>> deg_w = math.degrees(w2)
>>> deg_w
35.53767779197438
Слід відзначити, що ті ж самі функції тригонометричних перетворень
реалізовані у системі науково-технічних розрахунків MatLab [6, 7].

95
2.4.6 Гіперболічні та зворотні гіперболічні функції

У бібліотеці math інтерпретатора мови програмування Python


реалізований набір гіперболічних та зворотних гіперболічних функцій, які
широко використовуються у математиці [45] та можуть бути застосовані у
математичних виразах під час написання комп’ютерних програм [6, 7]. Хоча
гіперболічні функції використовуються для моделювання фізичних процесів
не настільки часто, як експоненціальна, логарифмічна, степенева функція та
тригонометричні функції [6, 7], проте саме з їх допомогою можуть бути
описані деякі фізичні явища в коливальних системах, зокрема в
надвисокочастотних та оптичних [6, 7].
Наведемо перелік гіперболічних та зворотних гіперболічних функцій,
реалізованих в бібліотеці math інтерпретатора мови Python.
1. sinh(x) – функція гіперболічного синуса [6, 7, 45],
exp( x ) − exp(− x )
sh ( x ) = . (2.5)
2
2. cosh(x) – функція гіперболічного косинуса [6, 7, 45],
exp( x ) + exp(− x )
sh ( x ) = . (2.6)
2
3. asinh(x) – функція зворотного гіперболічний синуса, або
ареасинуса. Назва ареа пов'язана з тим, що через цю функцію визначається
площа сектора, обмеженого двома променями, які виходять з початку
координат, та відрізком гіперболи x 2 − y 2 = 1 (рис. 2.9) [6, 7, 45].
y

x2-y2=1

S=arcsinh(x0)
x0 x

Рис. 2.9 Геометрична інтерпретація способу обчислення функції зворотного


гіперболічного синуса

96
Враховуючи те, що функція x = sh ( y ) визначається співвідношенням
(2.5), для зворотної до неї функції y = Arsh( x ) можна записати наступне
співвідношення [6, 7, 45]:

Arsh( x ) = ln x + x 2 + 1  . (2.7)


 
4. acosh(x) – функція зворотного гіперболічного косинусу, або
ареакосинусу.
Враховуючи співвідношення (2.6) для функції x = ch ( y ) , для зворотної
до неї функції y = Arch( x ) можна записати [6, 7, 45]:

Arch( x ) = ± ln x + x 2 − 1 , x ≥ 1. (2.8)


 
5. tanh(x) – функція гіперболічного тангенса [6, 7, 45]:
sinh ( x ) exp( x ) − exp(− x )
th ( x ) = = . (2.9)
cosh ( x ) exp( x ) + exp(− x )
6. atanh(x) – функція зворотного гіперболічного тангенса, або
ареатангенса. Враховуючи співвідношення (2.9), можна записати наступний
вираз для обчислення цієї зворотної гіперболічної функції [6, 7, 45]:
1 1+ x
Arth( x ) = ⋅ ln , x < 1. (2.10)
2 1− x
7. sech(x)– функція гіперболічного секанса [6, 7, 45]:
1 2
sch ( x ) = = . (2.11)
ch ( x ) exp( x ) + exp(− x )
8. asech(x) – функція ареасеканса, або гіперболічного арксеканса,
яка є зворотною до функції гіперболічного секанса [6, 7, 45]:
 1 + 1 − x2 
Arsch( x ) = ln . (2.12)
 x 
 
9. csh(x) – функція гіперболічного косеканса, яка задається
співвідношенням [6, 7, 45]:
1 2
csh ( x ) = = . (2.13)
sh ( x ) exp( x ) − exp(− x )

97
10. acsch(x) – функція, яка є зворотною до функції гіперболічного
косеканса [6, 7, 45]:
 1− 1 + x2
 , x < 0;
1 + sgn ( x ) 1 + x 2 ln
Arcsch( x ) = ln = x (2.14)
x  1+ 1 + x2
ln , x > 0.
x
11. coth(x) – функція гіперболічного котангенса, яка задається
співвідношенням [6, 7, 45]:
cosh ( x ) exp( x ) + exp(− x )
cth ( x ) = = . (2.15)
sinh ( x ) exp( x ) − exp(− x )
12. acoth(x) – функція, яка є зворотною до функції гіперболічного
котангенса, або функція ареакотангенса.
1  x + 1
Arcth( x ) = ⋅ ln , x > 1 . (2.16)
2  x − 1
Графіки деяких гіперболічних функцій наведені на рис. 2.10, а, а
зворотних гіперболічних функцій – на рис. 2.10, б.
Нижче наведені приклади обчислення значень гіперболічних та
зворотних гіперболічних функцій з використанням розглянутих вище
функцій бібліотеки math.
Приклад 2.17
>>> import math
>>> x = 1.5
>>> y = math.sinh(x)
>>> y
2.12927945509482
>>> z = math.cosh(x)
>>> z
2.35240961524325
>>> a_s = math.asinh(x)
a_s
1.19476321728711
98
а)

б)
Рис. 2.10 Графіки гіперболічних (а) та зворотних гіперболічних (б) функцій

>>> a_c = math.acosh(x)


>>> t =a_c

99
0.96242365011921
>>> t = math.tanh(x)
>>> t =
0.90514825364487
>>> x = 0.5
>>> a_t = math.atanh(x)
>>> a_t
0.54930614433405
>>> a_c_2 = math.acosh(x)
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ValueError: math domain error
>>>

2.4.7 Робота з комплексними числами в інтерпретаторі мови Python


Робота з комплексними числами у мові Python повністю підтримується
через функції бібліотеки cmath, до якої належить системна змінна j, що

визначається як j = − 1 . Слід відзначити, що математичний апарат алгебри


комплексних чисел широко використовується для проведення аналізу
електронних схем, зокрема, для розрахунку їх амплітудно-частотних
характеристик [6, 7]. До останнього часу єдиним інструментом для проведення
складних розрахунків із комплексними числами вважалась система науково-
технічних розрахунків MatLab [6, 7], проте сьогодні навіть стандартні
інтерпретатори Python версії Python 3 [25], не кажучи вже про систему Anaconda
[26], містять потужні бібліотеки математичних функцій, призначених для роботи
з комплексними числами.
Головними математичними операціями, які можна здійснювати із
комплексними числами з використанням засобів мови програмування Python, є
наступні.
1. Всі базові арифметичні операції, тобто додавання, віднімання,

100
множення, ділення та піднесення до степені [6, 7, 45].
2. Функції обчислення дійсної частини комплексного числа z Re(z) та його
уявної частини Im(z) [6, 7, 45].
3. Функції обчислення модуля комплексного числа [6, 7, 45]:

z= (Re(z ))2 + (Im(z ))2 (2.17)


та кута нахилу вектора комплексного числа до осі абсцис [6, 7, 45]:
 (Im( z )) 
ϕ( z ) = arctg . (2.18)
 (Re( z )) 
Слід відзначити, що для підвищення ефективності засобів роботи з
комплексними числами в інтерпретаторі мови програмування Python можна
використовувати тригонометричну функцію atan2(), а також функції
перетворення значень кутів degrees(x) та radians(deg), особливості
роботи яких були розглянуті у підрозділі 2.4.5.
4. Можливість використання степеневої, показникової, логарифмічної, а
також тригонометричних функцій для роботи з комплексними числами.
Слід відзначити, що в інтерпретаторі мови програмування Python всі
засоби функції для роботи із комплексними числами зроблені з використанням
засобів ООП, і це дає певні переваги над стандартними засобами структурного
програмування. Комплексне число розглядається як складний об’єкт, який
успадковує всі властивості класу, або типу дійсних чисел. Проте ситуація значно
спрощується тим, що особливості реалізації функцій для роботи із комплексними
числами у мові Python скриті від користувача через механізм абстрагування.
Комплексні числа у Python навіть не розглядаються як окремий тип даних. Тут
ситуація значно спрощується тим, що функції для роботи з дійсними та
комплексними числами належать до різних математичних бібліотек. Тому, якщо
в своїй програмі Ви передбачаєте роботу із комплексними числами, слід просто
замість бібліотеки math підключити іншу бібліотеку cmath, а для запису уявної
частини комплексних чисел використовувати системну змінну j. А всі функції
математичних бібліотек у системі програмування мови Python є

101
перевантаженими. Тип числа визначається автоматично, та залежно від того, які
обчислення проводяться, підключаються відповідні бібліотеки. Наприклад,
функція взяття модуля числа abs(x) реалізована наступним чином:
 z, якщо z - додатне число;

z = − z, якщо z - від' ємне число; (2.19)
 (Re( z ))2 + (Im( z ))2 , якщо z - комплексне число.

У записаному співвідношенні (2.19) цікавим є те, що у правій колонці
аналізується не значення змінної z, а її тип. У цьому і полягає головний принцип
ООП. Але оскільки у даному випадку механізми успадкування методів роботи з
об’єктом є скритими, користувачу системи програмування мови Python для
організації роботи із комплексними числами достатньо послатися на відповідну
бібліотеку cmath, далі компілятор все зробить автоматично, обираючи функцій
саме для роботи з ціми числами. Теж саме стосується перевантаженості
операторів, через які реалізовані операції додавання, віднімання, множення,
ділення та піднесення до степені. Слід відзначити, що у мові програмування С++
функції та оператори для роботи з комплексними числами, хоча і є
успадкованими від відповідних методів для роботи із дійсними числами, але
механізми цього успадкування скриті від користувача не повністю. Це у певній
мірі ускладнює роботу із такими функціями та операторами [10, 15]. Навпаки, у
системі науково технічних розрахунків MatLab способи створення функцій для
роботи із комплексними числами цілком скриті від користувача, що у значній
мірі спрощує їх використання. Аналогічно розроблена система програмування
інтерпретатора мови Python [25, 26]. Розглянемо приклад, в якому виконуються
математичні операції над комплексними числами.
Приклад 2.18
>>> import cmath
>>> c = 3 + 7j
>>> d = 5 - 6j
>>> e = c + d
>>> e

102
8.00000000000000 + 1.00000000000000j
>>> f = c*d
>>> f
57.00000000000000 +17.00000000000000j
>>> g = f/d
>>> g
3.00000000000000 + 7.00000000000000j
>>> h = f**e
>>> h
1.163998949411799e+014 +1.418247506318053e+013j
>>> o = cmath.exp(d)
>>> o
1.425019055182074e+002 +4.146893678992289e+001j
>>> p = cmath.asin(d)
>>> p
0.69071623417023 - 2.74934659697410j
>>> r = cmath.sinh(d)
71.24771797085290 + 20.73540973837024j
>>> q = asinh(r)
5.00000000000000 + 0.28318530717959j
>>> 7.55249849150359 + 6.61431901165645j
>>> q = cmath.asinh(r)
>>> q
3.00000000000000 + 0.71681469282041i
>>>

2.4.8 Функції як аргументи інших функцій


Як і в більшості інших мов програмування, у Python передбачена
можливість використання значень, обчислених через виклик однієї функції,
як параметрів іншої функції. На рис. 2.11 показаний приклад такого виклику
функції pow().
103
1 3

pow ( abs (–2), round (4.3) )

2 4
5

Рис. 2.11 Наочна ілюстрація способу використання одних функцій як


аргументів інших функцій

Зрозуміло, що для прикладу, наведеного на рис. 2.11, обчислюється


значення функції pow(abs(–2), round(4.3)). Тобто, аргументами
функції pow() є дві інші математичні функції: abs() та round().
Обчислення такого командного рядка здійснюється наступним чином.
1. Обчислюється значення abs(–2) = 2. Це перший аргумент
функції pow().
2. Обчислюється значення round(4.3) = 4. Це другий аргумент
функції pow().
3. Обчислюється значення pow(2, 4) = 16.
Тобто, у прикладі, який розглядається, послідовно здійснюється три
виклики різних функцій. Зрозуміло, що таку команду можна замінити
наступною послідовністю команд.
Приклад 2.19
>>> import math
>>> a = abs(–2)
>>> r = round(4.3)
>>> p = math.pow(a, r)
>>> p
16
Різниця між командним рядком, наведеним на рис. 2.11, та сукупністю
команд, наведеною у прикладі 2.19, полягає у тому, що для збереження
більшої кількості змінних необхідний відповідний обсяг оперативної пам’яті
прямого доступу, у той час як для багаторазового виклику функцій необхідно

104
мати більший об’єм стеку [5 – 7]. Тому програміст, під час написання
програми, може обирати, яку модель пам’яті, стекову чи прямого доступу

йому краще використовувати. Також зрозуміло, що запис − 2


[4,3] значно

легше читати та аналізувати, ніж послідовне обчислення функцій та


присвоєння їм значень змінних, як у прикладі 2.19.
Іншим цікавим способом використання функцій від багатьох
аргументів, добре відомим із основ програмування та із дискретної
математики [2], є рекурсивний виклик функцій [5 – 7]. З математичної точки
зору прикладом такого виклику є ітераційне, багаторазове обчислення
функції, коли кожне обчислене значення використовується як аргумент тієї ж
самої функції. Приклад рекурсивного виклику функції показаний на
рис. 2.12. У дискретній математиці такий виклик функції також називається
рекурентним [6, 7].
Більш цікавим, з обчислювальної точки зору, є рекурсивний виклик
функцій із зміною параметрів її виклику [6, 7]. Способи реалізації
відповідних ітераційних алгоритмів у мові програмування Python будуть
розглянуті у розділі 3.

4
2
f(... (f ( f ( f (x) ) ) ) )

1
3
n разів

Рис. 2.12 Ілюстрація принципу рекурентного виклику функцій f(x)

Нижче наведений ще один приклад використання одних функцій як


аргументів інших.
Приклад 2.20
>>> import math

105
>>> x = 4
>>> y = 3
>>> c = math.sqrt(pow(x,2) + pow(y,2))
>>> c
5.0000000000000000
>>> d = math.hypot(x, y)
>>> d
5.0000000000000000
>>> fi=0.001
>>> y = math.cos(cos(fi))
>>> y
0.54030272660353
>>> y = math.cos(cos(cos(cos(fi))))
>>> y
0.65428995416737
>>> y = math.cos(math.cos\
(math.cos(math.cos(math.\
cos(math.cos(math.cos(fi)))))))
>>> y
0.76395963708633
>>> y = math.cos(math.cos(math.\
cos(math.cos(math.cos(math.\
cos(math.cos(math.cos(fi))))))))
>>> y
0.72210245672042
>>> fi = y
>>> y = math.cos(math.cos(math.cos(math.cos(fi))))
>>> y
0.73560474689993
>>> fi = y
>>> y = math.cos(math.cos(math.cos(math.cos(fi))))

106
>>> y
0.73836920545068
>>> fi = y
>>> y = math.cos(math.cos(math.cos(math.cos(fi))))
>>> y
0.73893775698874
>>> fi = y
>>> y = math.cos(math.cos(math.cos(math.cos(fi))))
>>> y
0.73905479080320
>>> fi = y
>>> y = math.cos(math.cos(math.cos(math.cos(fi))))
>>> y
0.73907888600658
>>> math.cos(y)
0.73908934139559
>>>
Слід відзначити, що у прикладі 2.20 для формування довгого рядка
вперше у цьому підручнику використаний оператор перенесення рядку, який
задається зворотною нахиленою рискою \ [24, 25]. Слід відзначити, що такий
метод спрацьовує лише тоді, коли після символу зворотної нахиленої риски
не стоїть пробіл, тому на практиці користуватися таким методом не дуже
зручно. Тому частіше професіональні програмісти користуються іншим,
більш надійним методом, який полягає в тому, що весь рядок поміщається у
круглі дужки. Але у разі виклику функції із багатою кількістю рекурентних
повторень у такому випадку слід уникати іншої помилки – кількість правих
та лівих дужок у виразі має бути однаковою. Щодо використання символу
зворотної нахиленої риски – він є одним із спеціальних символів мови
програмування Python, призначених для роботи із рядковими змінними, які
розглядатимуться у підрозділі 2.6.3.
Розглянемо приклад, у якому для перенесення рядків, сформованих

107
через рекурентний виклик функції, використовується запис математичного
виразу у круглих дужках.
Приклад 2.21
>>> import math
>>> fi = 0.74
>>> (y = math.cos(math.cos(math.
>>> cos(math.cos(fi)))))
>>> y
0.73927354164707
>>> fi = y
>>> (y = math.cos(math.cos(math.
>>> cos(math.cos(fi)))))
>>> y
0.73909312060129
>>>
Для закріплення теоретичного матеріалу, розглянутого у підрозділі 2.4,
та для здобуття відповідних практичних навичок щодо написання кодів
програм із математичними функціями, необхідно виконати практичне заняття
№2, яке наведене у розділі 7.

2.5 Створення функцій користувача та робота з ними в


інтерпретаторі мови Python
2.5.1 Опції налаштування оболонки IDLE для системи програмування
Python 3
Відомо, що сучасні системи програмування, хоча вони, як і раніше,
орієнтовані на введення командного рядка, завжди мають зручний графічний
інтерфейс [6, 7, 12 – 14, 16]. Використання в системах програмування
оболонок графічного інтерфейсу має певні переваги, серед яких слід
відмітити наступні [16].
1. Можливість зручної роботи програміста у багатовіконному режимі.
2. Можливість зміни типу, кольору та розміру шрифтів, якими

108
пишеться текст програми, командні рядки та системні повідомлення про
помилки програмування.
3. Можливість більш ефективного аналізу програмного коду та його
відлагодження через отримання повідомлень про помилки у багатовіконному
режимі.
Хоча оболонка IDLE, призначена для роботи із мовою програмування
Python версії 3.4 під операційною системою Windows, є інтерпретатором, а не
компілятором, вона також має простий та зручний графічний інтерфейс. Цей
інтерфейс не перенасичений великою кількістю іконок та графічних
зображень, але має зручну та розвинену систему меню із ієрархією
командних вікон. Екранна копія головного вікна командного інтерпретатора
із верхнім рядком меню та великим робочим вікном для введення команд та
перегляду результатів їх виконання показана на рис. 2.13.

Рис. 2.13. Вікно командного інтерпретатора мови програмування Python 3.7


під ОС Windows (екранна копія)

109
Як видно з рисунка, головними командами системи меню цього
інтерпретатора є наступні.
1. File – загальновживані команди для роботи з файлами, зокрема:
створення нового файлу (New File), завантаження файлу (Open), збереження
файлу (Save), збереження під іншим ім’ям (Save As) та закриття
збереженого файлу після завершення роботи з ним (Close).
2. Edit – загальновживані команди для роботи з текстом, зокрема:
виділення фрагмента тексту (Select), виділення всього тексту (Select All),
копіювання виділеного фрагмента тексту до буфера обміну Windows (Copy),
видалення виділеного фрагмента тексту із копіюванням до буфера обміну
Windows (Сut), вставлення скопійованого фрагмента тексту із буфера обміну
Windows (Paste), пошук фрагмента тексту за заданим зразком (Find) та
відміна останньої виконаної операції (Undo).
3. Shell – можливість перезапустити оболонку через командне меню.
4. Options – параметри налаштування оболонки IDLE. Тут можна
змінити розмір шрифту, яким виводиться текст, а також його тип та колір.
Цікавим також є те, що в IDLE ключові слова мови Python, імена змінних,
імена бібліотек, повідомлення про помилки та системні повідомлення
можуть бути виведені на екран різними кольорами, що у значній мірі
спрощує сприйняття тексту програмістом. За замовченням в оболонці IDLE
встановлений білий колір вікна, а головний текст програми пишеться на
ньому чорним кольором. Якщо програміст більш звик до інверсної системи
кольорів програмної оболонки, коли пишуться білі літери на чорному фоні,
ці параметри налаштування можна змінити через опцію переваги
(Preference) команди меню Options. Доречи, слід пам’ятати про те, що
інверсний режим кольорів є більш економним з точки зору
енергоспоживання та його негативний вплив на зір користувача є значно
меншим [16]. В результаті виникає командне вікно, показане на рис. 2.14, яке
має декілька вкладенок. На вкладенці Fonts/Tab встановлюється тип та
розмір шрифту у командному вікні, які за замовченням становлять Corier та

110
10, та кількість символів тексту, яка відповідає табуляції. Використання
символу табуляції під час написання програм не є обов’язковим, але значно
спрощує роботу із текстом програми.

Рис. 2.14 Вікно налаштування стилів виведення тексту в оболонці IDLE


(екранна копія)
Працювати з вікном налаштування стилів виведення тексту, яке
розташоване на вкладенці Highlighting на наведене на рис. 2.15, слід
наступним чином. Під кнопкою Choose Colour for: розташована кнопка
обрання типу тексту, серед яких слід обрати той текст, колір виведення якого
ви бажаєте змінити.
Крім цього, перед натисненням кнопки обрання типу тексту слід за
допомогою перемикачів, розташованих під віконцем із кнопками, обрати
атрибут тексту, який змінюється. У разі необхідності зміни кольору тексту
слід обрати кнопку Foreground (передній план), а у разі необхідності зміни
кольору фону – кнопку Background (задній план). Для спрощення роботи із

111
вікном налаштування параметрів текстового вікна під вікном із кнопками на
вкладенці Highlighting показаний вигляд командного вікна з текстами різних
стилів. У разі зміни кольору відповідного тексту відразу змінюється вигляд
цього шаблона командного вікна.

Рис. 2.15 Вкладенка Highlighting вікна налаштування стилів тексту, який


відображується у командному вікні (екранна копія)

Після натиснення кнопки обрання типу тексту виникає спливаюче


вікно із рядками меню, наведене на рис. 2.15. Тут відображені такі головні
типи текстів, атрибути яких часто міняють користувачі, залежно від власних
бажань.
– Normal Text – звичайний текст, яким пишуться імена змінних та
вирази, які не містять функцій.
– Python Keywords – ключові слова мови Python.

112
– Python Definition – визначення мови Python, наприклад, визначення
типів даних або модулів.
– Python Comments – коментарі.
– Python Strings – рядкові змінні.
– Selected Text – виділений текст.
– Found Text – знайдений текст.
– Cursor – колір та фон для риски, яка показує положення курсору.
– Error Text – текст повідомлень про помилки.
Після обрання типу тексту, атрибути виведення якого необхідно
поміняти, змінюється надпис на кнопці із типом тексту. Тоді можна
натиснути на верхню кнопку «Choose Colours for:», що призводить до
виведення на екран стандартного вікна системи Windows із палітрою
кольорів, яке наведене на рис. 2.16. Для фіксації проведених змін необхідно
натиснути кнопки Apply та Ok у нижній частині вікна налаштування
властивостей.

Рис. 2.16 Вікно налаштування атрибутів тексту (екранна копія)

Вклідинка Keys у вікні налаштування властивостей оболонки IDLE


Preferences призначення для визначення сукупності гарячих клавіш, якими
часто користуються досвідчені програмісти. Вікно налаштування гарячих
клавіш показане на рис. 2.17.

113
Рис. 2.17 Вікно налаштування гарячих клавіш (екранна копія)

І нарешті, важливі опції налаштування базових функцій оболонки


програмування IDLE розташовані на останній вкладенці General. По-перше,
тут можна обрати тип оболонки, яка завантажується початково, опція At
Start. Можливе обрання таких варіантів.
– Open Edit Window – відкриття оболонки для редагування файлів.
– Open Shell Window – відкриття оболонки для введення командних
рядків.
Інша важлива опція на цій вкладенці – це обрання способу
автоматичного запам’ятовування тексту у вікні оболонки редагування
файлів. Тут можливі наступні варіанти.
– Prompt to Save – повідомляти користувача про те, що вміст файлу
буде автоматично збережений.

114
– No Prompt – не повідомляти користувача про збереження файлу.
Вікно інтерфейсу, яке відповідає вкладенці General, показане на рис. 2.18.

Рис. 2.18 Вкладенка General налаштування базових функцій оболонки


IDLE (екранна копія)

2.5.2 Створення власних функцій користувача та головні принципи


роботи з ними
Всі приклади роботи із командним рядком інтерпретатора Python,
розглянуті у підрозділі 2.4, були орієнтовані лише на введення командних
рядків в інтерактивному командному режимі, тобто у режимі «Запит
користувача» – «Відповідь комп’ютера». У такому режимі система
програмування, яка має багато математичних, системних та інших функцій,
працює лише як потужний калькулятор, оскільки програміст не може внести
зміни у командний рядок, який був визначений раніше. Слід відзначити, що в
інтерактивному режимі діалогу з комп’ютером може працювати і система
науково-технічних розрахунків MatLab, проте для створення повноцінних
програм необхідний інший підхід, пов’язаний із створенням власних функцій
користувача, програмних модулів та бібліотек [6, 7]. Як було сказано вище,
інтерпретатор мови Python у значній мірі схожий на інтерпретатор MatLab,
тому тут також передбачена можливість створення програмістом власних

115
функцій, модулів та бібліотек. Розглянемо спосіб створення власної функції,
записаної у файл, з використанням описаної вище оболонки IDLE. Для цього
необхідно виконати наступні кроки [24].
1. У меню програми IDLE обрати команду File → New File. Після
виконання цієї команди на екрані з’являється вікно текстового редактора, де
можна набирати командні рядки мови Python.
2. Набрати текст програми.
3. У меню програми IDLE обрати команду File → Save As. Це
необхідно для того, щоб зберігати файл під відповідним іменем у будь-якій
директорії на комп’ютерному диску.
4. У діалоговому вікні ввести англійськими літерами ім’я файлу,
наприклад, це може бути ім’я myprog. Всі файли, текст яких написаний на
мові програмування Python, повинні мати розширення py. У старих версіях
оболонки інтерпретатора це розширення необхідно було прописувати явно,
проте в оболонці IDLE для версії Python 3.4 розширення файлу формується
автоматично і його прописувати не треба.
5. Щоб запустити програму на виконання та відлагодити її, необхідно
виконати команду меню Debug → Run Mode, або натиснути клавішу F5.
Розглянемо приклад простої програми, яку можна зберегти як файл та
запустити на виконання.
Приклад 2.22
a = 5
b = a + 2
print (b)
print (b + 3)
Якщо набрати у редакторі оболонки IDLE цей текст, запам’ятати його у
файлі з ім’ям myprog та виконати команду Run Module опції меню Run, у
командному вікні з’являються рядки, аналогічні наступним.
>>>
======== RESTART C:/Python34/myprog.py ========

116
7
10
>>>
Слід відзначити, що C:/Python34/– це ім’я директорії Вашого
комп’ютера, де розташовані файли та бібліотеки інтерпретатора Python, тому
цей запис може для різних комп’ютерів бути різним. Проте другий, третій та
четвертий рядки командного вікна завжди будуть однаковими.
Зверніть увагу на те, що в розглянутому коді програми з’явилась нова
для нас команда print. Призначення цієї команди дуже просте – виведення
змінної на екран. Річ у тому, що якщо в режимі роботи із командним рядком
нам достатньо було для цього записати ім’я змінної, а команда print
викликалась у цьому разі за замовченням, в файлах, які виконуються, цю
команду вже необхідно писати явно.
Недолік зовнішньої функції myprog.py, наведеної у прикладі 2.22,
полягає у тому, що вона не може бути викликаною із заданими параметрами
та повертати свої значення з метою їх подальшого використання для
проведення обчислень. Як ми бачили, математичні функції, описані у
підрозділі 2.4, працювали саме таким чином.
Для описання таких функцій у мові програмування Python
використовуються декларації із ключовими словами def та return.
Ключове слово def використовується на початку функції для її описання та
визначення її імені, а ключове слово return – для повернення обчисленого
значення функції у командний рядок або в іншу програму, із якої вона
викликається. Якщо повернення результатів обчислень не передбачається –
ключове слово return не пишеться.
Розглянемо приклад формування такої функції з іменем myprog1.py.
Приклад 2.23
def f(x):
x *= 2 # Множення значення x на число 2
return x

117
Ось така досить проста функція, у якій всього три рядки. Якщо
запам’ятати її в файлі myprog1.py описаним вище способом, її вже можна
викликати через ім’я f із заданим числовим параметром та використовувати
для проведення обчислень разом з іншими функціями математичної
бібліотеки. Із написаного програмного коду зрозуміло, що ця функція
приймає значення вхідного параметра x, а потім це значення множиться на 2
та повертається як результат роботи функції f. Але у цьому програмному
коді є також відповідні особливості, які ще нам не відомі. Зупинимось на них
та розглянемо їх більш досконало для подальшого використання.
1. Для кращого розуміння написаних програм розробники
дотримуються єдиного стиля їх оформлення, одне з правил якого полягає в
тому, що рядки в тілі функції відділяється від початку рядка з її описанням
def чотирма пробілами. Таким чином виходить, що всі рядки розташовані
під ім’ям функції. Виконання цього правила не впливає на аналіз
програмного коду інтерпретатором, але програмісту читати та розуміти такі
програми значно простіше. Дійсно, як говорить нам перше з правил філософії
мови Python, наведених у підрозділі 1.5: «Красиве є кращим, ніж
виродливе».
2. Для кращого розуміння написаного програмного коду біля
командних рядків програмісти часто ставлять відповідні коментарі. Всі
символи, які стоять після символу #, вважаються коментарями. Обмежень на
довжину рядка із коментарем та на символи абетки, яки в ньому
використовуються, у мові програмування Python не існує, тобто, коментарі
можуть писатися англійською, українською або іншими мовами. Зазвичай
саме наявність коментарів полегшує розуміння програмного коду. Дійсно,
згідно із сьомим правилом філософії мови Python: «Читаність має
значення».
Якщо файл myprog1.py, рядки якого наведені в прикладі 2.23,
запустити на виконання через натиснення клавіші F5, результат цієї дії,
відображений у командному, вікні буде мати такий вигляд.
118
>>>
======== RESTART C:/Python34/myprog1.py ========
>>>
Зрозуміло, що командні рядки виконані інтерпретатором, але на екран
нічого не виводиться, оскільки серед виконаних команд немає команди
print.
У наступному прикладі розглянемо, як можна використовувати
визначену функцію f() у математичних виразах для проведення більш
складних обчислень.
Приклад 2.24
>>> import math
>>> import myprog1
>>> c = myprog1.f(12)/myprog1.f(4)
>>> c
3
>>> d = myprog1.f(2)**myprog1.f(1)
>>> d
16
>>> q = d/2
>>> r = c*d/q
>>> r
6
>>> h = math.pow(c,f(2))
>>> h
81.0000000000000000
>>> s = math.sin(f(2)*math.pi)
>>> s
0.0000000000000000
>>> cs = math.cos(((f(2)-1)*math.pi)/f(2))
>>> cs
-0.70710678118655
>>>

119
З іншого боку, якщо помістити у файл myprog1.py описану вище
системну функцію print, призначену для виведення результатів розрахунків
на екран, відповідні значення будуть виводитися у командному вікні.
Розглянемо наступний приклад.
Приклад 2.25
def f(x):
x *= 2 # Множення значення x на число 2
return x
print (f(12)/f(4))
# Виведення на екран значення виразу (f(12)/f(4))
print (f(2)**f(1))
# Виведення на екран значення виразу (f(2)**f(1))
import math
# Підключаємо бібліотеку маетматичних функцій math
print (math.pow(f(12)/f(4),f(2)))
# Виведення на екран значення виразу
# math.pow(f(12)/f(4),f(2))
print (math.cos(((f(2)-1)*math.pi)/f(2)))
# Виведення на екран значення виразу
# math.cos(((f(2)-1)*math.pi)/f(2))
Тоді результат виконання цієї функції, збереженої під іменем
myprog1.py, буде наступним.
>>> f()
3
16
81
-0.70710678118655
>>>
Зрозуміло, що команда f() у командному рядку інтерпретатора Python
відповідає натисненню клавіші F5 в оболонці IDLE. Єдиною відмінністю є

120
те, що рядок із знаками «=» та ім’ям файлу у цьому разі не пишеться [24, 25].
Такий формат виклику функції без параметрів був запозичений
розробниками мови Python із мов програмування С та С++ [3, 10, 15].
Слід відзначити, що часто використовувати системну функцію
print() у функціях користувача не варто, оскільки, по-перше, це
уповільнює виконання інтерпретатором програмного коду через багаторазове
виведення інформації на екран та виклик переривань, а по-друге, зазвичай
така інформаціє для програміста є зайвою. З іншого боку, цю команду можна
використовувати для контролю значень змінних під час відлагодження
програми в оболонці IDLE.
Важливим є те, що команда print() може мати кілька параметрів,
серед яких часто використовують рядкові змінні для виведення на екран
записаної інформації. Як було відмінено раніше, рядкова змінна у Python –
це просто набір відповідних символів, взятих у лапки. Більш досконало
рядкові змінні розглядатимуться у підрозділі 2.6, а параметри функції
print() – у підрозділі 2.6.4. Перепишемо приклад 2.25 наступним чином.
Приклад 2.26
def f(x):
x *= 2 # Множення значення x на число 2
return x
c = f(12)/f(4)
print (‘a = f(12)/f(4) = ’, c)
# Виведення на екран значення виразу (f(12)/f(4))
d = f(2)**f(1)
print (‘d = f(2)**f(1) =’, d)
# Виведення на екран значення виразу (f(2)**f(1))
import math
# Підключаємо бібліотеку маетматичних функцій math
h = math.pow(f(12)/f(4),f(2))
print (‘h = math.pow(f(12)/f(4),f(2)) = ’,h)

121
# Виведення на екран значення виразу
# cs = math.pow(f(12)/f(4),f(2))
cs = math.cos(((f(2)-1)*math.pi)/f(2))
print (‘cs = math.cos(((f(2)-1)*math.pi)/f(2)) = ’,cs)
# Виведення на екран значення виразу
# cs = math.cos(((f(2)-1)*math.pi)/f(2))
Результатом виклику цієї функції через команду f() будуть наступні
рядки у командному вікні інтерпретатора Python.
>>> f()
a = f(12)/f(4)= 3
d = f(2)**f(1) = 16
h = math.pow(f(12)/f(4),f(2)) = 81
cs = math.cos(((f(2)-1)*math.pi)/f(2)) = -0.70710678118655
>>>
Зрозуміло, що результат виклику функції f(), записаної у прикладі
2.26, є значно більш інформативним, ніж результат виклику більш простої
функції, наведеної у прикладі 2.25.
Також слід відзначити, що, на відміну від системи програмування
науково-технічних розрахунків MatLab, де вважається, що ім’я файлу та ім’я
функції, визначеної в ньому, повинні співпадати, у мові програмування
Python виконання цього правила не є обов’язковим. Тому під час написання
програм необхідно слідкувати за тим, щоб імена всіх функцій користувача,
визначених у файлах, були різними. Якщо виникає інша ситуація, коли
декілька файлів містять функції із однаковими іменами, обробка імен файлів
та виклик відповідних правильних функцій також можуть бути здійснені
інтерпретатором, але вже трішки інакше, за принципами модульного
програмування [6 – 9, 18, 19]. Відповідні теоретичні відомості будуть
наведені у підрозділі 2.5.4.

122
2.5.3 Способи роботи з функціями та визначення їхніх параметрів
та змінних через простір імен
Іншим важливим інструментом програмування мови Python для роботи
з функціями є апарат глобальних та локальних змінних. Він дозволяє
ефективно працювати із простором імен змінних, розрізняючи їх значення в
межах тіла функції та за його межами. Цей механізм працює наступним
чином. Змінним із вже визначеним іменем в тілі функції присвоюються інші
значення, котрі після виходу із функції вже не використовуються, оскільки їм
повертається надане раніше, попереднє значення. Такий механізм для роботи
зі змінними також реалізований та ефективно використовується в системі
науково-технічних розрахунків MatLab [6, 7]. Загалом він реалізує
концепцію абстрагування даних в ідеології об’єктно-орієнтованого
програмування, яка описується визначенням 1.7.
Надамо відповідні визначення [24 – 29].
Визначення 2.1 Глобальними змінними називаються такі змінні, які
визначаються та можуть використовуватися в межах всього програмного
модуля, якщо в тілі функції їх значення не перекриває локальна змінна, яка
має вищий пріоритет.
Визначення 2.2 Локальними змінними називаються такі змінні, які
можуть бути визначеними в тілі функції та замінюють значення глобальних,
оскільки локальні змінні мають вищий пріоритет. Після виходу за межі тіла
функції локальні змінні перестають працювати, тоді всім змінним,
визначеним як локальні, повертається попередні значення глобальних
змінних.
Пояснимо взаємозв’язок між локальними та глобальними змінними
наступним чином. Припустимо, що за межами тіла функції стоїть оператор
присвоювання a = 5. Ця змінна є глобальною і це значення, якщо воно не
змінюється, діє для всієї програми. Проте якщо у тілі функції записано
оператор присвоювання a = 3, ця декларація буде оголошувати локальну

123
змінну, а не зміну значення визначеної раніше глобальної змінної a. З
практичної точки зору це означає, що лише в тілі функції змінна a буде
приймати локальне значення 3, а після виходу за межі тіла функції змінній a
повертається глобальне значення 5.
Розглянемо приклад використання декларацій локальних та глобальних
змінних у мові Python.
Приклад 2.27
a = 3 # Глобальна змінна
print (‘Глобальна змінна a =’, a)
y = 8 # Глобальна змінна
print (‘Глобальна змінна y =’, y)
def func():
print (‘func(): Глобальна змінна a =’, a)
y = 5 # Локальна змінна
print (‘func(): Локальна змінна y =’, y)
func()# Виклик функції func()
print (‘??? y =’, y)
# Тепер відображується глобальна змінна
Після виконання цієї програми в оболонці IDLE через натиснення
функціональної клавіші F5 у командному вікні інтерпретатора отримуємо
наступний результат.
>>>
======== RESTART C:/Python34/myprog2.py ========
Глобальна змінна a = 3
Глобальна змінна y = 8
func(): Глобальна змінна a = 3
func(): Локальна змінна y = 5
??? y = 8
>>>
Цікавим є те, що у наведеному фрагменті програми відсутнє ключове
слово return. Як вже було відмічено раніше, воно пишеться в мові Python
124
лише тоді, коли обчислене значення функції необхідно повернути до
головної програми. У випадку, коли функціє лише виконує відповідні дії, а
результат обчислень не повертається, тілом функції вважаються ті рядки, які
стоять нижче ключового слова def та починаються з чотирьох пробілів.
Такій підхід, хоча і є дещо нестандартним, значно спрощує написання та
розуміння програмного коду.
Хоча розглянутий механізм визначення локальних та глобальних
змінних є досить універсальним та надійним для написання ефективного та
безпомилкового програмного коду, його недолік полягає в тому, що
усередині тіла функції неможливо змінити значення глобальної змінної. Для
уникнення цієї ситуації у разі необхідності виконання такої дії, слід спочатку
описати глобальну змінну в тілі функції з використанням ключового слова
global. Тоді така змінна не буде вважатися локальною. З урахуванням
сказаного перепишемо програмний код, наведений у прикладі 2.27,
наступним чином.
Приклад 2.28
a = 3 # Глобальна змінна
print (‘Глобальна змінна a =’, a)
y = 8 # Глобальна змінна
print (‘Глобальна змінна y =’, y)
def func():
print (‘func(): Глобальна змінна a =’, a)
global y # Описання глобальної змінної
y = 5 # Глобальна змінна
print (‘func(): Глобальна змінна y =’, y)
func()# Виклик функції func()
print (‘??? y =’, y)
# Тепер відображується глобальна змінна
Виконання цієї програми дає такий результат.
>>>

125
======== RESTART C:/Python34/myprog3.py ========
Глобальна змінна a = 3
Глобальна змінна y = 8
func(): Глобальна змінна a = 3
func(): Глобальна змінна y = 5
??? y = 5
>>>
Апарат локальних та глобальних змінних може бути ефективно
використаний для роботи із простором імен Вашої програми. Дійсно, як
сказано в останньому, шістнадцятому принципі філософії мови Python:
«Простори імен – це дуже гарна ідея, тому варто створювати їх
побільше». Проте, коли Ви будете це робити, не забувайте також про другий,
третій та четвертий принципи, які є більш важливими: «Явне є кращим, ніж
побічне»; «Просте є кращим, ніж складне»; «Складне є кращим, ніж
ускладнене». Тобто, якщо використання великої кількості локальних та
глобальних змінних певною мірою ускладнює Ваш програмний код, можливо
варто пошукати більш просте те ефективне рішення.
Оскільки функції, як і змінні та інші лінгвістичні конструкції,
описуються у мові Python через об’єкти, на ім’я функції можна послатися як
на відповідний описаний об’єкт. У разі такого посилання використовується
принцип інтерфейсної природи об’єкту, описаний у підрозділі 1.3. Тобто,
змінна лише посилається на ім’я функції та нібито є синонімом для нього, а
надалі звернення до змінної із відповідними параметрами відповідає виклику
функції. Цей механізм роботи з функціями легко зрозуміти на наступному
прикладі.
Приклад 2.29
def mean(x, y):
return (x + y)/2
f = mean
# Посилання на ім’я функції mean через змінну f

126
v = f(9, 5) # Виклик функції mean через змінну f
print (‘v =’, v)
Виконання цього програмного коду дає наступний результат у
командному вікні.
>>>
======== RESTART C:/Python34/myprog4.py ========
v = 7
>>>
Тобто, посилання на ім’я функції без параметрів у виразі f = mean
означає лише підбір еквівалентного імені, а не виклик функції та присвоєння
змінній обчисленого значення. Якщо функція не має параметрів, для її
виклику слід використовувати лінгвістичну конструкцію f(), де f – ім’я
функції.
Посилання на ім’я функції через ім’я змінної можна легко зрозуміти
через таку життєву ситуацію. Припустимо, що у Вас є друг Василь, дуже
кріпкий та міцний, який через це серед друзів має прізвисько «Силач». Тоді
Ви, а також всі інші друзі, може звертатися до нього за цим прізвиськом, і він
завжди зрозуміє, що звертаються саме до нього.
Цікавим є те, що у мові програмування Python параметри функції
можуть бути заданими за замовченням. У цьому разі, якщо параметр під час
виклику функції не переданий, береться його значення за замовченням, а
якщо він переданий – значення за замовченням ігнорується та
використовується передане значення. Тобто, у цьому випадку значення за
замовченням можна вважати глобальною змінною, а передане значення –
локальною. Перепишемо приклад 2.29 наступним чином.
Приклад 2.30
def mean(x, y = 0):
return (x + y)/2
f = mean
v = f(10) # Виклик функції mean з одним параметром

127
print (‘v =’, v)
q = f(10,6) # Виклик функції mean з двома параметрами
print (‘q =’, q)
Виконання програмного коду, записаного у цьому прикладі, дає
наступний результат у командному вікні.
>>>
======== RESTART C:/Python34/myprog5.py ========
v = 5
q = 8
>>>
Слід відзначити, що якщо є посилання на ім’я функції через змінну, ця
змінна може бути використана як аргумент іншої функції. Відповідна
лінгвістична конструкція мови програмування Python використана в
наступному прикладі.
Приклад 2.31
def mean(x, y = 0):
return (x + y)/2
def call_fcn(name_fcn, x, y):
return name_fcn(x, y)
v = call_fcn (mean,10)
# Виклик функції mean з одним параметром
# через функцію call_fcn
print (‘v =’, v)
q = call_fcn (mean,10,6)
# Виклик функції mean з двома параметрами
# через функцію call_mean
print (‘q =’, q)
Результат виконання цієї програми цілком аналогічний результату,
отриманому для прикладу 2.30. Проте така програма є більш універсальною,
оскільки ім’я функції, яка викликається для проведення розрахунків, можна
задавати як перший параметр іншої функції call_fcn.
128
Використання імені змінної, яка посилається на функцію, як аргументу
іншої функції, можна легко пояснити через наступну життєву ситуацію.
Нехай один із Ваших друзів має прізвисько «Силач», а інший – прізвисько
«Високий». Ви підходите до Василя за прізвиськом «Силач» та кажете йому:
«Силач, передай Високому 10 гривень!». Зрозуміло, що Василь без проблем
зрозуміє Вас і виконає Ваше прохання.
Тіла функцій у мові програмування Python можуть бути вкладеними,
проте вони не можуть перетинатися, що є загальним правилом структурного
програмування [3, 5 – 7]. Розглянемо принцип роботи вкладених функцій із
посиланням із зовнішньої функції на внутрішню у наступному прикладі.
Приклад 2.32
def outer(z, t):
def inner(x, y):
return (x + y)/2
return inner(z, t)
>>> v = outer(10,6)
>>> v
8
Код програми, яка наведена у прикладі 2.32, працює наступним чином.
1. Командним рядком v = outer(10,6) викликається функція
outer() із параметрами (10,6).
2. Згідно із командою return inner(z, t) яка завершує тіло
функції outer(), результатом роботи цієї функції є виклик внутрішньої
функції inner(z, t).
3. Параметри функції inner(x, y) у даному випадку передаються,
через механізм успадкування властивостей об’єктів, від зовнішньої функції
до внутрішньої. Це означає, що для випадку, який розглядається, x = z,
y = t.
4. Оскільки функція inner(x, y), згідно із командою
return (x + y)/2, повертає значення (x + y)/2, результатом виклику
129
функція outer() із параметрами (10,6) є значення (x + y)/2 = 8.
Іншим цікавим прикладом роботи із вкладеними функціями в мові
програмування Python є механізм зімкнення. Надамо відповідне визначення
[24 – 29].
Визначення 2.3 Зімкненням у мові програмування Python називається
посилання на ім’я внутрішньої функції із зовнішньої.
Робота із зімкненими функціями здійснюється наступним чином.
1. Тіло зовнішньої функції завершується ключовим словом return із
посиланням на ім’я внутрішньої функції без параметрів, наприклад, return
inner.
2. Посилання на внутрішню функцію здійснюється через оператор
присвоювання. Результатом роботи такого оператора є присвоєння
відповідній змінній посилання на відповідну адресу, де розташований
результат роботи зовнішньої функції.
3. Після виконання команди _name(), де _name() – ім’я змінної,
повертається обчислене значення функції, яке було збережено в пам’яті під
час створення цієї змінної.
Тобто, спочатку посилання на ім’я внутрішньої функції здійснюється
без параметрів, що відповідає не обчисленню значення функції, а посиланню
на її ім’я. Потім параметри зімкненої функції задаються підчас її виклику, але
змінній _name присвоюється не значення функції, а лише посилання на
відповідну адресу, за якою це значення зберігається. І лише після посилання
на визначену властивість об’єкта через команду _name() можна отримати
значення відповідної функції із заданим параметром.
Розглянемо приклад використання механізму зімкнення у
найпростішому варіанті.
Приклад 2.33
def kn(x, y):
def inner():
return (x + y)/2
130
return inner
>>> v = kn(10,6)
>>> v
<function kn.<locals>.inner at 0x0297A0C0>
>>> v()
8
Зрозуміло, що механізми вкладених та зімкнених функцій є досить
ефективними з точки зору роботи з функціями як з об’єктами та дозволяють
розв’язувати вкрай складні обчислювальні завдання з використанням
методології ООП. Дійсно, згідно із шістнадцятим правилом філософії мови
Python: «Простори імен – це дуже гарна ідея, тому варто створювати їх
побільше». Проте, якщо ви будете користуватися цим правилом, ніколи не
забувайте й інші, напевно, більш важливі правила, як-то: «Однорівневе є
кращим, ніж вкладене»; «Складне є кращим, ніж ускладнене»; «Явне є
кращим, ніж побічне»; «Якщо реалізацію складно пояснити, така ідея є
поганою»; «Читаність має значення». У будь-якому разі, сьогодні
головними перевагами мови програмування Python над іншими мовами
вважається її простота, лаконічність та орієнтація, головним чином, на явні, а
не на побічні методи описання властивостей об’єктів. А внутрішню
структуру складних об’єктів програмісти, які пишуть на мові Python,
зазвичай намагаються приховувати через використання механізму
абстрагування. Саме тому такі складні механізми роботи з функціями, як
апарат локальних та глобальних змінних, вкладені функції та зімкнення в
програмах, написаних на Python, використовуються лише в особливих
випадках. А згідно із восьмим правилом філософії мови Python: «Особливі
випадки є не настільки особливими, щоб порушувати загальні правила».
Більш поширеним та ефективним способом роботи з функціями в мові
програмування Python є використання модульної структури програм,
оскільки такий підхід зазвичай є значно простішим та дозволяє програмістам
працювати на вищому рівні абстрагування [24 – 29]. Наприклад, саме

131
модульний підхід був використаний для створення математичних бібліотек,
описаних у підрозділі 2.4.
Головні особливості роботи із модулями, реалізовані у мові Python,
будуть розглянуті у наступному підрозділі.

2.5.4 Програмні модулі та способи роботи з ними


У попередньому підрозділі під час описання засобів мови Python для
роботи із функціями не був розглянутий один важливий випадок. Виникають
доречні питання: «А що буде, якщо в різних файлах визначити функції з
однаковими іменами? Як інтерпретатор зможе розрізнити їх та викликати
необхідну функцію?».
У теорії ООП способи обробки функцій, або методів, які мають
однакові імена, але працюють із різними об’єктами, розглядаються окремо
[8 – 10, 15, 16]. Надамо відповідне визначення [8 – 10].
Визначення 2.4 Методи або функції, які мають однакові імена, але
використовуються для обробки різних об’єктів, у теорії ООП називаються
перевантаженими.
Зазвичай під час створення програмного коду звернення до
перевантаженої функції здійснюється через посилання на об’єкт, для якого
вона використовується у даній частині програмного коду. Саме такий
механізм обробки перевантажених функцій реалізований і в мові Python, і він
тісно пов’язаний із засобами модульного програмування. Більш того, ми вже
один раз інтуїтивно скористалися цим механізмом, але без його описання та
ретельного аналізу. Нам вдалося це зробити лише тому, що лінгвістичні
засоби мови Python для роботи з модулями є досить простими та наочними.
Тобто, ми нібито поступили як Журден у п’єсі відомого французького
драматурга Жана-Батиста Мольєра «Міщанин – шляхтич», який все життя
розмовляв прозою і нічого про це не знав.
Повернемося до математичних функцій, призначених для роботи із
дійсними та комплексними числами, які були розглянуті у підрозділі 2.4. Ці
функції мають однакові імена, наприклад, exp(), cos(), asin() тощо,
але вони реалізовані в різних бібліотечних файлах, або в різних модулях. Для
132
посилання на функції, призначені для роботи з дійсними числами, ми
використовували модуль math, а для обробки комплексних чисел був
використаний інший модуль cmath. У підрозділі 2.4 також були розглянуті
лінгвістичні засоби мови Python для роботи з модулями, які є досить
простими та формулюються у вигляді наступних двох правил.
1. Перед посиланням на функції, описані у відповідному модулі з ім’ям
module_name, необхідно підключити цей модуль до власної програми з
використанням директиви
include module_name.
2. Для виклику функції з ім’ям function_name(), яка належить до
модуля module_name, необхідно спочатку вказати ім’я модуля, а потім,
через крапку – ім’я функції. Тобто, відповідна лінгвістична конструкція мови
Python має наступний вигляд:
var_name = module_name.function_name(),
де var_name – ім’я змінної.
Оскільки модулі, як і функції, у Python створені через описання
об’єктів, на рівні ООП змінна id1 відповідає модулю, а змінні id2, id3, ... ,
idN – відповідним функціям, за такої умов кількість функцій, які
викликаються, складає N – 1. Спосіб автоматичного надання об’єктам імен
у мові Python був розглянутий у підрозділі 2.3.
Але можна імпортувати не модуль, а лише одну його окрему функцію,
відповідна лінгвістична конструкція мови Python має наступний вигляд [24 – 29]:
from module_name import function_name,
де function_name – ім’я функції, яка імпортується.
Якщо ж необхідно імпортувати не одну, а декілька функцій, ця
лінгвістична конструкція дещо змінюється [24 – 29]:
from module_name import (function_name_1,\
function_name_2, function_name_3, ..., \
last_function_name) ,
де last_function_name – ім’я останньої функції
Наприклад:
from math import (sin, cos, asin, acos)
133
Якщо здійснений імпорт функції, а не модуля, на такі функції можна
посилатися, не вказуючи імені модуля. Такий імпорт функцій із модуля має
певні переваги над імпортом всього модуля. По-перше, коди таких програм
займають менший об’єм в оперативній пам’яті комп’ютера, а по-друге, вони
у значній мірі спрощуються, оскільки відпадає необхідність перед ім’ям
функції вказувати ім’я модуля, якому вона належить. Проте спосіб імпорту
функцій може бути використаний лише тоді, коли в програмі
використовується невелика їх кількість та чітко відомо, які функції із модуля
мають бути використані.
Наприклад, перепишемо приклад 2.19, використовуючи не імпорт
модуля, а імпорт функцій.
Приклад 2.34
>>> from math import pow
>>> a = abs(–2)
>>> r = round(4.3)
>>> p = pow(a, r)
>>> p
16
Наведемо тепер інший приклад, у якому створимо перевантажену
функцію, та розглянемо, як працюють відповідні командні рядки.
Приклад 2.35
>>> def sqrt (x):
return x*x
>>> sqrt (5)
25
>>> from math import sqrt
>>> sqrt (9)
3.0
Результат роботи наведених команд мови програмування Python
неважко зрозуміти. У перших двох рядках створена функція sqrt (x), яка
обчислює квадрат від параметра x, який передається. І перший виклик цієї
функції дає саме такий результат, оскільки 52 = 25. Але після цього ми
завантажили з математичного модуля math іншу функцію, яка також має
ім’я sqrt. Із визначення 2.4 зрозуміло, що тепер функція sqrt є
134
перевантаженою. Також зрозуміло, що призначення функції sqrt модуля
math є зовсім іншим, ніж функції sqrt, створеної користувачем та описаної
в перших командних рядках. Дійсно, функція math.sqrt обчислює не
квадрат, а квадратний корінь від переданого аргументу. Саме такий результат
отриманий в двох останніх командних рядках. Цей результат легко пояснити
з точки зору принципів ООП. В результаті створення функції sqrt
інтерпретатор надає цьому об’єкту відповідне ім’я id1. Коли ми
завантажуємо із модуля math іншу функцію sqrt та не посилаємось на ім’я
відповідного модуля, інтерпретатор просто робить заміну значення змінної
id1. Тобто, під тим самим ім’ям завантажується інший об’єкт. Відповідність
між іменами змінних, які описують об’єкт «функція sqrt» та командними
рядками, записаними у прикладі 2.35, показана у таблиці 2.5.

Таблиця 2.5 – Об’єктні змінні, які відповідають рядкам завантаження


функцій, завантажених та використаних у прикладах 2.35 та 2.36
Приклад 2.35
Командний рядок Ім’я об’єктної Функція
змінної
def sqrt (x): id1 Функція користувача
sqrt
from math import sqrt id1 Функція sqrt
модуля math

Приклад 2.36
Ім’я об’єктної змінної Ім’я об’єктної Функція
змінної
def sqrt (x): id1 Функція користувача
sqrt (x)
math.sqrt (9) id3 Функція math.sqrt

Тепер розглянемо інший приклад, в якому звернення до функції sqrt


модуля math здійснюється інакше, через імпорт модуля.
135
Приклад 2.36
>>> def sqrt (x):
return x*x
>>> sqrt (5)
25
>>> import math
>>> math.sqrt (9)
3.0
>>> sqrt (9)
81
Як бачимо, тепер командні рядки працюють правильно. Єдиною
відмінністю цього програмного коду від коду, наведеного у прикладі 2.35, є
правильне описання перевантаженої функції sqrt. Виклик функції
користувача здійснюється безпосередньо через ім’я функції, а для виклику
функції sqrt модуля math вказується повне ім’я даного об’єкта, із
визначенням імені модуля. У такому випадку функції користувача відповідає
об’єктна змінна id1, модулю math – об’єктна змінна id2, а перевантаженій
функції sqrt модуля math – об’єктна змінна id3. Відповідність між
іменами функцій та іменами об’єктних змінних для прикладу 2.36 також
показана в таблиці 2.5.
У наведених прикладах 2.35 та 2.36 яскраво проілюстрований
одинадцятий принцип філософії мови програмування Python: «Якщо Ви
зустріли двозначність, не варто спокушати себе, що Ви вгадаєте вірне
значення».
Тепер, коли ми знаємо, як завантажувати модулі та описані в них
функції, неважко створити власний модуль. У графічній оболонці IDLE
запишемо наступний, дуже простий програмний код.
Приклад 2.37
def q():
return 5
Слід відзначити, що інтерфейс оболонки IDLE трішки відрізняється від
інтерфейсу програми Python Shell. Замість Опції меню Debug тут стоїть
136
опція Run, яка має наступні команди меню.
– Python Shell – перехід до вікна командного рядку.
– Check Module – перевірка модуля.
– Run Module – запустити модуль на обробку.
Рядок командного меню оболонки IDLE та спливаючи вікно для опції
Run показані на рис. 2.19.

Рис. 2.19 Опція меню Run оболонки редагування файлу IDLE (екранна копія)

Для створення модуля та подальшої роботи з ним необхідно записати


цей код до файлу із заданим ім’ям та із розширенням py, наприклад, до
файлу module_1.py. Проте, для подальшої коректної роботи із модулем,
цей файл необхідно зберегти у папці комп’ютера, яка є доступною для
читання інтерпретатором Python. Зазвичай такими є папками
C:\\Python34 та C:\\Python34\\Lib, проте завжди варто перевірити,
чи так є насправді. Це легко зробити з використанням системної функції
path, яка розташована в модулі sys. Тобто, згідно із теоретичними
відомостями, наведеними у підрозділі 2.5.4, в інтерпретаторі мови Python
необхідно виконати наступні команди.
Приклад 2.38
>>> import sys
>>> sys.path
Результатом виконання цих двох команд буде текст, виведений у вікні
інтерпретатора, аналогічний наступному.
[‘’,‘C:\\Python34\\Lib\\idlelib’,‘C:\\Python34\\Lib\\’,
‘C:\\Python34\\DLLs\\’,‘C:\\Python34\\’ ]
Професіональному програмісту такий текст не важко зрозуміти. Папки,

137
доступні для інтерпретатора, взяти в лапки та перелічені через коми.
Наприклад, доступною є папка ‘C:\\Python34\\Lib\\’, туди і
збережемо створений файл під ім’ям module_1.py.
Існує інша можливість подивитися шляхи до папок, які читаються
інтерпретатором Python. Після запуску оболонки IDLE необхідно зайти до
опції командного меню File → Path Browser. У цьому разі всі шляхи до
доступних папок відображуються в інформаційному вікні, аналогічному
наведеному на рис. 2.20.

Рис. 2.20 Перегляд папок, доступних для читання інтерпретатором з


використанням опції меню оболонки IDLE File → Path Browser (екранна
копія)

Вся підготовча робота зроблена. Тепер можна звернутися до функції q


через імпорт модуля module_1.py, відповідні лінгвістичні конструкції мови
Python вже були описані у цьому підрозділі вище. Розглянемо наступний
приклад.
Приклад 2.39
>>> import module_1
>>> import math
>>> module_1.q()
5
>>> c = math.sin(module_1.q()*math.pi/2)
>>> c
1.0000000000000000

138
>>>
Із прикладу 2.39 видно, що створена функція q(), розташована у
модулі module_1, працює коректно та може бути використана як аргумент
інших, зокрема математичних функцій.
Створимо ще один модуль з іменем module_2.py, який також
розташуємо у папці ‘C:\\Python34\\Lib\\’. В створеному файлі
module_2.py запишемо лише один командний рядок з виведенням тексту
на екран:
print (‘Тестування функцій роботи з модулем’)
Після збереження файлу module_2.py наберемо у вікні
інтерпретатора наступні командні рядки.
>>> import module_2
Тестування функцій роботи з модулем
>>> import module_2
>>>
Як бачимо, під час першого завантаження модуля рядок, заданий у
функції print, був виведений на екран, тобто, можна сказати, що операція
завантаження виконана. Але під час другого завантаження цей рядок чомусь
не виводиться. Річ у тому, що відповідний модуль вже завантажений, а
завантаження модуля – це досить ресурсоємна операція, вона потребує
певних ресурсів оперативної пом’яті комп’ютера. А повторне завантаження
того ж самого модуля – це зайва операція, оскільки модуль вже
завантажений. Тобто, у даному разі повторне завантаження модуля робиться
програмістом помилково, але інтелектуальний інтерпретатор Python у даному
випадку не повідомляє про це, а просто ігнорує невірну дію, оскільки вона
ніяк не може вплинути на подальше виконання будь-яких інших команд та на
хід проведення обчислень.
Такі ситуації бувають і у реальному житті. Наприклад, батько Вам
каже: «Синку, піди до крамниці купити хліба до вечері», проте Ви чітко
знаєте, що вже купили хліб, їдучи з університету додому. Оскільки Ви у цей
час виконуєте курсову роботу та дуже зайняті, Ви, хоча й чуєте батька, але,
вважаючи, що у даному разі він помиляється, можете просто ігнорувати його
139
прохання.
Дійсно, згідно із десятим принципом філософії мови програмування
Python: «Про помилки ніколи не можна замовчувати, якщо вони не
замовчуються явно».
Тепер припустимо іншу ситуацію. Модуль module_2 був змінений в
процесі роботи над програмою та його дійсно необхідно перевантажити.
Наприклад, замість рядка ‘Тестування функцій роботи з модулем’
написаний рядок ‘Робота з модулем та тестування функцій’. Як
бути у цьому випадку, адже ж тепер модуль module_2 дійсно необхідно
перезавантажити? Це можна зробити з використанням функції
інтерпретатора Python reload, яка належить до модуля imp [24].
Розглянемо відповідний приклад.
Приклад 2.40
>>> import module_2
Тестування функцій роботи з модулем
>>> import module_2
>>> import imp
>>> imp.reload(module_2)
Робота з модулем та тестування функцій
<module ‘module_2’ from ‘C:\\Python34\\Lib\\ module_2.py’>
>>>
Аналогічна ситуація також може статися і в реальному житті.
Припустимо, що Ваш діалог з батьком не закінчився. Ви мовчите, але батько
наполягає на тому, щоб Ви пішли в крамницю купити хліба до вечері. Ви
незадоволено відповідаєте, що вже купили, але батько відповідає Вам так:
«Знаю. Ти купив чорний хліб, а ми з мамою хотіли б на вечерю поїсти
білого». Тоді ви розумієте, що хоча поставлене батьком завдання частково
вже виконане, але не повністю, і Вам все ж таки прийдеться сходити до
крамниці.
Так само і в прикладі 2.40. Спочатку інтерпретатор Python ігнорував
вашу команду про повторне завантаження зміненого модуля module_2, але
через команду imp.reload(module_2) Ви змусили його виконати цю

140
операцію.
Не дуже зручним з точки зору ефективності написання програми є те,
що для кожного виклику функції слід писати повне її ім’я із зазначенням
модуля, в якому вона розташована. Якщо це ім’я є довгим, написання тексту
програми у значній мірі ускладнюється та займає багато часу. Спростити цю
задачу можна, якщо виконати імпорт модуля із наданням йому більш
короткого імені, яке називається псевдонімом. Відповідна лінгвістична
конструкція мови Python має такий вигляд:
import module_name as var_name
де var_name – ім’я змінної, якій у даному випадку присвоюється ім’я
модуля module_name.
Розглянемо приклад ефективного використання цієї лінгвістичної
конструкції, переписавши приклад 2.39 наступним чином.
Приклад 2.41
>>> import module_1 as m1
>>> import math
>>> m1.q()
5
>>> c = math.sin(m1.q()*math.pi/2)
>>> c
1.0000000000000000
Таким же чином, через псевдонім, можна інтегрувати із модулів і
окремі функції. Розглянемо відповідний приклад.
Приклад 2.42
>>> from math import degrees as dg
>>> from math import atan as atg
>>> fi = atg(1)
>>> fid = dg(fi)
>>> fid
45.000000000000
Тобто, як для імен модулів, так і для імен функцій, можна
використовувати псевдоніми. Як із Вашим другом Василем-Силачем, Ви
замість «Василю!» можете казати «Силач!», і він завжди Вас зрозуміє.

141
2.5.5 Робота у командному вікні інтерпретатора в діалоговому
режимі та тестування програмних модулів
Всі функції, які були написані нами раніше, викликалися або без
параметрів, або із параметрами, які обчислювались або задавались явно під час
виклику функції. Зазвичай на практиці більш важливим для забезпечення
ефективної роботи користувачів програмного забезпечення є реалізація
інтерактивного режиму роботи у текстовому або графічному вікні, коли
необхідні дані вводяться з клавіатури під час роботи з запущеною програмою, а
результати розрахунків виводяться після завершення її роботи [6, 7, 16].
Якщо для виведення даних у текстовому вікні інтерпретатора може
бути використана вже відома нам функцію print(), для введення даних для
введення даних з клавіатури використовується аналогічна їй команда
input() [24 – 29]. Відповідна лінгвістична конструкція мови
програмування Python записується наступним чином.
input (‘string_1’),
де string_1 – рядкова змінна, взята в лапки.
Функція введення даних input() працює наступним чином. Записана
рядкова змінна виводиться на екран, після чого програма переходить в режим
очікування введення даних з клавіатури. Введення даних закінчується через
натиснення клавіші «Enter», і вся введена інформація інтерпретується
програмою як рядок символів. Для переведення рядкової змінної до
числового формату використовуються функції int()або float(),
розглянуті у підрозділі 2.4.3. Більш досконало інтерактивний режим роботи
програми із введенням даних з клавіатури розглядатиметься у підрозділі
2.6.4.
Розглянемо наступний приклад програми, написаної мовою Python та
збереженої під ім’ям module_3. У цьому прикладі створений модуль, який
працює в діалоговому режимі.
Приклад 2.43
def func(x, y):
return x**y
142
x = int(input (‘Введіть значення x’))
y = int(input (‘Введіть значення y’))
print (‘x**y = ’,func(x, y))
Імпортування модуля module_3 у вікні інтерпретатора дає наступний
результат.
>>> import module_3
Введіть значення x
4
Введіть значення y
3
x**y = 64
Особливості створення графічного віконного інтерфейсу користувача з
використанням засобів мови програмування Python розглядатимуться у
розділі 5.
Останнім, але вкрай важливим етапом написання програмного
забезпечення, є його тестування для відповідних простих завдань із
заздалегідь відомим розв’язком. Слід відзначити, що в інтерпретаторі мови
Python тестування коду написаних функцій можна проводити автоматично з
використанням функції testmod(), розташованої у модулі doctest [24 –
29]. Розглянемо простий приклад формування тестів.
Приклад 2.44
def mean(v1, v2, v3):
“””Обчислення середнього арифметичного трьох чисел
та виведення результатів на екран з трьома
знаками після десяткової коми
>> mean(20, 30, 70)
40.0
>>> mean(1, 5, 8)
4.667
“””
return round((v1 + v2 + v3)/3,3)
import doctest

143
# Автоматична перевірка заданих тестів
# через запуск програми testmod()
# модуля doctest
# from doctest import testmod
testmod()
Якщо запустити таку програму на виконання, вона нічого не виводить
на екран, що свідчить про те, що тести пройдені успішно. Сутність таких
тестів є наступною. В них введені командні рядки інтерпретатора для
обчислення виразів (20 + 30 + 70)/3 та (1 + 5 + 8)/3 з точністю
до третього знаку. Зрозуміло, що (20 + 30 + 70)/3 = 40.0, а
(1 + 5 + 8)/3 = 4.667. Тобто, результати двох викликів функції
mean(), задані в тестах, є правильними, а у цьому разі функція тестування
testmod() не виводить на екран ніяких повідомлень.
Тепер спеціально внесемо в наші тести помилки, переписавши
програму, наведену у прикладі 2.44, наступним чином.
Приклад 2.45
def mean(v1, v2, v3):
“””Обчислення середнього арифметичного трьох чисел
та виведення результатів на екран з трьома
знаками після десяткової коми
>> mean(20, 30, 70)
60.0
>>> mean(1, 5, 8)
7.667
“””
return round((v1 + v2 + v3)/3,3)
import doctest
testmod()
Результат виконання програми, наведеної у прикладі 2.45, буде
наступним.
>>>

144
======== RESTART C:/Python34/module4.py ========
*****************************************************
File “C:/Python34/module4.py”, line 4 in __main__.mean
Failed example:
mean(20, 30, 70)
Excepted:
60.0
Cot:
40.0
*****************************************************
File “C:/Python34/module4.py”, line 4 in __main__.mean
Failed example:
mean(1, 5, 8)
Excepted:
6.667
Cot:
7.667
*****************************************************
1 item had 2 failures
2 of 2 in __main__.mean
***Test Failed*** 2 failures.
>>>
Зрозуміло, що тестування та відлагодження професійного програмного
забезпечення є вкрай важливим кінцевим етапом його розробки, тому
наявність спеціальної функції для проведення тестів написаних модулів в
інтерпретаторі мови Python свідчить про те, що ця мова орієнтована саме на
створення професійних програмних комплексів.

2.5.6 Приклади створення функцій, призначених для


автоматичного перерахунку значень фізичних величин
Тепер, коли ми знаємо головні відомості про створення функцій та модулів
в інтерпретаторі мови Python, перейдемо до створення власних функцій,
145
призначених для розв’язування конкретних практичних завдань. Спочатку
розглянемо одне із важливих завдань прикладної фізики. Створимо програмні
модулі, призначенням яких буде переведення фізичних величин з однієї системи
вимірювання до іншої. Спочатку сформулюємо головні вимоги до такої
програми.
1. Функція має бути універсальною та запускатися як із командного рядка,
так і з іншої функції.
2. Модуль повинен містити дві функції, для прямого і для зворотного
перетворення. Наприклад, якщо створюється функція для переведення значення
температури з градусів за Цельсієм до градусів за Фаренгейтом, слід також
створити іншу функцію, яка здійснює зворотне перетворення – з градусів за
Фаренгейтом до градусів за Цельсієм.
3. Всі значення дійсних чисел виводити із трьома знаками після десяткової
коми.
4. Окремо, у тому ж модулі, написати функції із виведенням на екран
супровідного тексту, у якому пояснюється, які значення вводяться та виводяться.
Слід відзначити, що такі конвертори є вкрай корисними та мають великий
попит. Зараз такі програми встановлюються на всіх комп’ютерах, ноутбуках,
мобільних телефонах та інших інформаційних пристроях. Наприклад, для
туристів або бізнесменів, які багато подорожують по світу, дуже важливим є
такий програмний додаток, як конвертор валют. Зазвичай на ноутбуках та
мобільних телефонах його виконують як розподілений додаток із доступом до
Інтернет, що дозволяє користувачу через підключення до мережі свого банку
відслідковувати курси валют в інтерактивному режимі [12 – 14].
Напишемо, з використанням засобів мови програмування Python, модуль, в
якому реалізуємо простий конвертор, що переводить значення температури за
Цельсієм до її значень за Фаренгейтом. Відомо, що зв’язок між значеннями
температур за шкалою Цельсія TЦ та за шкалою Фаренгейта TФ описується
наступним лінійним співвідношенням [24]:
5 ⋅ (TФ − 32 )
TЦ = . (2.20)
9
Відповідно, зворотне перетворення значення температури, з градусів за
Цельсієм до градусів за Фаренгейтом, здійснюється за співвідношенням:
TФ = 1,8 ⋅ TЦ + 32 . (2.21)

146
Слід відзначити, що існують аналогові та цифрові термометри, на яких
значення температури позначені за двома шкалами – за Цельсієм та за Фаренгейтом.
Фотографії таких вимірювальних приладів показані на рис. 2.21 [47, 48].

а) б)
Рис. 2.21 Аналоговий (а) та цифровий (б) термометри, які показують
значення температури за шкалами Цельсія та Фаренгейта [47, 48]

Програмний модуль convertor_celsius_fahrenheit із функціями,


які перераховують значення температур згідно із співвідношеннями (2.20) та
(2.21), написаними з використанням розглянутих вище засобів програмування
мови Python, може мати наступний вигляд.
Приклад 2.46
def ccf(tc):
return round((1.8*tc + 32), 3)
def cfc(tf):
return round(5*(tf - 32)/9, 3)
def ccf_if():
tc = float(input(‘Введіть значення темпера\
тури в Цельсіях: ’))
print(‘Значення температури в Фарен\
гейтах становить: ’, ccf(tc))

147
def cfc_if():
tc = float(input(‘Введіть значення темпера\
тури в Фаренгейтах: ’))
print(‘Значення температури в Цельсі\
ях становить: ’, cfс(tc))
Перевірити коректність роботи функцій такого конвертора значень
температури можна в командному інтерпретаторі з використанням наступних
рядків.
>>> from convertor_celsius_fahrenheit import ccf
>>> from convertor_celsius_fahrenheit import cfc
>>> from convertor_celsius_fahrenheit import ccf_if
>>> from convertor_celsius_fahrenheit import cfc_if
>>> tf = ccf(21)
>>> tf
69.800
>>> tc = cfc(69.8)
>>> tc
21.000
>>> tf = ccf(-26)
>>> tf
-14.800
>>> tc = cfc(-14.8)
>>> tc
-26.000
>>> ccf_if()
Введіть значення температури в Цельсіях: 21
Значення температури в Фаренгейтах становить: 69.800
>>> cfc_if()
Введіть значення температури в Фаренгейтах: 69.8
Значення температури в Цельсіях становить: 21.000
>>> ccf_if()
148
Введіть значення температури в Цельсіях: –26
Значення температури в Фаренгейтах становить: -14.8
>>> cfc_if()
Введіть значення температури в Фаренгейтах: -14.8
Значення температури в Цельсіях становить: –26.0
>>>
Як видно з результатів тестування написаного програмного модуля
convertor_celsius_fahrenheit, призначення створених функцій є таким:
– функція ccf() – переведення значення температури за шкалою
Цельсія до відповідного значення за шкалою Фаренгейта;
– функція cfc() – переведення значення температури за шкалою
Фаренгейта до відповідного значення за шкалою Цельсія;
– функція ccf_if() – переведення значення температури за шкалою
Цельсія до відповідного значення за шкалою Фаренгейта, значення
температури за шкалою Цельсія вводиться з клавіатури, а значення
за шкалою Фаренгейта виводиться на екран;
– функція cfc_if() – переведення значення температури за шкалою
Фаренгейта до відповідного значення за шкалою Цельсія, значення
температури за шкалою Фаренгейта вводиться з клавіатури, а
значення за шкалою Цельсія виводиться на екран.
Іншим аналогічним прикладом, дуже важливим для технології
виробництва засобів електронної техніки та сучасних мікроелектронних
приладів, є зв’язок між двома різними одиницями вимірювання тиску, а саме,
міліметрами ртутного стовпчика та Паскалями. Міліметри ртутного стовпчика є
досить зручною одиницею з точки зору можливості конструювання простого
приладу для вимірювання тиску на ртутній трубці, тому історично саме ця
одиниця почала використовуватися раніше. Проте, для взаємозв’язку різних
фізичних величин у міжнародній системі одиниць СІ, яка була прийнята у 1960 р.
на 11 Генеральній конференції з мір та ваг [49], зручніше використовувати як

149

міру тиску системну одиницю Паскаль, 1 Па = [50]. У разі, якщо тиск
2

виражений в Паскалях, значно легше проводити складні фізичні та інженерні
розрахунки, оскільки відпадає потреба постійно переводити значення тиску з
однієї системи вимірювань до іншої. Такі розрахунки часто є вкрай необхідними
для розробки технології виробництва напівпровідникових приладів.
Взаємозв’язок між цими двома одиницями вимірювання тиску виражається
простим математичним співвідношенням:
1 мм. рт. ст. = 133,32 Па , (2.22)
або, у зворотній формі

1 Па = 0,0075 мм. рт. ст. = 7,5 ⋅ 10-3 мм. рт. ст. (2.23)
Існують різні прилади для вимірювання тиску. Прилади для вимірювання
досить високого тиску називаються монометрами, а прилади для вимірювання
тиску розрядженого газу – вакуумметрами. Крім цього, окремо розрізняють
прилади для вимірювання атмосферного тиску, які називаються барометрами.
Окремий клас приладів для вимірювання тиску – медичні тонометри, призначені
для вимірювання кров’яного тиску людини. Також у теорії вимірювання тиску
окремо розглядаються диференціальні монометри як спеціальні прилади для
вимірювання різниці тиску [51]. Фотографії аналогового та цифрового
вакуумметрів показані на рис. 2.22, аналогового та цифрового барометрів – на
рис. 2.23, а аналогового та цифрового медичних тонометрів – на рис. 2.24.

а) б)
Рис. 2.22 Зовнішній вигляд сучасних промислових аналогового (а) та цифрового
(б) вакуумметрів [52, 53]

150
а) б)
Рис. 2.23 Зовнішній вигляд сучасних побутових аналогового (а) та цифрового (б)
барометрів [54, 55]

а) б)
Рис. 2.24 Зовнішній вигляд сучасних медичних аналогового (а) та цифрового (б)
тонометрів [56, 57]

Вимірювачі тиску класифікуються також за принципом дії відповідних


датчиків. За цією ознакою розрізняють механічні, гідравлічні та електронні
вимірювачі тиску, серед яких сьогодні найбільш поширеними стають
високонадійні та швидкодійні електронні вимірювачі [51]. Серед електронних
вимірювачів тиску розрізняють газорозрядні та твердотільні [51].
Зрозуміло, що більшість пристроїв для вимірювання тиску, які
виробляються та пропонуються споживачам, є цифровими та
багатофункціональними, і ця підвищена функціональність досягається за рахунок

151
того, що керування ними здійснюється з використанням складного програмного
забезпечення, зокрема розподілених додатків [12 – 14]. Наприклад, як видно з
рис. 2.23, цифровий барометр може одночасно вимірювати температуру повітря,
вказувати час, надавати статистику погоди та показувати її прогноз у вигляді
наочних малюнків. Цифрові тонометри, аналогічні показаному на рис. 2.24, б,
також є багатофункціональними приладами, одночасно вони можуть вимірювати
пульс та температуру. Також не підлягає сумніву багатофункціональність
технологічного цифрового вакуумметра, фотографія якого наведена на рис. 2.23,
б. Зв’язок таких вимірювальних приладів із комп’ютерами через мережу Інтернет
дозволяє не лише систематизувати результати вимірювань, але й проводити на їх
основі досить складні математичні розрахунки з використанням розподілених
програмних додатків [12 – 14].
Проте слід відзначити, що якщо конвертори температури із градусів
Цельсія до градусів Фаренгейта досить широко поширені і промисловістю
випускаються аналогові та цифрові термометри з двома шкалами, вимірювачі
тиску зазвичай мають лише одну шкалу. Шкали сучасних монометрів та
вакуумметрів найчастіше градуюються в Паскалях, а шкали барометрів та
танометрів – в міліметрах ртутного стовпчика. Саме тому задача створення
програмного перетворювача одиниць тиску для сучасних цифрових
вимірювальних приладів є важливою та актуальною. Така програма повинна
бути невеликою та ефективною. Але, що найважливіше, писати її бажано
відкритим кодом з метою забезпечення апаратної та системної незалежності та
можливості перенесення на мобільні пристрої. Тому обрання мови
програмування Python для створення такого конвертора є цілком обґрунтованим.
Щодо швидкодії такої програми, написаної мовою Python, вона у будь-якому разі
буде досить високою, оскільки арифметичні обчислення за співвідношеннями
(2.22, 2.23) є достатньо простими.
Будемо писати конвертор одиниць тису на основі готового відлагодженого
програмного коду для конвертора температури, наведеного у прикладі 2.46, дещо
змінюючи цей код відповідно до особливостей поставленого завдання. У теорії
програмування такий стиль називається програмуванням за шаблоном [5 – 7, 12 –
14]. Відповідний код функцій конвертування одиниць тиску, записаний до файлу

152
з іменем convertor_pascal_torr, наведений у наступному прикладі.
Приклад 2.47
def cpt(pp):
return round((0.0075*pp), 5)
def ctp(pt):
return round((133.32*pt), 3)
def cpt_if():
pp = float(input(‘Введіть значення тис\
ку в Паскалях: ’))
print(‘Значення тиску в міліметрах ртутно\
го стовпчика становить: ’, cpt(pp))
def ctp_if():
pt = float(input(‘Введіть значення тис\
ку в міліметрах ртутного стовпчика : ’))
print(‘Значення тиску в Паскал\
ях становить: ’, ctp(pt))
Тепер перевіримо коректність роботи написаних функцій конвертора
одиниць тиску в інтерпретаторі командного рядка.
>>> from convertor_pascal_torr import cpt
>>> from convertor_pascal_torr import ctp
>>> from convertor_pascal_torr import cpt_if
>>> from convertor_pascal_torr import ctp_if
>>> pt1 = cpt(1.5)
>>> pt1
0.01125
>>> pp1 = ctp(pt1)
>>> pp1
1.500
>>> pt2 = cpt(12)
>>> pt2
0.090
>>> pp2 = ctp(pt2)

153
>>> pp2
12.000
>>> cpt_if()
Введіть значення тиску в Паскалях: 12
Значення тиску в міліметрах ртутного стовпчика становить: 0.090
>>> ctp_if
Введіть значення тиску в міліметрах ртутного стовпчика: 0.09
Значення тиску в Паскалях становить: 11.999
>>>
Зрозуміло, що функції створеного модуля convertor_pascal_torr
аналогічні функціям із прикладу 2.46 та мають наступне призначення:
– функція cpt() – переведення значення тиску, заданого в Паскалях,
до відповідного значення в міліметрах ртутного стовпчика;
– функція ctp() – переведення значення тиску, заданого в
міліметрах ртутного стовпчика, до відповідного значення в
Паскалях;
– функція cpt_if() – переведення значення тиску, заданого в
Паскалях, до відповідного значення в міліметрах ртутного
стовпчика, значення тиску в Паскалях вводиться з клавіатури, а
значення в міліметрах ртутного стовпчика виводиться на екран;
– функція ctp_if() – переведення значення тиску, заданого в
міліметрах ртутного стовпчика, до відповідного значення в
Паскалях, значення тиску в міліметрах ртутного стовпчика
вводиться з клавіатури, а значення в Паскалях виводиться на екран.
Розглянемо тепер ще один приклад конвертора, оснований на
нелінійних перетвореннях фізичних величин. У сучасній електроніці,
радіотехніці та акустиці, часто використовується одиниця вимірювання
децибел, яка визначається за логарифмічною шкалою наступним чином:
I
K дБ = 10 ⋅ lg(K в ) ; Kв = , (2.24)
I0
де K дБ – значення відносної величини K в в децибелах за логарифмічною
шкалою, а I та I0 – значення отриманої та еталонної інтенсивностей сигналу,

154
які можуть визначатися різними способами. Наприклад, в електроніці та
радіотехніці часто вважається, що I – сигнал на виході системи, а I0 – вхідний
сигнал. Таким способом визначається коефіцієнт підсилення або загасання
сигналу [60]. В іншому випадку, коли аналізуються шумові характеристики
системи, вважається, що I – рівень сигналу, а I0 – рівень шуму [60]. В
акустичних системах використовують інші оцінки, згідно з якими I – рівень
акустичного сигналу, що спостерігається, а I0 – рівень мінімального
акустичного сигналу, який сприймає людське вухо [50]. Прилади для
вимірювання рівня звукового сигналу наведені на рис. 2.25. Такі прилади
часто використовуються для аналізу рівня акустичного сигналу в музичних
студіях та концертних залах, а також для аналізу рівня шумів від
автотранспорту на вулицях міст та від технологічного обладнання на
промислових підприємствах [58, 59].

а) б)
Рис. 2.25 Зовнішній вигляд аналогового (а) та сучасного цифрового (б) приладів
для вимірювання рівня звукового сигналу [58, 59]

Слід відзначити, що величина K дБ у співвідношеннях (2.24) може бути як


додатною, так і від’ємною. Від’ємне значення параметра K дБ означає, що
здійснюється не підсилення, а навпаки, ослаблення первинного сигналу.
Наприклад, ефект зменшення потужності електричного сигналу із відстанню є
результатом поширення електромагнітних хвиль у вільному просторі [51, 60].
Із співвідношень (2.24) зрозуміло, що зворотний перерахунок значення в
децибелах за логарифмічною шкалою до відповідного відносного значення

155
величини Kв , яка аналізується, можна зробити з використанням наступної
формули:

K в = 10
(K дБ 10 )
. (2.25)
По аналогії з прикладами 2.46 та 2.47 напишемо функції для перетворення
значень, заданих в децибелах, до відносних значень, та навпаки. Написану
функцію збережемо в файлі convertor_db_relative.
Приклад 2.48
def crdb(kr):
import math
return round((10*math.log(kr,10)),3)
def cdbr(kdb):
import math
return round(math.pow(10,kdb/10),3)
def cdbr_if():
kdb = float(input(‘Введіть значення величи\
ни в децибелах: ’))
print(‘Значення величини в відносних одини\
цях становить: ’, cdbr(pp))
def crdb_if():
kr = float(input(‘Введіть значення величи\
ни в відносних одиницях: ’))
print(‘Значення величини в деци\
белах становить: ’, crdb(kr))
Перевіримо коректність роботи написаних функцій конвертування
значень, заданих в децибелах, до відносних одиниць.
>>> from convertor_db_relative import crdb
>>> from convertor_db_relative import cdbr
>>> from convertor_db_relative import crdb_if
>>> from convertor_db_relative import cdbr_if
>>> kdb1 = crdb(1500)
>>> kdb1
31.761

156
>>> kr1 = cdbr(kdb1)
>>> kr1
1500.000
>>> kdb2 = crdb(0.15)
>>> kdb2
-8.239
>>> kr2 = cdbr(kdb2)
0.150
>>> crdb_if()
Введіть значення величини в відносних одиницях: 1500
Значення величини в децибелах становить: 31.761
>>> cdbr_if
Введіть значення величини в децибелах: 31.761
Значення величини в відносних одиницях становить: 1500
>>> crdb_if()
Введіть значення величини в відносних одиницях: 0.15
Значення величини в децибелах становить: -8.239
>>> cdbr_if
Введіть значення величини в децибелах: -8.239
Значення величини в відносних одиницях становить: 0.15
Зрозуміло, що на основі трьох розглянутих у цьому підрозділі програмних
модулів можна написати і конвертори інших фізичних величин. Для цього слід
користуватися довідниковою літературою з фізики, де вказаний взаємозв’язок
між різними одиницями вимірювання [50, 61], та змінювати назву відповідних
функцій конвертора, а також методи переведення з однієї одиниці вимірювання
до іншої. Деякі конкретні завдання щодо написання конверторів різних фізичних
та інформаційних величин сформульовані у розділі 7 у практичному занятті №3.
Програмні модулі, реалізовані в прикладах 2.46, 2.47 та 2.48 з
використанням засобів програмування мови Python, мають величезне практичне
значення та можуть бути використані під час розв’язування реальних завдань
прикладної фізики. Оскільки всі функції реалізовані за принципом модульного
програмування, вони можуть бути підключені до інших програмних модулів з
157
використанням директиви import. Єдиним недоліком написаних конверторів, з
точки зору зручності роботи з ними, є відсутність віконного графічного
інтерфейсу користувача, який сьогодні є безперечним стандартом для
професійного програмного забезпечення та зазвичай створюється на основі
сучасних технологій ООП [16]. Засоби програмування мови Python, призначені
для створення графічних інтерфейсів користувача, розглядатимуться у підрозділі
5.3.6. Там же будуть розглянуті приклади створення віконних інтерфейсів для
розглянутих нами у цьому підрозділі конверторів фізичних величин.

2.6 Операції з рядковими даними та функції мови програмування


Python для роботи з ними

2.6.1 Базові операції мови програмування Python для роботи із


рядковими даними
У всіх сучасних мовах програмування, крім реалізації алгоритмів
розрахунку через математичні функції, важливими є також операції над
рядковими даними. Ці операції забезпечують проведення таких важливих дій
над звичайними текстами, як пошук в них відповідної інформації та заміну
визначених фрагментів.
У мові програмування Python рядкові дані визначаються як дані типу
str, проте, як і для числових даних, зазвичай цей тип визначається за
замовченням [24 – 29]. Базовою операцією для роботи з рядками є визначення
рядкової змінної, яка записується в одинарних або подвійних лапках. Розглянемо
прості приклади формування рядкових змінних.
Приклад 2.49
>>> str1 = ‘Хто це?’
>>> str1
‘Хто це?’
>>> str2 = ‘Це студент Потапенко.’
>>> str2

158
‘Це студент Потапенко.’
>>> Привіт!
Traceback (most recent call last):
File “<pyshell#2>”, line 1, in <module>
Привіт!
NameError: name ‘Привіт!’ is not defined
>>> ‘Привіт!’
‘Привіт!’
>>> str3 = ‘’
>>> str3
‘’
>>>
Із наведеного прикладу цілком зрозумілі наступні правила роботи із
рядковими змінними, які притаманні мові програмування Python.
Правило 2.1. Рядкова змінна пишеться в одинарних або подвійних
лапках, обидві варіанти є еквівалентними.
Правило 2.2. Написання рядкової змінної без лапок розглядається
інтерпретатором як помилка.
Правило 2.3. Рядковій змінні може бути присвоєне ім’я. У цьому разі у
наступних командних рядках можна звертатися до визначеної змінної через це
ім’я.
Правило 2.4. Написання лапок без тексту в них розглядається
інтерпретатором як визначення порожнього рядка.
Слід відзначити, що у мові програмування Python базові операції над
рядками виконуються або через символи математичних операцій, або через
функції. Наприклад, важливою для розв’язування завдань обробки текстової
інформації є функція len модуля str, яка повертає значення довжини рядка у
символах. Розглянемо відповідний приклад.
Приклад 2.50
>>> str1 = ‘Хто це?’

159
>>> str2 = ‘’
>>> len(str1)
7
>>> len(str2)
0
>>> help(len)
Help on built-in function len in module builtins:
len(...)
len(module, object)
Return the number of items of a sequence or mapping.
>>>
Зверніть увагу на те, що для виклику функції len непотрібне
підключення ніяких модулів, оскільки вона є вбудованою функцією
інтерпретатора.
Розглянемо простий спосіб об’єднання рядків через використання
оператора додавання.
Приклад 2.51
>>> str1 = ‘Хто це? ’
>>> str2 = ‘Це студент Потапенко.’
>>> str1 + str2
‘Хто це? Це студент Потапенко.’
>>> str3 = ‘Який у Вас номер за списком, ’
>>> str4 = ‘студент Потапенко?’
>>> str3 + str4
‘Який у Вас номер за списком, студент Потапенко?’
Цікавим є також використання оператора множення для розмноження
рядків. Розглянемо цю можливість на наступному прикладі.
Приклад 2.52
>>> str1 = ‘Хто це? ’
>>> str1 * 3

160
‘Хто це? Хто це? Хто це?’
>>>
Зрозуміло, що для числових даних операція додавання означає
сумування чисел, а для рядкових – об’єднання рядків. Аналогічно, операція
множення для числових даних означає множення чисел, а для рядкових –
розмноження рядків. Відомо, що у теорії об’єктно-орієнтованого
програмування такі операції називаються перевантаженими. Перевантажені
оператори аналогічні перевантаженим функціям, які відповідають
визначенню 2.4. Надамо відповідне визначення.
Визначення 2.5 Однакові оператори, які використовуються для
обробки різних об’єктів, у теорії ООП називаються перевантаженими.
Перевантаженість операцій означає, що використовувати операції
додавання або множення для різних об’єктів, рядків та чисел, неможливо. Це
є помилкою програмування. Розглянемо відповідний приклад.
Приклад 2.53
>>> str3 = ‘Який у Вас номер за списком, ’
>>> str4 = ‘студент Потапенко?’
>>> str3 + str4
‘Який у Вас номер за списком, студент Потапенко?’
>>> str5 = ‘Мій номер за списком ’
>>> str6 = 17
>>> str5 + str6
Traceback (most recent call last):
File “<pyshell#2>”, line 1, in <module>
str5 + str6
TypeError: Can’t convert ‘int’ object to ‘str’
implicity
>>> str6 = ‘17’
>>> str5 + str6
‘Мій номер за списком 17’

161
У наведеному прикладі ми легко уникнули помилки, записавши число
17 як рядкову константу «17». Але як бути, якщо числові дані є результатом
обчислень або вимірювань? Наприклад, датчик вимірює температуру в
градусах Цельсія, передає виміряне значення через цифровий інтерфейс на
комп’ютер, а комп’ютер, з використанням функцій модуля
convertor_celsius_fahrenheit, наведених у прикладі 2.46 у підрозділі
2.5.6, переводить ці значення до градусів Фаренгейта.
Для обробки таких ситуацій у мові програмування Python існують
функції перетворення типів даних, які розглядатимуться у наступному підрозділі.

2.6.2 Функції перетворення рядкових даних до числових та числових


до рядкових
Розглянемо функції перетворення рядкових даних до числових та
числових до рядкових, які аналогічні функціям перетворення числових типів
даних, розглянутих у підрозділі 2.4.3. Для перетворення числа на рядок
використовується функція str, а для перетворення рядка на число – функції
int та float, залежно від типу числових даних, які необхідно отримати.
Розглянемо відповідний приклад.
Приклад 2.54
>>> ‘Скільки Вам років, студент Потапенко?’
‘Скільки Вам років, студент Потапенко?’
>>> str1 = ‘Мені ’
>>> str2 = 18
>>> str3 = ‘ років.’
>>> str1 + str2 + str3
Traceback (most recent call last):
File “<pyshell#2>”, line 1, in <module>
str1 + str2 + str3
TypeError: Can’t convert ‘int’ object to ‘str’
implicity

162
>>> str1 + str(str2) + str3
‘Мені 18 років’
>>> ‘Студент Потапенко, чи є у Вас брат?’
‘Студент Потапенко, чи є у Вас брат?’
>>> ‘Так’
‘Так’
>>> ‘Скільки років Вашему брату?’
‘Скільки років Вашему брату?’
>>> str4 = ‘Моєму брату ’
>>> str5 = ‘13’
>>> str6 = ‘ років.’
>>> str4 + str5 + str6
‘Моєму брату 13 років.’
>>> ‘А скільки років Вам і Вашему брату разом?’
‘А скільки років Вам і Вашему брату разом?’
>>> str7 = ‘Разом нам ’
>>> str8 = str5 + str(str2)
>>> str9 = ‘ років.’
>>> str7 + str8 + str9
‘Разом нам 1318 років.’
>>> ‘Скільки?’
‘Скільки?’
>>> ‘Пробачте!’
‘Пробачте!’
>>> str8 = str(int(str5) + str2)
>>> str9 = ‘ рік.’
>>> str7 + str8 + str9
‘Разом нам 31 рік.’
>>> str10 = ‘Добре! Тепер я бачу, студент ’
>>> str11 = ‘Потапенко, що Ви вмієте програмувати ’

163
>>> str12 = ‘на мові Python. Але Вам треба бути ’
>>> str13 = ‘трішки уважнішим та повторити ’
>>> str14 = ‘перетворення типів даних.’
>>> str10 + str11 + str12 + str13 + str14
‘Добре! Тепер я бачу, студент Потапенко, що Ви вмієте
програмувати на мові Python. Але Вам треба бути
трішки уважнішим та повторити перетворення типів
даних.’
>>>
Показовим у розглянутому прикладі є те, що результат виконання операції
сумування є різним для різних типів даних. Дійсно, 13 + 18 = 31 – для числових
даних, але «13» + «18» = «1318» для рядкових даних. У цьому і полягає
перевантаженість операції сумування, яка потребує використання функцій
перетворення типів даних.
Аналогічно для операції множення. Розглянемо відповідний приклад.
Приклад 2.55
>>> str1 = ‘13’
>>> str2 = str1 * 2
>>> str3 = int(str1) * 2
>>> str2
1313
>>> str3
26
>>>
Тобто 13 * 2 = 26, але «13» * 2 = «1313».
Розглянуті приклади 2.54 та 2.55 свідчать про те, що у разі
використання перевантажених операцій у мовах об’єктно-орієнтованого
програмування, зокрема в мові Python, вельми важливо слідкувати за
узгодженням типів даних.

164
2.6.3 Спеціальні символи мови програмування Python для роботи з
рядками
У мові програмування Python існує декілька спеціальних символів,
призначених для роботи з рядками [24 – 29]. Почнемо із символу лапок.
Проблема полягає в тому, що, з одного боку, лапки використовуються для
формування та запису рядкових констант, а, з іншого боку, лапки може бути
частиною рядка, як апостроф. Відомо, що апостроф досить часто
використовується в українському та англійському письмовому тексті. В
англійських словах він є знаком розділення для формування скорочень, а в
українських він ставиться для формування звуку дзвінкого приголосного
перед м’якою голосною. Наприклад, через апостроф пишуться такі англійські
слова, як don’t, can’t, та українські слова комп’ютер, м’який.
У мові програмування Python існує кілька способів написання лапок.
Розглянемо їх.
1. Вся фраза пишеться у подвійних лапках, а усередині фрази
ставляться одинарні. Наприклад:
>>> “I don’t understand”
“I don’t understand”
>>> “Персональний комп’ютер”
“Персональний комп’ютер”
>>>
2. Перед лапками ставиться знак лівої нахиленої риски, або зворотного
слеша. Наприклад:
>>> ‘I don\’t understand’
“I don’t understand”
>>> ‘Персональний комп\’ютер’
“Персональний комп’ютер”
>>>
Тут слід відзначити, що символ лівої нахиленої риски, оскільки він не
зустрічається в текстах, використовується для керування виведенням текстів

165
на екран. Цей синтаксис запозичений у мові Python із мови програмування C
[3, 5]. Розглянемо головні керувальні символи, які в літературі називаються
також escape-послідовностями [24 – 29].
1. \n – перехід на новий рядок;
2. \t – знак табуляції;
3. \\ – символ лівої нахиленої риски;
4. \’ – символ одиночних лапок;
5. \” – символ подвійних лапок;
Якщо необхідно ввести довгий рядок – це можна зробити з
використанням потрійних лапок. У цьому випадку вважається, що ліві
потрійні лапки – це початок рядка, а праві – його кінець. За такої умови
можна вводити одну рядкову константу в кількох окремих рядках. У разі
виведення на екран такої рядкової змінної між рядками ставиться символ
нового рядка \n. Розглянемо відповідний приклад.
Приклад 2.56
>>> ‘’’Студент Потапенко
здає залік‘’’
‘Студент Потапенко\n здає залік’
>>>
Розглянуті у цьому підрозділі спеціальні символи мови програмування
Python, призначені для роботи з рядковими змінними, часто
використовуються на практиці для формування інформаційних повідомлень
та їх виведення на екран [24 – 29].

2.6.4 Особливості введення та відображення рядкових змінних на


екрані з використанням системних функцій input() та print()
Функція виведення значення змінних на екран print(), розглянута у
підрозділі 2.5.2, у разі роботи із рядковими змінними також має свої певні
особливості. По-перше, для виведення рядків можна використовувати
керувальні символи, описані у підрозділі 2.6.3. Розглянемо відповідний

166
приклад.
Приклад 2.57
>>> print(‘Студент Потапенко\nнавчається добре’)
Студент Потапенко
навчається добре
>>> print(‘Студент Потапенко\nза списком має номер\t17’)
Студент Потапенко
за списком має номер 17
>>>
Взагалі функція print() у мові Python має декілька аргументів, які
зазвичай визначаються за замовченням, але можуть бути задані під час
виклику функції. Якщо в інтерпретаторі Python набрати команду допомоги
help (print), маємо наступний результат щодо описання параметрів
виклику цієї функції [24, 65]:
>>> help(print)
Help on built-in function print in module builtins:
print(...)
print(values, ..., sep=’ ’, end=’\n’,
file=sys.stdout, flush=False)
>>>
Згідно із повідомленням системи допомоги, функція print() має
наступні параметри.
values – змінні або об’єкти, які виводяться, вони можуть бути як
числового, так і рядкового типу.
sep – символ, який розділяє об’єкти. За замовченням це пробіл, але
змінивши значення цієї змінної, можна, для зручності читання та розуміння
тексту поставити інший символ. Наприклад, для розділення двох чисел часто
ставлять символи коми або двокрапки.
end – рядок, який виводиться після виведення останнього об’єкта. За
замовченням це перехід на новий рядок, але можна задати інший параметр.

167
Наприклад:
end = ‘Кінець виведення даних \n’
У цьому разі перед переходом на наступний рядок буде виведений
рядок Кінець виведення даних.
file – ім’я файлу, до якого буде здійснене виведення даних. За
замовченням це файл sys.stdout, що відповідає виведенню інформації на
екран.
flush – функція очищення буфера обміну даних у разі виведення
великої кількості інформації. За замовченням flush=False, що відповідає
встановленню операційною системою оптимального об’єму буфера даних. За
умови flush=True інформація виводиться примусово із максимальним
об’ємом буфера даних, що може заважати операційній системі виконувати
інші важливі завдання користувача.
Більш досконало можливості використання функції print() для
запису рядкових даних до файлів будуть розглянуті у наступному підрозділі.
Наприклад, розглянемо можливість використання символу розділення
даних, або сепаратора, та символу останнього рядка.
Приклад 2.58
>>> print(1, 3, 5, 7, 9)
1 3 5 7 9
>>> print(1, 3, 5, 7, 9, sep=‘,’)
1,3,5,7,9
>>> print(1, 3, 5, 7, 9, sep=‘:’)
1:3:5:7:9
>>> end_str=‘\nКінець виведення даних\n’
>>> print(1, 3, 5, 7, 9, sep=‘:’, end=end_str)
1:3:5:7:9
Кінець виведення даних
>>>
Цікавою є також можливість організації роботи програми в

168
інтерактивному режимі з використанням системних функцій інтерпретатора
мови Python input() та print(). Річ у тому, що функція input()

формує рядкову змінну з введеної з клавіатури інформації, а функція


print() може бути використана для виведення інформації. Тоді,

використовуючи операцію об’єднання рядків, розглянуту у підрозділі 2.6.1, а


також функції перетворення даних, розглянуті в підрозділі 2.6.2, можна
формувати повноцінне інформаційне повідомлення. У цьому разі слід
пам’ятати, що функція введення даних input() завжди зчитує не числову, а

рядкову константу. Для переведення введеного рядка до числового типу


необхідно використовувати функції int() або float(), залежно від типу

числової змінної, яку необхідно отримати. Розглянемо відповідний приклад.


Приклад 2.59
>>> print(‘Хто це?’)
Хто це?
>>> str1=input()
Студент Потапенко
>>> str2=‘Добрий день, ’
>>> str3=‘. Як Ви навчаєтесь?’
>>> str_out_1=str2+str1+str3
>>> print(str_out_1)
Добрий день, Студент Потапенко. Як Ви навчаєтесь?
>>> str4=input()
Добре
>>> str5=‘ навчається ’
>>> str6=‘.’
>>> str_out_2=str1+str5+str4+str6

169
>>> print(str_out_2)
Студент Потапенко навчається Добре.
>>>

Для закріплення знань щодо розглянутих операцій оброблення рядків


необхідно виконати практичні заняття №3 та №4, які наведені у розділі 7. У
підрозділі 2.6.8 розглядатиметься спосіб індексації символів рядків, який
впроваджений у мові програмування Python. Це дозволяє посимвольно
читати рядки та проводити їх аналіз, що є вкрай важливим для розв’язування
багатьох практичних завдань програмування. Цей матеріал також є важливим
для розуміння способів формування масивів числових даних у мові Python,
або списків, які розглядатимуться у розділі 4.

2.6.5 Запис текстової інформації до файлів


Окремі функції мови програмування Python призначені для запису
текстової інформації до файлів. Зрозуміло, що такий спосіб збереження
інформації на практиці використовується частіше, ніж просте виведення на
екран без збереження. Одним із способів записи рядкових даних до файлу є
використання функції print(), узагальнений синтаксис якої із можливими

аргументами був розглянутий у попередньому підрозділі. Проте способи


запису інформації до файлів та її читання в цьому посібнику ще не
розглядалися.
Загалом для роботи з файлами найчастіше застосовується п’ять функції
мови Python [24 – 29].
1. open() – відкрити файл.

2. read() – читати інформацію з файлу.

3. write() – запис до файлу.

170
4. print() – інший метод для запису інформації до файлу.

5. close() – закрити файл.

Функція open() має наступний формат:

var = open(‘filename’, ‘mode’),

де параметр var визначає змінну, через яку здійснюється посилання на

файловий об’єкт, параметр filename відповідає імені файлу, а параметр

mode характеризує режим роботи з ним.

Значеннями параметра mode характеризуються властивості файлу,

який відкривається [24 – 29]. Цей параметр складається із двох літер, перша з
яких описує можливі операції із відкритим файлом, а друга – його тип.
Можливими операціями над файлом можуть бути наступні [24 – 29].
1. r – лише читання файлу.

2. w – запис до файлу із стиранням попередньої інформації. Якщо файл

не існує – він буде створений, а якщо існує – попередня інформація із нього


стирається та записуються нові дані.
3. x – запис до файлу, але лише за умови, що файлу із заданим іменем

не існує.
4. a – запис до файлу із дописуванням інформації у разі, якщо файл із

заданим іменем існує. Якщо файл не існує – він буде створений.


Для параметра типу файлу можливі наступні значення [24 – 29].
1. t – текстовий файл.

2. b – двійковий файл.

Наприклад, запис wt для параметра mode функції open() означає, що

відкривається текстовий файл для запису інформації. Якщо параметр типу не


вказаний, за замовченням файл вважається текстовим.
Якщо операції над файлами, які задаються як параметр функції
171
open(), загалом є зрозумілими, особливості використання функцій

write() та print() для запису рядкових даних до файлу потребують

окремого пояснення. Річ у тому, що функція write() пише дані до файлу

підряд, без символів розділення, у той час для функції print() може бути

використані різні значення змінних sep та end. Особливості використання

цих змінних для організації роботи функції print() були розглянуті у

попередньому підрозділі.
В цілому робота з файлами у мові програмування Python організується
наступним чином. Файл із заданим іменем відкривається з використання
функції open(), а атрибути для подальшої роботи з файлом задаються як

параметри виклику цієї функції через змінну mode. Після цього, в інших

файлових функціях, посилання на відкритий файл здійснюється через змінну


var, якій було присвоєне значення функції open(). Посилання на файл

робиться як на об’єкт у форматі: var.function_name(), де

function_name – ім’я функції [24 – 29].

Розглянемо деякі приклади використання функцій роботи з текстовими


файлами.
Приклад 2.60
>>> str1=‘Студент’
>>> str2=‘Хоменко’
>>> str3=‘Потапенко’
>>> str4=‘та’
>>> str5=‘навчаються добре.’
>>> fwt=open(‘students’, ‘wt’)
>>> fwt.write(str1,str2,str4,str1,str3,str5)
>>> fwt.close()

172
>>> fwt2=open(‘students2’, ‘wt’)
>>> fwt2.print(str1,str2,str4,str1,str3,str5,sep=‘ ’)
>>> fwt2.close()
>>> frt=open(‘students’, ‘rt’)
>>> str_read_1=frt.read()
>>> str_read_1
‘СтудентХоменкотаСтудентПотапенконавчаються добре.’
>>> frt.close()
>>> frt2=open(‘students’, ‘rt’)
>>> str_read_2=frt.read()
>>> str_read_2
‘Студент Хоменко та Студент Потапенко навчаються добре.’
>>> frt2.close()

У розглянутих функціях, призначених для роботи зі рядковими даними,

важливим є те, що посилання на функцію здійснюється як на метод об’єкту.

Спочатку пишеться ім’я змінної, а потім, через крапку – ім’я функції. Це є

загальною концепцією програмування мови Python, тому так же само

організована робота і інших функцій, призначених для обробки рядків, які

розглядатимуться у наступному підрозділі.

2.6.6 Головні функції мови програмування Python для роботи з

рядками
У мові програмування Python існує велика кількість функцій,

призначених для обробки рядків, і всі вони реалізовані як методи роботи з

об’єктами [24 – 29]. Призначення деяких з цих функцій описано у таблиці 2.6.

173
Таблиця 2.6 – Основні функції мови Python для роботи з рядками

Функція Призначення
Повернення копії рядка, у якій перший символ написаний
capitalize()
великою літерою, а всі інші символи – малими літерами
Перевірка всіх символів рядка на задане значення
startswitch()
рядкової змінної, або контекстний пошук
Повернення заданого рядка, в якому відсутні символи
strip()
переходу на інший рядок та пробіли
upper() Всі символи заданого рядка пишуться великими літерами
lower() Всі символи заданого рядка пишуться малими літерами
swapcase() Зміна регістра всіх символів рядка на протилежний
Центрування визначеного рядка за довжиною, параметр
center(n)
n визначає довжину рядка.
title() Перший символ рядка пишеться з великої літери
Функція перевіряє, чи є всі елементи заданого рядка
isalpha()
літерами англійської абетки
Функція перевіряє, чи є всі елементи заданого рядка
isdigit()
цифрами
Функція перевіряє, чи є всі символи заданого рядка
isupper()
великими літерами
Функція перевіряє, чи є всі символи заданого рядка
islower()
малими літерами
Функція перевіряє, чи починається заданий рядок з
istitle()
великої літери
Функція перевіряє, чи є всі символи заданого рядка
isspace()
пробілами
Повертає значення позиції послідовності символів, яка
find(var)
задана змінною var, у заданому рядку, або значення –1
Повертає кількість повторень послідовності символів, яка
count(var)
задана змінною var, у заданому рядку, або значення –1

174
Окремого розгляду потребує функція format(), яка у мові Python
ефективно використовується як для роботи з числовими даними, так і з
рядковими. У разі обробки числових даних ця функція змінює подання числа з
однієї системи числення до іншої, а у разі обробки рядкових даних – об’єднує
визначені елементи рядка, нумерація яких починається з нуля [24 – 29].
Особливості індексації елементів у мові програмування Python
розглядатимуться у наступному підрозділі.
Наведемо приклади використання функції format().
Приклад 2.61
>>> ‘{1} та {0}’.format(‘Потапенко’, ‘Хоменко’)
‘Хоменко та Потапенко’
>>> ‘{0} та {1}’.format(‘Потапенко’, ‘Хоменко’)
‘Потапенко та Хоменко’
>>> n=10
>>> ‘{b}:’.format(n)# b - двійкова система числення
‘1010’
>>> ‘{d}:’.format(n)# d - десяткова система числення
‘10’
>>> ‘{x}:’.format(n)# d - шістнадцяткова система числення
>>> ‘{с}:’.format(n)# c – символ у форматі ASCII
‘\n’
Іншою цікавою особливістю мови програмування Python, яка ще більше
підвищує ефективність обробки рядків, є об’єднання методів [24 – 29]. Це
означає, що можна спочатку використати один метод, а потім другий,
об’єднавши їх в один рядок. Формат такого рядка має наступний вигляд:
var.method_1().method_2().
Цей запис означає, що до рядкової змінної var спочатку

175
застосовується method_1(), а потім method_2(). Розглянемо приклад
ефективного використання об’єднання методів.
Приклад 2.62
>>> n = 25
>>> ‘{b}:’.format(n).isdigit()
True
>>>
У наведеному прикладі спочатку число 25 переведене до двійкової
системи, а після цього отриманий рядок перевіряється на числове значення.
Зрозуміло, що результатом роботи такої команди є логічне значення True –
правильно. Основи роботи із логічними змінними у мові Python
розглядатимуться у підрозділі 3.2.
Розглянемо тепер приклад використання деяких методів роботи з
рядками, наведених у таблиці 2.6.
Приклад 2.63
>>> str1=‘Студент’
>>> str2=‘Хоменко’
>>> str3=‘Потапенко’
>>> str3.count(‘о’)
2
>>> str2.count(‘о’)
2
>>> str2.count(‘т’)
1
>>> str4=str1.upper()
>>> str4
‘СТУДЕНТ’
>>> str4.capitalize()
‘Студент’
>>> str4.isalpha()

176
True
>>> str4.isdigit
False
>>> str5=‘енко’
>>> n1=str1.find(str5)
3
>>> n2=str2.find(str5)
5
>>> str3.capitalize().istitle()
True
>>> str3.lower().istitle()
False
>>> str3.lower().islower()
True
>>>
Слід відзначити, що рядкову змінну, над якою виконується дія, також
можна вказувати як параметр функції, у цьому випадку посилання на метод
реалізується через модуль str. Наведемо приклад такого виклику функції
обробки рядка.
Приклад 2.64
>>> str1=‘Потапенко’
>>> str2=str.upper(str1)
>>> str2
‘ПОТАПЕНКО’
>>>
Розглянуті у цьому підрозділі функції, призначені для роботи із
рядками, мають не лише важливе практичне значення для формування
інформаційних повідомлень. Вони також є важливими з теоретичної точки
зору для розуміння операцій з об’єктами та методів, які розглядатимуться у
розділі 4. Використані для роботи з рядками логічні змінні, які мають

177
значення True або False, є результатом аналізу логічних виразів, які
розглядатимуться у підрозділі 3.2.

2.6.7 Формування тексту допомоги до власних функцій


користувача з використанням рядкових даних
Робота з рядковими даними також ефективно використовується у мові
програмування Python для формування тексту допомоги до створених
функцій та модулів. У попередніх підрозділах було показано, як можна
ефективно користуватися допомогою до бібліотечних функції мови
програмування Python через команду help(), проте спосіб формування
тексту допомоги у цьому посібнику ще не розглядався.
Насправді, текст допомоги створюється дуже просто. Після декларації
функції з використанням команди def перед першою командою, яка має
бути виконаною, пишеться відповідний текст, який заключається у потрійні
лапки ‘‘‘ ’’’. Вкрай важливим є те, що кількість символів та кількість
рядків у цьому тексті є необмеженими [24 – 29]. У цьому разі звернення до
написаної функції з використанням команди help(func_name), де
func_name – ім’я функції, призводить до того що на екран виводиться
текст, записаний в потрійні лапки.
Розглянемо приклад формування системи допомоги. Припустимо, що
до модуля, який має ім’я ext_math, введений текст, який наведений у
наступному прикладі.
Приклад 2.65
def sincos(x)
‘‘‘Функція, sincos(x) яка обчислює
суму синуса та косинуса від
заданого аргумента x, sin(x) + cos(x)’’’
return sin(x) + cos(x)

178
Тоді, якщо в інтерпретаторі командного рядка підключити модуль
ext_math та викликати функцію допомоги до описаної в ньому функції
sincos(x), на екран буде виведений текст, написаний у потрійних лапках.
Розглянемо відповідний приклад.
Приклад 2.66
>>> import ext_math
>>> help(ext_math.sincos)
Функція, sincos(x) яка обчислює
суму синуса та косинуса від
заданого аргументу x, sin(x) + cos(x)
>>>
Слід відзначити, що схожа організація системи допомоги
використовується також у системі науково-технічних розрахунків MatLab [6, 7].
Зрозуміло, що використання такої простої та розвиненої системи допомоги у
значній мірі спрощує роботу із складними програмними комплексами, які
містять багато функцій та модулів. Тому формування тексту допомоги до всіх
функцій вважається необхідною складовою будь-яких програм, написаних
мовою Python, хоча цей компонент програми і не є обов’язковим.
Дійсно, згідно із чотирнадцятим та п’ятнадцятим принципами
філософії мови програмування Python, наведеними у підрозділі 1.5: «Якщо
реалізацію складно пояснити, така ідея є поганою»; «Якщо реалізацію
легко пояснити, така ідея, можливо, є гарною».

2.6.8 Індексація елементів рядків


Оскільки для коректної обробки рядків з використанням програмних
засобів важливо знати номер кожного із елементів рядка, або кожного із
символів, з яких він складається, у всіх мовах програмування передбачена
нумераціє елементів рядка [3, 5, 6 – 10, 15 – 17]. Аналогічно, нумеруються
елементи рядків у мові програмування Python [24 – 29], і ця нумерація
здійснюється наступним чином. Кожний елемент має свій порядковий номер,
179
або індекс, і починається індексація елементів з нуля, тобто, перший елемент
рядка має індекс 0. Слідом за нульовим ідуть елементи із індексами 1, 2, і так
далі, до кінця рядка. Якщо необхідно подивитися, який символ відповідає
елементу рядка із заданим індексом, достатньо після імені рядкової змінної
вказати індекс елемента в квадратних дужках. Зрозуміло, що першому
символу рядка відповідає індекс 0, а останньому – індекс len(str1) – 1,
де str1 – ім’я рядкової змінної. Проте у мові Python, для зручності
написання програм, передбачена не лише пряма, але й зворотна індексація
елементів рядка. Для такої індексації останній елемент рядка має індекс –1,
передостанній – –2, і так далі. Слід також відзначити, що через індексацію
елементів рядка у мові Python програміст може лише переглянути
відповідний символ, але не може змінити його. На перший погляд це здається
не зовсім зручним, але такий підхід є цілком зрозумілим з точки зору
ідеології ООП. Дійсно, якщо рядок визначений як об’єкт класу «рядкова
змінна» із відповідним іменем, програміст може лише цілком змінити
значення цієї змінної, а не її окремих елементів. Проте це заборонне правило
не є критичним, оскільки у мові Python передбачені інші ефективні засоби
для обробки рядків, включаючи пошук та заміну відповідної інформації.
Одними із таких засобів є операції об’єднання та розмноження рядків, які
були розглянуті у підрозділі 2.6.1, а з іншими ми познайомимося у цьому
підрозділі трішки пізніше.
Розглянемо приклад індексації елементів рядка.
Приклад 2.67
>>> str1=‘Потапенко’
>>> str1[0] #Перший елемент рядка
‘П’
>>> str1[0]=H #Спроба змінити перший елемент рядка
Traceback (most recent call last):
File “<pyshell#2>”, line 1, in <module>
Str1[0]=H

180
TypeError: ‘str1’ object does not support item
assigment
>>> str1[3] #Четвертий елемент рядка
‘a’
>>> str1[8] #Дев’ятий, останній елемент рядка
‘о’
>>> str1[–1] #Останній елемент рядка
‘о’
>>> str1[–2] #Передостанній елемент рядка
‘к’
>>> str1=‘Хоменко’
>>> str1[0] #Перший елемент рядка
‘Х’
Для ефективної обробки рядків через зміну їх елементів із відповідними
індексами та формування нового рядка у мові програмування Python
використовується спосіб, який називається формуванням зрізів. Розглянемо
його більш детально. Для формування зрізу використовується два або три
індексу, які пишуться у квадратних дужках через символ двокрапки. У разі
використання двох індексів перший індекс відповідає першому елементу, який
переноситься із одного рядка в інший, а другий індекс – першому із елементів
базового рядка, який не треба переносити. Перший та другий індекс можуть
бути визначеними за замовченням, у цьому разі ставиться просто двокрапка, без
відповідного числа. За замовченням перший індекс дорівнює 0, а останній –
len(str) – 1. У разі використання трьох індексів третім є крок, із яким
вибираються елементи із базового рядка. Наприклад, запис [2:10:2] означає,
що треба взяти третій (3 = 2 + 1), п’ятий (5 = 2 + 2 + 1), сьомий (7 = 2 + 2 + 2 + 1)
та дев’ятий (9 = 2 + 2 + 2 + 2 + 1) елементи. Зрозуміло, що індексація
починається з нульового елемента, тому індекс елемента є на 1 меншим, ніж
його номер. Число 10 у наведеному прикладі – це індекс першого елемента,
який не переноситься із одного рядка в інший. Тому одинадцятий елемент,

181
якому відповідає індекс 10, вже не переходить до іншого рядка. Слід
відзначити, що за замовченням крок дорівнює 1, тобто, для послідовного
читання символів цей параметр можна не вказувати.
Можливим є також запис str [:], який означає копіювання всього
рядка. Крім цього, передбачене використання від’ємного кроку, який означає
копіювання елементів у зворотному порядку. Тоді за замовченням перший
елемент, який переноситься в інший рядок, має індекс –1, а це, як було сказано
вище, останній елемент рядка. У цьому випадку індексація елементів рядка
здійснюється у зворотному порядку, зправа-наліво, але індекси елементів мають
від’ємні значення. Слід відзначити, що такий спосіб обробки рядків є дуже
зручним для порозрядного читання та подальшої обробки чисел, записаних
арабськими цифрами [42].
Зрозуміло, що окремим випадком зрізу, який містить лише один елемент,
є проста індексація цього елементу, наприклад str[3].
Розглянемо приклади формування зрізів.
Приклад 2.68
>>> str1=‘Потапенко’
>>> str2=str1[:5]
>>> str2
‘Потап’
>>> str3=str1[:5:2]
>>> str3
‘Птп’
>>> str4=str1[::-1]
>>> str4
‘окнепатоП’
>>> str5=str1[-1::-2]
>>> str5
‘онпт’
>>> str6=str1[:-1]

182
>>> str6
‘Потапенк’
>>> str7=‘Павлюченко’
>>> str8=str7[:4]
>>> str8
‘Павл’
>>> str9=str1[5::]
>>> str9
‘енко’
>>> str8+str9
‘Павленко’
>>> str10=‘123’
>>> str11=str10[::-1]
>>> str11
‘321’
>>> int(str11[2])
1
Розглянемо інший приклад, в якому на основі базового текстового
шаблону з використанням зрізів формується інформаційне повідомлення.
Приклад 2.69
>>> str1=‘*** має порядковий номер *** та навчається ***’
>>> ‘Хто це?’
‘Хто це?’
>>> str2=input()
Студент Потапенко
>>> str3=‘Добрий день, ’
>>> str4=‘. Який Ваш порядковий номер за списком?’
>>> str5=str3+str2+str4
>>> str5
Добрий день, Студент Потапенко. Який Ваш

183
порядковий номер за списком?
>>> str6=input()
17
>>> str7=‘Як Ви навчаєтесь, ’
>>> str8=‘?’
>>> str9=str7+str2+str8
>>> str9
‘Як Ви навчаєтесь, Студент Потапенко?’
>>> str10=input()
Добре
>>> str11= str1[3:25];
>>> str11
‘ має порядковий номер ’
>>> str12=str1[29:43];
>>> str12
‘ та навчається ’
>>> str13=‘.’
>>> str14=str2+str11+str6+str12+str10+str13
str14
‘Студент Потапенко має порядковий номер 17
та навчається Добре.’
>>> ‘Хто це?’
‘Хто це?’
>>> str2=input()
Студент Хоменко
>>> str5=str3+str2+str4
>>> str5
Добрий день, Студент Хоменко. Який Ваш
порядковий номер за списком?
>>> str6=input()

184
24
>>> str9=str7+str2+str8
>>> str9
‘Як Ви навчаєтесь, Студент Хоменко?’
>>> str10=input()
Відмінно
>>> str14=str2+str11+str6+str12+str10+str13
str14
‘Студент Хоменко має порядковий номер 24
та навчається Відмінно.’
Зрозуміло, що для уникнення повторення рядків, в яких на екран
виводяться запитання та вводиться з клавіатури інформація про студента,
необхідно реалізовувати відповідну програму як функцію програмного модуля
та викликати її командним рядком. Спосіб написання таких програм на мові
Python був розглянутий у підрозділах 2.5.5 та 2.6.4.
Також слід відзначити, що розглянута у цьому підрозділі індексація
елементів рядка загалом базується на методах обробки списків у мові
програмування Python. Списки у цій мові являють собою складний об’єкт,
який створюється із окремих елементів. Способи формування списків та
основи роботи з ними розглядатимуться у підрозділі 3.7.
Для закріплення отриманих знань щодо розглянутих операцій
індексації елементів рядків, а також для здобуття відповідних навичок щодо
написання власних програм із створенням текстових шаблонів та їх аналізом
для формування інформаційного повідомлення, необхідно виконати
практичне заняття №4, яке наведене у розділі 7.

Контрольні питання та завдання до розділу 2


1. Під якими операційними системами може бути встановлений
інтерпретатор мови програмування Python версії 3?
2. Чим суттєво відрізняються версія 2 та версія 3 інтерпретатора мови

185
програмування Python?
3. Чому мова програмування Python вважається кросплатформеною?
4. В яких операційних системах інтерпретатор мови програмування
Python зазвичай вже встановлений, а для яких його необхідно встановлювати
окремо?
5. На яких сайтах в Інтернеті можна знайти інсталятори інтерпретатора
мови програмування Python?
6. Які головні операції необхідно виконати, щоб встановити на
персональному комп’ютері інтерпретатор мови програмування Python?
7. Які додаткові засоби програмування має система Anaconda?
8. На яких сайтах в Інтернеті можна знайти інсталятори системи
Anaconda?
9. Що являють собою пакети розширення мови програмування Python
pip та virtualenv?
10. Як можна запустити інтерпретатор мови Python під операційною
системою Windows?
11. Що являє собою інтегроване середовище програмування IDLE?
12. Як можна проводити прості арифметичні розрахунки в
інтерпретаторі мови Python? Наведіть власні приклади проведення таких
розрахунків.
13. Поясніть приклад 2.1.
14. Чим командний інтерпретатор мови Python схожий на
інтерпретатор системи науково-технічних розрахунків MatLab, а чим ці
інтерпретатори відрізняються?
15. Які головні арифметичні операції визначені у мові програмування
Python? Наведіть приклади виконання цих операцій.
16. Які спеціальні арифметичні операції, запозичені із мови
програмування С, реалізовані у мові Python?
17. Поясніть приклад 2.2.
18. Як у мові програмування Python реалізована обробка виключних

186
ситуацій?
19. Поясніть приклади 2.3 та 2.4.
20. Що являють собою типи змінних у мові програмування Python?
Наведіть власні приклади змінних різних типів.
21. Поясніть властивості 2.1 – 2.10.
22. Як здійснюється перетворення числових типів даних в
інтерпретаторі мови Python?
23. Поясніть приклад 2.5.
24. Що являє собою тип даних int? Наведіть приклади даних такого
типу.
25. Що являє собою тип даних float? Наведіть приклади даних такого
типу.
26. Як у мові програмування Python реалізований механізм
наслідування об’єктів, яким відповідають ім’я змінних? Поясніть свою думку
відповідним прикладом.
27. Поясніть дані, які наведені в таблиці 2.1.
28. Поясніть приклад 2.6.
27. Як у мові програмування Python можна визначити тип об’єкта?
Наведіть власні приклади визначення типа об’єкта.
28. Поясніть приклад 2.7.
29. Які у мові програмування Python існують привила формування імен
змінних? Наведіть власні приклади вірного та невірного імені змінної.
30. Що являють собою зарезервовані слова мови програмування
Python? Наведіть власні приклади зарезервованих слів цієї мови.
31. Поясніть дані, наведені у таблицях 2.2 та 2.3.
32. Як в інтерпретаторі мови програмування Python реалізована робота
з математичними функціями? Наведіть власні приклади виклику
математичних функцій.
33. Що являє собою модульний принцип побудови бібліотек
інтерпретатора мови програмування Python?

187
34. В якому модулі інтерпретатора мови програмування Python
реалізовані базові математичні функції?
35. Що являють собою математичні константи інтерпретатора мови
програмування Python та як вони можуть бути використані для проведення
арифметичних обчислень? Наведіть власні приклади такого використання
математичних констант.
36. Поясніть приклади 2.8, 2.9 та 2.10.
37. Поясніть значення всіх математичних функцій, наведених у
таблиці 2.4.
38. Які функції перетворення числових типів даних Вам відомі?
Наведіть власні приклади використання таких функцій.
39. Поясніть приклад 2.11.
40. Як в інтерпретаторі мови програмування Python реалізовані
експоненціальна, логарифмічна та степенева функції? Наведіть власні
приклади використання таких функцій у математичних виразах.
41. Поясніть приклади 2.12 – 2.15.
42. Як в інтерпретаторі мови програмування Python реалізовані
тригонометричні та зворотні тригонометричні функції? Наведіть власні
приклади використання таких функцій у математичних виразах.
43. Поясніть приклад 2.16.
44. Як в інтерпретаторі мови програмування Python реалізовані
гіперболічні та зворотні гіперболічні функції? Наведіть власні приклади
використання таких функцій у математичних виразах.
45. Поясніть співвідношення (2.5) – (2.16) та рис. 2.9.
46. Поясніть приклад 2.17.
47. Поясніть графічні залежності, які наведені на рис. 2.10.
48. Як в інтерпретаторі мови програмування Python реалізована робота із
комплексними числами? Наведіть власні приклади проведення арифметичних
операцій над комплексними числами у мові програмування Python.
49. Що являє собою бібліотека cmath інтерпретатора мови

188
програмування Python?
50. Поясніть приклад 2.18.
51. Яким чином функції інтерпретатора мови програмування Python
можуть бути використані як аргументи інших функцій? Наведіть власні
приклади такого використання функцій.
52. Поясніть рис. 2.11 та 2.12.
53. Поясніть приклади 2.19 – 2.21.
54. Які опції налаштування оболонки IDLE для інтерпретатора мови
програмування Python версії 3.4 Вам відомі?
55. Поясніть рис. 2.13 –2.18.
56. Які головні правила створення власних функцій користувача в
інтерпретаторі мови програмування Python Вам відомі? Наведіть власні
приклади використання цих правил.
57. Які операції необхідно виконати в оболонці IDLE для створення
власного модуля?
58. Поясніть приклад 2.22.
59. Як здійснюється описання власних функцій користувача в мові
програмування Python? Наведіть власні приклади створення функцій
користувача.
60. Що являє собою команда def мови програмування Python та як
вона використовується? Наведіть власні приклади використання цієї
команди.
61. Що являє собою команда return мови програмування Python та як
вона використовується? Наведіть власні приклади використання цієї
команди.
62. Поясніть приклади 2.23 та 2.24.
63. Які головні правила написання власних функцій Вам відомі та як
вони пов’язані із філософськими принципами мови програмування Python,
розглянутими у підрозділі 1.5?
64. Що являє собою функція print мови програмування Python та як

189
вона використовується. Наведіть власні приклади використання цієї функції.
65. Поясніть приклади 2.25 та 2.26.
66. Які змінні у мові програмування Python називаються глобальними?
Наведіть власні приклади визначення глобальних змінних.
67. Які змінні у мові програмування Python називаються локальними?
Наведіть власні приклади визначення локальних змінних.
68. Поясніть приклад 2.27.
69. Що являє собою описання global та як воно використовується в
мові програмування Python? Наведіть власні приклади ефективного
використання цього описання.
70. Поясніть приклад 2.28.
71. Як простори імен пов’язані із філософськими принципами мови
програмування Python, які були описані у підрозділі 1.5?
72. Що являє собою посилання на ім’я функції через змінну у мові
програмування Python? Наведіть власні приклади такого посилання.
73. Поясніть приклади 2.29 – 2.31.
74. Що являє собою механізм вкладених функцій у мові програмування
Python? Наведіть власні приклади вкладених функцій.
75. Поясніть приклад 2.32.
76. Що являє собою механізм зімкнених функцій у мові програмування
Python? Наведіть власні приклади зімкнених функцій.
77. Які головні правила роботи із зімкненими функціями існують у мові
програмування Python?
78. Поясніть приклад 2.33.
79. Що являють собою перевантажені методи у технології об’єктно-
орієнтованого програмування? Наведіть приклади описання перевантажених
методів у мові програмування Python.
80. Поясніть визначення 2.4.
81. Які існують головні правила роботи із модулями у мові
програмування Python? Наведіть власні приклади використання цих правил.

190
82. Що являє собою імпорт функцій у мові програмування Python та
чим цей механізм відрізняється від імпортування модулів? Наведіть власні
приклади імпорту функцій.
83. Поясніть приклади 2.34 – 2.36.
84. Як створюються модулі у графічній оболонці IDLE інтерпретатора
мови Python?
85. Поясніть рис. 2.19.
86. Поясніть приклад 2.37.
87. Як можна визначити, які папки комп’ютера є доступними для
інтерпретатора мови Python? Наведіть власні приклади визначення таких
папок.
88. Поясніть приклад 2.38.
89. Поясніть рис. 2.20.
90. У чому полягають особливості роботи з функціями, написаними
через модулі? Наведіть власні приклади написання таких функцій.
91. Поясніть приклади 2.39 – 2.42.
92. Що являє собою функція input в інтерпретаторі мови програмування
Python? Наведіть власні приклади використання цієї функції?
93. Як з використанням функції input здійснюється введення числових
та текстових даних з клавіатури? Наведіть власні приклади такого
використання функції input.
94. Поясніть приклад 2.43.
95. Як у мові програмування Python здійснюється тестування
програмних модулів? Наведіть власні приклади тестування програм в
інтерпретаторі мови Python.
96. Поясніть приклади 2.44 та 2.45.
97. Які властивості повинні мати програмні модулі, призначені для
переведення значень фізичних величин із однієї системи вимірювання до
іншої. Наведіть можливі приклади таких програмні модулі, написаних мовою
програмування Python.

191
98. Як можна перевести значення температури із градусів Цельсія до
градусів Фаренгейта? Наведіть приклад програмного модуля, який виконує
таке перетворення.
99. Поясніть співвідношення (2.20) та (2.21) та наведіть приклади їх
використання.
100. В яких електронних пристроях, призначених для вимірювання
температури, аналогових чи цифрових, може бути використана програма
переведення значення температури із градусів Цельсія до градусів
Фаренгейта? Свою відповідь обґрунтуйте.
101. Поясніть приклад 2.46.
102. У яких галузях науки та техніки має важливе значення
розв’язування задачі переведення значення тиску із однієї одиниці
вимірювання до іншої?
103. Чому завдання вимірювання тиску є вкрай важливим для
технологій виробництва сучасної електронної техніки, незважаючи на те, що
сьогодні майже всі електронні прилади є напівпровідниковими?
104. Наведіть узагальнену класифікаційну схему приладів для
вимірювання тиску та опишіть її з точки зору методології ООП.
105. Наведіть узагальнену класифікаційну схему способів вимірювання
тиску та опишіть її з точки зору методології ООП.
106. Поясніть співвідношення (2.22) та (2.23).
107. Що являють собою сучасні багатофункціональні вимірювальні
пристрої і чи може бути багатофункціональним пристрій, призначений для
вимірювання тиску?
108. Поясніть приклад 2.47.
109. Що являє собою одиниця вимірювання децибел та у яких галузях
сучасної науки та техніки вона використовується?
110. Поясніть співвідношення (2.24) та (2.25).
111. Чому перетворення відносного значення відношення інтенсивності
сигналів до відповідного значення в децибелах вважається нелінійним? Свою

192
відповідь обґрунтуйте та наведіть інші приклади нелінійних перетворень
фізичних величин.
112. Поясніть приклад 2.48.
113. Чому операції над рядковими даними маються вельми важливе
значення у всіх сучасних мовах програмування?
114. Як визначається тип рядкових даних у мові програмування Python?
115. Поясніть приклад 2.49.
116. Які загальні правила мови програмування Python для роботи із
рядковими даними Вам відомі? Наведіть власні приклади використання цих
правил.
117. Поясніть правила 2.1 – 2.4.
118. Як у мові програмування Python задається порожній рядок?
119. Що являє собою функція len() та як вона використовується для
роботи із рядковими даними?
120. Поясніть приклад 2.50.
121. Як у мові програмування Python для роботи із рядками
використовується операція додавання? Наведіть власні приклади
використання цієї операції для роботи із рядковими даними.
122. Як у мові програмування Python для роботи із рядками
використовується операція множення? Наведіть власні приклади
використання цієї операції для роботи із рядковими даними.
123. Поясніть приклади 2.51 – 2.53.
124. Що являють собою перевантажені оператори з точки зору теорії
ООП? Поясніть визначення 2.5.
125. Які функції перетворення рядкових даних до числових та числових
до рядкових, реалізовані в мові програмування Python, Вам відомі? Наведіть
власні приклади використання таких функцій.
126. Поясніть приклади 2.54 та 2.55.
127. Які спеціальні символи мови програмування Python
використовуються для роботи з рядками? Наведіть власні приклади

193
використання таких символів.
128. Поясніть приклад 2.56.
129. Як функції мови програмування Python print() та input()
можуть бути використані для організації роботи програми в інтерактивному
режимі? Наведіть власні приклади такого використання цих функцій.
130. Поясніть приклад 2.57.
131. Які параметри виклику має функція print() та як вони можуть
бути використані для формування інформаційних повідомлень? Наведіть
власні приклади використання параметрів функції print().
132. Поясніть приклади 2.58 та 2.59.
133. Що являє собою функція open() мови програмування Python та як
вона використовується для роботи з файлами? Наведіть власні приклади
використання цієї функції.
134. Що являє собою функція read() мови програмування Python та як
вона використовується для роботи з файлами? Наведіть власні приклади
використання цієї функції.
135. Що являє собою функція write() мови програмування Python та
як вона використовується для роботи з файлами? Наведіть власні приклади
використання цієї функції.
136. Що являє собою функція print() мови програмування Python та
як вона використовується для роботи з файлами? Наведіть власні приклади
використання цієї функції.
137. Що являє собою функція close() мови програмування Python та
як вона використовується для роботи з файлами? Наведіть власні приклади
використання цієї функції.
138. Як у мові програмування Python визначаються можливі операції
над файлом, який відкривається? Наведіть власні приклади визначення таких
операцій.
139. Як у мові програмування Python визначається тип файлу? Наведіть
власні приклади визначення типу файлу.
194
140. Поясніть приклад 2.60.
141. Які функції мови програмування Python, призначені для роботи з
рядками, Вам відомі? Наведіть власні приклади використання таких функцій.
142. Як функції обробки рядків мови програмування Python в пов’язані
із методологією ООП? Свою відповідь обґрунтуйте.
143. Поясніть дані, наведені у таблиці 2.6.
144. Що являє собою функція format мови програмування Python та як
вона використовується для роботи із числовими та рядковими даними?
Наведіть власні приклади використання цієї функції.
145. Поясніть приклад 2.61.
146. Що являє собою операція об’єднання методів у мові
програмування Python та як ця операція використовується для роботи з
рядками? Наведіть власні приклади використання цієї операції для роботи з
рядками.
147. Поясніть приклад 2.62.
148. Поясніть приклади 2.63 та 2.64.
149. Як у мові програмування Python у файлах функцій користувача
формується текст допомоги? Наведіть власні приклади формування такого
тексту.
150. Поясніть приклади 2.65 та 2.66.
151. Чому написання текстів допомоги для власних функцій у мові
програмування Python вважається обов’язковим та як це пов’язано із
філософськими принципами цієї мови?
152. Як у мові програмування Python здійснюється індексація елементів
рядка? Наведіть власні приклади проведення індексації елементів рядка.
153. Що являє собою зворотна індексація елементів рядка у мові
програмування Python та як вона проводиться? Наведіть власні приклади
проведення зворотної індексації елементів рядка.
154. Чому у мові програмування Python будь-який елемент рядка не
може бути змінений через його індексацію?

195
155. Поясніть приклад 2.67.
156. Що являють собою зрізи рядків у мові програмування Python та як
вони використовуються для обробки рядків? Наведіть власні приклади
використання зрізів для обробки рядків.
157. Поясніть приклад 2.68.
158. Як з використанням зрізів на основі текстового шаблону можна
сформувати інформаційне повідомлення? Наведіть власні приклади такого
використання зрізів.
159. Поясніть приклад 2.69.
160. Перепишіть командні рядки, наведену у прикладі 2.69,
реалізувавши введення та виведення текстової інформації через виклик
функції.
161. З використанням операцій обробки рядків мови програмування
Python написати програму, яка за шаблоном
Студент *** групи *** з предмету *** має оцінку ***.
формує відповідне інформаційне повідомлення. Прізвище студента, назву групи,
назву предмета та оцінку вводити з клавіатури в інтерактивному режимі роботи
програми.

196
Розділ 3 Розгалуження, структуровані дані та цикли у мові
програмування Python
У цьому розділі розглядаються засоби програмування мови Python, основані на
формуванні логічних виразів, а також умовні оператори та цикли. Показано,
що застосування арифметико-логічних виразів для обробки числових даних
дозволяє у багатьох випадках уникнути використання умовних операторів та
перейти до новітніх технологій логічного програмування. На прикладі аналізу
значення електропровідності та діелектричної проникності матеріалів
розглядається можливість використання умовного оператора для
розв’язування завдань прикладної фізики. Надано поняття про списки та
розглянуті способи роботи ним у мові програмування Python. Розглянуті
також можливості використання циклів для роботи зі списками. Окремо
розглядаються два типа циклів – із заданою кількістю повторень та із
заданою умовою. Розглянуті приклади розв’язування задач дискретної
математики, обчислювальної математики та прикладної фізики з
використанням циклічних структур. Як приклади оригінальних засобів
програмування, яких не існує в інших мовах, розглянуті анонімні лямбда-
функції та функції генератора числових послідовностей.

3.1 Базові операції порівняння даних у мові програмування


Python
Всі програми, які були розглянуті нами у розділі 2, мали просту лінійну
структуру. Обчислення у таких програмах завжди проводяться послідовно, без
переходів на інші частини програми в результаті аналізу ходу її виконання та
перевірки результатів попередніх обчислень. Така організація
обчислювального процесу є вкрай простою, і обчислювальний пристрій із
такою організацією не є інтелектуальним, оскільки він не може вирішувати
завдання вибору. Наприклад, лінійну структуру програми мають конвертори
фізичних величин, які розглядалися у підрозділі 2.5.6. Обчислювальні
завдання із лінійною структурою більше притаманні простим настільним
калькуляторам, ніж сучасним інтелектуальним комп’ютерним програмам та
програмованим електронним пристроям.
Для розв’язування завдань вибору у системах програмування
використовуються оператори розгалуження, які формуються на основі аналізу
логічних виразів [5 – 7]. Теоретичним підґрунтям для формування логічних

197
виразів є теорія предикатів, на основі якої, через оператори відношень,
формуються порівняння [2]. Також для формування логічних виразів
використовуються функції логічних відношень AND, OR, XOR та NOT, які
формуються на основі алгебри Буля [42]. На базі фундаментальних понять
логічних функцій та логічних виразів формуються більш складне поняття
арифметико-логічного виразу. Такі вирази у теорії програмування зазвичай
розглядаються як комбінації арифметичних та логічних функцій. Поняття
арифметико-логічного виразу та способи формування таких виразів будуть
розглянуті у підрозділі 3.3.
Надамо визначення операторів порівняння та логічних виразів.
Визначення 3.1 Операціями порівняння називаються базові операції
дискретної математики, пов’язані із визначенням математичних співвідношень
рівності або нерівності дійсних чисел.
Головними операціями порівняння, реалізованими у всіх мовах
програмування, є наступні [5 – 7, 24 – 29, 42].
1. Операція дорівнює. Визначає рівність двох чисел або змінних, не
змінюючи, на відміну від оператора присвоювання, змінної, яка стоїть у лівій
частині виразу. У мові програмування Python операція дорівнює позначається,
на відміну від оператора присвоювання, двома знаками рівності (==). Слід
відзначити, що досить частою помилкою починаючих програмістів, які не
мають відповідного досвіду програмування, є використання оператора
присвоювання замість операції порівняння «дорівнює». Приклади
використання операції дорівнює: 5==5; 5==3; a==b; a==5.
2. Операція не дорівнює. Визначає нерівність двох чисел або змінних,
які стоять у лівій та правій частині порівняння. У мові програмування Python
операція не дорівнює позначається двома символами !=. Приклади
використання операції дорівнює: 5!=5; 5!=3; a!=b; a!=5.
3. Операція більше. Означає, що число або змінна, яке стоїть у лівій
частині нерівності, є більшим за число або змінну, які стоять у його правій
частині. У мові програмування Python операція більше позначається символом

198
>. Приклади використання операції більше: 5>5; 5>3; a>b; a>5.
4. Операція менше. Означає, що число або змінна, яке стоїть у лівій
частині нерівності, є меншим за число або змінну, які стоять у його правій
частині. У мові програмування Python операція менше позначається символом
<. Приклади використання операції менше: 5<5; 5<3; a<b; a<5.
5. Операція більше або дорівнює. Означає, що число або змінна, яке
стоїть у лівій частині нерівності, є не меншим за число або змінну, які стоять у
його правій частині. У мові програмування Python операція більше або
дорівнює позначається символом >=. Приклади використання операції більше
або дорівнює: 5>=5; 5>=3; a>=b; a>=5.
6. Операція менше або дорівнює. Означає, що число або змінна, яке
стоїть у лівій частині нерівності, є не більшим за число або змінну, які стоять у
його правій частині. У мові програмування Python операція менше або
дорівнює позначається символом <=. Приклади використання операції менше
або дорівнює: 5<=5; 5<=3; a<=b; a<=5.
Результатом виконання операцій порівняння є значення змінної алгебри
Буля [42]. Як відомо з основ математичної логіки, такі змінні можуть
приймати два логічних значення: True (Істина) або False (Хибність), яким у
числовій формі відповідають значення 1 (Істина) або 0 (Хибність) [5 – 7].
Слід відзначити, що у деяких випадках у мовах програмування логічним
змінним присвоюється значення булевої змінної, а у деяких, навпаки, числове
значення. Тут слід мати на увазі, що якщо для формування логічних виразів,
які розглядатимуться у підрозділі 3.2, тип логічної змінної зазвичай немає
значення, то в арифметико-логічних виразах, які розглядатимуться у підрозділі
3.3, можуть бути використані лише числові значення логічних змінних. Для
примусового перетворення булевих значень логічних змінних на числові в
мові програмування Python може бути використана функція перетворення
типів даних int.
Розглянемо результати виконання деяких операцій порівняння.
5==5 – результат True, або 1. 5==3 – результат False, або 0.
199
5!=3 – результат True, або 1. 5<5 – результат False, або 0.
5<=5 – результат True, або 1. 5<=3 – результат False, або 0.
Розглянемо тепер приклади запису операцій порівняння чисел та
змінних в інтерпретаторі мови програмування Python.
Приклад 3.1
>>> 7>3
True
>>> a = 4
>>> b = 5
>>> a==b
False
>>> a=b
>>> a==b
True
>>> c=int(a==b)
>>> c
0
>>> type(c)
<class ‘int’>
>>> d = (a==b)
>>> type(d)
<class ‘bool’>
>>>
На основі базових операцій порівняння формуються логічні вирази, які
розглядатимуться у наступному підрозділі.

3.2 Логічні вирази


Логічні вирази формуються на основі операцій порівняння з
використанням функцій математичної логіки та алгебри Буля, а також теорії
предикатів та регулярних мов [2]. Надамо відповідні визначення [42].
Визначення 3.2 Логічним виразом у вузькому значенні цього слова

200
називається будь-який вираз, який формується на основі логічних функцій та
операцій порівняння.
Таке визначення є вірним з точки зору дискретної математики, проте у
теорії предикатів та у сучасній теорії програмування логічні вирази зазвичай
розуміють значно ширше. Тому надамо інше визначення.
Визначення 3.3 Логічним виразом у широкому значенні цього слова
називається будь-яке висловлення, відносно якого можна однозначно сказати,
є воно істинним чи хибним.
Розглянемо взаємозв’язок між визначеннями 3.2 та 3.3 як властивість
логічних виразів.
Властивість 3.1 Логічний вираз у вузькому значенні слова завжди є
також логічним виразом у широкому значенні слова. Противне твердження є
неправильним.
Наприклад, логічний вираз 4<5 є логічним виразом у вузькому значенні
слова, тому він є логічним виразом також у широкому значенні слова.
Навпаки, вираз «Потапенко – студент» є логічним виразом у широкому
значенні слова, але його не можна вважати логічним виразом у вузькому
значенні слова, оскільки він не сформований із операцій порівняння.
Зрозуміло, що логічні вирази у вузькому значенні слова легко
аналізувати і завжди можна сказати, є вони істинними чи хибними. Цього не
можна сказати про логічні вирази у широкому значенні слова. Висловлення
«Потапенко – студент» легко перевірити, якщо прочитати списки студентів
факультету, а ось висловлення «Він студент» перевірити неможливо без
додаткової інформації щодо людини, про яку йде мова. Те ж саме можна
сказати про інші вирази, у яких не йдеться про конкретний об’єкт. Наприклад,
не можна вважати логічними виразами наступні висловлення: «Десь літає
птах» (невідомо де), «У неї карі очі» (невідомо у кого), «Це блакитні квіти»
(невідомо, що за квіти). Якщо надати додаткову інформацію, ці висловлення
можуть стати логічними виразами. Наприклад: «В саду над яблунею літає
птах», «У Наталки карі очі», «Незабудки – блакитні квіти».
Логічні вирази можна об’єднувати з використанням логічних операцій

201
алгебри Буля: and, or, xor та not. Якщо об’єднуються два логічних вирази,
значення яких відомо, можна легко знайти значення остаточного виразу. Для
цього використовуються відомі правила алгебри Буля, які у загальному
вигляді, для різних значень числових аргументів логічних функцій, зведені у
таблиці 3.1 [42].

Таблиця 3.1 – Результати виконання логічних операцій алгебри Буля


для різних значень аргументів логічних функцій

Функція and or xor not


1 1 0 0 1 1 0 0 1 1 0 0 1 0
Аргументи
1 0 1 0 1 0 1 0 1 0 1 0 – –
Результат 1 0 0 0 1 1 1 0 0 1 1 0 0 1

Зрозуміло, що запам’ятати результати всіх логічних операцій, наведені


у таблиці 3.1, досить важко. Тому варто також знати наступні чотири прості
правила алгебри Буля, які дозволяють легко ці результати поновити.
Правило 3.1 Якщо хоча б один із аргументів логічної функції and
дорівнює 0, результат виконання цієї функції також дорівнює 0, у
противному випадку результат її виконання дорівнює 1.
Правило 3.2 Якщо хоча б один із аргументів логічної функції or
дорівнює 1, результат виконання цієї функції також дорівнює 1, у
противному випадку результат її виконання дорівнює 0.
Правило 3.3 Результат виконання логічної функції xor є таким, що
кількість одиниць в обох аргументах цієї функції та у отриманому результаті
має або бути парним числом або дорівнювати нулю.
Правило 3.4 Результатом виконання логічної функції not є зміна
значення аргументу цієї функції на протилежне.
Наведемо приклади обчислення логічних виразів з використанням
засобів програмування мови Python.

202
Приклад 3.2
>>> (7>3) or (5>10) # 1 or 0 = 1
True
>>> (7>3) and (5>10) # 1 and 0 = 0
False
>>> (7>3) xor (5>10) # 1 xor 0 = 1
True
>>> not (7>3) # not(1) = 0
False
>>>
На основі простих логічних виразів, які об’єднують дві операції
порівняння, формуються більш складні вирази. Розглянемо відповідний
приклад.
Приклад 3.3
>>> ((7>3)or(5>10))and(15>40) #1 or 0=1; 1 and 0=0;
False
>>> ((7>3)and(5>10))or(15>40) #1 and 0 = 0; 0 or 0 = 0;
False
>>> ((7>3)xor(5>10))and((15>40)xor(20<40)) # 1 xor 0 = 1; \n
0 xor 1 = 1; 1 and 1 = 1;
True
>>> not((7>3)xor(5>10)) # 1 xor 0 = 1; not(1) = 0;
False
>>>
Ці приклади є цілком зрозумілими, але всі вони основані на
використанні операцій порівняння та на алгебрі Буля, і тому відповідають
лише логічним виразам у вузькому значенні цього слова. Тому виникає
питання, а чи можна у мові програмування Python формувати логічні вирази
у широкому значенні слова? Тут слід відзначити, що у мові Python поняття
логічних виразів, порівняно із іншими мовами програмування, значно
розширено, і можна формувати логічні вирази не лише для роботи із
203
операціями порівняння, але й для роботи з об’єктами. Розглянемо головне
правило, згідно із яким у мові Python формуються логічні вирази у широкому
значенні цього слова [24, 25].
Правило 3.5 У мові програмування Python будь-яке дійсне число, яке
не дорівнює 0, а також будь-який не порожній об’єкт, зокрема не порожній
рядок, інтерпретуються як істина. Навпаки, число, яке дорівнює 0, порожній
об’єкт або спеціальний об’єкт None інтерпретуються як хибність.
Саме використання наведеного правила 3.5 дозволяє значно поширити
класичне поняття логічного виразу і розглядати також логічні вирази у
широкому значенні слова, які описуються визначенням 3.3. Наведемо
приклади формування та аналізу логічних виразів у широкому значенні
слова.
Приклад 3.4
>>> ‘’ and 2 # False and True = False
‘’
>>> ‘’ or 2 # False or True = True
2
>>> None and 2 # False and True = False = None
>>> None or 2 # False or True = True
2
>>> int(None and 2)
0
>>> int(None or 2)
2
>>>
У наведеному прикладі цікавим є використання функції перетворення
типів даних int(None or 2). Якщо результатом виконання логічної
операції є пустий об’єкт, пустий рядок або системна змінна None, функція
повертає значення int(False) = 0. Якщо ж результатом виконання
логічної операції є числове значення, воно після перетворення з

204
використанням функції int() або, у разі дійсного числа, округлюється до
найближчого цілого, або, у разі цілого числа, залишається незмінним.
Наприклад, як видно із прикладу 3.4, результатом обчислення логічного
виразу у широкому значенні слова може бути число 2.
Зрозуміло, що у разі використання логічних виразів у широкому
значенні слова всі дані, наведені у таблиці 3.1, є правильними, але якщо
значенню 0 завжди відповідає 0, то замість значення 1 може бути будь-яке
дійсне число. Інакше кажучи, якщо операндами логічного виразу є не числа,
а об’єкти, результатом виконання операції буде об’єкт. Тобто, у даному
випадку дійсні числа також розглядаються як об’єкти, відповідні теоретичні
відомості щодо подання чисел як об’єктів у мові програмування Python
розглядалися у підрозділі 2.3.
Але тоді виникає інше питання. Якщо для логічних виразів у широкому
значенні слова булева змінна True може приймати значення будь-якого
дійсного числа, тоді яке із цих значень буде використане для обчислення
значення складного логічного виразу, сформованого з використанням
логічних функцій and та or? У цьому випадку значення логічних виразів
обчислюються за наступними правилами.
Правило 3.6 Для обчислення значення логічного виразу, який містить
функцію and, перевіряються всі її аргументи у напрямку зліва направо та
повертається значення першого аргументу, який має значення «False», або
крайнього правого аргументу.
Правило 3.7 Для обчислення значення логічного виразу, який містить
функцію or, перевіряються всі її аргументи у напрямку зліва направо та
повертається значення першого аргументу, який має значення «True», або
крайнього лівого аргументу.
Розглянемо приклади використання правил 3.6 та 3.7.
Приклад 3.5
>>> 3 and 2
# Згідно із правилом 3.6 результатом є правий аргумент
205
2
>>> 0 and 2
# Згідно із правилом 3.6 результатом є 0
2
>>> 2 or 3
# Згідно із правилом 3.7 результатом є лівий аргумент
2
>>> 0 or 3
# Згідно із правилом 3.7 результатом є значення 3
3
>>> None or 3
# Згідно із правилом 3.7 результатом є значення 3
3
>>>
Слід відзначити, що логічні вирази можна комбінувати, проте тут слід
враховувати порядок виконання дій в інтерпретаторі програмування Python,
який визначається наступним правилом.
Правило 3.8 Пріоритет виконання арифметичних операцій у мові
програмування Python є вищим, ніж для операцій порівняння.
Розглянемо приклад виконання послідовності дій, пов’язаних із
проведенням арифметичних та логічних операцій над числами.
Приклад 3.6
>>> 1 + 3 > 8 # Пріоритет + є вищим, ніж пріоритет >
False
>>> int(1 + 3 > 8)
0
>>> 1 + (3 > 8)
1
>>>
Всі порівняння, розглянуті вище, були однобічними, тобто

206
зрівнювались значення двох чисел або змінних, які стоять зправа та зліва від
операції порівняння. Відомо, що в математиці часто використовуються також
двобічні порівняння, які в літературі іноді називають інтервальними
оцінками [66]. Наприклад, порівняння 0,5 < x < 1,2 означає, що змінна x
лежить в числовому інтервалі ]0,5; 1,2[, тобто x > 0,5, і одночасно x < 1,2.
Неважко зрозуміти, що інтервальну оцінку легко замінити через логічну
функцію and.. Дійсно, висловлення (0,5 < x < 1,2) та (x > 0,5 and. x < 1,2) з
точки зору теорії предикатів є еквівалентними. Саме тому у більшості мов
програмування двосторонні порівняння не використовуються, оскільки
вважається, що їх можна легко замінити логічними виразами [5 – 10, 12 – 17].
Проте у мові програмування передбачена можливість використання
двосторонніх порівнянь. Тобто, запис –5 < x < 10 з точки зору
синтаксису цієї мови програмування є цілком правильним. Розглянемо
приклади використання двосторонніх порівнянь.
Приклад 3.7
>>> x = 3
>>> –5 < x < 10
True
>>> –5 < x < 1
False
>>>
Зрозуміло, що, згідно із визначенням 3.2, двосторонні порівняння
можна розглядати як логічні вирази у вузькому значенні слова.
Слід також відзначити, що значення логічного виразу у мові Python
може бути присвоєно логічній змінній, яка має тип ‘bool’ [24, 25]. Цілком
зрозуміло, що після надання їм відповідного значення ці змінні можуть бути
використані в інших логічних виразах. Розглянемо відповідний приклад.
Приклад 3.8
>>> x = 5 < 10
>>> x

207
True
>>> y = 25 > 40
>>> y
False
>>> c = x and y
>>> c
False
>>> r = x or y
>>> r
True
>>> q = x xor y
>>> q
True
>>> e = c and r
>>> e
False
>>> d = r xor q
False
>>>
Одним із ефективних способів використання логічних виразів є
обробка виключних ситуацій. Річ у тому, що якщо значення арифметичного
виразу не може бути обчисленим, інтерпретатор мови програмування Python
повертає для відповідного об’єкта значення змінної None. На практиці це
дозволяє уникнути системних повідомлень про помилку через обробку
виключних ситуацій з використанням логічних виразів. Розглянемо
1
відповідний приклад для функції .
x
Приклад 3.9
>>> x = 0
>>> 1/x

208
Traceback (most recent call last):
File <division_error>, line 1, in <module>
Zero_Division_Error: division by zero
>>> x = 1
>>> x and 1/x
1.0
>>> x = 0
>>> x and 1/x
0
>>>
Проаналізуємо наведений приклад 3.9. За умови x = 1 значення логічного
виразу (x and 1/x) дорівнює 1, оскільки x = 1 та 1/x = True = 1, тобто,
остаточно 1 and 1 = 1. Навпаки, за умови x = 0 значення логічного виразу
(x and 1/x) дорівнює 0, оскільки x = 0, а 1/x = None = False = 0, тобто,
остаточно 0 and 0 = 0. Таким чином, незалежно від значення змінної x
результат логічного виразу (x and f(x)) за умови невизначеної функції
f(x) дорівнює 0, оскільки f(x) = None = False. Із наведеного прикладу
можна зробити висновок про те, що використання логічних виразів у широкому
значенні слова значно розширює можливості мови програмування Python та
дозволяє, через аналіз властивостей об’єктів, писати інтелектуальні програми
із ускладненими алгоритмами обробки даних [24, 25].
І нарешті, розглянемо у цьому підрозділі можливості використання
логічних виразів мови програмування Python для аналізу значень рядкових
змінних. Будь-який рядок складається із символів, які мають відповідні
числові коди згідно із форматом ASCII [1] або Unicode [67]. Слід відзначити,
що якщо символи ASCII містять лише літери англійської абетки, цифри та
керувальні символи, до стандарту Unicode включені символи майже всіх
абеток світу. Крім цього, цей стандарт містить зарезервовані цифрові коди,
які можна використовувати у майбутньому [67]. Зокрема, символам кирилиці
відповідають значення кодів від U+0400 до U+052F, від U+2DE0 до U+2DFF

209
та від U+A640 до U+A69F [68]. Визначити код символу за стандартом
Unicode у мові програмування Python можна з використанням функції
ord(). Розглянемо наступний приклад.
Приклад 3.10
>>> ord(‘L’)
76
>>> ord(‘Ф’)
1060
>>> ord(‘A’)
65
Тепер стає зрозумілим, що оскільки в стандарті Unicode всі символи
упорядковані та мають відповідні номери, можна порівняти два символи
через логічний вираз. Розглянемо відповідний приклад.
Приклад 3.11
>>> ‘L’ > ‘A’
True
>>> ‘C’ > ‘M’
False
>>> ‘К’ > ‘В’
True
>>> ‘К’ > ‘П’
False
Порівняння рядків виконується посимвольно. Розглянемо відповідний
приклад.
Приклад 3.11
>>> ‘L1’ > ‘A1’
# Перший символ лівого рядка більший,
# ніж перший символ правого
True
>>> ‘А1’ > ‘Ф1’

210
# Перший символ лівого рядка менший,
# ніж перший символ правого
False
Слід відзначити, що зазвичай для розв’язування практичних завдань
обробки рядків більш корисним та ефективним є оператор in. Цей оператор
мови програмування Python широко використовується для обробки структур
даних та визначає наявність елемента у структурі. Оскільки рядкові дані теж
є структурами, до них може бути застосований цей оператор. Розглянемо
відповідний приклад.
Приклад 3.12
>>> ‘s’ in ‘start’ # У слові ‘start’ є мала літера ‘s’
True
>>> ‘S’ in ‘start’ # У слові ‘start’ немає великої літери ‘S’
False
>>> ‘в’ in ‘вага’ # У слові ‘вага’ є мала літера ‘в’
True
>>> ‘’ in ‘’ # Пустий рядок містить пустий рядок.
# Це вірне твердження
True
>>> ‘’ in ‘вага’ # Будь-який рядок містить пустий рядок.
# Це вірне твердження
True
Більш досконало можливості використання оператора in для роботи зі
структурованими даними розглядатимуться у підрозділі 3.6. Для закріплення
матеріалу, розглянутого у цьому підрозділі, необхідно виконати практичне
заняття №4, яке наведене у розділі 7.

3.3 Арифметико-логічні вирази


Узагальненням поняття логічного виразу для більш широкого кола
завдань програмування є поняття арифметико-логічного виразу [6, 7]. Такі

211
вирази широко використовуються для описання аналітичних функцій,
кусково заданих на заздалегідь визначених інтервалах. Надамо відповідне
визначення [6, 7].
Визначення 3.4 Арифметико-логічним виразом називається вираз,
який має вигляд [6, 7]:
AL(x) = A1(x)·L1(x) + A2(x)·L2(x) + ... + Ai(x)·Li(x) + ... + An(x)·Ln(x), (3.1)
де Ai(x) – арифметичні вирази, Li(x) – логічні вирази. Зрозуміло, що
необхідною умовою коректного завдання співвідношення (3.1) є
незалежність числових інтервалів, заданих логічними функціями L1(x),
L2(x), ..., Li(x), ..., Ln(x). Ці інтервали не повинні перетинатися. Важливим
також є те, що область визначення аргументу арифметико-логічного виразу x
має цілком описуватися логічними функціями L1(x), L2(x), ..., Li(x), ..., Ln(x), у
противному випадку вираз (3.1) є некоректним з математичної точки зору.
Також цілком зрозуміло, що для проведення коректного обчислення виразу
(3.1) логічні функції L1(x), L2(x), ..., Li(x), ..., Ln(x) повинні мати не булеве, а
числове значення. Для ручного перетворення булевого значення логічної
змінної на числове може бути використана системна функція int, хоча у
більшості випадків інтерпретатор мови програмування Python таке
перетворення проводить автоматично [24, 25].
Наочна графічна інтерпретація визначення арифметико-логічного
виразу (3.1) наведена на рис. 3.1.
L1(x) L2(x) Li(x) Ln(x)
A1(x) A2(x) Ai(x) An(x) x
x0 x1 x2 xi – 1 xi xn – 1 xn

Рис. 3.1 Наочна ілюстрація загального принципу формування арифметико-


логічного виразу (3.1)

Наведемо деякі приклади арифметико-логічних виразів [6, 7]:


0·(x < 0) + 1·(x ≥ 0); exp(–x)·(x < 0) + exp(x)·(x ≥ 0);
sin(x)·(x ≤ 0) + cos(x)·(x > 0); sin(x)·(x ≤ 0) – sin(x)·(x > 0). (3.2)

212
Зрозуміло, що вирази, аналогічні співвідношенням (3.2), досить легко
реалізувати з використанням розглянутих вище засобів програмування мови
Python. Розглянемо відповідний приклад, у якому розраховується значення
функції
AL1(x) = 0·(x ≤ 0) + (sin(x) + cos(x))·((x > 0)&(x ≤ 3π))+
+ sin(x)·((x > 3π)&(x ≤ 5π)) + cos(x)·((x > 5π)&(x ≤ 7π)) +
+0·(x >7π ). (3.3)
Слід відзначити, що комбінації тригонометричних функцій, аналогічні
арифметико-логічному виразу (3.3), часто використовуються у статистичній
радіотехніці для описання цифрової модуляції двійкових сигналів [66].
Сформулюємо головні вимоги до функції, яка має бути створена.
1. Значення x необхідно передавати як параметр.
2. Значення функції AL1(x) необхідно повертати до головної функції.
3. Для визначення інтервалів, на яких обчислюється значення
арифметико-логічного виразу, слід використовувати двосторонні оцінки.
4. У разі, якщо функція викликається із командного рядка, передбачити
можливість введення значення параметра x з клавіатури.
Способи реалізації вимог, сформульованих у пунктах 1, 2 та 3,
розглядалися у підрозділах 2.5 та 3.2. Що стосується четвертої вимоги, спосіб
написання програм із різними способами виклику із інтерпретатора та із
оболонки IDLE з використанням засобів програмування мови Python
необхідно розглянути окремо.
По-перше, можна використовувати визначення значення вхідної
змінної за замовченням, як у прикладі 2.30. Проте у мові програмування
Python існує також інший ефективний спосіб визначення методу запуску
функції, пов’язаний із аналізом посилання на об’єкт, який їй відповідає, та з
перевіркою значення відповідної змінної. Розглянемо цей спосіб більш
досконало. Значення змінної __main__, пов’язаною із функцією, яка
викликається, у мові Python здійснюється наступним чином. Якщо запуск
функції здійснюється через оболонку IDLE, відповідній змінній надається

213
рядка ‘__main__’, а у противному випадку – ім’я модуля, із якого вона
імпортується через директиву import. Інакше кажучи, якщо функція
запускається із іншого файлу або із інтерпретатора командного рядка через
технологію імпортування, тоді значення змінної, яка на неї посилається, буде
відрізнятися від рядка ‘__main__’. У наведеному нижче прикладі
реалізовані обидва метода визначення вхідного параметра x: через введення
його значення за замовченням у параметрах функції та через аналіз значення
змінної __main__.
Приклад 3.13
def arith_log(x = 0):
from math import sin
from math import cos
from math import pi
if _main_ == ‘_main_’:
x = input(‘Введіть значення аргумента x:’)
al=(0*(x<=0)+(sin(x)+cos(x))*(0<x<=3*pi)\
+sin(x)*(3*pi<x<=5*pi)\
+cos(x)*(5*pi<x<=7*pi)\
+0*(x>7*pi))
return al
Припустимо, що текст програми, написаний у прикладі 3.13, записаний
до файлу ar_log_sin_cos. Розглянемо результат роботи цієї функції у
разі її запуску через інтерпретатор командного рядка.
Приклад 3.14
>>> from ar_log_sin_cos import arith_log
>>> arith_log()
0.0
>>> с=5
>>> arith_log(с)
-0.67526208919991

214
>>> с=5*math.pi
>>> arith_log(с)
6.123233995736766e-016
>>> arith_log(10)
-0.54402111088937
>>>
У прикладі 3.13 для роботи з логічним виразом використаний умовний
оператор if, синтаксис якого більш досконало буде розглянутий у
наступному підрозділі.

3.4 Синтаксис умовного оператора та відповідні лінгвістичні


конструкції мови програмування Python
Обмеженість арифметико-логічних виразів, записаних у формі
співвідношення (3.1), з точки зору їх практичного використання для
розв’язування прикладних завдань програмування, полягає у тому, що вони
призначені лише для роботи із числовими даними. Тобто, у разі необхідності
обробки рядків або виклику функції через аналіз подій необхідно провести
попередню обробку отриманих даних та надати їм числові значення. Крім
цього, розрахунки за співвідношенням (3.1) зазвичай є надлишковими. Це
пов’язано з тим, що на всіх числових інтервалах розраховуються значення
арифметичних функцій, а потім більшість із цих значень множиться на 0.
Аналіз ефективності алгоритмів розрахунку значень арифметико-логічних
виразів був проведений у навчальному посібнику [7].
Тому у разі необхідності виконання певних дій, пов’язаних із обробкою
даних та реалізацією розгалужених алгоритмів, зазвичай ефективнішим є
використання умовного оператору [6, 7].
У мові програмування Python розглядається два різновиди умовного
оператора – з узагальненою та із спрощеними синтаксичними конструкціями.
Загалом лінгвістичні конструкції умовного оператора будуються на принципі
запису логічних виразів усередині інструкції if, а ця інструкція складається

215
із ключових слів, символу двокрапка та блоків виразів [24 – 29]. Ключовими
словами, із яких формується лінгвістична конструкція умовного оператора,
можуть бути слова if, elif та else. Саме із сукупності цих трьох
ключових слів у мові програмування Python будується узагальнена
лінгвістична конструкція умовного оператора, яка має наступний вигляд
[24 – 29]:
if <логічний вираз>:
<блок операторів та функцій>
<elif логічний вираз>:
<блок операторів та функцій>
<else>:
<блок операторів та функцій>.
Існують також дві спрощені форми синтаксичних конструкцій
умовного оператора, а саме:
1. без ключового слова elif, тобто:
if <логічний вираз>:
<блок операторів та функцій>
else:
<блок операторів та функцій>
2. без ключових слів elif та else, тобто:

if логічний вираз:
<блок операторів та функцій>.
Наведемо приклади використання умовних операторів для проведення
подальших обчислень згідно із введеними та обчисленими значеннями
числових змінних.
Приклад 3.15
def test_if():
import math
x = input(‘Введіть значення аргументу x:\n’)
if x > 0:
216
y = math.sin(x)
print (‘y = ’, y)
if x < 0:
y = math.cos(x)
print (‘y = ’, y)
if x == 0:
print (‘y = ’, 0)
Припустимо, що наведена у прикладі 3.15 функція test_if записана
до модуля module_test_if. Тоді виклик цієї функції здійснюється
наступним із командного рядка інтерпретатора Python наступним чином.
Приклад 3.16
>>> import module_test_if
>>> import math
>>> module_test_if.test_if()
>>> Введіть значення аргументу x:
>>> 0
y=0.0000000000000000
>>> module_test_if.test_if()
>>> Введіть значення аргументу x:
>>> math.pi/2
y=1.0000000000000000
>>> module_test_if.test_if()
>>> Введіть значення аргументу x:
>>> -math.pi
y=-1.0000000000000000
Недоліком програми, наведеної у прикладі 3.15, є те, що для аналізу
введеного значення змінної x в ній використовується три умовних оператора
зі спрощеною лінгвістичною конструкцією. Розглянемо інший приклад, в
якому цей аналіз здійснюється з використанням єдиної узагальненої

217
конструкції умовного оператора.
Приклад 3.17
def test_if
import math
x = input(‘Введіть значення аргументу x:’)
if x > 0:
y = math.sin(x)
print (‘y = ’, y)
elif x < 0:
y = math.cos(x)
print (‘y = ’, y)
else:
print (‘y = ’, 0)
Цілком зрозуміло, що результати роботи програм, наведених у
прикладах 3.15 та 3.17, будуть цілком однаковими. Різниця цих програм
полягає у тому, що аналіз введеного значення змінної x у прикладі 3.17
виконаний одним умовним оператором. У разі використання спрощеної
лінгвістичної конструкції всі умови розглядаються окремо. Тобто,
використання узагальненої форми умовного оператора дозволяє виконувати
комплексний аналіз всіх можливих ситуацій за будь-якої умови, що значно
спрощує написання та аналіз програм із розгалуженими алгоритмами.
Тобто, хоча згідно із п’ятим принципом філософії мови програмування
Python, сформульованим у підрозділі 1.5: «Однорівневе є кращим, ніж
вкладене», для написання програм із аналізом складних ситуацій та великою
кількістю розгалужень зазвичай краще користуватись четвертим принципом:
«Складне є кращим, ніж ускладнене».
Тим же четвертим принципом філософії мови програмування Python
слід користуватися у разі вибору між використанням арифметико-логічних
виразів та умовного оператору. З одного боку, арифметико-логічні вирази
точніше відображують математичні аспекти складних розгалужених

218
розрахунків через комплексний аналіз логічних функцій, але з іншого боку
використання узагальненої форми умовного оператора значно спрощує
написання та розуміння програмного коду [6, 7, 24, 25]. Тому перепишемо
приклад 3.13 з використанням узагальненої форми умовного оператора.
Приклад 3.18
def arith_log(x = 0):
from math import sin
from math import cos
from math import pi
if __main__ == ‘__main__’:
x = input(‘Введіть значення аргумента x:’)
if x<=0:
al=0
elif 0<x<=3*pi:
al=sin(x)+cos(x)
elif 3*pi<x<=5*pi:
al=sin(x)
elif 5*pi<x<=7*pi:
al=cos(x)
else:
al=0
return al
Зрозуміло, що коди програм, наведених у прикладах 3.13 та 3.18, з
точки зору логіки їх роботи є еквівалентними, але код, наведений у прикладі
3.18 та написаний з використанням узагальненої форми умовного оператора є
значно простішим для розуміння. Тобто, дійсно, згідно із четвертим
принципом філософії мови програмування Python: «Складне є кращим, ніж
ускладнене».
У наступному підрозділі будуть розглянуті можливості використання
умовного оператора для розв’язування прикладних фізичних завдань.

219
3.5 Приклади розв’язування деяких прикладних завдань фізичної
електроніки з використанням умовного оператора
Розглянемо два практичних завдання електрофізики, розв’язування
яких пов’язано із аналізом числових значень заданих величин та потребує
використання умовного оператора. Це визначення типу провідникового
матеріалу за значенням його електропровідності та типу діелектричного
матеріалу за значенням його діелектричної проникності. Значення
відповідних електрофізичних параметрів будемо брати з довідникової
літератури, але надавати їм не точкові, а інтервальні оцінки [50]. Також
будемо вважати, що можливий інтервал значень електропровідності лежить у
межах 5 – 10% від середнього значення цього параметру. Якщо введене
значення не відповідає жодному із матеріалів, будемо вважати це значення
помилковим. Наприклад, інтервальні значення питомого електричного опору
для металів, які найчастіше використовуються в сучасній радіотехніці та
електроніці, наведені у таблиці 3.2 [50].
Таблиця 3.2 – Значення питомого електричного опору для різних
металів та графіту
№ п/п Метал Питомий опір, Ом·м
1. Вольфрам 5,4·10–8 – 5,6·10–8
2. Чисте залізо 9,9·10–8 – 1,15·10–7
3. Сталь 1,3·10–7– 1,5·10–7
4. Олово 1,18·10–7– 1,25·10–7
5. Константан (сплав) 4,8·10–7– 5,2·10–7
6. Чавун 9,9·10–7 – 1,1·10–6
7. Срібло 1,58·10–8 – 1,62·10–8
8. Мідь 1,7·10–8 – 1,75·10–8
9. Алюміній 2,6·10–8 – 2,8·10–8
10. Цинк 4,9·10–8 – 5,2·10–8
11. Свинець 1,9·10–7 – 2,1·10–7
12. Графіт 7,9·10–6 – 8,1·10–6

220
Код програми, яка визначає матеріал за значенням його питомого
електричного опору або електропровідності, може мати наступний вигляд.
Приклад 3.19
def el_cond():
n = int(input('Яка величина задається:\
1 – електропровідність, 0 –\
електричний опір:'))
if n == 0:
x = float(input ('Опір становить:'))
elif n == 1:
y = float(input ('Електропровідність\
становить:'))
x = 1/y
else:
x = 0
print('Невірно заданий тип \
завдання. Перевірте \
вхідні дані.\n')
if 5.4e-8 <= x <= 5.6e-8:
print('Вольфрам')
elif 9.9e-8 <= x <= 1.15e-7:
print('Чисте залізо')
elif 1.3e-7 <= x <= 1.5e-7:
print('Сталь')
elif 1.18e-7 <= x <= 1.25e-7:
print('Олово')
elif 4.8e-7 <= x <= 5.2e-7:

221
print('Константан')
elif 9.9e-7 <= x <= 1.1e-6:
print('Чавун')
elif 1.58e-8 <= x <= 1.62e-8:
print('Срібло')
elif 1.7e-8 <= x <= 1.75e-8:
print('Мідь')
elif 2.6e-8 <= x <= 2.8e-8:
print('Алюміній')
elif 4.9e-8 <= x <= 5.2e-8:
print('Цинк')
elif 1.9e-7 <= x <= 2.1e-7:
print('Свинець')
elif 7.9e-6 <= x <= 8.1e-6:
print('Графіт')
else:
print('Введене невірне значення \
електропровідності або електричного\
опору. Перевірте вхідні дані')

Результати роботи програми, наведеної у прикладі 3.19, за умови її


запису до файлу з іменем elc, показані у прикладі 3.20.
Приклад 3.20
>>> import elc
>>> elc.el_cond()
Яка величина задається: 1 – електропровідність,
0 – електричний опір: 0
Опір становить: 2.7e-8
Алюміній

222
>>> elc.el_cond()
Яка величина задається: 1 – електропровідність,
0 – електричний опір: 1
Електропровідність становить: 3.7e+007
Алюміній
>>> elc.el_cond()
Яка величина задається: 1 – електропровідність,
0 – електричний опір: 3
Невірно заданий тип завдання.
Перевірте вхідні дані.
Введене невірне значення
електропровідності або електричного
опору. Перевірте вхідні дані
>>> elc.el_cond()
Яка величина задається: 1 – електропровідність,
0 – електричний опір: 0
Опір становить: 7e-6
Введене невірне значення
електропровідності або електричного
опору. Перевірте вхідні дані
>>> elc.el_cond()
Яка величина задається: 1 – електропровідність,
0 – електричний опір: 1
Електропровідність становить: 1.4e+005
Введене невірне значення
електропровідності або електричного
опору. Перевірте вхідні дані
>>>
Легко зрозуміти, чим суттєво відрізняється програма, наведена у
прикладі 3.19, від програм, наведених у підрозділах 2.5 та 2.6, зокрема, від

223
конверторів фізичних величин. Ця програма містить багато числових даних,
які дозволяють, з використанням умовного оператора, робити інтервальні
оцінки введеної величини та робити відповідні висновки щодо матеріалу,
якому відповідає задане значення електропровідності або електричного
опору. Важливим є те, що умовний оператор, на відміну від арифметико-
логічного виразу, дозволяє відразу виводити на екран інформацію про
відповідний матеріал.
За створеним шаблоном напишемо іншу програму, в якій будемо
визначати тип діелектрика за значенням його діелектричної проникності.
Інтервальні значення наведені у таблиці 3.3 [50]. Зрозуміло, що інтервальні
оцінки для значення діелектричної проникності є значно ширшими, ніж для
питомого електричного опору та становлять 15 – 30% від середнього
значення цієї величини.
Таблиця 3.3 – Значення діелектричної проникності для різних
матеріалів
Діелектрична
№ п/п Матеріал
проникність, відн. од
1. Ізоляційне масло на основі кремнію 2,2 – 2,8
2. Дерево 3,5 – 4,9
3. Фарфор 5– 5,9
4. Слюда 6 – 10
5. Скло 11 – 15
6. Етиловий спирт 25,1 – 25,5
7. Дистильована вода 30 – 31

Код комп’ютерної програми, призначеної для визначення типу


діелектричного матеріалу за значенням його діелектричної проникності,
наведений у прикладі 3.21.
Приклад 3.21
def el_ perm():

224
x = float ((input (‘Діелектрична проник\
ність становить:’))
if 2.2 <= x <= 2.8:
print(‘Ізоляційне масло на основі кремнію’)
elif 3.5 <= x <= 4.9:
print(‘Дерево’)
elif 5.0 <= x <= 5.9:
print(‘Фарфор’)
elif 6.0 <= x <= 10.0:
print(‘Слюда’)
elif 11 <= x <= 15:
print(‘Скло’)
elif 25.1 <= x <= 25.5:
print(‘Етиловий спирт’)
elif 30 <= x <= 31:
print(‘Дистильована вода’)
else:
print(‘‘‘Введене невірне значення
діелектричної проникності.
Перевірте вхідні дані’’’)
Результати тестування програми, наведеної у прикладі 3.21, у
командному вікні інтерпретатора Python, наведені у прикладі 3.22.
Передбачається, що текст програми збережений у файлі diel_perm.
Приклад 3.22
>>> from diel_perm import el_ perm
>>> el_ perm()
Діелектрична проникність становить: 2.25
Ізоляційне масло на основі кремнію
>>> el_ perm()
Діелектрична проникність становить: 5.5

225
Фарфор
>>> el_ perm()
Діелектрична проникність становить: 10,5
Введене невірне значення
діелектричної проникності.
Перевірте вхідні дані
У підрозділі 5.3 для програм, коди яких наведені у прикладах 3.19 та
3.21, буде розглянутий інший спосіб введення та виведення інформації, з
використанням засобів віконного інтерфейсу.

3.6 Списки у мові програмування Python та способи роботи з


ними

3.6.1 Визначення списків та базові функції мови програмування Python


для роботи з ними
Всі приклади програм, які розглядалися раніше, були орієнтовані на
обробку одного числового значення, що значно звужує коло прикладних
завдань, які можуть бути розв’язані з використанням таких програм.
Розглянемо конкретний приклад. Припустимо, що розглядається тиск у
технологічній камері в ході проведення експерименту, і особливість
проведення вимірювань є такою, що прилад видає значення в міліметрах
ртутного стовпчика, а подальші обчислення та обробку експериментальних
даних необхідно проводити для значень тиску в Паскалях. Зрозуміло, що для
розв’язування такого завдання можна скористатися формулою (2.23) та кодом
програми, наведеним у прикладі 2.47. Єдина проблема полягає у тому, що
якщо необхідно перерахувати не одно, а десять значень тиску, програму
необхідно запустити 10 разів, а для ста значень – сто разів, і так далі. Тобто,
хоча для одного значення тиску поставлене завдання є вкрай простим, у разі
необхідності обробки великої кількості числових даних це завдання у значній
мірі ускладнюється.
Відомо, що для розв’язування аналогічних завдань у більшості мов

226
програмування використовують упорядковані набори числових значень, які
називаються масивами [5 – 10, 12 – 19]. Але розробники мови програмування
Python пішли значно далі та ввели у цю мову структуру нового типу, яка
називається списком. Надамо відповідне визначення [24 – 26].
Визначення 3.5 Списком у мові програмування Python називається
упорядкована структура, елементами якої можуть бути дані різного типу.
Слід відзначити, що надане поняття списку базується на понятті
множини у дискретній математиці [60], але тут важливим є те, що в списку
можуть об’єднуватися дані різних типів. З точки зору теорії множин це
означає, що список – це множина, елементами якої можуть бути об’єкти
різної природи [60].
Розглянемо два головних правила, за яким у мові Python формуються
списки.
Правило 3.9 Всі елементи списку пишуться через кому у квадратних
дужках.
Правило 3.10 Елементами списку можуть бути дані будь-якого типу,
зокрема інші списки.
Наведемо приклади списків:
[1, 2, 3];
[1.5, 2.8, 3e-4];
[‘A’, ‘B’, ‘C’];
[‘Further’, ‘Mother’, ‘Daughter’];
[‘Тато’, ‘Мама’, ‘Донька’];
[‘1’, ‘2’, ‘3’];
[1, ‘2’, ‘3’, ‘Тато’, ‘Mother’];
[1, 2, 3, [3, 2, 1]].
На елементи списку можна посилатися через індекси, у цьому разі слід
пам’ятати, що перший елемент списку має нульовий індекс. Можна також
посилатися на останній елемент списку, який має індекс –1. Тобто, індексація
елементів списку цілком відповідає індексації елементів рядка, яка була

227
розглянута у підрозділі 2.6.8. Це пов’язано з тим, що рядки у мові
програмування Python також формуються як списки із текстовими змінними
[24 – 26]. Різниця полягає у том, що рядок у мові Python розглядається як
завершений список, елементи якого не можна змінити через їхню індексацію
з використанням оператора присвоєння. Як було відмічено у підрозділі 2.6.8,
обробка рядків з використанням індексації їхніх елементів може бути
здійснена лише через формування зрізів. На відміну від цього, будь-який
елемент списку може бути змінений через його індексацію з використанням
оператора присвоєння. Щодо неможливості використання цієї операції для
обробки рядків, тут спрацьовує принцип ООП про абстрагування даних, який
був розглянутий у підрозділі 1.2.
Адресація елементів списку у пам’яті комп’ютера здійснюється
наступним чином. Нульовий елемент розташований за адресою id1,
перший – за адресою id2, останній, відповідно – за адресою idn, а змінній,
яка посилається на весь список, відповідає адреса idn + 1 [24 – 26]. Проте
зазвичай комірки пам’яті для здійснення посилання на елемент списку не
мають суттєвого значення, оскільки такі посилання можна робити через
індекси. У зв’язку з цим розглянемо ще два правила, пов’язані із роботою зі
списками в мові Python.
Правило 3.11 Списку може бути надано ім’я змінної з використанням
оператора присвоєння.
Правило 3.12 Звертатися до елементів списку та змінювати їхні
значення можна через посилання на їхні індекси, які вказуються у квадратних
дужках після змінної, що відповідає імені списку. Нумерація елементів
списку починається з нуля, а останній елемент має індекс –1.
Правило 3.13 Посилання на елемент списку, якого не існує, є
помилковим.
Розглянемо приклад, у якому аналізуються можливості роботи зі

228
списком згідно з правилами 3.9 – 3.13.
Приклад 3.23
>>> s=[1, 2, 3, 4, 2.8, 3.5, ‘Pressure’]
>>> s[0]
1
>>> s[2]
3
>>> s[–1]
‘Pressure’
>>> s[–1]=‘Тиск’
>>> s
[1, 2, 3, 4, 2.8, 3.5, ‘Тиск’]
>>> s[4]=4.6
>>> s
[1, 2, 3, 4, 4.6, 3.5, ‘Тиск’]
>>> s[–2]=8.3
>>> s
[1, 2, 3, 4, 4.6, 8.3, ‘Тиск’]
>>> s[7]=3
Traceback (most recent call last):
File “<pyshell#10>”, line 1, in <module>
s[7]=H
IndexError: list index out of range
>>>

Якщо список містить дані одного типу, наприклад, числові або рядкові,
до такого списку можуть бути застосовані відповідні функції обробки
списків, які перелічені у таблиці 3.4.

229
Таблиця 3.4 – Функції обробки списків мови програмування Python

Функція Призначення функції


len(L) Повертає кількість елементів списку L
max(L) Повертає максимальний елемент списку L
min(L) Повертає мінімальний елемент списку L
sum(L) Повертає суму елементів списку L
sorted(L) Повертає копіє списку L, у якій всі елементи впорядковані за
зростанням, не змінюючи список L, який обробляється

Розглянемо приклади використання функцій для роботи зі списками,


наведених у таблиці 3.4.
Приклад 3.24
>>> L=[1.3, 10.5, 13, 41, -2.8, 18.5]
>>> n=len(L)
>>> n
6
>>> max_s=max(L)
>>> max_s
41
>>> min_s=min(L)
>>> min_s
-2.8
>>> sm=sum(L)
81.5
>>> LS=sorted(L)
>>> LS
[-2.8, 1.3, 10.5, 13, 18.5, 41]
>>>
Цікавим є те, що результати використання функцій обробки списку

230
цілком відповідають введеним значенням, перетворення типів даних у
даному випадку не здійснюється. Функції для роботи зі списками належать
до вбудованих функцій інтерпретатора, тому у разі звернення до них
непотрібно вказувати ім’я модуля. Особливості використання функції len()
для обробки рядків були розглянуті у підрозділі 2.6. Слід відзначити, що
схожі функції для роботи із структурами числових даних існують також у
системі науково-технічних розрахунків MatLab.
Також цікавою є можливість використання для роботи зі списками
операцій додавання та множення. Вони аналогічні використанню цих
операцій для роботи з рядками. Сформулюємо особливості використання цих
операцій для роботи зі списками у вигляді наступних правил [24 – 26].
Правило 3.14 Сумою списків є узагальнений список, який містить
послідовно всі елементи списків, які сумуються, із повтореннями елементів.
Правило 3.15 Добутком списку на число є узагальнений список, який
складається із початкового списку, повтореного відповідну кількість разів.
Розглянемо приклади використання операцій додавання та множення
для роботи зі списками.
Приклад 3.25
>>> a=[1, 2, 3, 4]
>>> b=[5, 6, 7]
>>> a+b
[1, 2, 3, 4, 5, 6, 7]
>>> b+a
[5, 6, 7, 1, 2, 3, 4]
>>> a*2
[1, 2, 3, 4, 1, 2, 3, 4]
>>> b*3
[5, 6, 7, 5, 6, 7, 5, 6, 7]
>>>

231
Розглянемо можливості використання списків як параметрів функцій
користувача на прикладі наступної простої функції.
Приклад 3.26
def f(x, y)
return x + y
Перевіримо, як працює ця функція зі списками, з рядками та з
числовими даними.
Приклад 3.27
import my_module as mm
>>> a=[1, 2, 3, 4]
>>> b=[5, 6, 7]
>>> c = mm.f(a, b)
>>> c
[1, 2, 3, 4, 5, 6, 7]
>>> d = ‘1234’
>>> e = ‘5678’
>>> f1 = mm.f(d, e)
>>> f1
‘12345678’
>>> g = mm.f(2,3)
>>> g
5
Приклад 3.27 можна пояснити наступним чином. Параметрами функції
f(x, y), описаної у прикладі 3.26, можуть бути різні об’єкти, зокрема
числові, рядкові дані або списки. Але оскільки оператор сумування «+» є
перевантаженим і для різних типів даних він виконується по-різному,
результати роботи функції f(x, y) для різних типів даних також
відрізняються. Зокрема, для списків та для рядків результатом виконання
операції «+» є об’єднання двох структур, а для чисел – сума цих чисел. Якщо
типи даних не співпадають, операція сумування не може бути виконана без

232
використання функцій перетворення типів даних.
Як і для рядків, для списків існує можливість використання оператора
in та виконання операції зрізу. Оператор in зазвичай використовується в
операціях порівняння разом із умовним оператором if. Розглянемо
відповідні приклади.
Приклад 3.28
>>> s = [1, 3.5, 8, 2, 4]
>>> v = float(input(‘Введіть значення: ’))
Введіть значення: 3.5
>>> if v in s:
print (‘Значення ’, v, ‘ є в списку 1’)
else:
print (‘Значення ’, v, ‘ немає в списку 1’)
Значення 3.5 є в списку 1
>>> r = s[0:3]
>>> r
[1, 3.5, 8]
>>> if v in r:
print (‘Значення ’, v, ‘ є в списку 2’)
else:
print (‘Значення ’, v, ‘ немає в списку 2’)
Значення 3.5 є в списку 2
>>> v = int(input(‘Введіть значення: ’))
Введіть значення: 2
>>> if v in s:
print (‘Значення ’, v, ‘ є в списку 1’)
else:
print (‘Значення ’, v, ‘ немає в списку 1’)
Значення 2 є в списку 1
>>> if v in r:

233
print (‘Значення ’, v, ‘ є в списку 2’)
else:
print (‘Значення ’, v, ‘ немає в списку 2’)
Значення 2 немає в списку 2
>>>

У мові програмування Python існує оператор копіювання списків, який

аналогічний оператору присвоєння, але має свої певні особливості роботи.

Розглянемо їх більш досконало. Річ у тому, що інтерпретатор мови Python із

міркувань економії пам’яті не створює дві області пам’яті із однаковими

списками, а посилається на одну область пам’яті. Тому, якщо визначені дві

однакові структури, у разі зміни однієї з них автоматично буде змінена інша.

Про це просте правило завжди слід пам’ятати під час роботи зі структурами.

Перевірити, чи є дві структури еквівалентними, завжди можна з

використанням логічного виразу з оператором is. Наведемо відповідний

приклад.

Приклад 3.29
>>> a = [1, 2, 3, 4, 5, 6]
>>> b = a
>>> b is a
True
>>> b[0] = -1;
>>> a
[–1, 2, 3, 4, 5, 6]
>>> x = y = [1, 2]
>>> x is y
True

234
>>> z = [1, 2]

>>> t = [1, 2]

>>> z is t

False

>>>

Зрозуміло, що за допомогою операторів in та is формуються логічні

вирази у широкому значенні цього слова, визначення яких було наведено у

підрозділі 3.2.

Слід відзначити, що у мові програмування Python до списків можуть

бути застосовані два види копіювання, поверхневе та глибоке. Надамо

відповідні визначення [24 – 26].

Визначення 3.6 Поверхневим копіюванням у мові програмування

Python називається створення нового об’єкта, заповненого посиланнями на

елементи об’єкта-оригінала. У разі використання поверхневого копіювання

змінення елементів створеного об’єкта призводить до зміни елементів

об’єкта-оригінала.

Визначення 3.7 Глибоким копіюванням у мові програмування Python

називається створення нового об’єкта, до якого рекурсивно переписуються

значення всіх елементів об’єкта-оригінала. У разі використання глибокого

копіювання змінення елементів створеного об’єкта не призводить до зміни

елементів об’єкта-оригінала.

Виконання глибокого копіювання списків можливе лише з

використанням функції deepcopy, розташованої у модулі copy [24 – 26].

Розглянемо наступний приклад, у якому наочно пояснюється

відмінність операцій поверхневого та глибокого копіювання.

235
Приклад 3.30
>>> a = [1, 2, 3, 4, 5, 6]
>>> b = a[:] # Здійснюємо копіювання списків
>>> b is a # Списки не співпадають
False
>>> b[0] = -3 # Змінюємо перший елемент структури b
>>> a[0] # Автоматично змінився перший елемент структури a
–3
>>> import copy
>>> c = copy.deepcopy(a) # Здійснюємо копіювання списків
>>> c is a # Списки не співпадають
False
>>> c[0] = -6 # Змінюємо перший елемент структури c
>>> a[0] # Перший елемент структури a не змінився
–3
>>>

Слід відзначити, що у першому випадку здійснене поверхневе

копіювання структур з використанням оператора присвоєння b = a[:].

Тому, хоча початкова та створена структури не є еквівалентними

(b is a = False), зміна одного із елементів об’єкта b призводить до

зміни відповідного елемента об’єкта a. Навпаки, у другому випадку

копіювання виконане з використанням функції deepcopy модуля copy, і

саме тому зміна одного із елементів об’єкта b не призводить до зміни

відповідного елемента об’єкта a.

У таблиці 3.5 наведені важливі функції мови програмування Python,

призначені для роботи з рядками.

236
Таблиця 3.5 – Функції обробки списків мови програмування Python

Функція Призначення функції


Видалення із списку L одного елемента або групи
елементів. n1 – перший елемент, який видаляється,
del(L[n1:n2:n3])
n2 – перший елемент, який не видаляється, n3 – крок
зміни номерів елементів, що видаляються
Функція перетворює рядок або багатопозиційне число
list(S)
у список
Функція перетворює список L у рядок, рядок S
S.join(L)
використовується як роздільник
S.split() Інша функція, яка перетворює рядок у список
Функція додає елементи списку L2 до елементів
L1.extend(L2)
списку L1
L.append(E) Функція додає елемент E до елементів списку L
L.insert(n1,E) Функція вставляє елемент E на позицію n1 списку L
L.remove(E) Функція видаляє із списку L елемент E
L.count(E) Функція підраховує кількість елементів E у списку L
Функція повертає позицію першого елемента E у
L.index(E)
списку L
Функція видаляє останній елемент із списку L та
V = L.pop()
повертає його значення, яке можна присвоїти змінній V
Функція розташовує елементи списку L у зворотному
L.reverse()
порядку
L.clear() Функція видаляє із списку L всі елементи

Розглянемо приклади використання методів роботи зі списками, які


наведені у таблиці 3.5. Почнемо з функцій del(), list(), join() та

237
split(), які у практиці програмування використовуються найбільш часто,
оскільки ці функції дають можливість перетворювати списки на рядки.
Приклад 3.30
>>> a = [1, 2, 3, 4, 5, 6]
>>> del(a[2:4])
>>> a
[1, 2, 5, 6]
>>> del(a[:])
>>> a
[]
>>> S = ‘Студент Потапенко’
>>> L = list(S)
>>> L
[‘С’, ‘т’, ‘у’, ‘д’, ‘е’, ‘н’, ‘т’, ‘ ’, ‘П’,
‘о’, ‘т’, ‘а’, ‘п’, ‘е’, ‘н’, ‘к’, ‘о’]
>>> L[8] = ‘Х’
>>> L[10] = ‘м’
>>> L
[‘С’, ‘т’, ‘у’, ‘д’, ‘е’, ‘н’, ‘т’, ‘ ’, ‘Х’,
‘о’, ‘м’, ‘а’, ‘п’, ‘е’, ‘н’, ‘к’, ‘о’]
>>> del(L[11:13])
>>> L
[‘С’, ‘т’, ‘у’, ‘д’, ‘е’, ‘н’, ‘т’, ‘ ’, ‘Х’,
‘о’, ‘м’, ‘е’, ‘н’, ‘к’, ‘о’]
>>> S = ' '.join(L)
>>> S
Студент Хоменко
>>> L2 = S.split()
# Для функції split() за замовченням як
# роздільник елементів у списку, який формується,
# використовується пробіл
>>> L2

238
[‘Студент’, ‘Хоменко’]
>>> N = 4353424214
>>> L3 = list(str(N))
>>> L3
[‘4’, ‘3’, ‘5’, ‘3’, ‘4’, ‘2’, ‘4’, ‘2’, ‘1’, ‘4’]
>>> L = [‘Студенти’, ‘Потапенко’, ‘та’, ‘Хоменко’]
>>> L1 = ‘’.join(L)
>>> L1
‘СтудентиПотапенкотаХоменко’
>>> L2 = ‘ ’.join(L)
>>> L2
‘Студенти Потапенко та Хоменко’
>>> L3 = ‘***’.join(L)
>>> L3
‘Студенти***Потапенко***та***Хоменко’
>>>
Як видно з наведеного прикладу, функції join() та split() дають
можливість через використання функції del() та зміну елементів списку
проводити ефективну обробку рядків, незважаючи на те, що, як було
відмічено у підрозділі 2.6.8, безпосередня зміна елементів рядка через їх
індексацію та оператор присвоєння є неможливою.
Розглянемо приклади використання інших функцій для роботи зі
списками.
Приклад 3.31
>>> L = [‘Хоменко’, ‘Потапенко’, ‘Сидоренко’]
>>> L1 = L.extend(‘Науменко’, ‘Шинкаренко’)
>>> L1
[‘Хоменко’, ‘Потапенко’, ‘Сидоренко’,
‘Науменко’, ‘Шинкаренко’]
>>> L1.append(‘Ігнатенко’)
>>> L1
[‘Хоменко’, ‘Потапенко’, ‘Сидоренко’,

239
‘Науменко’, ‘Шинкаренко’, ‘Ігнатенко’]
>>> L1.insert(2, ‘Литвиненко’)
>>> L1
[‘Хоменко’, ‘Потапенко’, ‘Литвиненко’, ‘Сидоренко’,
‘Науменко’, ‘Шинкаренко’, ‘Ігнатенко’]
>>> L1.remove(‘Сидоренко’)
>>> L1
[‘Хоменко’, ‘Потапенко’, ‘Литвиненко’,
‘Науменко’, ‘Шинкаренко’, ‘Ігнатенко’]
>>> L1.index(‘Литвиненко’)
2
>>> L1.reverse()
>>> L1
[‘Ігнатенко’, ‘Шинкаренко’, ‘Науменко’,
‘Литвиненко’, ‘Потапенко’, ‘Хоменко’]
>>> L1.sort()
[‘Ігнатенко’, ‘Литвиненко’, ‘Науменко’,
‘Потапенко’, ‘Хоменко’, ‘Шинкаренко’]
>>> L1.clear()
>>> L1
[]
>>>
Розглянуті у цьому підрозділі методи обробки рядків з використанням
списків можуть бути ефективно використані під час написання прикладних
комп’ютерних програм. Для закріплення матеріалу, наведеного у цьому
підрозділі, необхідно виконати практичне заняття 3, яке наведене у розділі 7.

3.6.2 Створення матриць з використанням списків


У підрозділі 3.6.1 було відмічено, що у мові програмування Python
елементами списків можуть бути інші, більш короткі списки. Розглянемо
приклади таких списків.
[[‘Хоменко’, ‘Потапенко’], [‘Сидоренко’, ‘Шевченко’]]

240
[[1, 2], [‘А’, ‘Б’]]
[[1, 2], [3, 4]]
Такі списки, елементами яких є інші списки, у мові програмування Python
називаються вкладеними. Наведемо відповідне визначення та розглянемо правила
роботи з вкладеними списками.
Визначення 3.8 Вкладеними списками у мові програмування Python
називаються такі списки, елементами яких є інші списки.
Правило 3.16 Індексація списків як елементів вкладеного списку
здійснюється через посилання на їх порядковий номер у вкладеному списку.
Правило 3.17 Індексація окремих елементів вкладеного списку
здійснюється через окремі посилання на номер списку, у якому знаходиться
цей елемент, та на номер елемента у списку. Обидва номери вказуються в
окремих квадратних дужках.
Розглянемо приклади індексації списків як елементів вкладеного
списку та їхніх окремих елементів.
Приклад 3.31
>>> L = [[1, 2], [‘А’, ‘Б’]]
>>> L[0]
[1, 2]
>>> L[1]
[‘А’, ‘Б’]
>>> L[0][0]
1
>>> L[0][1]
2
>>> L[1][0]
‘А’
>>> L[1][1]
‘Б’
>>>
Цікавим є те, що, як видно з наведених прикладів, елементами
вкладених списків можуть бути об’єкти різної природи, наприклад, числові

241
та рядкові змінні. Крім цього, кількість елементів у списках, вкладених до
загального списку, може бути різною. Такий спосіб формування вкладених
списків відповідає визначенню впорядкованої множини у дискретній
математиці [42].
Як окремі випадки вкладених списків у мові програмування Python
розглядаються матриці. Відомо, що матриця в математиці – це впорядковані числа із
подвійними індексами, які визначають номер рядка та номер стовпчика [42]. Надамо
визначення матриці в мові програмування Python, яке базується на понятті про
вкладені списки.
Визначення 3.9 Матрицями в мові програмування Python називаються
вкладені списки, в яких всі елементи є числовими, а кількість елементів у всіх
елементарних списках, які належать до загального списку, є однаковою.
На основі визначення 3.9 можна сформулювати поняття квадратної
матриці [42]. Надамо відповідне визначення.
Визначення 3.10 Квадратною матрицею в мові програмування Python
називається матриця, в якій кількість елементів у всіх елементарних списках
відповідає кількість елементарних списків у загальному.
Розглянемо приклад формування матриці та індексації їхніх елементів.
Зрозуміло, що індексація елементів матриці здійснюється з використанням
правил 3.16 та 3.17.
Приклад 3.32
>>> M = [[1, 2, 3], [4, 5, 6]] #Прямокутна матриця
>>> M[0][1] # Посилання на елемент прямокутної матриці
2
>>> M[0][1] = 5 # Зміна елемента прямокутної матриці
>>> M
[[1, 5, 3], [4, 5, 6]]
>>> M2 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # Квадратна матриця
>>> M2[1][2] # Посилання на елемент квадратної матриці
6
>>> M2[1][2] = 12 # Зміна елемента квадратної матриці
>>> M2

242
[[1, 2, 3], [4, 5, 12], [7, 8, 9]]
>>>
Загалом індексація елементів прямокутних та квадратних матриць,
сформованих у мові програмування Python як списки, базується на правилах 3.16
та 3.17, та є зрозумілою з прикладу 3.32. Проте якщо із однієї матриці створюється
інша, слід пам’ятати про правила поверхневого та глибокого копіювання у мові
Python, які задаються визначеннями 3.6 та 3.7. Зрозуміло, що якщо здійснене
поверхневе копіювання, у разі зміни елементів створеної матриці змінюються також
елементи початкової матриці. Якщо програміст бажає змінити лише елементи
створеної матриці, а початкову залишити незмінною, таку операцію можна зробити
лише з використанням функції глибокого копіювання.
Наведемо відповідні приклади.
Приклад 3.33
>>> M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> A = M
>>> A
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> A is M # Списки співпадають
True
>>> A[1][2] = 12
>>> A
[[1, 2, 3], [4, 5, 12], [7, 8, 9]]
>>> M
[[1, 2, 3], [4, 5, 12], [7, 8, 9]]
>>> M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> import copy
>>> B = copy.deepcopy(M);
>>> B[1][2] = 12
>>> B
[[1, 2, 3], [4, 5, 12], [7, 8, 9]]

243
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Для закріплення матеріалу, наведеного у цьому підрозділі, необхідно виконати
практичні заняття 5 та 8, які наведені у розділі 7.

3.7 Оператори циклу із заданою кількістю повторень та заданою


умовою
3.7.1 Оператор циклу із заданою кількістю повторень та його
використання для формування списків
Створення списків та матриць мало що дає само по собі, без
ефективних засобів їхньої обробки. Із засобів програмування мови Python
найбільш ефективним та корисним для розв’язування практичних завдань
обробки списків та формування відповідних інформаційних повідомлень є
оператор циклу із заданою кількістю повторень [24 – 29]. У загальному
вигляді лінгвістична конструкція такого оператору записується наступним
чином [24, 25]:
for <змінна> in <список>:
<тіло циклу>.
Почнемо з конкретного прикладу. Визначити, чи є у заданому списку
число 0,8 можна наступним чином.
Приклад 3.34
>>> L = [1.2, 2.4, 3.6, 4.5, 5.7, 6.8, 7.2, 0.8, 9.5]
>>> x=0
>>> for i in L:
if L[i] == 0.8
print(‘Елемент №’, i, ‘дорівнює 0,8.’)
x=1
>>> if x==0:
print(‘Елемента із значенням 0,8 в списку немає.’)
>>>

244
Результат роботи цього фрагмента програми буде наступним.
Елемент № 7 дорівнює 0,8.
Розглянемо інший приклад, у якому необхідно знайти великі літери у
заданому реченні.
Приклад 3.35
>>> S = ‘Студенти Потапенко та Хоменко’
>>> x=0
>> for ch in S:
if ch.isupper()
print(‘Літера № ’, ord(ch)+1, ‘ є великою. /n’)
x=1
>>> if x==0:
print(‘У цьому реченні великих літер немає.’)
>>>
У прикладі 3.35 використана функція роботи з рядками isupper(),
яка була розглянута у підрозділі 2.6.6.
Результат роботи командних рядків, наведених у прикладі 3.35, буде
наступним.
Літера № 1 є великою.
Літера № 10 є великою.
Літера № 23 є великою.
Командні рядки інтерпретатора мови Python, наведені у прикладах 3.34
та 3.35, є досить простими. Частіше у практиці програмування приходиться
розв’язувати більш складні завдання, пов’язані з формуванням
послідовностей цілих чисел. Теоретичним підґрунтям для формулювання та
розв’язування завдань такого типу є теорія чисел та методи дискретної
математики [42].
Для розв’язування таких прикладних завдань програмування у мові
програмування Python використовується оператор range(), який, разом із
оператором циклу for, формує послідовності цілих чисел. Ця функція

245
формує списки із цілих чисел і значення елементів такого списку лежать у
заданому діапазоні із заданим кроком квантування. У дискретній математиці
такі послідовності називаються арифметичними прогресіями [42].
Функція range() мови програмування Python записується у вигляді
наступної лінгвістичної конструкції [24 – 29].
range(n1, n2, n3),
де n1 – значення початкового, нульового елемента списку, n2 – значення
першого елемента, який не входить до списку, n3 – крок зміни значень
елементів. Слід відзначити, що число n3, так само, як і числа n1 та n2, може
бути від’ємним. Від’ємне значення кроку зміни елементів списку означає, що
вони не збільшуються, а зменшуються. Слід відзначити, що таким же чином
у мові Python здійснюється індексація символів рядка, відповідні теоретичні
відомості були наведені у підрозділі 2.6.8.
За замовченням n1 дорівнює 0, а n3 – 1. Якщо крок зміни елементів
списку має від’ємне значення, його необхідно вказувати явно.
Конструкція оператора циклу for, в яку входить функція range(),
має наступний вигляд [24 – 29].
for <змінна> in range(n1, n2, n3):
<тіло циклу>.
Наведемо приклади формування циклічних структур з використанням
функції range().
Приклад 3.36
>>> for i in range (0,10):
print(i)
0 1 2 3 4 5 6 7 8 9
>>> for i in range (2,20,2):
print(i)
>>> 2 4 6 8 10 12 14 16 18
>>> for i in range (20,2,–2):
print(i)
246
>>> 20 18 16 14 12 10 8 6 4
>>> S = 0
>>> for i in range (101):
S = S+i
>>> print(S)
5050
>>>
У прикладі 3.36 наочно показано, як з використанням оператора циклу
та функції range () можна розв’язувати завдання обчислювальної
математики, наприклад, знаходити суму елементів послідовностей. У
наведеному вище прикладі обчислена сума натуральних чисел від 1 до 100.
Розглянемо у наступному підрозділі різні способи формування списків
з використанням оператора циклу.

3.7.2 Способи обробки списків з використанням оператора циклу


Загалом у мові програмування Python існує сім різних способів
створення списків з використанням оператора циклу із заданою кількістю
повторень [24 – 29]. Спочатку перелічимо їх, а потім послідовно розглянемо.
1. Використання функції створення списку list(), наведеної у
таблиці 3.5 та описаної у підрозділі 3.6.1.
2. Створення елементів списку із елементів іншого списку через їх
індексацію та математичні операції.
3. Спочатку створюється порожній список, а потім він заповнюється з
використанням спискової функції append() або оператора «+», тобто,
здійснюється зчеплення нових, обчислених елементів із заповненою
структурою. Способи роботи функції append() та операції зчеплення,
призначених для обробки списків, були розглянуті у підрозділі 3.6.1.
4. Використання генератора списків, який базується на способах їх
обробки. Цей спосіб в літературі називають також списковим включенням.
5. Формування одного списку на основі іншого з використанням

247
методів обробки списків. Цей спосіб базується на генераторі списків та може
бути віднесеним до нього, але відмінність його полягає у тому, що в ньому не
використовується функція створення діапазону range (). У зв’язку з цим
цей спосіб є більш універсальним, оскільки структури, які створюються, не
прив’язані до арифметичних прогресій та інших послідовностей дискретної
математики. Наприклад, елементами таких числових структур можуть бути
експериментальні дані. Слід відзначити, що ця властивість притаманна також
другому способу створення списків.
6. Використання функцій користувача, параметрами яких можуть бути
інші функції.
7. Введення даних з клавіатури з використанням циклічних структур.
Найпростішим є перший спосіб, оснований на створенні списку з
використанням функцій list() та range(). Відповідна лінгвістична
конструкція у загальному випадку має наступний вигляд.
list(range(n1, n2, n3)).
Згідно із наведеним вище описанням особливостей роботи функції
range() зрозуміло, що параметри n1 та n3 можуть бути пропущені.
Наведемо деякі приклади формування списків з використанням
функцій list() та range().
Приклад 3.37
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(2, 10, 2))
[2, 4, 6, 8]
>>> list(range(20, 1, -2))
[20, 18, 16, 14, 12, 10, 8, 6, 4, 2]
Розглянемо тепер у наступному прикладі спосіб створення списку із
елементів іншого списку з використанням оператора циклу for та функції

248
створення діапазону range().
Приклад 3.38
>>> L = [4, 2, 5, 6, -3, 8, 5, -2]
>>> for i in range(len(L)):
L2[i]=L[i]**2
>>> print(L2)
[16, 4, 25, 12, 9, 64, 25, 4]
>>> for i in range(len(L)):
L3[i]=3*L[i]**3
>>> print(L3)
[192, 24, 375, 648, -81, 1536, 375, -24]
>>>
Особливостями цього способу створення структур є наступні.
1. Кількість елементів у початковому списку визначається його
довжиною.
2. Перебираються всі елементи списку, які мають індекси від 0 до
len(L)–1. Для створення діапазону значень індексу використовується
функція range(len(L)).
3. Через індексацію елементів початкового списку L та математичні
функції створюються елементи нового списку.
Розглянемо тепер спосіб автоматичного створення списку із заданою
послідовністю чисел із пустого списку з використанням оператора сумування
[24, 25].
>>> L = []
>>> for i in range(1,15):
L = L + [i]
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>>
Слід відзначити, що нажаль такий спосіб створення списків працює не

249
для всіх версій інтерпретатора Python. Найбільш цікавим з точки зору теорії
програмування є створення списків з використанням генератора, або метод
спискового включення. Команда спискового включення є досить простою та
базується на основі наступної лінгвістичної конструкції.
L = [<Вираз із змінною n> for n in range(n1, n2, n3)],
де n – змінна, відносно якої проводяться обчислення, n1, n2 та n3 –
параметри функції range(). Генератор списків працює досить просто.
Змінна n змінюється в діапазоні, визначеному функцією range(), а
обчислення елементів списку L проводяться згідно із математичним,
логічним, або арифметико-логічним виразом, який стоїть на початку
конструкції. Наведемо приклади формування списку з використанням
генератора.
Приклад 3.39
>>> L = [i**2 for i in range(1,10)]
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> L2 = [3*i+4 for i in range(1,15)]
>>> L2
[7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49]
Можливою є інша, трішки ускладнена лінгвістична конструкція
генератора структури, яка має наступний вигляд.
L = [<Вираз із змінною n> for n in range(n1, n2, n3)\
if n <Оператор відношення> <Логічний вираз>],
Відмінність її від наведеної вище конструкції полягає у тому, що
список формується лише у разі виконання умови, записаної в умовному
операторі. Якщо ця умова є хибною, відповідний елемент до списку не
додається. Розглянемо відповідний приклад.
Приклад 3.40
>>> L = [i**2 for i in range(1,10) if !(4 <= i <= 8)]
>>> L

250
[1, 4, 9, 81, 100]
>>> L2 = [3*i+4 for i in range(1,15) if !(7 <= n <= 12)]
>>> L2
[7, 10, 13, 16, 19, 22, 43, 46, 49]
>>>
З використанням генераторів списків можна формувати структуру на
основі елементів іншої, наперед заданої структури. У цьому разі посилання у
виразі на індекс n відповідає не номеру елемента, а посиланню на елемент
початкового списку із відповідним індексом [24, 25]. Таким чином, новий
список формується із елементів початкового списку, проте для посилання на
елемент початкового списку замість L[n] пишеться просто номер елемента
n. Розглянемо приклади роботи такого генератора списків.
Приклад 3.41
>>> L = [2, 3, 4, 5, 6, -2, -3, -4]
>>> L1 = [n**2 for n in L]
>>> L1
[4, 9, 16, 25, 36, 4, 9, 16]
>>> L3 = [3*n+4 for n in L]
>>> L3
[10, 13, 16, 19, 22, -2, -5, -8]
>>>
Аналогічно генератори списків працюють із рядками. Різниця полягає в
тому, що для рядкових даних визначені лише перевантажені операції
додавання та множення, описання цих операцій було наведене у підрозділі
2.6.1. Розглянемо відповідний приклад.
Приклад 3.42
>>> S = ‘Студент Потапенко’
>>> L = [3*n for n in S]
>>> L
[‘ССС’, ‘ттт’,‘ууу’,‘ддд’,‘еее’, ‘ннн’, ‘ттт’, ‘ ’,
‘ППП’, ‘ооо’, ‘ттт’, ‘ааа’, ‘ппп’, ‘еее’, ‘ннн’, ‘ккк’, ‘ооо’]

251
>>> L1 = [5*n for n in S ]
>>> L1 = [5*n for n in S if n<7]
[‘ССССС’, ‘ттттт’,‘ууууу’,‘ддддд’,‘еееее’, ‘ннннн’, ‘ттттт’]
>>>
Іншим ефективним засобом створення списків мови програмування
Python є використання власних функцій користувача, у цьому разі виклик
функції здійснюється через системну функцію map(). Параметрами функції
map() є ім’я функції та список, який необхідно обробити. Для створення
списків таким способом разом із функцією map() використовується також
розглянута вище функція створення списків list(). Розглянемо
відповідний приклад.
Приклад 3.43
>>> def f(x)
return x + 3
>>> list(map(f,[3,4,5]))
[6,7,8]
>>> list(map(f,‘abc’))
[‘aaa’,‘bbb’,‘ccc’]
>>> list(map(f,[3, 6, 8]))
[6,9,11]
>>> list(map(f,368))
371
>>> list(map(f,‘368’))
[‘333’, ‘666’, ‘888’]
>>>
Показовим у прикладі 3.43 є те, що функції з перевантаженими
операторами «+» та «*» треба використовувати дуже обережно, оскільки для
рядкових і числових даних ці оператори мають різне значення. Помилки, які
можуть виникати у разі неправильного використання таких операторів, були
розглянуті у підрозділі 2.6.2 у прикладі 2.54. Із наведеного прикладу також

252
видно, що функція map()мови програмування Python працює з рядками як із
списками, де символи рядка є елементами списку.
Розглянемо тепер, як можна створити список через введення даних з
клавіатури з використанням системної функції input() та функції роботи з
рядками append(), розглянутої у підрозділі 3.6.1.
Приклад 3.44
def inpl:
a=[0]
n = int(input(‘Введіть кількість елементів\
у списку: ’))
# Вводиться значення кількості елементів у списку
for i in range(n):
print (‘Введіть елемент №’, i, ‘: ’)
a.append(int(input()))
del(a[0])
print (a)
Результати роботи програми, наведеної у прикладі 3.44, мають
наступний вигляд.
>>> import input_list
>>> input_list.inpl
Введіть кількість елементів у списку: 5
Введіть елемент № 1: -4
Введіть елемент № 2: 2
Введіть елемент № 3: 5
Введіть елемент № 4: -1
Введіть елемент № 5: 1
[-4, 2, 5, -1, 1]
З використанням генераторів списку програму, наведену у прикладі

253
3.44, можна переписати одним рядком [24].
Приклад 3.45
a = [int(input()) for i in range(int(input()))]
У цьому підрозділі були розглянуті різні можливості формування
списків з використанням циклів. Вибір будь-якого з них насамперед
пов’язаний із власними вподобаннями програміста та із стилем написання
програми. У будь-якому разі, намагайтесь дотримуватись дванадцятого
принципу філософії мови програмування Python: «Має існувати один – і
бажано лише один – очевидний спосіб щось зробити, хоча спочатку він
для Вас може бути не очевидним, якщо Ви не голландець».

3.7.3 Вкладені цикли та їх використання для формування матриць


Однією з цікавих можливостей використання циклів в мові
програмування Python є формування вкладених циклів. Зокрема, у різних
мовах програмування вкладені цикли дуже широко використовуються для
формування матриць [5 – 10, 23].
Спосіб створення вкладених циклів в мові програмування Python
майже зовсім не відрізняється від способу створення звичайного
однорангового циклу. Для створення вкладених циклів зазвичай
використовуються два списки з індексами, хоча, якщо діапазони зміни
індексів співпадають, може вистачити і одного списку.
Розглянемо простий приклад створення вкладених циклів.
Приклад 3.46
def embloop:
outer = [1, 2, 3, 4]
inner = [5, 6, 7, 8]
for i in outer:
for j in inner:
print (‘i=’, i, ‘j=’, j)
Результати роботи програми, наведеної у прикладі 3.46, мають

254
наступний вигляд.
Приклад 3.47
>>> import embedded_loop
>>> embedded_loop.embloop
i=1 j=5
i=1 j=6
i=1 j=7
i=1 j=8
i=2 j=5
i=2 j=6
i=2 j=7
i=2 j=8
i=3 j=5
i=3 j=6
i=3 j=7
i=3 j=8
i=4 j=5
i=4 j=6
i=4 j=7
i=4 j=8
Розглянемо способи автоматичного та ручного формування матриць з
використанням вкладених циклічних структур.
Слід відзначити, що складність написання програм з вкладеними циклами
у оболонці IDLE полягає в тому, що цикли другого рівня необхідно писати з
сьомої позиції, де за замовченням стоїть знак табуляції. Щоб уникнути цієї
проблеми, можна писати цикли в оболонці інтерпретатора, де пробіли та
табуляції проставляються автоматично, а потім копіювати написаний та
відлагоджений текст програми в оболонку IDLE.
Для введення значень елементів матриці четвертого порядку з клавіатури
може бути використаний наступний програмний код.

255
Приклад 3.48
def mat44():
M = [0, 1, 2, 3]
a=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
for i in M:
for j in M:
S=‘ Введіть значення елементу a[i][j]:’
print (‘i= ’, i, ‘ j=’, j, S)
a[i][j]=int(input())
print (‘i=’, i, ‘j=’, j, ‘a[i][j]=’, a[i][j])
print (a)
return a
Результат роботи цієї програми у командному рядку інтерпретатора Python
буде мати наступний вигляд.
Приклад 3.49
>>> import create_mat_manualy()
>>> create_mat_manualy.mat44
i=0 j=0 Введіть значення елементу a[i][j]: 35
i=0 j=0 a[i][j]=35
i=0 j=1 Введіть значення елементу a[i][j]: 21
i=0 j=1 a[i][j]=21
i=0 j=2 Введіть значення елементу a[i][j]: 64
i=0 j=2 a[i][j]=64
i=0 j=3 Введіть значення елементу a[i][j]: 85
i=0 j=3 a[i][j]=85
i=1 j=0 Введіть значення елементу a[i][j]: 43
i=1 j=0 a[i][j]=43
i=1 j=1 Введіть значення елементу a[i][j]: 24
i=1 j=1 a[i][j]=24
i=1 j=2 Введіть значення елементу a[i][j]: 37
i=1 j=2 a[i][j]=37

256
i=1 j=3 Введіть значення елементу a[i][j]: 28
i=1 j=3 a[i][j]=28
i=2 j=0 Введіть значення елементу a[i][j]: 32
i=2 j=0 a[i][j]=32
i=2 j=1 Введіть значення елементу a[i][j]: 16
i=2 j=1 a[i][j]=16
i=2 j=2 Введіть значення елементу a[i][j]: 84
i=2 j=2 a[i][j]=84
i=2 j=3 Введіть значення елементу a[i][j]: 91
i=2 j=3 a[i][j]=91
i=3 j=0 Введіть значення елементу a[i][j]: 96
i=3 j=0 a[i][j]=96
i=3 j=1 Введіть значення елементу a[i][j]: 78
i=3 j=1 a[i][j]=78
i=3 j=2 Введіть значення елементу a[i][j]: 82
i=3 j=2 a[i][j]=82
i=3 j=3 Введіть значення елементу a[i][j]: 33
i=3 j=3 a[i][j]=33
[[35, 21, 64, 85], [43, 24, 37, 28],
[32, 16, 84, 91], [96, 78, 82, 33]]
В наступному прикладі розглянемо, як можна змінити стовпчик
матриці.
Приклад 3.50
>>> import create_mat_manualy
>>> from copy import deepcopy
>>> M1 = create_mat_manualy.mat44()
... ... ... ... ... ... ... ...
>>> V1 = [47, 53, 31, 26]
>>> M2 = deepcopy(M1)
>>> for j in range(0,4):

257
M2[j][1] = V1[j]
>>> M2
[[35, 47, 64, 85], [43, 53, 37, 28],
[32, 31, 84, 91], [96, 26, 82, 33]]
>>> M1
[[35, 21, 64, 85], [43, 24, 37, 28],
[32, 16, 84, 91], [96, 78, 82, 33]]
Розглянемо інший спосіб створення квадратної матриці четвертого
порядку, оснований на використанні генератора випадкових цілих чисел.
Функція randint(n1, n2) модуля random створює випадкові числа у
заданому діапазоні, від числа n1 до числа n2. Створимо з використанням цієї
функції квадратну матрицю четвертого порядку, заповнену випадковими
числами від 1 до 10.
Приклад 3.51
def rmat44():
from random import randint
a=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
for i in range(0,4):
for j in range(0,4):
a[i][j]=randint(1,11)
print(a)
return(a)
Результат роботи цієї програми буде мати наступний вигляд.
>>> from random_mat import rmat44
>>> rmat44()
[[11, 2, 8, 2], [1, 3, 7, 10],
[9, 9, 2, 2], [2, 11, 2, 8]]
>>>
Цілком зрозуміло, що числа у такому списку можуть бути різними.
Недоліком розглянутих способів ручного та автоматичного

258
формування матриць через операції зі списками є те, що вони орієнтовані на
розмірність заздалегідь заданої матриці, яка на початку програм, наведених у
прикладах 3.48 та 3.51, заповнюється нульовими елементами, а потім
значення цих елементів змінюються. Більш ефективним є інший метод, коли
розмірність матриці задається з клавіатури, а введені елементи додаються до
списків з використанням функції append(). Таким чином спочатку
створюються вкладені структури, із яких формуються рядки матриці M, а
після цього ці структури об’єднуються до прямокутної матриці з
використанням оператора M.append(V), де V – створений рядок. Спосіб
створення векторів як числових структур з використанням функції
append() був розглянутий у прикладі 3.44. Розглянемо тепер відповідні
функції, призначені для ручного та автоматичного створення прямокутних
матриць довільного порядку, написані на мові програмування Python.
Приклад 3.52
def rom():
n = int(input(‘Введіть кількість стовпчиків: ’))
# Вводиться значення кількості стовпчиків
m = int(input(‘Введіть кількість рядків: ’))
# Вводиться значення кількості рядків
M=[0]
for i in range(0, m):
V=[0]
for j in range(0, n):
S = ‘Введіть значення елементу M[i][j]:’
print (‘i= ’, i, ‘ j=’, j, S)
V.append(int(input()))
print (‘i=’, i, ‘j=’, j, ‘M[i][j]=’, V[j+1])
del(V[0])
M.append(V)
del(M[0])

259
print (M)
return M
В наступному прикладі здійснюється автоматичне формування матриці
довільного порядку та заповнення її елементів випадковими числами, які
лежать в діапазоні від 1 до 10.
Приклад 3.53
def r_rom():
from random import randint
n = int(input(‘Введіть кількість стовпчиків: ’))
# Вводиться значення кількості стовпчиків
m = int(input(‘Введіть кількість рядків: ’))
# Вводиться значення кількості рядків
M=[0]
for i in range(0, m):
V=[0]
for j in range(0, n):
V.append(randint(1,11))
del(V[0])
M.append(V)
del(M[0])
print (M)
return M
На основі програми, створеної у прикладі 3.53, розв’яжемо іншу цікаву
прикладну задачу дискретної математики [42]. Створимо матрицю, елементи
якої обчислюються через елементи двох векторів. Перший рядок є
результатом множення всіх елементів першого вектора на перший елемент
другого вектора, другий рядок – результатом множення всіх елементів
першого вектора на другий елемент другого вектора, і так далі. Зрозуміло, що
розмірності першого та другого вектора можуть не співпадати.
Приклад 3.54
def m_form_v():

260
m = int(input(‘Введіть кількість елемен\
тів першого вектора: ’))
# Вводиться значення кількості
# елементів першого вектора
n = int(input(‘Введіть кількість елемен\
тів другого вектора: ’))
# Вводиться значення кількості
# елементів другого вектора
M=[0]
V1 = [0]
V2 = [0]
for i in range(0, m):
V1.append(int(input()))
del(V1[0])
print (‘V1 =’, V1)
for j in range(0, n):
V2.append(int(input()))
del(V2[0])
print (‘V2 =’, V2)
for i in V2:
V3 = [0]
for j in V1:
V3.append(i*j)
del(V3[0])
M.append(V3)
del(M[0])
print (M)
return M
Програма працює наступним чином. У перших двох циклах, які є
послідовними, а не вкладеними, вводяться значення елементів векторів, а
потім ці вектори, як структури, виводяться на екран. Після цього ідуть

261
вкладені цикли, в які беруться значення елементів введених векторів та
перемножуються між собою за заданим алгоритмом. Спочатку, у першому
циклі, результати множення об’єднуються до векторів, із яких потім
формуються рядки матриці, а після цього, в кінці другого вкладеного циклу,
ці рядки послідовно об’єднуються в єдину структуру – прямокутну матрицю.
Результати роботи програми, наведеної у прикладі 3.54, представлені у
прикладі 3.55.
Приклад 3.55
>>> import matrix_from_vector
>>> M1 = matrix_from_vector.m_form_v()
Введіть кількість елементів першого вектора: 5
Введіть кількість елементів другого вектора: 4
1
2
3
4
5
V1 = [1, 2, 3, 4, 5]
6
7
8
9
V2 = [6, 7, 8, 9]
M2 = [[6, 12, 18, 24, 30], [7, 14, 21, 28, 35],
[8, 16, 24, 32, 40], [9, 18, 27, 36, 45]]
Під час написання програм із формуванням матриць слід пам’ятати про
п’ятий, шостий та дев’ятий філософські принципи мови програмування
Python: «Однорівневе є кращим, ніж вкладене», «Розряджене є кращим,
ніж щільне», «Практичність є важливішою за бездоганність». Дійсно,
писати вкладені цикли та використовувати їх для формування списків не
настільки просто, проте інших способів формування матриць в мові

262
програмування Python не існує, а математичний апарат матричного аналізу є
вкрай важливим для розв’язування багатьох практичних завдань дискретної
та обчислювальної математики [42, 64].
Для закріплення матеріалу цього підрозділу необхідно виконати
практичне заняття 8, наведене у розділі 7.

3.7.4 Розрахунок значень функцій, матриць та числових


послідовностей з використанням циклічних структур
Розглянемо тепер можливості використання циклів із заданою
кількістю повторень для розв’язування деяких завдань дискретної
математики. Слід зазначити, що багато з таких завдань вже розв’язані та
реалізовані як функції мови програмування Python, тому таких завдань ми
торкатися не будемо. Наприклад, функцію взяття факторіала можна
реалізувати через цикл із заданою кількістю повторень наступним чином.
Приклад 3.56
def fact(n):
f=1
if (n==0):
f=1
elif(n>0):
for i in range (1,n+1)
f *= i;
else
print(‘Невірне значення n.’)
return f
Існують також інші способи обчислення факторіала, наприклад, через
рекурсивний виклик процедури [5 – 7]. Проте, як було відмічено у підрозділі
2.4.2, функція factorial(n) є вбудованою функцією інтерпретатора мови
програмування Python, тому немає необхідності створювати аналогічну
власну функцію. Будемо розглядати лише такі завдання, рішення для яких в

263
бібліотеках інтерпретатора мови програмування Python не існує.
Приклад 3.57 Знайти суму квадратів чисел від 1 до заданого числа n.
def sum_sqr(n):
S=0
if (n==0):
S=0
elif(n>0):
for i in range (1,n+1):
S+=(i**2)
else:
print(‘Невірне значення n.’)
return S
>>> from sum_sqr import sum_sqr
>>> sum_sqr(10)
385
>>>
Приклад 3.58 Знайти значення функції f(x) у заданому діапазоні
[x1; x2]. Значення x1, x2, кількість відлікових значень n та саму функцію f(x)
задати як параметри функції.
Для розв’язування цього завдання насамперед необхідно знайти крок
зміни величини x за співвідношенням:
x −x
hx = 2 1 , (3.4)
n −1
звідки випливає рекурентне співвідношення для розрахунку відлікових точок
аргументу функції:
x0 = x1; xi = xi – 1 + h; i = 1…n. (3.5)
З урахуванням співвідношень (3.4) та (3.5) поставлене завдання можна
розв’язати наступним чином.
def tab_fun(f,x2,x1,n):
h = (x2–x1)/(n-1)

264
x = [x1]
y = [f(x1)]
for i in range (1,n+1):
c = x[i-1] + h
x.append(c)
y.append(f(c))
print(x,\t y \n)
return (x,y)
>>> from tab_fun import tab_fun
>>> from math import (sin, pi)
>>> x1 = 0
>>> x2 = 2*pi
>>> tab_fun(sin, x1, x2, 10)
[0.0, 0.6427876096865393, 0.984807753012208,
0.8660254037844387, 0.3420201433256689,
-0.34202014332566866, -0.8660254037844384,
-0.9848077530122081, -0.6427876096865396,
-2.4492935982947064e-16, 0.6427876096865391]
Приклад 3.59 Обчислити перші n елементів рекурентної
послідовності Фібоначі, яка задається наступним чином [6, 7]:
c1 = 1, c2 = 1, ci = ci-2 + ci-1. (3.6)
Враховуючи рекурентні співвідношення (3.6), відповідний програмний
код можна записати наступним чином.
def fib(n):
c = [1, 1]
for i in range (2,n):
c.append(c[i-2]+c[i-1])
return c
>>> from fibonaci import fib
>>> fib(10)

265
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Приклад 3.60 З використанням програмних засобів мови Python для
роботи зі списками та шаблонів програм, наведених у прикладах 3.52 – 3.56,
написати програму для розрахунку транспонованої матриці.
Почнемо роботу над створенням такої програми з формування
відповідного алгоритму. З урахування того, що матриці у мові
програмування Python формуються як вкладені списки, алгоритм
транспортування матриці буде мати наступний вигляд.
1. Введення початкової матриці, або формування цієї матриці з
використанням генератора випадкових чисел чи інших відповідних числових
алгоритмів.
2. Визначення кількості рядків n у матриці як кількості вкладених
списків, які входять до загального списку, з використанням функції len().
3. Визначення кількості елементів m у всіх вкладених списках з
використанням функції len().
4. Якщо всі значення m співпадають, вважати матрицю правильною та
проводити операцію її транспортування з переходом на пункт 5. У
противному випадку вважати матрицю неправильною та припинити роботу
програми з переходом на пункт 17.
5. Задаємо номер початкового рядка i = 1 транспонованої матриці, яка
формується. Цей номер відповідає першому стовпчику початкової матриці M.
6. Визначення списку, до якого буде записуватись транспортована
матриця з використанням оператора присвоєння MТ = [0].
7. Організація циклу для формування відповідного рядка матриці.
Вважаємо, що номер рядка дорівнює i.
8. Задаємо номер початкового елемента рядка j = 1.
9. Формування вектора, в який будуть записуватися рядок
транспортованої матриці, з використанням оператора присвоєння V = [0].
10. Зчитування елементу Mji та запис його до вектора V з
використанням функції append(). Зрозуміло, що для задачі, яка

266
розв’язується, j – це рядок початкової матриці, а i – стовпець.
12. Якщо j < m +1, збільшення значення j на 1 та перехід до пункту 10,
у противному випадку перехід до пункту 13.
13. Видалення нульового елементу вектора V з використанням функції
del(V[0]).
14. Запис вектора V до структури списку, який відповідає матриці MТ, з
використанням функції append().
15. Якщо i < n +1, збільшення значення i на 1 та перехід до пункту 9, у
противному випадку перехід до пункту 16.
16. Видалення нульового елементу матриці MТ з використанням
функції del(MT[0]).
17. Завершення роботи програми та виведення результатів.
Блок-схема описаного алгоритму наведена на рис. 3.2.
Слід також відзначити, що введення значень елементів матриці з
клавіатури є окремим завданням, яке вже було розв’язане у прикладі 3.52.
Тому для введення елементів прямокутної матриці довільного порядку
будемо використовувати написану функцію rom(), яка збережена у модулі
rand_ord_mat.
Відповідний програмний код можна записати наступним чином.
def trans_mat():
from rand_ord_mat import rom
M1=rom()
n=len(M1)
m=len(M1[0])
p=m
c=0
for i in range (1,n+1):
p=len(M1[i])
if (p!=m): c=1
if c=0:
MТ = [0]
for i in range (1,n+1):
V=[0]

267
Початок
4

Введення еле-
1 ментів матриці M i = 1; MT = [0]
6

Визначечння 7 j=1
2 кількості рядків 14
n

8 V = [0]
11
Визначення кіль-
кості елементів m
3 у всіх вкладених 9 V.append(M[j-1][i-1])
списках

10
4
Значення m j < m+1? 11
6
співпадають?
Ні
Ні
12
Формування i < n+1? 13
5
повідомлення
про помилку
Ні

15 del(MT[0])
Кінець

12
Кінець

13 j=j+1
10

del(V[0])
11 j=j+1
14 MT.append(V)

9
8

Рис 3.2 Блок-схема алгоритму роботи програми транспортування матриці,


наведеної у прикладі 3.60
268
for j in range (1,m+1):
V.append(M[j-1][i-1])
del(V[0])
MT.append(V)
del(MT[0])
else:
print(‘Матриця задана \
неправильно.\n’)
print(‘Перевірте вхідні дані.’)
return MT
Приклад 3.61 З використанням засобів програмування мови Python
написати програму для обчислення добутку двох матриць. У програмі
передбачити аналіз коректності розмірності заданих матриць для
розв’язування поставленої задачі.
З основ матричного аналізу відомо, що елементи матриці, яка є
добутком двох матриць M1 розмірності (lxm) та M2 розмірності (mxn),
визначаються наступним чином [42]:
r
MPij = ∑ M1ik M2 kj , i = 1…l, j = 1…n. (3.7)
k =1
Згідно із співвідношенням (3.7) необхідною та достатньою умовою
коректності операції множення матриць є те, що кількість рядків першої
матриці та кількість стовпчиків другої повинні співпадати.
Тобто, у тезових формулюваннях алгоритм множення матриць, заданий
співвідношенням (3.7), формулюється наступним чином.
1. Вводяться матриці M1 та M2.
2. Перевірка коректності визначення обох матриць, тобто, чи є
однаковою розмірність їх елементарних елементів.
3. Перевірка необхідної та достатньої умови коректності операції
множення, яку запишемо у вигляді:
R(M1) = C(M2), (3.8)
де функція R(M) визначає кількість рядків матриці M, а C(M) – кількість її

269
стовпчиків. Як і в прикладі 3.59, кількість рядків у матриці будемо визначати
з використанням оператора присвоєння n = len(M), а кількість
стовпчиків – з використанням оператора присвоєння m = len(M[i]).
Зрозуміло, що значення m для всіх номерів елементів i повинні співпадати.
4. Визначаємо розмірність матриці результату, кількість рядків у якій
становить l = R(M1), а кількість стовпчиків n = C(M2).
5. Визначаємо параметр r = C(M1) = R(M2), який відповідає кількості
складових для суми у формулі (3.7).
6. Визначення списку, до якого буде записуватись результат множення
матриць з використанням оператора присвоєння MP = [0].
7. Організація циклу для формування відповідного рядка матриці
результату. Вважаємо, що номер рядка дорівнює i.
8. Задаємо номер початкового елемента рядка j = 1.
9. Формування вектора, в який будуть записуватися рядок матриці
результату, з використанням оператора присвоєння V = [0].
10. Задаємо значення k = 1 для проведення обчислення суми за
формулою (3.7).
11. Задаємо початкове значення суми у співвідношенні (3.7) S = 0.
12. Організація циклу для обчислення елементів матриці згідно із
співвідношенням (3.7). Обчислення проводяться через оператор присвоєння
S = S + M1[i][k]*M2[k][j].
13. За умови k < r – збільшення значення k на 1 та перехід до пункту
12, у противному випадку – перехід до пункту 14.
14. Запис обчисленого значення S до вектора V з використанням
функції append().
15. Якщо j < m +1, збільшення значення j на 1 та перехід до пункту 12,
у противному випадку – перехід до пункту 16.
16. Видалення нульового елементу вектора V з використанням функції
del(V[0]).

270
17. Запис вектора V до структури списку, який відповідає матриці MP, з
використанням функції append().
18. Якщо i < n +1, збільшення значення i на 1 та перехід до пункту 9, у
противному випадку перехід до пункту 19.
19. Видалення нульового елементу матриці MP з використанням
функції del(MP[0]).
20. Завершення роботи програми та виведення результатів.
Блок-схема описаного алгоритму наведена на рис. 3.3. Зрозуміло, що
цей алгоритм дуже схожий на алгоритм транспортування матриці, наведений
на рис. 3.2. Єдина відмінність полягає у тому, що кожний елемент матриці,
яка обчислюється, не береться безпосередньо із початкової матриці, а
обчислюється в окремому циклі через сумування добутків відповідних
елементів двох матриць з використанням формули (3.7). Тому, на відміну від
прикладу 3.59, у даному випадку обчислювальна процедура складається не з
двох, а з трьох вкладених циклів. Тобто, програму для цього прикладу можна
писати за шаблоном програми з прикладу 3.59, але з у рахуванням визначеної
відмінності. Відповідний код програми має наступний вигляд.
def prod_mat():
from rand_ord_mat import rom
M1=rom()
n=len(M1)
m1=len(M1[0])
p=m1
c=0
for i in range (1,n):
p=len(M1[i])
if (p!=m1): c=1
M2=rom()
m2=len(M2)
l=len(M2[0])
p2=m
d=0
271
Початок
4

1 Введення елементів 6 i = 1; MT = [0]


матриць M1 та M2

Визначечння 7 j=1
2 значень l = R(M1) 19
та n = C(M2)

8 V = [0]
12
Визначення
3 значень r = C(M1)
та h = R(M2) 9 V.append(S)

10
4
Значення m та h j < m+1? 11
6
співпадають?
Ні
Ні
16
Формування i < l+1? 18
5
повідомлення
про помилку
Ні
13
17 del(MT[0])
Кінець

10 j=j+1 16
13 Кінець

11 S = 0, k = 1 12 j=j+1
9 18
15

12 S=S+M1[i-1][k-1]*
Ні 14 del(V[0])
k < m + 1? 13 M2[k-1][j-1]
19 MT.append(V)

15 j=j+1
14
8
12

Рис. 3.3 Алгоритм множення матриць для прикладу 3.60


272
for i in range (1,l+1):
p2=len(M2[i])
if (p2!=m2):
d=1
if p1!=p2:
e=1
else:
e=0
if c=0 and d=0 and e=0:
MТ = [0]
for i in range (1,n+1):
V=[0]
for j in range (1,l+1):
S = 0
for k in range (1,m1+1):
P=M1[i–1][k–1]*M2[k–1][j–1]
S = += P
V.append(S)
del(V[0])
MP.append(V)
del(MP[0])
else:
print(‘Матриці задані неправильно.\n’)
print(‘Перевірте вхідні дані.’)
return MP
Приклад 3.62 З використанням оператора циклу обчислити значення
ланцюгового дробу:
1
L = n1 + ,
1
n2 +
1
n3 + K +
nk
де n1, n2, n3, …, nk – натуральні числа [42]. Послідовність натуральних чисел

273
задати як вектор, значення k та значення всіх елементів вектора вводити з
клавіатури.
Відповідна програма, написана мовою програмування Python, буде
мати наступний вигляд.
def l_f():
k = int(input(‘Введіть кількість елементів: ’))
# Вводиться значення кількості елементів
D = [0]
for i in range(0, k-1):
h = int(input(‘Введіть елемент ’, i, ‘: ’))
D.append(h)
del(D[0])
S = 1/D[-1]
for j in range(k-2,0,-1):
S = 1/(S + D[j])
S = S + D[0]
return S
У цьому підрозділі була розглянута низка прикладних завдань,
пов’язаних із обчисленням числових послідовностей та матриць з
використанням алгоритмів дискретної математики та матричного аналізу
[42]. Ці завдання мають вельми важливе значення в сучасній теорії
інформаційних електронних систем, зокрема в теорії кодування сигналів для
створення необхідних кодових послідовностей [60]. У наступному підрозділі
розглянемо можливості використання вкладених циклів для розв’язування
завдань квантової електроніки та оптоелектроніки.

3.7.5 Розрахунок спектрів випромінювання за формулою Рідберга


з використанням циклічних структур
Відомо, що теоретичним підґрунтям сучасної квантової електроніки є
не математичний аналіз неперервних величин та відповідні числові
алгоритми, а, навпаки, алгоритми дискретної математики. Зокрема, такі

274
алгоритми можуть бути використані для розрахунку спектрів
випромінювання різних речовин [50]. Зрозуміло, що алгоритми дискретного
аналізу можна легко реалізувати через структури вкладених циклів [42].
Наприклад, розглянемо розрахунок спектрів випромінювання атому водню за
довжиною хвилі з використання відомої формули Рідберга [50]:

1  1 1  1
= RZ 2  − , λ= , (3.9)
λ  n2 n2   1 1 
 1 2
RZ 2  −
 n2 n2 
 1 2

де R – стала Рідберга, яка має різні значення для різних речовин, Z – заряд,
або атомний номер елемента, n1 та n2 – цілі числа, такі, що n1 < n2. Наприклад,
для атому водню RH = 1096,775834 м–1.
Будемо визначати не лише довжину хвилі з використанням
співвідношення (3.9), але й належність даної спектральної лінії до
відповідного світлового діапазону, від інфрачервоного (І) до
ультрафіолетового (У). Зрозуміло, що для розв’язування цього завдання
необхідно використовувати умовний оператор. Класифікація діапазонів
світлового випромінювання за довжиною хвилі наведена у таблиці 3.6 [50].
Таблиця 3.6 – Класифікація діапазонів світлового випромінювання за
довжиною хвилі

Інфра-
Червоний Помаранчевий Жовтий Зелений
Колір червоний
(Ч) (П) (Ж) (З)
(І)
Діапазон
565 – 500 –
довжини >740 625 – 740 590 – 625
590 565
хвилі, нм
Блакитний Ультрафіолетовий
Колір Синій (С) Фіолетовий (Ф)
(Б) (У)
Діапазон
довжини 485 – 500 440 – 485 380 – 440 < 380
хвилі, нм

275
Приклади розв’язування фізичних завдань, пов’язаних із класифікацією
об’єктів за визначеними ознаками, були розглянуті у підрозділі 3.5. Для
розв’язування подібних завдань був використаний умовний оператор із
логічним виразом у вузькому значенні цього слова.
У наступному прикладі наведений програмний код функції, яка
визначає довжину хвилі спектра оптичного випромінювання та діапазон
цього випромінювання за довжиною хвилі, а також показані результати
роботи цієї програми.
Приклад 3.63 З використанням співвідношення (3.9) та класифікації
діапазонів світлового випромінювання, наведеної у таблиці 3.6, розрахувати
серії спектрів випромінювання атома водню в діапазоні значень від 1 до

n1max , вважаючи, що максимальне значення n2 становить n2max , та визначити

оптичний діапазон цих спектрів. Провести числові розрахунки для значень

( )
n1max = 1K6 та n2max = n1max + 1 K12 .
Програма для розрахунку спектрів випромінювання атомів водню може
бути написана на мові програмування Python наступним чином.
def rb(n1_max, n2_max):
if (n2_max > n1_max):
for n1 in range (1, n1_max+1):
print('Серія', n1)
for n2 in range (n1+1, n2_max+1):
L=(1./(10967758.34*(1/(n1**2)-\
1/(n2**2))))*1e9
if (L>740):
Sout = ‘І’
elif (625<L<=740):
Sout = ‘Ч’
elif (590<L<=625):
Sout = ‘П’
elif (565<L<=590):

276
Sout = ‘Ж’
elif (500<L<=565):
Sout = ‘З’
elif (485<L<=500):
Sout = ‘Б’
elif (440<L<=485):
Sout = ‘С’
elif (380<L<=440):
Sout = ‘Ф’
else:
Sout = ‘У’
print('n2=',n2,'; \tL=',L, ' н\n
м;', '\tДіапазон: ', Sout)
else:
print(‘Невірні значення квантових \n’)
print(‘чисел n1 та n2. Необхідна умова:\n’)
print(‘n1 < n2. Перевірте вхідні дані.’)
Результати роботи такої програми у командному рядку інтерпретатора
будуть мати наступний вигляд.
>>> from reedberg import rb
>>> rb(16, 12)
Невірні значення квантових
чисел n1 та n2. Необхідна умова:
n1 < n2. Перевірте вхідні дані.
>>> rb(6, 12)
Серія 1
n2=2; L=121.56844562034117 нм; Діапазон: У
n2=3; L=102.57337599216287 нм; Діапазон: У
n2=4; L=97.25475649627293 нм; Діапазон: У
n2=5; L=94.97534814089154 нм; Діапазон: У
n2=6; L=93.78137233569177 нм; Діапазон: У

277
n2=7; L=93.07584117807372 нм; Діапазон: У
n2=8; L=92.62357761549804 нм; Діапазон: У
n2=9; L=92.31603839294658 нм; Діапазон: У
n2=10; L=92.09730728813724 нм; Діапазон: У
n2=11; L=91.93613700038301 нм; Діапазон: У
n2=12; L=91.8139309580199 нм; Діапазон: У
Серія 2
n2=3; L=656.4696063498424 нм; Діапазон: Ч
n2=4; L=486.27378248136466 нм; Діапазон: Б
n2=5; L=434.17302007264703 нм; Діапазон: Ф
n2=6; L=410.29350396865146 нм; Діапазон: Ф
n2=7; L=397.1235890264478 нм; Діапазон: Ф
n2=8; L=389.01902598509173 нм; Діапазон: Ф
n2=9; L=383.6510686460117 нм; Діапазон: Ф
n2=10; L=379.90139256356616 нм; Діапазон: У
n2=11; L=377.1738953861867 нм; Діапазон: У
n2=12; L=375.1254893427671 нм; Діапазон: У
Серія 3
n2=4; L=1875.6274467138353 нм; Діапазон: І
n2=5; L=1282.167199902036 нм; Діапазон: І
n2=6; L=1094.1160105830706 нм; Діапазон: І
n2=7; L=1005.219084723196 нм; Діапазон: І
n2=8; L=954.8648819634071 нм; Діапазон: І
n2=9; L=923.1603839294658 нм; Діапазон: І
n2=10; L=901.7439647662669 нм; Діапазон: І
n2=11; L=886.5270353608362 нм; Діапазон: І
n2=12; L=875.2928084664566 нм; Діапазон: І
Серія 4
n2=5; L=4052.2815206780397 нм; Діапазон: І
n2=6; L=2625.8784253993695 нм; Діапазон: І
n2=7; L=2166.128667416988 нм; Діапазон: І

278
n2=8; L=1945.0951299254587 нм; Діапазон: І
n2=9; L=1817.9158329687941 нм; Діапазон: І
n2=10; L=1736.6920802905881 нм; Діапазон: І
n2=11; L=1681.1179337212893 нм; Діапазон: І
n2=12; L=1641.1740158746059 нм; Діапазон: І
Серія 5
n2=6; L=7459.881890339116 нм; Діапазон: І
n2=7; L=4653.792058903685 нм; Діапазон: І
n2=8; L=3740.567557548959 нм; Діапазон: І
n2=9; L=3297.0013711766633 нм; Діапазон: І
n2=10; L=3039.2111405085293 нм; Діапазон: І
n2=11; L=2873.004281261969 нм; Діапазон: І
n2=12; L=2758.27565693211 нм; Діапазон: І
Серія 6
n2=7; L=12371.927196593182 нм; Діапазон: І
n2=8; L=7502.509786855341 нм; Діапазон: І
n2=9; L=5908.226457148581 нм; Діапазон: І
n2=10; L=5128.668799608144 нм; Діапазон: І
n2=11; L=4672.518962842995 нм; Діапазон: І
n2=12; L=4376.464042332283 нм; Діапазон: І
Особливістю написання програми, наведеної у прикладі 3.62, є те, що
довжина хвилі L відразу перераховується з метрів до нанометрів, що у
значній мірі спрощує аналіз розрахунків. Крім цього, у разі невірного

визначення максимальних значень квантових чисел n1max та n2max

розрахунки не виконуються та виводиться повідомлення про помилку


вхідних даних.
Слід відзначити, що діапазон світлового випромінювання у квантовій
електроніці може визначатися не лише за довжиною хвилі, але й також за
частотою випромінювання або за його енергією [50]. У такому випадку слід
використовувати конвертори фізичних величин, аналогічні тим, які були
описані у підрозділі 2.5.6. Завдання для написання таких конверторів та

279
числові параметри, які необхідно знати для перерахунку значень відповідних
фізичних величин, наведені у практичному занятті 3 підрозділу 7.3.

3.7.6 Оператор циклу із заданою умовою та можливості його


використання для розв’язування прикладних завдань
програмування
Із розглянутих в попередньому підрозділі прикладів цілком зрозуміло,
що цикли із заданою кількістю повторень, зокрема вкладені цикли, можуть
бути ефективно використані для розв’язування прикладних завдань
обчислювальної математики та прикладної фізики. Також зрозуміло, що для
реальних завдань оператор циклу із заданою кількістю повторень зазвичай
необхідно використовувати разом із умовним оператором, або
перераховувати кількість повторень з використанням оператора присвоєння.
Недолік такої синтаксичної конструкції полягає у тому, що необхідно знати
наперед, скільки ітерацій необхідно виконати у циклі. Якщо для обробки
векторів або матриць такий підхід зазвичай можна вважати ефективним, у
разі аналізу числових послідовностей він часто потребує або перерахунку
значень змінних, або виконання додаткових перевірок через умовний
оператор, що у значній мірі ускладнює структуру програми. Тому у всіх
мовах програмування, крім циклів із заданою кількістю повторень, вводяться
також команди циклів із заданою умовою виконання [5 – 10, 15 – 19].
Організація роботи таких структур відрізняється тим, що кількість повторень
наперед може бути невідомою, вона визначається в процесі роботи через
обчислені значення змінних. Якщо ці значення виходять за межі визначеного
діапазону, виконання ітерацій у циклі припиняється та здійснюється перехід
до виконання команди, яка стоїть безпосередньо після циклу.
Зрозуміло, що використання циклів із виходом за заданою умовою
значно спрощує написання програм та аналіз програмного коду.
У мові програмування Python лінгвістична конструкція для циклу з
виходом за заданою умовою має наступний вигляд [24 – 26].
while <логічна змінна>:

280
<тіло циклу>.
Зазвичай тіло циклу виконується до тих пір, поки значення логічної
змінної є істинним. Слід відзначити, що для організації циклів з виходом за
заданою умовою можна використовувати логічні вирази у широкому
значенні цього слова, що значно розширює можливості використання таких
лінгвістичних конструкцій у мові програмування Python.
Існує також інший спосіб виходу з циклу із заданою, пов’язаний з
використанням інструкцій переривання та продовження, які будуть
розглянуті у підрозділі 3.7.7.
Слід відзначити, що цикл із заданою кількістю повторень з точки зору
теорії регулярних мов є окремим випадком циклу із заданою умовою. Дійсно,
якщо проводяться обчислення для значень n від 1 до 100 зі збільшенням n на
1, можна сказати, що вихід із циклу здійснюється за умови n < 101. У деяких
випадках використання циклу із заданою умовою трішки ускладнює
програмний код, іноді ці два варіанти циклів є майже еквівалентними, але у
багатьох випадках у разі використання циклів із заданою умовою виходу
програмний код значно спрощується.
Розглянемо приклади використання циклів із заданою умовою виходу.
Приклад 3.64 З використанням оператора циклу із виходом за
заданою умовою знайти суму квадратів натуральних чисел від 1 до 10.
Зрозуміло, що така програма аналогічна програмі, наведеній у прикладі
3.57. Відповідний програмний код для заданої умови задачі можна записати
наступним чином.
>>> i = 0
>>> S = 0
>>> while i < 101:
S+=(i**2)
i+=1
>>> S
385
>>>

281
Із наведеного прикладу зрозуміло, що у циклі з виходом за заданою
умовою, на відміну від циклу із заданою кількістю повторень, обчислення
змінної, яка аналізується, проводиться в тілі циклу. Це у деякій мірі
утруднює аналіз таких структур, проте дозволяє запобігти використання
умовного оператора для аналізу процесу проведення обчислень. Проте, у
разі, якщо ітераційні обчислення здійснюються за однією змінною, іноді
простіше записати умову циклу через кількість повторень безпосередньо в
інструкції циклу.
Розглянемо тепер інший приклад, для якого використання оператора
циклу із заданою умовою у значній мірі спрощує програмний код.
Приклад 3.65 З використанням оператора циклу із виходом за
заданою умовою знайти значення функції y(x) = sin(x) в інтервалі [0; 2π] з
кроком 0,2·π.
>>> x = 0
>>> from math import (sin, pi)
>>> while x <= 2*pi:
y = sin(x)
print(‘x= ’,x\t,‘y= ’,y \n)
x += 0.2*pi
>>>
x= 0 y= 0.0
x= 0.6283185307179586 y= 0.5877852522924731
x= 1.2566370614359172 y= 0.9510565162951535
x= 1.8849555921538759 y= 0.9510565162951536
x= 2.5132741228718345 y= 0.5877852522924732
x= 3.141592653589793 y= 1.2246467991473532e-16
x= 3.7699111843077517 y= -0.587785252292473
x= 4.39822971502571 y= -0.9510565162951535
x= 5.026548245743669 y= -0.9510565162951536
x= 5.654866776461628 y= -0.5877852522924734
x= 6.283185307179586 y= -2.4492935982947064e-16
282
Зрозуміло, що для розв’язування цього завдання використання циклу з
виходом за заданою умовою є значно простішим, ніж циклу із заданою
кількістю повторень, як було зроблено у прикладі 3.58.
Приклад 3.66 Чисельно розв’язати рівняння x 3 – x 2 –8 x + 12 = 0
методом Стеффенсона. Відповідний програмний код написати з
використанням оператора циклу із виходом за заданою умовою.
Із основ обчислювальної математики відомо, що ітераційний метод
Стеффенсона, призначений для чисельного розв’язування нелінійних
рівнянь, записується у вигляді наступного рекурентного співвідношення [63]:

f 2 ( xn )
xn +1 = xn − . (3.10)
f ( xn + f ( xn )) − f ( xn )
Будемо розв’язувати поставлену задачу послідовно та писати програму
за модульним принципом, що у значній мірі спрощує її розуміння. Функцію
stef(t,x0), в який необхідно реалізувати ітераційний алгоритм за
співвідношенням (3.10) через цикл із виходом за заданою точністю
обчислень, реалізуємо окремим модулем у файлі steffensen. Як
параметри будемо передавати до цієї функції дві змінні: t – ім’я функції, для
якої проводиться пошук нульового значення, та початкове наближення x0.
Щодо точності проведення обчислень, будемо вважати її для будь-якого
рівняння однаковою та рівною 10-6. Після закінчення проведення розрахунків
будемо повертати із функції steffensen два значення: знайдений корінь
рівняння x та кількість проведених ітерацій n.
У файлі cubic_poly реалізуємо допоміжну функцію
c_p(c3,c2,c1,c0,xi) для обчислення значення кубічного полінома
С3x3 + С2x2 + С1x + С0 для відомого аргументу xі, а у функції my_cp(xii) модуля
my_cubic_poly – обчислення значення поліному P(x) = x3 – x2 – 8x + 12 для
аргументу xii через виклик функції c_p(c3,c2,c1,c0,xi). Тоді для
поставленого завдання t = my_cp.
Зрозуміло, що такий модульний принцип побудови не лише спрощує
написання програми, але й робить її більш функціональною. Відповідний

283
програмний код можна записати наступним чином.
def stef(t,x0):
x = x0
c = 2*x0
n=0
while abs(x - c) > 1e-6:
f=t(x)
f1=t(x+f)
r = -(f**2)/(f1-f)
c = x
x += r
n+=1
return(x,n)
def c_p(c3,c2,c1,c0,xi):
cp=c3*xi**3+c2*xi**2+c1*xi+c0
return(cp)
def my_cp(xii):
from cubic_poly import c_p
cp_my=c_p(1,-1,-8,12,xii)
return(cp_my)
Проаналізуємо особливості роботи написаного програмного коду,
викликаючи функцію stef з різними параметрами через командний рядок
інтерпретатора.
>>> from steffensen import stef
>>> from my_cubic_poly import my_cp
>>> stef(my_cp,1.5)
(-3.0, 39)
>>> stef(my_cp,2.5)
(2.0000024653617623, 22)
>>> stef(my_cp,4)
(2.000002463995141, 56)
284
>>> stef(my_cp,-1)
(-3.000000000000004, 35)
>>>
Із наведених результатів виконання програми зрозуміло, що рівняння
x3 – x2 – 8x + 12 = 0 має два корені: x = 2 та x = –3. У більшості випадків ітераційні
розрахунки, які проводяться за співвідношенням (3.10), збігаються до точки
x = –3, і лише за умови x > 2 досягається збіжність до кореня x = 2.
Проаналізуємо функцію P(x) = x3 – x2 – 8x + 12 на відрізку x ∈ [− 4;4]. Графік цієї
функції на заданому відрізку, отриманий з використанням засобів програмування
системи MatLab [6, 7], наведений на рис. 3.4.

Рис. 3.4 Графік функції P(x) = x3 – x2 – 8x + 12 на відрізку x ∈ [− 4;4] , отриманий


з використанням засобів програмування системи MatLab

Із наведеної графічної залежності видно, що рівняння P(x) = 0 дійсно має


ці два корені, але особливість полягає в тому, що за умови x = 2 функціє також має
мінімум. Із теорії чисельних методів відомо, що пошук таких коренів завжди є
ускладненим та потребує великої кількості ітерацій [63]. Проте перевага
ітераційного співвідношення (3.10) полягає в тому, що воно не потребує
обчислення похідної від функції f(x). Відомо, що за умови використанням таких
ітераційних алгоритмів пошук коренів, яким відповідають нульові значення

285
похідної, значно спрощується [63]. Взагалі метод Стеффенсона є методом
другого порядку збіжності, хоча він і не потребує використання похідної.
Замість взяття похідної у співвідношенні (3.10) використане обчислення
значення функції f ( xn + f ( xn )) .
Недоліком розглянутого модульного принципу побудови
обчислювального процесу є велика кількість модулів, що у значній мірі
утруднює аналіз програмного коду. Іншим, більш ефективним засобом
створення власних функцій користувача у мові програмування Python є
анонімні лямбда-функції, спосіб побудови та використання яких
розглядатиметься у підрозділі 3.7.8.
Для закріплення матеріалу, наведеного у цьому підрозділі, необхідно
виконати практичне заняття 6, наведене у розділі 7.

3.7.7 Примусове переривання та продовження циклів


Недолік написання циклів із заданою умовою для програм із складною
логікою полягає в тому, що зазвичай важко сформувати умову завершення
циклу з використанням логічних виразів. Часто простіше це можна зробити
через умовний оператор, розглянутий у підрозділі 3.4. Нажаль, умовний
оператор не може бути використаний для формування умови виходу з циклу
в декларації while, проте існує інший вихід із цієї ситуації. Можна написати
умовний оператор у тілі циклу, а вихід із нього реалізувати з використанням
ключових слів break та continue. Відмінність цих команд полягає у тому,
що у разі використання команди break виконання циклу повністю
припиняється із переходом на першу команду, яка стоїть після тіла циклу. У
разі використання команди continue, навпаки, виконання циклу не
переривається, але здійснюється перехід на першу команду тіла циклу із
збереженням всіх значень змінних. Тобто, виконання команди continue
приводить до того, що всі команди, які у тілі циклу розташовані нижче за неї,
ігноруються. Зрозуміло, що використання команд break та continue як
окремих інструкцій не є ефективним для реалізації складних алгоритмів,
оскільки дії, які вони виконують, є тривіальними. Команда break завжди
286
приводить до завершення циклу, а команда continue без аналізу умови її
виконання взагалі є помилковою, оскільки вона веде до організації вічного
циклу із нескінченною кількістю повторень. Але використання цих команд
разом із умовним оператором значно спрощує організацію логіки складних
програм та їх написання. Слід відзначити, що аналогічні оператори існують
сьогодні майже у всіх сучасних мовах програмування [5 – 10, 12 – 19].
Розглянемо приклад написання комп’ютерної гри із досить складною
логікою, в якому використання команд переривання та продовження циклу
приводить до значного спрощення програмного коду.
Приклад 3.67 З використанням засобів програмування мови Python
написати програму для комп’ютерної гри «Вгадай число». Правила гри
є наступними. З використанням функції randint() модуля random
комп’ютер обирає випадковим чином натуральне число від 0 до 9, а
користувач, вводячи числа з клавіатури, намагається це число вгадати.
Якщо користувач не вгадав, комп’ютер видає повідомлення про те,
більшим чи меншим є загадане число та дає можливість виконати
повторну спробу. Якщо число вгадане правильно, комп’ютер нараховує
користувачу відповідну кількість очок, залежно від кількості виконаних
спроб. Якщо число було вгадане з першої спроби – користувач отримає
10 очок, якщо з другої – 9, і так далі. Загальна кількість спроб не
перевищує 10. Відповідно, якщо число вгадано з десятої спроби,
користувач отримує 1 очко, а якщо число не вгадане – 0 очок. Таким
чином необхідно відгадати 10 чисел. Всі отримані користувачем очки
сумуються, і саме таким способом визначається результат гри.
Проте користувач також може перервати гру двома способами.
Перша можливість – припинити вгадувати загадане число і перейти до
наступного. У цьому разі вважається, що число не вгадане,
зараховується невдала спроба та користувач очок не отримує. Друга
можливість – це повністю припинити гру із нарахованими очками. Для
виконання першої дії необхідно натиснути українську літеру «П» або
англійську літеру «І», а для виконання другої дії – українську літеру

287
«С» або англійську літеру «S».
Почнемо написання цієї програми з аналізу особливості роботи функції
randint() модуля random. Ця функція має два параметри, які визначають
діапазон цілих чисел для роботи генератора. Першим завжди стоїть
мінімальне значення, а другим – максимальне. Тобто, для завдання, яке
розв’язується, необхідно вказати параметри виклику randint(0,9).
Тепер складність поставленого завдання полягає лише у тому, що
досить важко запрограмувати запропоновану логіку гри. Відповідна
програма повинна мати два вкладених цикли. В зовнішньому циклі число
загадується, а у внутрішньому – послідовно відгадується із виведенням на
екран відповідних повідомлень. Проте таки події, як натиснення клавіш «П»,
«І» (англійська), «С» (українська) та «S» повинні аналізуватися окремо.
Якщо натиснено не цифрова клавіша та не клавіша із обраного набору
{«П», «І», «С», «S»}, ця подія вважається помилковою та просто
ігнорується програмою.
Почнемо розв’язування поставленого завдання з формування блок-
схеми алгоритму роботи програми згідно із описаними правилами гри. Така
блок-схема наведена на рис. 3.5. Нижче наведений код програми f_d(),
написаної за цим алгоритмом, та результати її тестування через командні
рядки інтерпретатора. Одна з особливостей цієї програми полягає у тому, що
для переривання та продовження внутрішнього циклу використані команди
break та continue.
def f_d():
from random import randint
P=0
n=0
inp='.'
while ((inp!='S') and (inp!='С') and (n<=10)):
c=randint(0,9)
k=0
D=0
288
Початок

P=0 n=0
1 5
inp='.' 6 11

6
2 c=randint(0,9) Ні
inp=«П»|«І»? 7

3 k=0 D=0 R=0 2


7 12

6
Введення з екрана
4 значення змінної
inp 7
Ні
«0»≤inp≤«9»? 4
5
Ні
inp=«С»|«S»? 6

8 k=k+1
Кінець
9
Ні
int(inp)==c? 12

R=10-k
Формування повідомлення про 10 P=P+R
12 те, є загадане число більшим D=1 n=n+1
чи меншим

Формування повідомлення про


4 11 кількість набраних очок R та
загальну кількість очок P

Рис. 3.5 Блок –схема алгоритму комп’ютерної гри для прикладу 3.67

289
while (D==0) and (k<=10):
inp=input('Введіть число від 0 до 9 або S,\
C - закінчити, I, П - перервати.')
if ord(inp)>ord('9')and (inp!='S')and\
(inp!='I') and (inp!='С')and
(inp!='П')\
or(ord(inp)<ord('0')):
continue
elif ord(inp)>ord('9')and((inp=='I')\
or(inp=='П')or (inp!='S') or (inp!='С')):
break
else:
if int(inp)==c:
D=1
P+=(10-k)
print('Ви вгадали та набрали', 10-\
k, ' очок. Загальна сума ', P, '\
очок.')
elif (int(inp)<c and k<10):
print('Ви не вгадали. Число є біль\
шим. Спробуйте ще раз.')
elif (int(inp)>c and k<10):
print('Ви не вгадали. Число є мен\
шим. Спробуйте ще раз.')
k+=1
n+=1
>>> from find_digit import f_d
>>> f_d()
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.8

290
Ви не вгадали. Число є меншим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.1
Ви не вгадали. Число є більшим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.3
Ви не вгадали. Число є більшим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.5
Ви не вгадали. Число є більшим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.6
Ви не вгадали. Число є більшим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.7
Ви вгадали та набрали 5 очок. Загальна сума 5 очок.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.6
Ви не вгадали. Число є меншим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.П
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.9
Ви не вгадали. Число є меншим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.8
Ви не вгадали. Число є меншим. Спробуйте ще раз.
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.7
Ви вгадали та набрали 8 очок. Загальна сума 13 очок.

291
Введіть число від 0 до 9 або S, C - закінчити, I, П -
перервати.S
>>>

3.7.8 Анонімна лямбда-функція та генератори


Іншими ефективними способами спрощення програмного коду є
анонімні функції, або лямбда-функції, та генератори. Слід відзначити, що
якщо функції переривання та продовження циклів, розглянуті у
попередньому підрозділі, існують у більшості сучасних мов програмування,
анонімні функції та генератори є новітніми підходами до створення
програмного коду, які сьогодні реалізовані лише у мові програмування
Python.
Лямбда-функції у значній мірі спрощують написання складних
програмних комплексів із великою кількістю функцій. Особливість
використання цього стилю програмування полягає у тому, що якщо одна з
функцій викликає іншу, та ім’я функції, яка викликається з іншої,
передається як параметр, можна не створювати новий файл із новою
функцією, а просто записати її як анонімну функцію через командний рядок.
Тобто, здійснюється перехід від модульного стилю програмування до більш
простого декларативного.
Розглянемо відповідні приклади.
Приклад 3.68 З використанням лямбда-функції написати програму,
яка допомагає викладачу сформувати список студентів групи. Всі прізвища
студенів у списку пишуться з великої літери, а після прізвища ставиться
двокрапка для занесення оцінок.
Якщо користуватися розглянутим раніше модульним стилем
програмування, відповідний програмний код можна записати наступним
чином.
>>> def st_list(names, func):
for name in names:
print (func(name))

292
>>> s=[‘ігнатенко’,‘потапенко’,‘хоменко’]
>>> def f(name)
return name.capitalize()+‘:’
>>> st_list(s,f)
Ігнатенко:
Потапенко:
Хоменко:
Створений програмний код є досить простим. Єдиний його недолік
полягає у тому, що виникла необхідність створити додаткову функцію f()
лише для того, щоб передати її як параметр до функції st_list().
Уникнути такої необхідності дозволяє анонімна лямбда-функція.
Відповідний спрощений програмний код можна переписати наступним
чином.
>>> def st_list(names, func):
for name in names:
print (func(name))
>>> s=[‘ігнатенко’,‘потапенко’,‘хоменко’]
>>> st_list(s, lambda name: name.capitalize()+‘:’)
Ігнатенко:
Потапенко:
Хоменко:
Видно, що різниця між наведеними програмними кодами полягає лише
в тому, що в першому випадку необхідні дії, або методи об’єкта, були
записані окремою функцією із оператором повернення її значення return, а
у другому ті ж самі дії записані через двокрапку через ім’я змінної.
Зрозуміло, що другий програмний код є значно коротшим та простішим.
Слід відзначити, що хоча в інших мовах програмування повної
альтернативи лямбда-функції не існує, вона в значній мірі схожа на
внутрішні функції мов програмування С та С++ [3, 5, 8 – 10, 39, 40], або на
inline-функції системи науково-технічних розрахунків MatLab [6, 7].
Розглянемо інший приклад.
293
Приклад 3.69 З використанням лямбда-функції переписати командні
рядки виклику функції steffensen, написаної для прикладу 3.66.
>>> from steffensen import stef
>>> from cubic_poly import c_p
>>> x0 = 1.5
>>> stef(lambda xii: c_p(1,-1,-8,12,xii), x0)
(-3.0, 39)
>>> stef(lambda xi: xi**3-xi**2-8*xi+12, x0)
(-3.0, 39)
Проблема полягає у тому, що не завжди функцію, за якою необхідно
проводити обчислення, можна задати заздалегідь у явному вигляді. Іноді
функція, яка має бути використана як параметр, залежить від результатів
попередніх обчислень. У цьому разі анонімна лямбда-функція не може бути
використана безпосередньо через формування рядкової змінної. Розглянемо
відповідний програмний код, який сформуємо на основі прикладу 3.69.
>>> from steffensen import stef
>>> str = ‘xi**3-xi**2-8*xi+12’
>>> stef(lambda xi: str, x0)
У даному випадку помилка полягає лише у тому, що для використання
рядкової змінної як параметра функції виклику необхідно застосовувати
функцію eval() [26]. Командні рядки, наведені у прикладі 3.70, є цілком
коректними.
Приклад 3.70
>>> from steffensen import stef
>>> str = ‘xi**3-xi**2-8*xi+12’
>>> stef(lambda xi: eval(str), x0)
(-3.0, 39)
Слід відзначити, що функція eval() є одним із ефективних засобів
логічного програмування для створення систем штучного інтелекту, оскільки
вона дозволяє автоматично генерувати програмний код [26 – 29]. Наприклад,
саме ця функція була використана у системі науково-технічних розрахунків

294
MatLab для автоматичного формування арифметико-логічних виразів для
проведення рекурентних обчислень за різними алгоритмами [6, 7].
Іншою цікавою можливістю роботи з функціями у мові програмування
Python є використання функції генератора. Вона є дуже подібною до функції
генератора цілих чисел range(), яка була розглянута у підрозділі 3.7.1.
Проте відмінність полягає у тому, що функція генератора створюється з
використанням оператора циклу із виходом за зазначеною умовою, і
результатом роботи цієї функції можуть бути не лише цілі, але й дійсні
числа. Тобто, можливості функції генератора, порівняно із функцією
range(), значно розширені. Для забезпечення повернення значень із
функції генератора замість команди return використовується команда
yeild, яка ставиться у тілі циклу. Параметрами цієї функції зазвичай є
перше та останнє значення аргументу, а також крок зміни аргументу [25].
Приклад 3.71 Написати функцію генератора для створення числової
послідовності будь-якого діапазону.
Для створення такої функції слід передати їй відповідні параметри,
серед яких має бути перше значення, останнє значення та крок зміни
аргументу. За замовченням задамо такі значення:
перше значення: first = 0.
крок зміни аргументу: step = 1.
останнє значення: last = 10.
Спосіб визначення аргументів функції за замовченням був розглянутий
у підрозділі 2.5.3.
Обчислення значення аргументу number будемо реалізовувати у циклі
while та повертати це значення з використанням команди yeild.
Відповідний програмний код можна записати у наступному вигляді.
>>> def my_range(first = 0., last = 10., step = 1.):
number = first
while number < last:
yeild number
number += step
295
Обчислити значення послідовності цілих чисел з використанням
функції генератора можна наступним чином.
>>> from my_range_function import my_range
>>> r = my_range(1,5)
>>> for x in r:
print(x)
1
2
3
4
З наведеного прикладу зрозуміло, що функція генератора працює
аналогічно функції range(), тобто останнє значення на екран не
виводиться. Це пов’язано з тим, що оператор присвоєння, який збільшує
значення змінної number на величину step, розташований у тілі циклу
нижче, ніж команда повернення значення yeild number.
Тепер розглянемо інший приклад, у якому з використанням функції
генератора обчислюється послідовність дійсних чисел.
Приклад 3.72 З використанням функції генератора, створеної у
прикладі 3.70, переписати програму для прикладу 3.64.
Зрозуміло, що у даному випадку:
first = 0.,
last = 2*math.pi+step,
step = 0.2*math.pi.
Тоді відповідні командні рядки будуть мати наступний вигляд.
>>> from my_range_function import my_range
>>> from math import (sin, pi)
>>> f = 0.
>>> s = 0.2*pi
>>> l = 2*pi+s
>>> a = my_range(f,l,s)
>>> for x in a:

296
sn = sin(x)
print('x = ', x,';\t', 'sn = ', sn)
x = 0.0 ; sn = 0.0
x = 0.6283185307179586; sn = 0.5877852522924731
x = 1.2566370614359172; sn = 0.9510565162951535
x = 1.8849555921538759; sn = 0.9510565162951536
x = 2.5132741228718345; sn = 0.5877852522924732
x = 3.141592653589793; sn = 1.2246467991473532e-16
x = 3.7699111843077517; sn = -0.587785252292473
x = 4.39822971502571; sn = -0.9510565162951535
x = 5.026548245743669; sn = -0.9510565162951536
x = 5.654866776461628; sn = -0.5877852522924734
x = 6.283185307179586; sn = -2.4492935982947064e-16
>>>
Результат роботи цієї програми цілком відповідає результату,
отриманому у прикладі 3.64.
Слід відзначити, що послідовності, які створюють генератори, цілком
відповідають функціям визначення табульованих значень векторів у системі
науково технічних розрахунків MatLab.

3.7.9 Обробка виключних та помилкових ситуацій у мові


програмування Python
Перед вивченням цього підрозділу необхідно повторити підрозділи 3.4, 2.2 та 2.4
Одним із важливих завдань під час створення комп’ютерних програм є
автоматична обробка виключних ситуацій та помилок виконання програми.
Загалом завдання обробки виключних ситуацій полягає у тому, що
відлагоджена програма не повинна виходити на системні повідомлення про
помилки виконання [16]. Для цього необхідно заздалегідь передбачити
можливі помилки та, у разі їх виникнення, виводити відповідне повідомлення
про помилкову роботу програми. Більшість виключних ситуацій можна

297
обробити з використанням умовного оператора. Розглянемо наступний
приклад, у якому наочно показана така можливість.
Приклад 3.73
>>> from math import sqrt
>>> x = float(input())
0
>>> if(x == 0):
print (‘Помилка ділення’)
else:
print (5/x)
Помилка ділення
>>> z = float(input())
-5
>>> if(z < 0):
print (‘Помилковий аргумент’)
else:
print (sqrt(z))
Помилковий аргумент
>>> z = float(input())
2
>>> if(z < 0):
print (‘Помилковий аргумент’)
else:
print (sqrt(z))
1.41421356237310
Як бачимо, у прикладі 3.73 обидві виключні ситуації, як-то ділення на
нуль та взяття квадратного кореня від від’ємного числа, коректно оброблені з
використанням умовного оператора. Такий спосіб дійсно є дуже ефективним
для визначення неправильних аргументів математичних функцій.
Але проблема полягає у тому, що під час виконання комп’ютерних
програм можуть виникати різні виключні ситуації, а у цьому випадку їх

298
аналіз через перевірку відповідних умов вкрай ускладнюється. Загалом
розрізняють такі типи виключних ситуацій під час роботи програмного
забезпечення [16, 24].
1. Неправильне підключення або відсутність необхідного електронного
комп’ютерного обладнання.
2. Відсутність на комп’ютері необхідного системного забезпечення,
наприклад, драйверів зовнішніх пристроїв.
3. Відсутність на комп’ютері необхідного програмного забезпечення.
4. Помилки перетворення типів даних.
5. Невизначені операції, наприклад, помилка ділення на нуль.
6. Неправильні аргументи математичних функцій.
Зрозуміло, що проаналізувати всі ці типи помилок та виявити їх з
використанням умовного оператора вкрай важко. Тому розробники мови
програмування Python передбачили іншу можливість обробки виключних
ситуацій, яка зазвичай є більш ефективною та значно спрощує програмний код.
Цей спосіб обробки виключних ситуацій базується на тому, що інтерпретатор
намагається виконати програмний код, а у разі, якщо він не може бути
виконаним, виводиться повідомлення про помилку. Ця операція виконується з
використанням лінгвістичної конструкції try: ... except:, яка є дуже
подібною до конструкції умовного оператора if: ... else: та має
наступний синтаксис [24 – 26]:
try:
<блок операторів та функцій>
except:
<блок операторів та функцій>
Оператор перевірки коректності виконання програмного коду
try: ... except: працює наступним чином. Якщо блок
операторів, який стоїть після інструкції try , виконується коректно,
виконання програми продовжується далі, а в блоці інструкції except
зазвичай виводиться повідомлення про помилку виконання

299
програмного коду.
Розглянемо приклад, аналогічний прикладу 3.73, у якому замість
умовного оператора використаний оператор аналізу виконання
програмного коду.
Приклад 3.74
>>> from math import sqrt
>>> x = float(input())
0
>>> try:
print (5/x)
except:
print (‘Помилка ділення’)
Помилка ділення
>>> z = float(input())
-5
>>> try:
print (sqrt(z))
except:
print (‘Помилковий аргумент’)
Помилковий аргумент
>>> z = float(input())
2
>>> try:
print (‘Помилковий аргумент’)
except:
print (sqrt(z))
1.41421356237310
>>> x = float(input())
r
>>> try:

300
print (5/x)
except:
print (‘Помилка ділення’)
Помилка ділення
Із наведеного прикладу зрозумілі дві важливі переваги оператора
обробки виключних ситуацій над умовним оператором.
1. Синтаксис оператора обробки виключних ситуацій є
простішим, оскільки він не потребує використання логічного виразу
для описання відповідної умови, за якою функція, що обчислюється, є
невизначеною.
2. Функціональність оператора обробки виключних ситуацій є
значно більшою, оскільки він виявляє будь-які помилки виконання
програмного коду, а не лише неправильні аргументи математичних
функцій.
Проблема використання оператора обробки виключних ситуацій
у прикладі 3.74 полягає лише у тому, що він неправильно визначив
тип однієї з помилок. Дійсно, якщо для змінної x замість числового
значення помилково була введена літера r , така помилка відповідає
помилці перетворення типів даних, а не невірному аргументу функції
ділення.
Проте тут важливими є два моменти. По-перше, умовний
оператор if(x == 0): взагалі не виявляє помилку цього типу, а по-
друге, оператор обробки виключних ситуацій може визначати також
тип помилки через аналіз значення системної змінної, яка відповідає
цій помилці. Значення цієї текстової змінної можна легко визначити,
якщо виконати відповідну команду у командному рядку
інтерпретатора. Деякі приклади аналізу помилок у математичних
виразах розглядалися у підрозділах 2.2 та 2.4. Розглянемо ще один
відповідний приклад та використаємо інформацію, яку інтерпретатор
надає про помилку, для створення відповідної лінгвістичної

301
конструкції оператора обробки виключних ситуацій.
Приклад 3.75
>>> 4/0
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ZeroDivisionError: division by zero
>>> int(r)
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ValueError: invalid literal for int() with base 10: ‘r’
>>> q = math.sqrt(–9)
Traceback (most recent call last):
File <stdin>, line 1, in <module>
ValueError: math domain error
Тобто, інтерпретатор мови програмування Python дає значення
наступних системних змінних для різних типів помилок.
1. ZeroDivisionError – невизначена операція, помилка ділення
на нуль.
2. ValueError – помилка перетворення типів даних або
неправильний аргумент функції.
Тепер розглянемо приклад використання оператора обробки
виключних ситуацій, у якому помилка ділення на нуль розрізняється
від помилки перетворення типів даних.
Приклад 3.76
>>> x = float(input(‘Введіть значення аргументу:
’))
Введіть значення аргументу: 0
>>> try:
print (5/x)
except ZeroDivisionError:

302
print (‘Помилка ділення’)
except ValueError:
print (‘Введене нечислове значення’)
Помилка ділення
>>> x = float(input(‘Введіть значення аргументу: ’))
Введіть значення аргументу: p
>>> try:
print (5/x)
except ZeroDivisionError:
print (‘Помилка ділення’)
except ValueError:
print (‘Введене нечислове значення’)
Введене нечислове значення
Із наведених прикладів зрозуміло, що оператор обробки
виключних ситуацій try є більш ефективним засобом аналізу
програмного коду, ніж умовний оператор, та дозволяє виявляти різні
типи помилок. Проте для аналізу помилкових значень аргументу
математичних функцій зазвичай зручніше використовувати умовний
оператор. Крім того, використання оператора обробки виключних
ситуацій try у значній мірі спрощує програмний код.

Контрольні питання та завдання до розділу 3


1. Що являють собою операції порівняння у дискретній математиці та
як ці операції реалізовані у мові програмування Python? Наведіть приклади
використання таких операцій.
2. Які головні операції порівняння Вам відомі та як вони реалізовані у
мові програмування Python?
3. Яким може бути результат виконання операцій порівняння та як він
залежить від операндів цієї операції? Наведіть власні приклади обчислення
результату операції порівняння.
4. Поясніть приклад 3.1.
303
5. Що являють собою логічні функції алгебри Буля та як вони
використовуються для формування логічних виразів? Поясніть таблицю 3.1
та правила 3.1 – 3.4. Наведіть власні приклади формування логічних виразів з
використанням функції алгебри Буля.
6. Що являють собою логічні вирази у вузькому значенні цього слова та
як вони формуються? Поясніть визначення 3.2. Наведіть власні приклади
формування логічного виразу у вузькому значенні цього слова.
7. Що являють собою логічні вирази у широкому значенні цього слова
та як вони формуються? Поясніть визначення 3.3. Наведіть власні приклади
формування логічного виразу у широкому значенні цього слова.
8. Поясніть властивість 3.1.
9. Поясніть приклади 3.2 та 3.3.
10. Які особливості формування логічних виразів у широкому значенні
цього слова існують у мові програмування Python? Поясніть правила 3.5 – 3.8
та приклади 3.4 – 3.12.
11. Що являють собою арифметико-логічні вирази та яким способом
вони можуть бути реалізовані у мові програмування Python? Наведіть власні
приклади формування арифметико-логічних виразів.
12. Поясніть визначення 3.4 та рис. 3.1.
13. Поясніть співвідношення 3.1 – 3.3 та приклади 3.13, 3.14.
14. Поясніть, чому арифметико-логічні вирази досить рідко
використовуються під час написання програм мовою програмування Python?
Які альтернативні рішення використовуються у цій мові для описання задач
математичної логіки?
15. Які форми синтаксису умовного оператора існують у мові
програмування Python? Наведіть власні приклади формування таких
синтаксичних конструкцій.
16. Поясніть приклади 3.15 – 3.18.
17. Як умовний оператор може бути використаний для розв’язування
завдань прикладної фізики? Наведіть власні приклади такого використання
умовного оператора.

304
18. Поясніть приклади 3.19 – 3.22.
19. Що являють собою списки у мові програмування Python та як вони
формуються? Наведіть сласні приклади формування списків у мові
програмування Python.
20. Поясніть визначення 3.5, правила 3.9 – 3.13 та приклад 3.23.
21. Які функції обробки списків мови програмування Python Вам
відомі? Поясніть таблицю 3.4.
22. Поясніть приклад 3.24.
23. Як у мові програмування Python визначається сума двох списків та
добуток списку на число? Поясніть правила 3.14 та 3.15.
24. Чим операції сумування та множення, визначені для роботи зі
списками у мові програмування Python, суттєво відрізняються від матричних
операцій, реалізованих у системі науково-технічних розрахунків MatLab?
25. Поясніть приклади 3.25 – 3.27.
26. Як для обробки списків у мові програмування Python
використовується операція зрізу? Поясніть приклади 3.28 та 3.29.
27. Що являє собою поверхневе та глибоке копіювання структур у мові
програмування Python? Поясніть визначення 3.6 та 3.7 та приклад 3.30.
28. Які функції обробки списків мови програмування Python вам
відомі? Поясніть таблицю 3.5 та приклади 3.30, 3.31.
29. Що являють собою вкладені списки у мові програмування Python
та як на основі вкладених списків формуються матриці? Поясніть спосіб
формування матриці із списків з точки зору методології об’єктно-
орієнтованого програмування, описаної у підрозділі 1.
30. Поясніть визначення 3.8 та правила 3.16, 3.17.
31. Поясніть приклад 3.31.
32. Поясніть визначення 3.9, 3.10 та приклади 3.32, 3.33.
33. Яка форма синтаксису оператора із заданою кількістю повторень у
мові програмування Python? Наведіть власні приклади формування
синтаксичних конструкцій для цього оператора.
34. Поясніть приклади 3.34 та 3.35.

305
35. Що являє собою функція range() мови програмування Python та
як вона може бути використана, разом із оператором циклу, для
розв’язування прикладних завдань дискретної та обчислувальної
математики? Наведіть власні приклади такого використання функції
range().
36. Поясніть приклад 3.36.
37. Які способи створення списків з використанням оператора циклу
вам відомі? Наведіть власні приклади створення списків з використанням цих
способів.
38. Поясніть приклади 3.37 – 3.45.
39. Як способи створення списків пов’язані із філософськими
принципами мови програмування Python, сформульованими у підрозділі 1.5?
40. Що являють собою вкладені цикли у мові програмування Python та
як вони можуть бути використані для формування матриць? Наведіть власні
приклади такого використання вкладених циклів.
41. Поясніть приклади 3.46 та 3.47.
42. Які способи введення значень елементів матриці з клавіатури з
використанням засобів програмування мови Python вам відомі? Наведіть
власні приклади використання таких способів формування матриць.
43. Які способи автоматичного формування матриць з використанням
засобів програмування мови Python вам відомі? Наведіть власні приклади
використання таких способів формування матриць.
44. Поясніть приклади 3.48 та 3.49.
45. Як з використанням засобів мови програмування Python можна
замінити стовпчик матриці? Поясніть приклад 3.50.
46. Як комп’ютерна програма, призначена для заміни стовпчика
матриці, може бути використана для розв’язування систем лінійних рівнянь?
Наведіть власні приклади такого використання цієї програми.
47. Поясніть приклад 3.51.
48. Чим суттєво відрізняється спосіб формування матриці з
використанням готового шаблону від способу, основаному на використанні

306
функції append()? Наведіть власні приклади формування матриці з
використанням функції append().
49. Поясніть приклади 3.52 та 3.53.
50. Як з використанням засобів мови програмування Python можуть
бути розв’язані складні завдання лінійної алгебри та матричного аналізу?
Наведіть власні приклади такого використання засобів програмування мови
Python.
51. Поясніть приклади 3.54 та 3.55.
52. Як способи формування матриць пов’язані із філософськими
принципами мови програмування Python, сформульованими у підрозділі 1.5?
53. Як оператор циклу із заданою кількістю повторень може бути
використаний для формування числових послідовностей із наперед заданими
властивостями? Наведіть власні приклади такого використання оператора
циклу.
54. Поясніть приклади 3.56 – 3.59.
55. Як з використанням засобів мови програмування Python можна написати
програму для транспортування заданої матриці? Поясніть приклад 3.60 та блок-
схему алгоритму, наведену на рис. 3.2.
56. Як з використанням засобів мови програмування Python можна
написати програму для множення двох матриць заданої розмірності?
Поясніть співвідношення (3.7), блок-схему алгоритму, наведену на рис. 3.3,
та приклад 3.61.
57. Як оператор циклу із заданою кількістю повторень може бути
використаний для обчислення значень ланцюгового дробу? Поясніть приклад
3.62.
58. Як оператор циклу із заданою кількістю повторень може бути
використаний для розв’язування завдань квантової фізики та дискретної
електроніки? Наведіть власні приклади такого використання оператора циклу
із заданою кількістю повторень.
59. Поясніть співвідношення (3.9), таблицю 3.6 та приклад 3.63.
60. Яка форма синтаксису оператора циклу із заданою умовою у мові

307
програмування Python? Наведіть власні приклади формування синтаксичних
конструкцій для цього оператора.
61. Як оператор циклу із заданою умовою може бути використаний для
розрахунку числових послідовностей із наперед заданими властивостями?
Наведіть власні приклади такого використання цього оператора.
62. Поясніть приклади 3.64 та 3.65.
63. Як оператор циклу із заданою умовою може бути використаний для
чисельного розв’язування нелінійних рівнянь? Поясніть формулу (3.10),
рис. 3.4 та приклад 3.66.
64. Як для організації роботи циклів із заданою умовою може бути
використана команда переривання циклу break? Наведіть власні приклади
використання цієї команди.
65. Як для організації роботи циклів із заданою умовою може бути
використана команда продовження циклу continue? Наведіть власні
приклади використання цієї команди.
66. Поясніть приклад 3.67 та блок-схему алгоритму, яка наведена на
рис. 3.5.
67. Що являє собою анонімна лямбда-функція як ефективний засіб
мови програмування Python для спрощення програмного коду? Наведіть
власні приклади використання анонімної лямбда-функці.
68. Поясніть приклади 3.68 та 3.69.
69. Як можна використовувати анонімну лямбда-функцію для роботи із
рядковими змінними? Наведіть власні приклади такого використання
лямбда-функції.
70. Що являє собою функція eval() та як фона використовується для
параметричного виклику інших функцій? Наведіть власні приклади
використання функції eval().
71. У яких ще системах програмування використовується функція
eval()?
72. Поясніть приклад 3.70.
69. Що являє собою функція генератора як ефективний засіб мови

308
програмування Python для спрощення програмного коду? Наведіть власні
приклади формування та використання функції генератора.
70. Поясніть приклади 3.71 та 3.72.
71. Що являє собою оператор обробки виключних ситуацій try:
except: та як він використовується для аналізу виконання програмного
коду? Наведіть власні приклади використання цього оператора.
72. Як з використанням оператора обробки виключних ситуацій можна
визначати тип помилки? Наведіть власні приклади визначенні типу помилки
з використанням цього оператора.
73. Поясніть приклади 3.73, 3.74, 3.75 та 3.76.
74. З використанням засобів програмування мови Python написати
програму для обчислення суми квадратів та кубів всіх чисел від 1 до 1000.
75. З використанням засобів програмування мови Python написати
програму для обчислення значень функцій sin(φ) + cos(φ), sin(φ) – cos(φ) та
sin(φ)cos(φ) в діапазоні значень аргумента φ [–2π, 2π].
76. З використанням засобів програмування мови Python написати
програму для обчислення значень функцій cos(exp(x) – ln(x))1/2 та
sin(exp(x) + ln(x)) 1/2 в діапазоні значень x від –5 до 5. У програмі передбачити
обробку виключних ситуацій.
77. З використанням засобів програмування мови Python написати
програму для реалізації алгоритма Евкліда пошуку найбільшого спільного
дільника двох чисел [42].
78. З використанням засобів програмування мови Python написати
програму для розв’язування рівнянь Діофанта [42].
79. З використанням засобів програмування мови Python написати
програму для виконання алгебраїчних операцій в групах Галуа [42].

309
Розділ 4 Способи роботи з об’єктами та структурованими даними
в мові програмування алгоритма
Перед вивченням цього розділу необхідно повторити перший та другий
розділи
4.1 Об’єкти та класи в мові програмування Python

4.1.1 Створення та використання класів


У першому розділі були наведені поняття сучасної теорії об’єктно-
орієнтованого програмування та розглянуті головні правила роботи з об’єктами.
Також було відмічено, що сьогодні саме мова програмування Python вважається
однією з розвинутих мов об’єктно-орієнтованого програмування, проте всі коди
програм, розглянуті у другому та третьому розділах, написані з використанням
відомих засобів структурного програмування.
З іншого боку, у другому розділі зверталась увага на те, що всі числові
дані та змінні у мові Python розглядаються як об’єкти, більшість
властивостей яких для зручності роботи приховується від користувача.
Дійсно, всі типи даних у Python розглядаються як класи, а сам клас являє
собою колекцію даних та функцій, які називаються атрибутами та методами.
Для будь-якого об’єкта атрибут – це змінна, а метод – функція. Доречи, в
мові Python об’єктами є не лише змінні, а також числа, списки, функції,
модулі тощо. Саме це і є головною причиною того, що Python сьогодні
вважається мовою не структурного, а об’єктно-орієнтованого програмування
[24, 70]. Проте всі перелічені об’єкти належать до стандартних типів, а
користувач на основі цих об’єктів, з використанням властивостей
інкапсуляції та наслідування, розглянутих у першому розділі, може
створювати власні класи та об’єкти, як екземпляри класів [70]. Надамо
відповідне визначення [70].
Визначення 4.1 Об’єкт, створений на основі деякого класу із
успадкуванням його властивостей, називається екземпляром цього класу.

310
Для доступу до екземплярів класу використовуються змінні, і такі
змінні зберігають посилання на екземпляр класу. Для доступу до атрибутів
або методів конкретного екземпляру класу використовується точка, яка
розділяє ім’я об’єкта або змінної та ім’я атрибута або метода.
Створюється клас з використанням ключового слова class [24, 70].
Наведемо приклад створення порожнього класу.
Приклад 4.1
class A:
pass
У разі збереження такого програмного коду до файлу та виконання
його через опцію меню Run у робочому вікні інтерпретатора з’являється
інформація про створений клас. Після створення класу з’являється
можливість створювати конкретні елементи цього типу, для чого
використовується наступна синтаксична конструкція.
Ім’я = Назва_Класу([параметри])
Наприклад, посилаючись на порожній клас, створений у прикладі 5.1,
можна створити об’єкти, які належать до цього класу, у цьому разі після
імені класу, як і після імені функції, ставляться подвійні круглі дужки.
>>> a = A()
>>> b = A()
Головне правило програмування на мові Python з використанням класів
полягає у тому, що визначення класу у тексті програми має стояти перед
першим посиланням на нього [24, 70].
Методи класу у мові програмування Python, як і звичайні функції,
описуються з використанням директиви def. Наведемо відповідний приклад
описання методу.
Приклад 4.2
class B():
def g(self):
return ‘Привіт, ’ + self.arg + ‘!’

311
У наступному прикладі створимо об’єкти класу B та звернемося до
його атрибутів та методів.
Приклад 4.3
>>> b1 = B()
>>> b2 = B()
>>> b1.arg = ‘cтудент Хоменко’
>>> b2.arg = ‘cтудентка Костюченко’
>>> b1.g()
Привіт, cтудент Хоменко!
>>> b2.g()
Привіт, cтудентка Костюченко!
Розглянемо приклад 4.3 більш досконало. По-перш за все, треба
звернути увагу на те, що метод об’єкту g() має обов’язковий аргумент
self, який являє собою посилання на екземпляр класу. Тобто, всім методам
класу це посилання має бути передано як параметр. Саме через цю змінну у
тілі метода здійснюється доступ до атрибутів та методів класу, у цьому разі
ім’я методу або атрибуту пишеться через точку, наприклад, self.arg. Із
наведеного коду також видно, що за межами класу доступ до його атрибутів
також здійснюється через точку, наприклад, b1.arg, b2.arg. Також слід
звернути увагу на те, що у разі виклику метода g() аргумент self не
вказується, на відміну від описання цього метода. Посилання на екземпляр
класу компілятор генерує автоматично, і команда b1.g() замінюється
командою g(b1).
Тіло класу являє собою послідовність команд, які виконуються один
раз на етапі визначення класу, а не кожний раз під час створення об’єктів як
екземплярів класу. Вище був розглянутий приклад створення класу в
інтерактивній оболонці IDLE, але зазвичай інструкції створеного класу
виконуються іншим чином, а саме – через імпорт модуля, в якому описаний
його код.
Також слід звернути увагу на те, що сама собою інструкція class не

312
створює ніякого об’єкту. Визначення класу, з цієї точки зору, можна
розглядати як певний шаблон.
Поки, напевно, не зовсім зрозуміло, навіщо ускладнювати код
програми, вводячи до неї об’єкти, якщо все можна зробити засобами
структурного програмування, описаними у другому та третьому розділах.
Для розуміння ефективності об’єктно-орієнтованого підходу розглянемо
наступний приклад [24].
Приклад 4.4 З використанням засобів програмування мови Python
виводити на екран інформацію про людину, зокрема, її ім’я, вік, сімейний
стан, наявність дітей та адресу проживання.
Якщо використовувати засоби структурного програмування, можна
записати наступний програмний код.
person_name = ‘Потапенко’
person_age = ‘18’
person_marriage = ‘не одружений’
person_child = ‘немає’
person_city = ‘м. Київ’
person_street = ‘вулиця Політехнічна’
person_home = ‘3’
person_flat = ‘57’
person_zip = ‘03056’
У разі такого описання даних функція для виведення інформації про
людину буде мати наступний вигляд.
def PrintPerson(name, marriage, child, city, \
street, home, flat, zip):
str_out = ‘Студент ’
if name != []:
str_out = str_out + name + ‘,’
if age != []:
str_out = str_out + age + ‘ років,’

313
if marriage != []:
str_out = str_out + marriage + ‘, діти – ’
if child != []:
str_out = str_out + child + ‘. Проживає \
за адресою: ’
if city != []:
str_out = str_out + city + ‘, ’
if street != []:
str_out = str_out + street + ‘, буд. ’
if home != []:
str_out = str_out + home
if flat != []:
str_out = str_out + ‘, кв.’ + flat + ‘, ’
if zip != []:
str_out = str_out + zip + ‘.’
print(str_out)
Зрозуміло, що результатом виклику цієї функції з заданими вище
параметрами
PrintPerson(person_name, person_age, \
person_marriage, person_child, person_city, \
person_street, person_home, person_flat, \
person_zip)
буде виведення на екран наступного рядка.
Студент Потапенко, 18 років, не одружений, діти –
немає. Проживає за адресою: м. Київ, вулиця
Політехнічна, буд. 3, кв. 57, 03056.
До сих пір нібито все просто. Тепер припустимо, що крім цієї
інформації необхідно ще додати назву академічної групи, в якій навчається
студент. Для цього слід послідовно виконати наступні дії.
1. До описання імен змінних та операторів присвоєння додати рядок:

314
person_group = ‘ДЕ - 72’
2. До параметрів виклику функції PrintPerson() додати змінну
group.
3. До коду функції PrintPerson() додати наступну послідовність
команд.
if group != []:
str_out = str_out + ‘ Навчається в групі ’\
+ group + ‘.’
print(str_out)
Тобто, у разі внесення незначних змін в інформаційне повідомлення,
яке необхідно виводити, програмний код структурної програми у значній мірі
ускладнюється. Для формування цього коду були використані операції з
рядковими змінними, які розглядалися у підрозділі 2.6.
Для того, щоб трішки полегшити удосконалення програмного коду,
можна використовувати списки, які розглядалися у підрозділі 3.6, але у
даному випадку створення класу є значно більш ефективним рішенням.
Створимо відповідний клас наступним чином.
class Pers():
name = ‘’
age = ‘’
marriage = ‘’
child = ‘’
city = ‘’
street = ‘’
home = ‘’
flat = ‘’
zip = ‘’
group = ‘’
Після цього легко заповнити всі поля класу, із посиланням на них після
імені класу через крапку. Це можна зробити наступним чином.

315
student = Pers
student.name = ‘Потапенко’
student.age = ‘18’
student.marriage = ‘не одружений’
student.child = ‘немає’
student.city = ‘Київ’
student.street = ‘Політехнічна’
student.home = ‘3’
student.flat = ‘57’
student.zip = ‘03056’
student.group = ‘ДЕ - 72’
У разі подання даних про студента через описання об’єкта student як
екземпляра класу Person механізм коду виклику наведеної вище функції
PrintPerson() трішки змінюється. Ця зміна полягає у тому, що між
іменем об’єкта та іменем відповідної його властивості замість знака
підкреслення ставиться крапка. Тоді команда виклику функції
PrintPerson() буде мати наступний вигляд.
PrintPerson(student.name, student.age, \
student.marriage, student.child, student.city, \
student.street, student.home, student.flat, \
student.zip, student.group)
Приклад 4.5 На основі прикладу 4.4 із копіюванням властивостей
об’єкту student створити інший об’єкт student_weekend, де вказати
сільську адресу студента, за якою він проживає в вихідні дні. Інформацію
про студента вивести з використанням функції PrintPerson(), написаної
для об’єктів класу Person.
Відповідний програмний код буде мати наступний вигляд.
>>> student_weekend = student
>>> student_weekend.city = 'с.м.т. Борова, \
Фастівський район'

316
>>> student_weekend.street = 'вулиця Українська'
>>> student_weekend.home = '10'
>>> student_weekend.flat = ''
>>> student_weekend.zip = '12003'

Тоді результат виклику функції PrintPerson() буде наступним.


>>> PrintPerson(student_weekend.name, \
student_weekend.age, student_weekend.marriage, \
student_weekend.child, student_weekend.city, \
student_weekend.street, student_weekend.home, \
student_weekend.flat, student_weekend.zip, \
student_weekend.group)
Студент Потапенко, 18 років, не одружений, діти -
немає. Проживає за адресою: с.м.т. Борова, Фастівський
район, вулиця Українська, буд. 10, 12003.
Навчається в групі ДЕ - 72.
>>>

Як бачимо, частина інформації про успадкований об’єкт залишилась


попередньою, оскільки відповідні властивості не були змінені. Наприклад, не
змінилося прізвище студента, його вік та група, в який він навчається. Проте
оскільки властивості об’єкту, які відносяться до місця проживання студента,
змінилися, виведений на екран рядок є дещо іншим.
Тобто, через успадкування властивостей об’єкта та внесення
відповідних змін можна легко змінити інформацію про цей об’єкт. Такий
спосіб обробки інформації часто використовується для роботи з сучасними
базами даних [12 – 14]. Наслідування властивостей об’єкта як екземпляра
відповідного класу здійснюється у мові програмування Python простим
копіюванням.
317
4.1.2 Приклад формування методів класу та посилань на них
через створені об’єкти
Єдиним недоліком розглянутого способу формування інформації про
студента є те, що функція PrintPerson() реалізована окремо від
створеного класу Pers та, відповідно, не є його методом. У розглянутих
прикладах 4.4 та 4.5 під єдиним класом Pers об’єднані лише змінні, які
використовуються для формування повідомлення. Іншим, більш ефективним
підходом, який був використаний для написання програмного коду,
наведеного у прикладах 4.2 та 4.3, є об’єднання властивостей та методів в
межах одного класу. Як видно із наведених вище прикладів, у такому
випадку посилання та метод відповідного об’єкту здійснюється через змінну
self.
Розглянемо це один схожий приклад, у якому створимо об’єкт класу
Dog.
Приклад 4.6 На основі прикладів 4.2 та 4.3 створити об’єкт класу
Dog – собака. Описати в цьому методі такі властивості собаки, як ім’я
(name), вік (age), колір (color) та вага (weight). Як метод реалізувати у
класі Dog функцію voice(), яка виводить на екран у вікно командного
рядка інформаційне повідомлення про те, як звуть собаку, який він має вік,
колір шерсті, вагу, та, головне, що він говорить.
Відповідний програмний код, згідно із шаблонами програм, наведених
у прикладах 4.2 та 4.3, запишемо наступним чином.
>>> class Dog ():
name = ‘’
age = 0
color = ‘’
weight = 0
def voice(self):
str_d = ‘Собака ’

318
str_d = str_d + self.name + ‘, ’
str_d = str_d + str(self.age) + \
‘років , ’
str_d = str_d + self.color + ‘, ’
str_d = str_d + str(self.weight) + \
‘килограмів, ’ + ‘, ’
str_d = str_d + ‘говорить Гав.’
Тепер, через посилання на визначений клас Dog створимо новий
об’єкт, у якому опишемо собаку з іменем «Шарік» та виведемо інформацію
про нього з використанням функції voice(self). Згідно із прикладами 4.3,
4.4 та 4.5, поставлене завдання можна виконати з використанням наступних
командних рядків.
>>> my_dog = Dog ()
>>> my_dog.name = ‘Шарік’
>>> my_dog.age = 6
>>> my_dog.color = ‘білий з чорними плямами’
>>> my_dog.weight = 13
>>> my_dog.voice()
Собака Шарік, 6 років, білий з чорними плямами,
13 килограмів, говорить Гав.
Із наведеного прикладу чітко видно, що змінна self визначає
посилання у класі Dog на створений об’єкт my_dog. Після цієї змінної в тілі
класу через крапку можна посилатися на будь-яку властивість створеного
об’єкту, що належить до цього класу. Саме такий спосіб посилання на
властивості створеного об’єкту використаний у функції voice(). Проте для
виклику методу my_dog.voice() змінна self не використовується,
звернення до цього методу здійснюється без параметрів із безпосереднім
посиланням на ім’я об’єкту my_dog. Інакше кажучи, у тілі класу Dog в
момент звернення до методу voice() через посилання my_dog.voice()
встановлюється тотожність self = my_dog. У разі посилання на цю
функцію через об’єкт з іншим іменем внутрішня змінна self завжди
приймає значення імені цього об’єкту.

319
4.1.3 Конструктори та визначення властивостей об’єктів
Приклади 4.2 – 4.6, у яких були створені та використані класи, хоча і є
правильними, але вони не зовсім коректні з точки зору загальної методології
об’єктно-орієнтованого програмування. Такі програми за певних умов
можуть видавати помилки інтерпретатора, що не має бути притаманним
надійним та функціональним програмним засобам.
Повернемося до прикладу 4.3 та розглянемо окремий випадок, коли
поля об’єкту не визначені перед викликом методу g(). Результат роботи
такого програмного коду буде наступним.
Приклад 4.7
>>> b1 = B()
>>> b2 = B()
>>> b1.g()
AttributeError: ‘B’ object has no attribute ‘arg’
Тобто, для цієї виключної ситуації інтерпретатор видає помилку,
сутність якої полягає у тому, що аргумент arg, на який іде посилання методі
g(), не був визначений перед викликом цієї функції.
Розглянемо інший приклад.
Приклад 4.8
>>> b1 = B()
>>> b2 = B()
>>> b1.arg = ‘студент Потапенко’
>>> b1.g()
Привіт, студент Потапенко
>>> b2.g()
AttributeError: ‘B’ object has no attribute ‘arg’
У даному випадку виклик методу b1.g() пройшов цілком коректно,
але, оскільки для екземпляра b2 класу B властивість arg не була визначена,
посилання не метод g() від цього об’єкта b2.g(), знову ж таки, приводить
до помилки інтерпретатора.

320
Зрозуміло, що за умови створення великої кількості об’єктів, як
екземплярів класу, ініціалізацію всіх необхідних полів програмісту вкрай
важко проконтролювати. Тому, з метою уникнення будь-якої можливості
виникнення таких помилкових ситуацій, у всіх сучасних мовах об’єктно-
орієнтованого програмування розроблений спеціальний метод
безпомилкового створення об’єкту, в якому відразу автоматично
ініціалізуються всі його необхідні властивості. У теорії ООП такий метод
називається конструктором. Надамо відповідне визначення [8 – 10, 15, 16].
Визначення 4.2 Метод створення об’єкту, як екземпляра класу, в
якому відразу, в процесі створення, задаються значення всіх необхідних його
полів, називається конструктором.
Конструктор є методом класу і описується першим із всіх методів. У
мові програмування Python конструктором є метод __init__().
Параметрами цього метода, крім системної змінної self, є всі поля класу,
які мають бути ініціалізовані як властивості об’єкту для подальшої коректної
роботи програмного коду.
Відповідна синтаксична конструкція функції __init__() має
наступний вигляд [70].
__init__(self, [name_1, name_2, ..., name_n])
де name_1, name_2, ..., name_n – імена полів створюваного
екземпляра класу, які необхідно ініціалізувати.
Зверніть особливу увагу на те, що у методі конструктора об’єкту
__init__() на початку та на кінці стоїть не один знак підкреслення, а два.
З використанням розглянутих у цьому підрозділі теоретичних
відомостей. перепишемо програмний код створення класу B, наведений у
прикладі 4.2, трішки інакше, створюючи цей клас через конструктор. Тоді
відповідні командні рядки будуть мати наступний вигляд.
Приклад 4.9
class B():
def __init__(self, name):

321
self.arg = name
def g(self):
return ‘Привіт, ’ + self.arg + ‘!’
>>> b1 = B(‘cтудент Хоменко’)
>>> b2 = B(‘cтудентка Костюченко’)
>>> b1.g()
Привіт, cтудент Хоменко!
>>> b2.g()
Привіт, cтудентка Костюченко!
Розглянемо, на основі прикладу 4.9, особливості створення об’єктів
через конструктор. У цьому прикладі конструктор має два параметри –
системну змінну self та параметр імені name. В тілі конструктора стоїть
лише один оператор присвоєння:
self.arg = name
Саме таким чином і визначена властивість створюваного об’єкту
self.arg, яка використовується для формування рядкової змінної у функції
g(self). Тепер об’єкт класу B може бути створений лише тоді, коли
параметром його створення є рядкова змінна, у противному випадку
інтерпретатор видає помилку про відсутність атрибута об’єкта. У прикладі
4.9 наведені відповідні командні рядки для створення об’єктів b1 та b2, вони
мають наступний вигляд:
>>> b1 = B(‘cтудент Хоменко’)
>>> b2 = B(‘cтудентка Костюченко’)
Слід також відзначити, що значення цих властивостей можуть бути
змінені в командному вікні інтерпретатора з використанням оператора
присвоєння. Розглянемо відповідний приклад.
Приклад 4.10
>>> b1.arg = ‘cтудент Потапенко’
>>> b1.g()
Привіт, cтудент Потапенко!

322
З використанням теоретичних відомостей про конструктор об’єктів,
наведений у цьому підрозділі перепишемо програмні коди для прикладів 4.4
та 4.6.
Приклад 4.11 Переписати програмний код для прикладу 4.4,
створюючи об’єкти класу Pers через конструктор. Показати спосіб
створення відповідних об’єктів. Крім цього, зробити функцію
PrintPerson(), використану у прикладах 4.4 та 4.5, методом класу Pers.
Код класу Pers, вводячи в нього конструктор класу та метод
PrintPerson(), можна переписати наступним чином.
class Pers():
def __init__(self, name, age, marriage, \
child, city, street, home, flat, zip, \
group):
self.arg1 = name
self.arg2 = age
self.arg3 = marriage
self.arg4 = child
self.arg5 = city
self.arg6 = street
self.arg7 = home
self.arg8 = flat
self.arg9 = zip
self.arg10 = group
def PrintPerson(self):
c = ‘, ’
str_out = ‘Студент ’ + self.arg1 + c + \
self.arg2 + ‘ років, ’ + self.arg3 + c +‘діти – ’\
+ self.arg4 + ‘. Проживає за адресою: м. ’
+ self.arg5 + c + self.arg6 + c + ‘буд. ’ \
+ self.arg7 + ‘, кв.’ + self.arg8 + c \

323
+ self.arg9 + ‘. ’ + ‘ Навчається в групі ’ \
+ self.arg10 + ‘.’
print(str_out)
У разі використання написаного вище програмного коду створити
об’єкт класу Pers та сформувати повідомлення через виклик функції
PrintPerson() можна наступним чином.
>>> from Pers_file import *
>>> student = Pers(‘Потапенко’, ‘18’, \
не одружений’, ‘немає’, ‘Київ’, ‘вулиця \
Політехнічна’, ‘3’, ‘57’, ‘03056’, ‘ДЕ-72’)
>>> student.PrintPerson()
Результат роботи цих командних рядків є аналогічним результату,
отриманому у прикладі 5.4.
Приклад 4.12 Переписати програмний код для прикладу 4.6,
створюючи об’єкти класу Dog через конструктор.
Код програми, наведеної у прикладі 4.6, можна переписати наступним
чином.
class Dog ():
def __init__(self, name, age, color, weight):
self.name = name
self.age = age
self.color = color
self.weight = weight
print('Народився новий собака, \
якого звуть ', self.name, ‘.’)
def voice(self):
c = ', '
str_d = 'Собака '
str_d = str_d + self.name + c
str_d = str_d + str(self.age) + \

324
' років' + c
str_d = str_d + self.color + c
str_d = str_d + str(self.weight) + \
' килограмів, ' + c
str_d = str_d + 'говорить Гав.'
print(str_d)
У разі використання наведеного у цьому прикладі програмного коду,
записаного до файлу Dog_File, створити новий об’єкт, який належить до
класу Dog, та отримати інформацію про нього, можна наступним чином.
>>> from Dog_File import *
>>> New_Dog = Dog(‘Шарік’, 6, \
‘білий з чорними плямами’, 13)
Народився новий собака, якого звуть Шарік.
>>> New_Dog.voice()
Собака Шарік, 6 років, білий з чорними плямами,
13 килограмів, говорить Гав.
Зрозуміло, що результат виконання метода New_Dog.voice()
аналогічний результату, отриманому у прикладі 4.6.
З наведених у цьому розділі прикладів зрозуміло, що конструктор
об’єктів повинен мати дві необхідні складові.
1. Всі властивості об’єкта необхідно передати до методу __init__()
як параметри. Розташовуються вони після параметру self, який відповідає
посиланню на ім’я об’єкта.
2. У тілі метода __init__() повинні стояти оператори присвоєння
для властивостей об’єкта із посиланням на змінну self, аналогічні
оператору self.name = name.
Пояснити такий спосіб визначення властивостей можна на наступному
прикладі. Якщо під час виклику конструктора атрибут об’єкта стоїть серед
параметрів виклику, але відповідній властивості не присвоєне значення, ця
властивість вважається не визначеною. Ми назвали її, але не поставили
відповідність між нею та вказаним значенням. Тому поки інтерпретатор не
325
знає, які з переданих значень відповідають тій чи іншій властивості.
Цю особливість легко зрозуміти через таку життєву ситуацію.
Припустимо, що Ви придбали собаку та вирішили назвати його «Шарік». Але
він не відразу стане відкликатися на це ім’я, собаці потрібно пояснити, що за
цим ім’ям Ви звертаєтесь саме до нього, а не до когось іншого. А коли вже
він звикне до цього імені, то буде відкликатися відразу. У випадку роботи з
об’єктами у мові Python оператор присвоєння self.name = name є саме
такою інструкцією, яка ставить відповідність між створеним об’єктом та його
властивістю.
Недолік програмних кодів, наведених у прикладах 4.7 – 4.12 полягає у
тому, що посилання на властивість здійснюється декларативно, через
звернення до відповідних полів. Такий підхід вважається не дуже зручним,
оскільки він пов’язаний із аналізом внутрішньої структури об’єктів, яку
розробники програмного забезпечення зазвичай намагаються приховувати.
Тому в мові програмування Python розроблений інший підхід, пов’язаний із
визначенням та зміною властивостей об’єктів через виклик відповідних
функцій [24]. У цьому разі таких функцій має бути дві: функція читання
властивостей get() та функція зміни властивостей set(). Ці функції
посилаються на відповідну властивість об’єкта через системну змінну self
та зазвичай мають дуже простий код. Функція
об’єкт.set_властивість(параметр)
встановлює властивість об’єкта з використанням відповідного оператора
присвоєння
self.властивість = параметр.
Функція c = об’єкт.get_властивість()
лише повертає визначену властивість об’єкта, тому вона має дуже простий
код із одного рядка:
return self.властивість
У наступному прикладі розглянемо функції get_Name() та
set_Name() для об’єкта Dog, створеного у прикладі 4.12.
Приклад 4.13 Написати функції get_Name() та set_Name() для
об’єкта Dog, створеного у прикладі 4.12, та використати ці функції для
326
формування повідомлення про собаку.
class Dog ():
def __init__(self, name, age, color, weight):
self.name = name
self.age = age
self.color = color
self.weight = weight
print('Народився новий собака, \
якого звуть ', self.name, ‘.’)
def set_Name(self, New_name):
self.name = New_name
def get_Name(self):
return self.name
def voice(self):
c = ', '
str_d = 'Собака '
str_d = str_d + self.get_Name() + c
str_d = str_d + str(self.age) + \
' років' + c
str_d = str_d + self.color + c
str_d = str_d + str(self.weight) + \
' килограмів, ' + c
str_d = str_d + 'говорить Гав.'
print(str_d)
>>> from Dog_File import *
>>> New_Dog = Dog(‘Шарік’, 6, \
‘білий з чорними плямами’, 13)
Народився новий собака, якого звуть Шарік.
>>> New_Dog.set_Name(‘Тузік’)
>>> New_Dog.voice()

327
Собака Тузік, 6 років, білий з чорними плямами,
13 килограмів, говорить Гав.
Аналогічно можна створити функції get()та set() для читання та
зміни інших властивостей об’єктів.
Часто методи get()та set() використовуються для формування
об’єктів віконного інтерфейсу. Відповідні способи роботи з властивостями
таких об’єктів розглядатимуться у підрозділі 5.3.
Якщо об’єкт був створений з використанням конструктора, для його
видалення із пам’яті комп’ютера може бути використаний деструктор, який
реалізований через метод __del__(). Цей метод не може бути
використаний, доки на відповідний екземпляр класу існує хоча б одне
посилання. Проте слід відзначити, що, на відміну від інших мов
програмування з реалізованою парадигмою ООП [8 – 10, 15, 16], у мові
Python деструктори використовуються не часто [70].
Наприкінці цього підрозділу розглянемо програмний код ще одного
класу Person, який призначений для збереження інформації про людей [70].
У деякій мірі код цієї програми нагадує код програми, наведеної у
прикладі 4.11.
Приклад 4.14 Створити клас Person, призначений для збереження
інформації про людей, полями якого є ім’я, місто, де людина проживає, та
дата її народження.
class Person():
def __init__(self, name, city, date):
self.name = name
self.city = city
self.date = date
def print(self):
print(‘Name: ’, self.name, ‘; Adress:’, \
self.city, ‘; Birthday:’, date)
Наведемо приклад використання створеного класу Person.
>>> Pers1 = Person(‘Vasyl’, ‘Kyiv’, ‘21-12-1995’)

328
>>> Pers2 = Person(‘Petro’, ‘Lviv’, ‘18-06-1996’)
>>> Pers3 = Person(‘Sergiy’, ‘Kharkiv’, \
‘23-09-1995’)
>>> Pers1.print()
Name: Vasyl; Adress: Kyiv; Birthday: 21-12-1995
>>> Pers2.print()
Name: Petro; Adress: Lviv; Birthday: 18-06-1996
>>> Pers3.print()
Name: Sergiy; Adress: Kharkiv; Birthday: 23-09-1995
Розглянемо тепер, як у мові програмування Python реалізовані
механізми інкапсуляції та захисту приватних властивостей класів. Базові
поняття цих концепцій об’єктно-орієнтованого програмування були надані у
першому розділі посібника.

4.1.4 Інкапсуляція та приватні методи класу


Загальне поняття про інкапсуляцію було наведене у першому розсліді,
визначення 1.8. У мові програмування Python механізм інкапсуляції дозволяє
не лише об’єднувати поля та методи в рамках одного класу з використанням
засобів програмування, розглянутих у попередньому підрозділі, але й
обмежувати доступ до атрибутів та методів, які належать до відповідного
класу. Фактично, інкапсуляція надає можливість зробити так, щоб захищені
атрибути або методи були доступними лише в межах класу, де вони
визначені [24, 70].
Для визначення приватних методів класу у мові програмування Python
використовується символ підкреслення. Якщо ім’я атрибуту або методу
починається з символу підкреслення, це вже є ознакою того, що цей метод
рекомендується використовувати лише для роботи з об’єктами даного класу
[70]. Але, у будь-якому разі, такий метод може бути застосовано для об’єктів
даного класу. Наведемо відповідний приклад [70].
Приклад 4.15
class A:
def _private(self):

329
print(‘У разі використання підкреслення \
викликати метод не рекомендується.’)
>>> a = A()
>>> _private()
AttributeError: can’t set attribute
>>> a._private()
У разі використання підкреслення
викликати метод не рекомендується.
Використання на початку імені метода подвійного підкреслення надає
можливість цілком заборонити використання цього метода за межами класу,
такий метод можна викликати лише із посиланням на клас. Синтаксична
конструкція відповідної команди має наступний вигляд [70].
[ім’я об’єкту]._[ім’я класу]__[ім’я методу]
Розглянемо відповідний приклад.
Приклад 4.16
class В:
def __private(self):
print(‘Це захищений метод для класу В.’)
>>> b = B()
>>> b.__private()
MethodError: can’t use private method without
reference to class
>>> b._B__private()
Це захищений метод для класу В.
В цілому головна концепція мови програмування Python полягає у
тому, що за замовченням всі атрибути та методи класу є відкритими, або
публічними [24]. Тобто, наявність власних методів для читання та зміни
властивостей, як у прикладі 4.13, не захищає від доступу до атрибутів, а
використання знаку підкреслення, як у прикладах 4.15 та 4.16, надає
відповідний захист, але лише згідно із особливостями синтаксису мови
програмування Python, які є загальновідомими. Тому частіше для закриття
атрибутів об’єктів використовують метод property() [24]. Розглянемо

330
відповідні приклади.
Приклад 4.17
class Hidden_Dog ():
def __init__(self, input_name):
self.hidden_name = input_name
def set_name(self, input_name):
self.hidden_name = input_name
print(‘Функція встановлює нове ім’я об’єкту \
всередені класу Hidden_Dog. Нове ім’я ’, \
self.hidden_name, ‘.’)
def get_name(self):
print(‘Функція зчитує ім’я об’єкта \
всередені класу Hidden_Dog. Поточне ім’я ’, \
self.hidden_name, ‘.’)
return self.hidden_name
name = property(get_Name, set_name)
Розглянутий приклад майже нічим не відрізняється від прикладу 4.13,
але останній рядок name = property(get_Name, set_name) вказує
на методи читання get_name() та зміни set_name() для об’єктів класу
Hidden_Dog.
Результати роботи програмного коду, наведеного у прикладі 4.17,
зрозумілі з наступних командних рядків.
>>> f = Hidden_Dog (‘Тузік’)
>>> print (f.name)
# Згідно з інструкцією
# name = property(get_name, set_name)
# звернення до поля f.name автоматично
# приводить до виклику метода get_name()
print (f. get_name())
Функція зчитує ім’я об’єкта всередині
класу Hidden_Dog. Поточне ім’я Тузік.
331
>>> f.name = ‘Шарік’
# Згідно з інструкцією
# name = property(get_name, set_name)
# присвоєння значення полю f.name автоматично
# приводить до виклику метода set_name()
set_name(‘Шарік’)
Функція встановлює нове ім’я об’єкту
всередині класу Hidden_Dog. Нове ім’я Шарік.
У мові програмування Python існує зв’язок між властивостями об’єкта,
які обчислюються, та захищеними полями. Якщо у програмі передбачена
автоматична зміна властивості через проведення обчислень і ця властивість є
захищеною, її неможна змінити вручну. Це наочно видно з наступного
прикладу, де діаметр кола обчислюється як подвійне значення його радіусу
та є захищеною властивістю цього об’єкта. Для описання захищених
властивостей об’єкта, які обчислюються, перед ключовим словом property
ставиться знак амперсанду @ [24, 25]. Розглянемо відповідний приклад.
Приклад 4.18
class Circle():
def __init__(self, radius):
self.radius = radius
@property
def diameter(self)
return 2*self.radius
Результат роботи програмного коду, наведеного у прикладі 4.18,
зрозумілий із наступної послідовності команд та результатів їхнього
виконання.
>>> c = Circle(5)
>>> print(c.radius)
5
>>> print(c.diameter)
10
>>> c.radius = 7

332
>>> print(c.diameter)
14
>>> c.diameter = 20
AttributeError: can’t set attribute
Взагалі синтаксична конструкція команди property має наступний
вигляд [70].
ім’я_влістивості = property(ім’я_методу_для_читання,\
ім’я_методу_для_запису, \
ім’я_методу_для_видалення, \
ім’я_методу_для_створення_документа)
У перших трьох аргументах методу property() вказуються
відповідні посилання на методи класу для читання, запису властивості, та для
видалення класу у разі відсутності посилань на нього через імена об’єктів.
Якщо як будь-який з цих аргументів вказане значення None, це означає, що
відповідний метод для цієї властивості не підтримується.
Розглянемо приклад використання властивості property() у
наведеному вище форматі [70].
Приклад 4.19
class test():
def __init__(self, val):
self.__arg = val
def getvalue(self):
return self.__arg
def setvalue(self, val):
if val > 0:
self.__arg = val
else:
self.__arg = 0
def delvalue(self):
del self.__arg
print(‘Атрібут видалений’)
v = property(getvalue, setvalue, delvalue)

333
Результати роботи програмного коду, наведеного у прикладі 4.19,
можна зрозуміти з наступних командних рядків [70].
>>> tval = test(123)
>>> tval.v = 456
>>> print(tval.v)
456
>>> tval.v = –25
0
>>> delvalue(v)
‘Атрибут видалений’
У наступному підрозділі розглянемо реалізацію механізму
наслідування класів у мові програмування Python.

4.1.5 Успадкування класів у мові програмування Python та


формування списків із об’єктів визначеного класу
Перед вивченням цього підрозділу необхідно повторити підрозділ 3.6.1
Загальне поняття про успадкування властивостей об’єктів було надане
у першому розділі, визначення 1.9. Слід відзначити, що саме успадкування є
одним із базових принципів об’єктно-орієнтованого програмування, оскільки
воно у найбільшій мірі пов’язане із способом мислення людини та із
загальними принципами організації її пам’яті [24]. Люди найчастіше
розпізнають об’єкти за їхніми унікальними особливостями. Наприклад, якщо
запитати пересічену людину «Чи вміє канарейка співати?», вона зазвичай
відповість на це питання швидко та безпомилково, а якщо її запитати «Чи
вміє канарейка дихати?» – вона замислиться і не зможе зразу відповісти. Це
аналітичне дослідження є результатом соціологічного опитування багатьох
тисяч людей і з точки зору соціальної статистики його можна вважати
правильним [24]. Цей результат безпосередньо пов’язаний з тим, що вміння
гарно співати є унікальною властивістю канарейки, яка притаманна лише їй.
Способи створення ієрархічних діаграм щодо успадкування властивостей
об’єктів розглядалися у підрозділі 1.2 та у практичному занятті 1 розділу 8.
Розглянемо тепер, як реалізуються механізми успадкування

334
властивостей об’єктів, розглянуті в підрозділі 1.2, у мові програмування
Python.
У цій мові існує комплекс правил, за якими створюються похідні, або
дочірні класи. Ці класи успадковують всі властивості та методи
батьківського класу, а у багатьох випадках містять свої, власні атрибути та
методи. Крім цього, у дочірньому класі частина методів та властивостей
батьківського класу можуть бути замінені [70].
В цілому механізм успадкування класів у мові програмування Python
реалізований досить просто. Під час створення нового, дочірнього класу,
батьківський клас необхідно вказати як параметр. В результаті цього всі
атрибути та методи батьківського класу будуть запозичені до дочірнього
класу.
Розглянемо простий приклад успадкування класів, який базується на
описаному вище механізмі.
Приклад 4.20
class base():
def f1(self):
print(‘Метод f1() належить до класу base.’)
def f2(self):
print(‘Метод f2() належить до класу base.’)
class derive(base):
def f3(self):
print(‘Метод f3() належить до класу derive.’)
Проаналізуємо результати роботи програмного коду, наведеного у
прикладі 4.20, з використанням наступних командних рядків [70].
>>> d = derive()
>>> d.f1()
Метод f1() належить до класу base.
>>> d.f2()
Метод f2() належить до класу base.
>>> d.f3()
Метод f3() належить до класу derive.

335
Особливістю програмного коду. наведеного у прикладі 4.20, є те, що
для дочірнього класу derive батьківський клас base вказаний у круглих
дужках. Дочірній клас наслідує методи батьківського класу f1() та f2(), а
також має власний метод f3(), що відображено у відповідних
інформаційних повідомленнях.
Згідно із синтаксисом мови програмування Python у загальному випадку у
визначені дочірнього класу можна вказувати декілька батьківських класів. Така
парадигма успадкування називається множинним успадкуванням [70]. Тобто, у
загальному випадку синтаксична конструкція мови програмування Python для
формування дочірнього класу має наступний вигляд.
class ім’я_дочірнього_класу(ім’я_батьківського_класу_1,
ім’я_батьківського_класу_2, ... ,
ім’я_батьківського_класу_n):
За правилами мови програмування Python ієрархія успадкування передбачає
можливість співпадання імен властивостей та методів у батьківському та
дочірньому класі. У цьому випадку за замовченням викликається метод
дочірнього класу. У теорії програмування такі методи називаються
перевантаженими [24, 70]. Якщо у випадку перевантаженого методу необхідно
викликати метод із базового класу, у мові програмування Python це можна зробити
двома способами [70]. Перший з них полягає у тому, що перед іменем метода
вказується ім’я базового класу, а в аргументі, який стоїть перед крапкою,
вказується посилання на об’єкт, який є екземпляром батьківського класу. Другий
спосіб, який можна використовувати для посилання на перевантажений об’єкт
батьківського класу – це застосування системної функції super(). Синтаксична
конструкція для виклику цієї функції має наступний вигляд [70].
super([ім’я_батьківського_класу,
посилання на змінну self])
Для наочної ілюстрації описаних вище способів викликів
перевантажених функцій перепишемо програмний код, наведений у прикладі
4.20, наступним чином.
Приклад 4.21
class base():

336
def f1(self):
print(‘Метод f1() належить до класу base.’)
def f2(self):
print(‘Метод f2() належить до класу base.’)
def f3(self):
print(‘Метод f3() належить до класу base.’)
class derive(base):
def f3(self):
print(‘Метод f3() належить до класу derive.’)
super().f3()
def f4(self):
print(‘Метод f4() належить до класу derive.’)
base.f3(self)
super(derive, self).f3()
Описані вище методи виклику перевантажених функцій для
програмного коду, наведеного у прикладі 4.21, можна проаналізувати з
використанням наступних командних рядків.
>>> d = derive()
>>> d.f1()
Метод f1() належить до класу base.
>>> d.f2()
Метод f2() належить до класу base.
>>> d.f3()
Метод f3() належить до класу derive.
Метод f3() належить до класу base.
>>> d.f4()
Метод f4() належить до класу derive.
Метод f3() належить до класу base.
Метод f3() належить до класу base.
Зверніть особливу увагу на різні способи виклику метода базового
класу f3() у прикладі 4.21. У випадку виклику цього метода із метода f3()
класу derive використовується системна функція super() без параметрів.

337
Із метода f4() класу derive метод f3() базового класу base
викликається двічі: через безпосереднє посилання на клас base та через
виклик методу super() із заданими параметрами. Із наведеного прикладу
видно, що системна змінна може використовуватись у разі виклику функції
super(), достатньо посилання на перевантажений метод у вигляді
super().f3(). Але у разі, коли використовується виклик функції super() з
параметрами, першим параметром є на батьківський, а дочірній клас
derive, а другим – системна змінна self. У разі такого виклику пошук
перевантаженого методу здійснюється інтерпретатором у всіх базових класах
за ієрархією успадкування, доки такий метод не буде знайдений [70]. У разі
безпосереднього посилання на клас base метод цього класу f3()
викликається із параметром self, тобто, синтаксична конструкція цієї
команди має вигляд base.f3(self).
Розглянемо приклад формування списків студентів через створення
відповідної ієрархії класів [70].
Приклад 4.22 На основі батьківського класу Person, створеного у
прикладі 4.14, створити дочірній клас Student. Для введення імені
студента, міста, де він навчається та дати його народження використати поля
батьківського класу Person, а у дочірньому класі Student створити
додаткові поля, в яких необхідно записувати університет, факультет та групу,
де навчається студент. Для виведення інформації про студентів створити
метод __str__(), у якому записувати поля класу Student у такому
порядку.
1. Прізвище, поле name.
2. Дата народження, поле date.
3. Університет, поле univ.
4. Місто, поле city.
5. Факультет, поле dept.
6. Група, поле group.
Відповідний програмний код буде мати наступний вигляд.
class Student (Person):

338
def __init__(self, name, city, date, univ, \
dept, group):
super().__init__(name, sity, date)
self.univ = univ
self.dept = dept
self.group = group
def __str__(self):
c = ‘, ’
strng = self.name + c + self.date + c + \
self.univ + c + self.city + c + \
self.dept + c + self.group + ‘.’
return strng
Розглянемо приклад створення об’єкта класу студент та виведення
інформації про нього.
>>> Std1 = Student(‘Потепенко’, ‘Київ’, ‘13.01.2000’, \
‘КПІ ім. І.Сікорського’, ‘ФЕЛ’, ‘ДЕ – 72’)
>>> print(str(Std1))
Потепенко, 13.01.2000, КПІ ім. І.Сікорського,
Київ, ФЕЛ, ДЕ – 72.
У коді програми, наведеної у прикладі 4.22, зверніть особливу увагу на
те, що конструктор об’єкту Person викликається із дочірнього об’єкту
Student примусово з використанням методу super(). Відповідна
синтаксична конструкція має наступний вигляд [70].
super().__init__(поля_батьківського_об’єкту)
Такий спосіб ініціалізації полів батьківського класу у дочірньому є
завжди необхідним, оскільки у мові програмування Python конструктор
батьківського класу у разі створення об’єкту дочірнього класу автоматично
не запускається [70].
У прикладі 4.22 була введена та отримана інформація на одного
студента, і така програма у наданому вигляді не може безпосередньо бути
використана для формування списку студентів, зокрема студентів із різних
університетів України. Для виконання цього завдання необхідно сформувати

339
список із об’єктів визначеного класу, та використати для обробки цього
списку оператор циклу із заданою кількістю повторень. Відповідні
теоретичні відомості про списки та про оператор for були наведені у
підрозділі 3.6.1. Розглянемо наступний приклад, у якому список студентів
формується з використанням функції append(), а виведення інформації про
них здійснюється з використанням оператору циклу for [70].
Приклад 4.23
>>> from studfile import *
>>> Std1 = Student(‘Потепенко’, ‘Київ’, \
‘13.01.2000’, ‘КПІ ім. І.Сікорського’, ‘ФЕЛ’, \
‘ДЕ – 72’)
>>> Std2 = Student(‘Починок’, ‘Харків’, ‘13.01.1998’, \
‘ХДУ ім. В.Каразіна’, ‘ФІТ’, ‘IT – 51’)
>>> Std3 = Student(‘Ярош’, ‘Львів’, ‘24.04.1999’, \
‘Львівська політехніка’, ‘ІКТ та ІТ’, ‘АС – 42’)
>>> Std4 = Student(‘Петренко’, ‘Суми’, ‘28.05.1999’, \
‘СДУ’, ‘ФЕ та ІТ’, ‘ПІ - 41’)
>>> Std5 = Student(‘Хоменко’, ‘Київ’, ‘14.08.1996’, \
‘КПІ ім. І.Сікорського’, ‘ФЕЛ’, ‘ДЕ – 71’)
>>> Std5 = Student(‘Чередніченко’, ‘Київ’, \
‘13.08.2000’, ‘КПІ ім. І.Сікорського’, ‘ММФ’, \
‘ММ – 71’)
>>> Stud_List = []
>>> Stud_List.append(Std1)
>>> Stud_List.append(Std2)
>>> Stud_List.append(Std3)
>>> Stud_List.append(Std4)
>>> Stud_List.append(Std5)
>>> for stud in Stud_List:
print(str(stud))
Потепенко, 13.01.2000, КПІ ім. І.Сікорського,
Київ, ФЕЛ, ДЕ – 72.
340
Починок, 13.01.1998, ХДУ ім. В.Каразіна, Харків, ФІТ,
IT – 51.
Ярош, 24.04.1999, Львівська політехніка, Львів,
ІКТ та ІТ, АС – 42.
Петренко, 28.05.1999, СДУ, Суми, ФЕ та ІТ, ПІ – 41
Хоменко, 14.08.1996, КПІ ім. І.Сікорського,
Київ, ФЕЛ, ДЕ – 71.
Чередніченко, 13.08.2000, КПІ ім. І.Сікорського,
ММФ, ММ – 71
Недоліком сформованого списку є те, що в ньому міститься інформація
про всіх введених студентів і серед неї важко знайти студентів, які
навчаються на відповідному факультеті відповідного університету. Таке
завдання також легко розв’язати. Для цього необхідно поставити фільтр з
використанням умовного оператора і виводити інформацію про студента
лише у тому випадку, коли значення полів univ та dept співпадають
співпадають із наперед заданими. Аналогічно можна вивести список
студентів заданої групи, або студентів, які навчаються в Києві.
Розглянемо відповідний приклад, для виконання якого візьмемо список
студентів, сформований у прикладі 4.23.
Приклад 4.24 На основі списку студентів, який був сформований у
прикладі 4.23, сформувати список студентів, які навчаються в Національному
технічному університеті України «КПІ імені Ігоря Сікорського» на
факультеті електроніки (ФЕЛ).
Відповідний цикл for для формування списку згідно із поставленим
завданням, можна записати наступним чином.
>>> for stud in Stud_List:
if ((stud.univ == ‘КПІ ім. І.Сікорського’ ) and \
(stud.dept == ‘ФЕЛ’)):
print(str(stud))
Результат роботи цього програмного коду буде наступним.
Потепенко, 13.01.2000, КПІ ім. І.Сікорського,
Київ, ФЕЛ, ДЕ – 72.

341
Хоменко, 14.08.1996, КПІ ім. І.Сікорського,
Київ, ФЕЛ, ДЕ – 71.
У прикладах 4.22 – 4.24 показані можливості використання класів для
обробки та систематизації великої кількості інформації з використанням
списків як впорядкованих структур даних. Такий підхід є вкрай ефективним
для роботи з реляційними базами даних, зокрема для створення
впорядкованих списків та звітів [12, 14]. У наступному підрозділі буде
показана можливість використання об’єктно-орієнтованого підходу для
визначення типу металів за їхніми електрофізичними властивостями. Спосіб
створення такої програми з використанням засобів структурного
програмування був розглянутий у підрозділі 3.5, приклад 3.19, проте
використання класів та об’єктів для розв’язування цього практичного
завдання прикладної електроніки має певні особливості.

4.1.6 Написання програми для визначення типу матеріалу за його


електропровідністю з використанням методів об’єктно-
орієнтованого програмування
Перед вивченням цього підрозділу необхідно повторити підрозділ 3.5
У прикладі 3.19 визначення типу металевих матеріалів проводилось за
значенням їхньої питомої електропровідності. Граничні значення цього
електрофізичного параметру металів були наведені у таблиці 3.2. Проте у
прикладі 3.19 аналіз відповідності заданого значення електропровідності
будь-якому з металів проводився з використанням великої кількості умовних
операторів. У разі проведення аналізу для невеликої кількості наперед
визначених металів такий підхід є можливим та, навіть, у деякій мірі
виправданим, проте, у будь-якому випадку, велика кількість умовних
операторів вкрай ускладнює аналіз та розуміння написаного програмного
коду.
Значно ефективніше для написання програм такого типу
використовувати об’єктно-орієнтований підхід. У цьому випадку необхідно
342
сформувати клас металів та як властивості цього класу розглянути
максимальне та мінімальне значення електропровідності. У такий спосіб
знання про властивості металів у значній мірі систематизуються. Тоді можна
кожен із металів описати як окремий об’єкт цього класу та сформувати з них
список, аналогічний списку студентів, який був сформований у прикладі
4.23. За умови заданого значення електропровідності пошук металу, який
відповідає цьому значенню, може бути здійснений з використанням умовного
оператора як фільтра числових даних. Такий спосіб застосування умовного
оператора був розглянутий у прикладі 4.24.
Розглянемо приклад написання такої програми.
Приклад 4.25 Написати програму для визначення типу металу за його
питомим електричним опором з використанням об’єктно-орієнтованого
підходу.
Згідно з вищесказаним, окремі завдання для написання програми
визначення типу металу за його електрофізичними властивостями з
використанням методів об’єктно-орієнтованого програмування, можна
сформулювати наступним чином.
1. Створити клас з іменем Metals. Цей клас повинне мати наступні
три поля:
– текстове поле, де визначається назва металу;
– числове поле, де визначається мінімальне значення
питомого електричного опору;
– числове поле, де визначається максимальне значення питомого
електричного опору.
2. Створити об’єкти класу Metals, властивості яких визначити згідно
з числовими значеннями, які наведені у таблиці 3.2
3. На основі створених об’єктів класу Metals сформувати список
List_Metals.

343
4. Створити метод Find_Metal(R) класу Metals. У цьому методі,
через аналіз переданого значення питомого електричного опору R, визначати
тип металу.
5. У створеному методі Find_Metal(R) аналіз відповідності значення
питомої питомого електричного опору R граничним значенням цього
параметру для кожного з мітелів, які розглядаються, проводити через перегляд
елементів списку List_Metals з використанням оператору циклу for.
Відповідний програмний код можна записати наступним чином.
class Metals:
def __init__(self, metal, min_res, max_res):
self.metal = metal
self.min_res = min_res
self.max_res = max_res
def Find_Metal(self, R):
List_Metals = []
Wolf = Metals(‘Вольфрам’, 5.4e-8, 5.6e-8)
Pure_Iron = Metals(‘Чисте залізо’, 9.9e-8, \
1.15e-7)
Stal = Metals(‘Сталь’, 1.3e-7, 1.5e-7)
Tin = Metals(‘Олово’, 1.18e-7, 1.25e-7)
Const = Metals(‘Константан’, 4.8e-7, 5.2e-7)
Cast_Iron = Metals(‘Чавун’, 9.9e-7, 1.1e-6)
Silver = Metals(‘Срібло’, 1.58e-7, 1.62e-8)
Copper = Metals(‘Мідь’, 1.7e-8, 1.75e-8)
Aluminium = Metals(‘Алюміній’, 2.6e-8, 2.8e-8)
Zinc = Metals(‘Цинк’, 4.9e-8, 5.2e-8)
Lead = Metals(‘Свинець’, 1.9e-7, 2.1e-7)
Carbon = Metals(‘Графіт’, 7.9e-6, 8.1e-6)
List_Metals.append(Wolf)

344
List_Metals.append(Pure_Iron)
List_Metals.append(Stal)
List_Metals.append(Tin)
List_Metals.append(Const)
List_Metals.append(Cast_Iron)
List_Metals.append(Silver)
List_Metals.append(Copper)
List_Metals.append(Aluminium)
List_Metals.append(Zinc)
List_Metals.append(Lead)
List_Metals.append(Carbon)
ii = 0
for Met in List_Metals:
if (Met.max_res >= R >= Met.min_res):
print(‘Метал: ’, Met.metal)
ii = 1
if (ii == 0):
print(‘Введене неправильне значен\
ня питомого електричного опору. Пе\
рвірте вхідні дані.’)
>>> from Define_Metals import *
>>> Metals.Find_Metal('',5.5e-8)
Метал: Вольфрам
>>> Metals.Find_Metal('',5e-8)
Метал: Цинк
>>> Metals.Find_Metal('',5e-5)
Введене неправильне значення питомого електричного
опору. Первірте вхідні дані.
>>>

345
Проведемо порівняльний аналіз програм, наведених у прикладах 3.19
та 4.25. За функціональним призначенням це однакові програми, але суттєва
перевага програми, наведеної у прикладі 4.25, полягає у тому, що вона
містить лише один умовний оператор, розташований у тілі циклу, де
аналізуються елементи списку. Написання програми з об’єктами
спрощується також за рахунок того, що можна легко додавати інші об’єкти
як екземпляри класу Metals. Для того, щоб додати до списку один метал,
достатньо ввести до коду програми два додаткових рядки.
New_Metal = Metals(‘Назва металу’, мінімальне значення \
питомого опору, максимальне значення питомого опору)
......................................................
List_Metals.append(New_Metal)
Зрозуміло, що такий алгоритм пошуку металу можна реалізувати через
створення списку без використання об’єктів, проте об’єктно-орієнтований
підхід дозволяє досягти більшої систематизації числових та текстових даних,
особливо у разі необхідності введення великої кількості інформації для
кожного об’єкту заданого класу. Тобто, цілком зрозуміло, що для створення
складних програмних комплексів саме об’єктно-орієнтований підхід є
найбільш ефективним.
Блок-схема алгоритму роботи програми, наведеної у прикладі 4.25,
представлена на рис. 4.1.
Підводячи підсумки, можна сказати, що використання об’єктно-
орієнтованого підходу значно спрощує створення складних програмних
комплексів із розширеними функціональними можливостями та із великою
кількістю об’єктів, які розглядаються. Це спрощення досягається за рахунок
строгої систематизації властивостей об’єктів та методів роботи з ними. У
наступному підрозділі буде наведений узагальнений перелік правил об’єктно-
орієнтованого програмування мови Python, які були розглянуті вище [70].

346
5
Початок

Введення значення питомої 6 n = 0


1 електропровідності R

7 ii = 0
Створення класу Metals з 12
2 полями metal, min_res та
max_res
8 Met = List_Metals(n)

Описання властивостей металів як


екземплярів класу Metals у 9
3 форматі: Met.max_res >= R Ні
12
New_Metasl = Metals(metal, >= Met.min_res
min_res, max_res)

Створення структури 10 ii = 1
4 List_Metals як
порожнього списку
Виведення повідомлення:
11 Метал: Met.metal
Додавання екземплярів класу
5 Metals до списку List_Metals
з використанням функції append()
Кінець

9 13
6

12 n = n + 1 Виведення повідомлення:
Неправильне
14
значення питомого
опору
13
(ii == 0) and (n > Ні
8
len(List_Metals)) Кінець

14

Рис. 4.1 Блок-схема алгоритму роботи програми визначення типу металу за


його питомою електропровідністю, наведеної к прикладі 4.25

347
4.1.7 Загальний перелік правил об’єктно-орієнтованого
програмування мови Python
У цьому підрозділі перелічимо окремо головні правила об’єктно-
орієнтованого програмування мови Python, які були розглянуті у попередніх
підрозділах.
Правило 4.1 Визначення класу у комп’ютерних програмах, написаних
з використанням методів об’єктно-орієнтованого програмування, є
обов’язковим. Для виконання цієї операції використовується ключове слово
class.
Правило 4.2 Доступ до атрибутів та методів класу виконується з
використанням оператору «.» (крапка).
Правило 4.3 Доступом до атрибутів та методів класу можна керувати
з використанням символу «_» (підкреслення). Методи та атрибути без
підкреслення є відкритими, з одним підкресленням – такі, які не
рекомендується використовувати за межами класу, а із двома
підкресленнями – закритими.
Правило 4.4 Повноцінний контроль за використанням атрибутів
класу здійснюється через застосування системної функції property, яка
безпосередньо призначена для створення захищених методів класу.
Правило 4.5 Спеціальний метод класу, який дозволяє автоматично
створювати екземпляри класу, або об’єкти, називається конструктором.
Правило 4.6 Конструктор класу завжди має принаймні один параметр
self, який являє собою посилання на відповідний екземпляр класу.
Правило 4.7 Деструктором називається спеціальний метод, який
автоматично викликається у разі знищення всіх екземплярів класу.
Правило 4.8 Методи класу можуть бути визначені або в тілі класу,
або за його межами.
Правило 4.9 Кожен метод класу має принаймні один параметр self,
що являє собою посилання на відповідний екземпляр класу, через який цей
метод викликається.
Правило 4.10 Якщо атрибут визначений всередині класу за межами

348
його методів, він вважається атрибутом класу та визначається лише один раз,
незалежно від кількості екземплярів класу.
Правило 4.11 До атрибуту класу можна звертатися через ім’я класу та
операції «.» (крапка) без посилання на екземпляр класу.
Правило 4.12 Для класів можна створювати методи із стандартними
іменами, як-то __del__, __call__, __cmp__, __str__, __get__,
__set__ та інші. Виклик таких методів здійснюється через відповідний
клас.
Деякі інші базові перевантажені методи класів, призначені для роботи з
числовими даними, розглядатимуться у підрозділі 4.4.3.
Правило 4.13 Для класів можна визначати перевантажені операції. Це
дозволяє використовувати екземпляри класу для здійснення відповідних
математичних, рядкових, системних та інших операцій. Для перевантаження
операції у класі необхідно створити метод із відповідною назвою.
Правило 4.14 Ієрархія успадкування класів дозволяє створювати
похідні класи. У такому випадку базовий клас зазвичай називається
батьківським, а похідний – дочірнім. Створення дочірнього класу
реалізується через посилання на батьківський, який у цьому випадку
записується у круглих дужках.
Правило 4.15 У мові програмування Python припускається
можливість множинного успадкування від кількох класів.
Правило 4.16 Дочірній клас наслідує всі поля та методи
батьківського класу, але в ньому можуть бути використані нові поля та
методи, зокрема перевантажені.
Правило 4.17 У разі використання перевантажених методів за
замовченням із дочірнього класу викликається метод дочірнього класу. Якщо
у такому випадку необхідно викликати перевантажений метод батьківського
класу, це можна зробити або через безпосереднє посилання на батьківський
клас, або з використанням спеціального методу super(), призначеного для
роботи з класами.

349
4.1.8 Порівняльний аналіз можливостей використання об’єктів та
модулів у мові програмування Python
Перед вивченням цього підрозділу необхідно повторити підрозділ 2.5
Із розглянутого у цьому посібнику матеріалу зрозуміло, що Python є
багатофункціональною мовою програмування, і, за такої умови, обрання
найкращого стиля програмування для створення відповіднизх програмних
засобів є власним вибором програміста. Проте існують і загальні
рекомендації, які дозволяють у значній мірі спростити написання
програмного коду. Одним із таких завдань вибору є вибір між класами та
модулями. Якщо перед програмістом стоїть саме таке завдання вибору,
зазвичай можна користуватися наступними рекомендаціями, які наведені у
навчальному посібнику [25].
1. Об’єкти є найбільш корисними, коли необхідно мати певну кількість
окремих екземплярів класу, які мають однакову поведінку, і тому їхні методи
співпадають, але вони різняться своїми станами, або атрибутами.
2. Класи, на відміну від модулів, підтримують концепцію
успадкування, яка визначається правилами 4.14 – 4.17.
3. Якщо необхідно створити лише один об’єкт даного типу, модуль
зазвичай підходить краще. Незалежно від того, скільки звернень до модуля
має програма, інтерпретатор завантажує лише одну копію коду цього модуля.
4. Якщо постановка завдання програмування передбачає використання
кількох змінних, які можуть мати різне значення та передаватися як
аргументи до кількох функцій, зазвичай зручніше визначити класи та
змінювати властивості об’єктів цих класів. Наприклад, для роботи із
комп’ютерною графікою найбільш ефективним способом є створення
об’єктів класу Image, які мають відповідні властивості size та color та
методи scale() та transform() для масштабування та перетворення
об’єктів. Основи роботи з графічними об’єктами у мові програмування
Python розглядатимуться у підрозділі 5.4.
5. У деяких випадках замість об’єктів спеціалісти рекомендують
використовувати іменовані кортежі. Основи роботи із структурами даних
такого типу будуть описані у підрозділі 5.3.2.

350
6. Загалом, слід користуватися порадою розробника мови Python Гвідо
ван Россума: «Запобігайте використання ускладнених структур даних» [25].
Дійсно, згідно із третім та четвертим принципами філософії мови
програмування Python, наведеними у підрозділі 1.5: «Просте є кращим, ніж
складне», «Складне є кращим, ніж ускладнене».
Наприклад, програма, наведена у прикладі 4.25 та написана з
використанням об’єктів, є більш простою та зрозумілою, ніж аналогічно
програма, код якої був наведений у прикладі 3.19. Ще однією перевагою
програми, код якої наведений у прикладі 4.25, є те, що вона спрощує процес
введення інформації про нові типи металів. Відповідні переваги цієї
програми розглядалися у підрозділі 4.1.6.
Серед відомих програмних комплексів модульний стиль
програмування притаманний системі науково-технічних розрахунків
MatLab [6, 7], а з використанням об’єктно-орієнтованого підходу написана
система UML [8 – 10, 18, 19], а також система для створення
конструкторської документації AutoCAD, для створення якої була
використана мова об’єктно-орієнтованого програмування LISP [8 – 10]. З
іншого боку, у всіх сучасних мовах програмування існують відповідні
програмні засоби, призначені для створення об’єктів та для роботи з ними.

4.2 Множини у мові програмування Python

4.2.1 Визначення множин та головні правила роботи з ними

Перед вивченням цього підрозділу необхідно повторити підрозділ 3.6


Розглянемо тепер ще деякі структуровані типи даних, які широко
використовуються в мові програмування Python. Одним з таких типів даних є
множина, визначення якої цілком співпадає з математичним визначенням
множини. Надамо відповідне визначення [24].
Визначення 4.3 Множиною у мові програмування Python називають
невпорядкований набір незмінних, унікальних елементів.
Тобто, базові поняття та об’єкти мови програмування Python у значній
мірі пов’язані із основними поняттями та принципами дискретної

351
математики [2, 42]. Насамперед це обумовлено тим, що ця мова з самого
початку створювалась математиком Г. ван Россумом з метою мати
ефективний та простий засіб програмування для математиків.
Множина у мові програмування Python визначається ключовим словом
set (від англійського слова set – набір, множина).
Спочатку розглянемо простий приклад створення множин.
Приклад 4.26
>>> empty_set = set()
>>> empty_set
set()
>>> even_numbers = {0, 2, 4, 6, 8}
>>> even_numbers
{0, 8, 2, 4, 6}
>>> odd_numbers = {1, 3, 5, 7, 9}
>>> odd_numbers
{9, 3, 1, 5, 7}
>>> rand_set_1 = {‘A’, ‘C’, 4, ‘5’, ‘B’}
>>> rand_set_1
{‘C’, ‘B’, ‘5’, 4, ‘A’}
>>> rand_set_2 = {‘A’, ‘C’, 4, ‘5’, ‘B’, 4}
>>> rand_set_2
{‘C’, ‘B’, ‘5’, 4, ‘A’}
>>> home_animals = {‘Cat’, ‘Dog’, ‘Mouse’, ‘Pig’, ‘Cow’}
>>> home_animals
{‘Mouse’, ‘Cat’, ‘Pig’, ‘Dog’, ‘Cow’}
Наприклад, на рис. 4.2 наведений наочний приклад множини
{‘C’, ‘B’, ‘5’, 4, ‘A’}, яка подана у вигляді діаграми Вейля [42].
Слід відзначити, що універсальність поняття множини у дискретній
математиці полягає у тому, що у загальному випадку множина може містити
в собі об’єкти різної природи. Подання сукупності таких об’єктів у вигляді
множини значно спрощує їхній аналіз з точки зору методів теорії інформації

352
[2, 42, 60]. З цієї точки зору поняття множини у мові програмування Python,
яке було наведене у визначенні 4.2, цілком співпадає із відповідним
математичним визначенням [42].

‘C’ ‘5’
4
‘B’ ‘A’

Рис. 4.2 Зображення множини {‘C’, ‘B’, ‘5’, 4, ‘A’} у вигляді


діаграми Вейля

Із наведеного прикладу 4.26 зрозумілі наступні загальні правила мови


програмування Python, які використовуються для роботи з множинами.
Правило 4.18 Елементами множини можуть бути будь-які рядкові або
числові дані.
Правило 4.19 Елементи множини записуються у фігурних дужках та
є невпорядкованими.
Правило 4.20 Під час виведення елементів множини на екран
порядок їхнього розташування не має суттєвого значення.
Правило 4.21 Елементи множини мають бути унікальними та їхнє
повторення не припускається.
Правило 4.22 Для визначення порожньої множини використовується
команда set().
Зверніть особливу увагу на правило 4.22. У математиці порожня
множина зазвичай визначається або символом , або двома фігурними
дужками, відкритою та закритою: {}. Оскільки у мові програмування Python
порожній список визначається двома квадратними дужками, з точки зору
логіки та простоти синтаксису цієї мови можна було б для визначення
порожньої множини використовувати дві фігурні дужки. Використання
функції set() для цієї простої операції пов’язано лише з тим, що початково

353
дві фігурні дужки розробники стали використовувати для створення
порожнього словника, і на тому етапі, коли до інтерпретатора вводилось
поняття множини, суттєво міняти синтаксис мови вже не було особливого
сенсу [25]. Особливості роботи зі словниками у мові програмування Python
будуть розглянуті у підрозділі 4.4.
Розглянемо ще одне важливе правило для роботи із множинами, яке
притаманне мові програмування Python.
Правило 4.23 Множини у мові програмування Python, на відміну від
списків, створюються одноразово та не можуть бути змінені.
Слід також відзначити, що множини можуть бути створені на основі
списків. Відповідна синтаксична конструкція мови програмування Python має
простий вигляд.
Ім’я_множини = set(Список)
Розглянемо приклад такого створення множини.
Приклад 4.27
>>> set_from_lits = set([3, 6, 5, 3, 6])
>>> set_from_lits
{3, 5, 6}
У прикладі 4.27 зверніть особливу увагу на те, що під час створення
множини з використанням функції set() із списку були викреслені
елементи, які повторювались. Такий ефективний спосіб може бути
використаний для формування нового списку, у якому всі елементи йдуть без
зайвих повторень. Розглянемо відповідний приклад.
Приклад 4.28 Взявши за основу приклад 4.27, написати програму, в
якій із списку [3, 6, 5, 3, 6] сформувати новий список, де кожний
елемент має повторюватись лише один раз. Порядок слідування елементів у
новому списку не має суттєвого значення.
З використанням стандартних функцій мови програмування Python
set() та list() поставлене завдання можна розв’язати через формування

354
наступних командних рядків.
>>> new_list = list(set([3, 6, 5, 3, 6]))
>>> new_list
[3, 5, 6]
Зрозуміло, що оскільки множину можна формувати із списку, для
формування множини чисел заданого діапазону також можна
використовувати функцію range(). Розглянемо відповідний приклад.
Приклад 4.29 З використанням функції range() сформувати
множину цілих чисел від 0 до 9.
Завдання, поставлене у цьому прикладі, можна розв’язати через
формування наступних командних рядків.
>>> set_09 = range(10)
>>> set_09
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
У наступному підрозділі розглядатимуться основні операції над
множинами, які реалізовані у мові програмування Python.
Перетворити на множину можна не лише список, але й рядок.
Розглянемо відповідний приклад [24].
Приклад 4.30
>>> set_str = set(‘letters’)
>>> set_str
{l, e, t, r, s}
Зверніть увагу на те, що, як і для списку, у прикладі 4.30 літери, які
повторюються у рядку, у множині зустрічаються лише один раз. У цьому і
полягає один із головних принципів формування множини – унікальність
всіх її елементів. Цьому принципу відповідає правило 4.21.

4.2.2 Операції над множинами у мові Python

У мові програмування Python реалізована низка функцій для роботи з


множинами. Ці функції реалізовані як методи об’єктів, тому загальна їх

355
синтаксична конструкція має наступний вигляд [24, 25].
Ім’я_множини.метод()
Головними методами для роботи з множинами у мові програмування
Python є наступні.
add() – додати елемент до множини.
intersection() – обчислення перетину двох множин.
union() – обчислення об’єднання двох множин.
Зрозуміло, що операції перетину та об’єднання множин цілком
відповідають цим операціям у дискретній математиці [42].
Розглянемо приклади, у яких вище перелічені методи
використовуються для роботи з множинами.
Приклад 4.31
>>> set_05 = range(5)
>>> set_05
{0, 1, 2, 3, 4}
>>> set_02 = range(2)
>>> set_02
{0, 1}
>>> set_05.add(5)
>>> set_05
{0, 1, 2, 3, 4, ‘5’}
>>> s1_int = set_05.intersection(set_02)
>>> s1_int
{0, 1}
>>> s1_un = set_05.union(set_02)
>>> s1_un
{0, 1, 2, 3, 4, ‘5’}
Приклад 4.32 З використанням засобів мови програмування Python
знайти перетин та об’єднання двох множин: M1 = {‘A’, ‘B’, ‘C’, ‘D’} та
M2 = {‘A’, ‘B’, ‘D’, ‘F’}. Перевірити отриманий результат з використанням
діаграм Вейля.
Відповідну послідовність командних рядків можна записати наступним
чином.
>>> M1 = {‘A’, ‘B’, ‘C’, ‘D’}
>>> M2 = {‘A’, ‘B’, ‘D’, ‘F’}
356
>>> M_int = M1.intersection(M2)
>>> M_int
{‘A’, ‘B’, ‘D’}
>>> M1_un = M1.union(M2)
>>> M1_un
{‘A’, ‘B’, ‘C’, ‘D’, ‘F’}
Наочна ілюстрація проведених математичних дій над множинами з
використанням діаграм Вейля показана на рис. 4.3.

M1 M_un
‘C’ ‘C’
‘D’ M_int ‘D’ ‘D’
‘F’
‘B’ ‘A’ ‘B’ ‘A’ ‘B’ ‘A’

M2 ‘F’
Перетин Об’єднання
Рис. 4.3 Ілюстрація виконання операцій перетину та об’єднання множин M1
та M2 з використанням діаграм Вейля

Іншими операціями теорії множин, які також використовуються у мові


програмування Python, є наступні [25].
difference() – пошук різниці двох множин M1 та M2, яка
визначається як сукупність елементів M1, які не належать до M2 [42]. Для
виконання цієї операції, крім функції difference(), може бути
використаний символ – [25].
symmetric_difference() – пошук всіх елементів множин M1 та
M2, які не є спільними. Така операція в дискретній математиці також
називається диференціальною різницею, операцією «Виключного АБО» [42].
Для виконання цієї операції, крім функції symmetric_difference(),
може бути використаний символ ^ [25].
issubset() – перевірка, чи є множина M1 підмножиною множини
M2 [42]. Для виконання цієї операції також може бути використана
сукупність символів <= [25].

357
issuperset() – перевірка, чи є множина M2 підмножиною множини
M1, або, у визначеннях дискретної математики, чи є множина M1
супермножиною для M2. Цілком зрозуміло, що операція визначення
сепермножини є зворотною для операції визначення підмножини [42]. Для
виконання цієї операції також може бути використана сукупність символів
>= [25].
Результатом виконання функцій issubset() та issuperset() є
значення логічних змінних True та False, розглянутих у підрозділі 3.1.
Загалом ці функції можна розглядати як логічні вирази у широкому сенсі
цього слова, оскільки вони відповідають визначенню 3.3.
Як і для операцій перетину та об’єднання множин, для описаних вище
операцій використовується стандартна синтаксична конструкція мови Python:
Ім’я_множини.метод()
Зрозуміло, що операції –, ^, <= та >= у мові програмування Python є
перевантаженими, оскільки для чисел та для множин вони мають різне
значення.
Розглянемо деякі приклади використання описаних вище додаткових
операцій над множинами.
Приклад 4.33 З використанням засобів мови програмування Python
знайти різницю та диференціальну двох множин: M1 = {‘A’, ‘B’, ‘C’, ‘D’} та
M2 = {‘A’, ‘B’, ‘D’, ‘F’}. Перевірити отриманий результат з використанням
діаграм Вейля.
Відповідну послідовність командних рядків можна записати наступним
чином.
>>> M1 = {‘A’, ‘B’, ‘C’, ‘D’}
>>> M2 = {‘A’, ‘B’, ‘D’, ‘F’}
>>> M_dif1 = M1.difference(M2)
>>> M_dif1
{‘C’}

358
>>> M_dif2 = M2.difference(M1)
{‘F’}
>>> M_sym = M1.symmetric_difference(M2)
{‘C’, ‘F’}
Результат виконання цих операцій над множинами з використанням
діаграм Вейля наочно показаний на рис. 4.4.

M1
‘C’ ‘C’ ‘C’
‘D’ M_sym
M_dif1
‘B’ ‘A’ ‘F’

M2 ‘F’ Дифіренціальна
Різниця
різниця

Рис. 4.4 Ілюстрація виконання операцій різниці та диференціальної різниці


для множин M1 та M2 з використанням діаграм Вейля

Приклад 4.34 З використанням засобів мови програмування Python


перевірити, чи є множина M1 = {‘A’, ‘B’} підмножиною множини M2 = {‘A’,
‘B’, ‘D’, ‘F’}, та навпаки, чи є множина M2 супермножиною для множини
M1. Перевірити отриманий результат з використанням діаграм Вейля. Знайти
різницю множин M2 – M1.
Відповідну послідовність командних рядків для виконання цього
прикладу можна записати наступним чином.
>>> M1 = {‘A’, ‘B’}
>>> M2 = {‘A’, ‘B’, ‘D’, ‘F’}
>>> M_sub = M1.issubset(M2)
>>> M_sub
True
>>> M_sup = M2.issuperset(M1)
True
>>> M2 – M1
{‘D’, ‘F’}

359
Множини М1 та М2 для прикладу, який розглядається, наочно показані
на рис. 4.5 з використанням діаграми Вейля.

‘D’

‘B’‘A’ M2
M1
‘F’

Рис. 4.5 Діаграма Вейля для прикладу 4.34

Наявність відповідного елемента у заданій множині можна перевірити


через застосування оператора циклу із заданою кількістю повторень з
використанням ключового слова in. Така синтаксична конструкція для цього
оператора була описана у підрозділі 3.6. Розглянемо відповідний приклад.
Приклад 4.35 З використанням засобів мови програмування Python
визначити, чи присутній елемент «F» у множинах M1 = {‘A’, ‘B’, ‘C’, ‘D’} та
M2 = {‘A’, ‘B’, ‘D’, ‘F’}.
Відповідну послідовність командних рядків для цього прикладу можна
записати наступним чином.
>>> M1 = {‘A’, ‘B’, ‘C’, ‘D’}
>>> M2 = {‘A’, ‘B’, ‘D’, ‘F’}
>>> for E in M1
if E == ‘F’
print(‘Елемент ‘F’ належить до мно\
жини М1’)
break
>>> for E in M2
if E == ‘F’
print(‘Елемент ‘F’ належить до мно\
жини М2’)
break

360
Елемент ‘F’ належить до множини М2
Слід відзначити, що хоча множини та математичні операції над ними
не відіграють особливо важливої ролі у мові програмування Python,
розглянутий у цьому підрозділі теоретичний матеріал є необхідним для
кращого розуміння багатьох загальних положень дискретної математики,
зокрема теорії множин [42]. На практиці множини часто використовуються
для роботи зі списками та зі словниками. Поняття про словники та способи
роботи з ними будуть розглянуті у підрозділі 4.4.

4.3 Кортежі як структуровані дані та способи роботи з ними

4.3.1 Поняття про кортежі та загальні правила їхнього


формування та роботи з ними
Іншими важливими структурованими типами даних мови
програмування Python, які за своєю структурою та способом формування є
дуже близькими до списків, є кортежі [24, 25]. Надамо відповідне визначення
[24].
Визначення 4.4 Кортежем у мові програмування Python називають
невпорядкований набір незмінних елементів, якими можуть бути числові,
рядкові дані або списки.
Кортеж у мові програмування Python визначається ключовим словом
tuple (від англійського слова tuple – фрагмент даних в інформаційному
блоці, кортеж, запис).
Розглянемо спочатку головні правила, яких слід дотримуватись під час
роботи з кортежами [24, 25].
Правило 4.24 Кортежі у мові програмування Python створюються з
використанням круглих дужок, а всі їх елементи записуються через кому.
Правило 4.25 Якщо створюється кортеж із одного елементу, після
нього обов’язково ставиться кома.
Правило 4.26 Згідно з правилами мови програмування Python кортеж
є незмінною структурою. Це означає, що всі елементи кортежу є незмінними,
їх неможна також видаляти із кортежу та додавати в нього.

361
Розглянемо деякі прості приклади формування кортежів.
Приклад 4.36 З використанням засобів мови програмування Python
сформувати порожній кортеж.
Відповідні командні рядки можна записати наступним чином [25].
>>> empty_tulip = ()
>>> empty_tulip
()
Приклад 4.37 З використанням засобів мови програмування Python
сформувати кортеж, який містить один елемент – рядкову змінну ‘4’.
Відповідні командні рядки можна записати наступним чином.
Командні рядки для цього прикладу можна записати наступним чином.
>>> tulip_one_element = (‘4’,)
tulip_one_element
(‘4’,)
Розглянемо ще кілька важливих правил, пов’язаних із роботою з
кортежами у мові програмування Python.
Правило 4.27 Під час запису елементів кортежу круглі дужки можна
пропускати.
Дійсно, якщо повернутися до прикладу 4.37, запис
tulip_one_element = (‘4’,)
є еквівалентним більш простому запису
tulip_one_element = ‘4’,
Зверніть особливу увагу на те, що, на відміну від круглих дужок, кома
після єдиного елементу кортежу, згідно з правилом 4.25, є обов’язковою.
Правило 4.28 З використанням кортежу можна присвоювати
значення одночасно кільком змінним.
Розглянемо приклад, у якому проілюструємо особливості використання
правила 4.28.
Приклад 4.38 З використанням засобів мови програмування Python
сформувати кортеж із двох чисел (10, 5).
Згідно з правилами 4.26 та 4.27, командні рядки для виконання
завдання цього прикладу можна записати наступним чином [24].

362
>>> x, y = 10, 5
>>> x
10
>>> y
5
Правило 4.29 Елементи кортежу можна міняти місцями.
Розглянемо приклад використання правила 4.29, використовуючи в
ньому кортеж, сформований у прикладі 4.38 [24].
Приклад 4.39
>>> x, y = 10, 5
>>> x, y = y, x
>>> x
5
>>> y
10
Слід відзначити, що подання числових даних у вигляді кортежу є дуже
зручним для розгляду таких складних об’єктів обчислювальної математики
та аналітичної геометрії, як комплексні числа та точки на площині або у
просторі. Тут важливим є також використання об’єктно-орієнтованого
підходу мови програмування Python. Спочатку комплексне число або точка
на площині описуються як кортежі, а потім для цих об’єктів формуються
відповідні методи, які реалізують відомі правила обчислювальної математики
та аналітичної геометрії. Способи використання кортежів для розв’язування
деяких геометричних задач розглядатимуться у підрозділі 4.3.
Правило 4.30 Кортеж можна формувати з елементів списку з
використанням ключового слова tuple().
Розглянемо приклад використання правила 4.30.
Приклад 4.40
>>> t1 = tuple(range(4))
>>> t1

363
(0, 1, 2, 3)
>>> t2 = tuple([1, 3, 5, 8, ‘1’])
>>> t2
(1, 3, 5, 8, ‘1’)
Правило 4.31 Для об’єднання елементів двох кортежів може бути
використаний оператор «+».
Розглянемо приклад використання правила 4.31.
Приклад 4.41
>>> t1 = tuple(range(4))
>>> t1
(0, 1, 2, 3)
>>> t2 = tuple([‘1’, ‘2’])
>>> t2
(‘1’, ‘2’)
>>> t1 + t2
(0, 1, 2, 3, ‘1’, ‘2’)
Правило 4.32 До елементів кортежу, як і до елементів списку, можна
звертатись через індекс у квадратних дужках.
Відповідні правила індексації елементів списку були розглянуті у
підрозділі 3.6.
Правило 4.33 Елементами кортежу у мові програмування Python
можуть бути списки.
Правило 4.34 Елементи списків, які входять до кортежу, можуть бути
змінені.
Наведемо приклад використання правил 4.33 та 4.34.
Приклад 4.42
>>> t1 = (1, [1, 3], ‘3’)
>>> t1
(1, [1, 3], ‘3’)
364
>>> t1[1]
([1, 3])
>>> t1[1][0] = ‘1’
>>> t1
(1, [‘1’, 3], ‘3’)
Окремим випадком кортежів, як структурованих даних, у мові
програмування Python є іменовані кортежі, які розглядатимуться у
наступному підрозділі. Слід відзначити, що іменовані кортежі у мові
програмування Python розглядаються як одна з альтернатив використання
об’єктів.

4.3.2 Іменовані кортежі


Перед вивченням цього підрозділу необхідно повторити підрозділ 4.1.6
Іменовані кортежі за своєю структурою дещо схожі на об’єкти. Для
створення такого об’єкту мови програмування Python, як іменований кортеж,
необхідно виконати дві операції [25].
1. Створити іменований кортеж з використанням методу
namedtuple().
2. Визначити елемент, який належить іменованому кортежу, через
оператор присвоювання.
Синтаксис команди визначення іменованого кортежу namedtuple()
має наступний вигляд [25].
ім’я_кортежу = namedtuple(‘ім’я_кортежу’ .\
‘Поле_1 Поле_2 Поле_3 ... Поле_n’)
Тоді створити елемент такого кортежу можна з використанням
наступних операторів присвоювання.
ім’я_елементу = ім’я_кортежу(Поле_1 = ‘Значення_1’.
Поле_2 = ‘Значення_2’. ... Поле_n = ‘Значення_n’)
Розглянемо відповідний прилад створення іменованого кортежу.
Приклад 4.43 Розглянути повторно приклад 4.25, визначивши тип

365
металу як іменований кортеж.
Згідно із наведеними вище теоретичними відомостями, у цьому
випадку описання структуруктурованих даних для параметрів металів буде
мати наступний вигляд.
Metals = namedtuple(‘Metals’ . ‘Name \
min_res max_res’)
Тоді такий метал, як вольфрам, створюється з використанням наступної
синтаксичної конструкції.
Wolf = Metals(‘Вольфрам. 5.4e-8. 5.6e-8’)
Тобто, якщо порівняти із прикладом 4.25, різниця між екземпляром
класу та іменованим кортежем полягає у тому, що в екземплярі класу поля
пишуться окремо через кому, а в іменованому кортежі – в лапках та через
крапку.
Цікавим є те, що звертатися до окремих елементів іменованих кортежів
можна і через їхню індексацію. Наприклад, для структури Wolf, створеної у
цьому прикладі, посилання Wolf.Name цілком відповідає посиланню Wolf[1]
та має відповідне значення Wolf.Name = Вольфрам. Зрозуміло, що посилання
Wolf[1] більше відповідає роботі з іменованим кортежем як із списком, а
посилання Wolf.Name – роботі з ним як з об’єктом. Доступ до елементу
іменованого кортежу за іменем передбачає використання конструкції
ім’я_об’єкту.ім’я_поля, а доступ за індексацією – використання
конструкції [offset] [25].
Розглянемо головне правило, яке пов’язане із роботою з іменованими
кортежами [25].
Правило 4.35 Елементи іменованого кортежу не можуть бути
зміненні. Проте можна змінювати значення полів створеного кортежу,
створюючи на основі його інший кортеж.
Для виконання операції заміни елементів кортежу, яка описана у
правилі 4.35, використовується метод replace(). Відповідна синтаксична
конструкція має наступний вигляд [25].
366
ім’я_нового_елементу = ім’я_старого_\
елементу.replace (Поле_1 = ‘Нове_Значення’.Поле_2 =\
‘Нове_Значення’. ... Поле_n = ‘Нове_Значення’)
Розглянемо відповідний приклад, аналогічний прикладу 4.25.
Wolf = Metals(‘Вольфрам. 5.4e-8. 5.6e-8’)
Stal = Wolf.replace(Name = ‘Сталь’. min_res = 1.3e-7. \
max_res = 1.5e-7)
Зрозуміло, що іменовані кортежі відрізняються від об’єктів тим, що їхні
поля є незмінними, що у деякій мірі ускладнює використання цих синтаксичних
конструкцій у практиці програмування. Проте є деякі випадки, в яких
використання іменованих кортежів є простішим, ніж створення об’єктів [25].

4.3.3 Приклади використання класів та кортежів для роботи з


геометричними об’єктами
Розглянемо тепер особливості використання об’єктів та кортежів у
деяких завданнях прикладного програмування, зокрема для розв’язування
геометричних завдань. Тут насамперед слід відзначити, що у мові
програмування Python всі класи є дочірніми від базового класу object [24,
25, 70]. Спочатку створимо з використанням кортежу базовий клас Point.
Потім в межах цього класу створимо перевантажені методи __init__(),
__eq__() та __str__(). Серед цих методів метод __init__() є
конструктором об’єкту, він був розглянутий у підрозділі 4.1.3. Метод
__eq__() призначений для порівняння двох точок, а метод __str__() –
для виведення координат точки на екран у консольному режимі. Зрозуміло,
що ці методи є перевантаженими, оскільки вони існують також для
батьківського класу object.
Відповідний програмний код для класу Point можна записати
наступним чином [24].
Приклад 4.44
class Point:

367
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __eq__ (self, other):
return (self.x == other.x) and \
(self.y == other.y)
def __str__(self):
return ‘({0.x},{0.y})’.format(self)
def func(self):
return abs(self.x - self.y)
Проаналізуємо результат роботи програми, наведеної у прикладі 4.44, з
використанням наступних командних рядків інтерпретатора.
>>> a = Point()
>>> print(str(a))
(0, 0)
>>> b = Point(3, 4)
>>> print(str(b))
(3, 4)
b.x = –19
>>> print(a.func())
0
>>> print(str(b))
(-19, 4)
>>> print(a == b, a != b)
False True
Приклад 4.45 Створити від батьківського класу Point новий
дочірній клас Circle, який описує коло. Для роботи з цим об’єктом
визначити наступні функції.
– area() – обчислення площі кола.
– circumference() – обчислення довжини окружності.

368
Реалізувати в цьому класі також перевантажені методи __eq__() та
__str__().
Відповідний програмний код з використанням засобів об’єктно-
орієнтованого програмування мови Python можна записати наступним
чином [24].
class Circle:
def __init__(self, radius, x = 0, y = 0):
super().__init__(x, y)
self.radius = radius
def area(self):
return math.pi * (self.radius**2)
def circumference(self):
return 2 * math.pi * self.radius
def __eq__ (self, other):
return (self.radius == other.radius) and \
super().__eq__(other)
def __str__(self):
return ‘({0. radius}, \
{0.x},{0.y})’.format(self)
Проаналізувати результат роботи програми, наведеної у прикладі 4.45,
можна з використанням наступних командних рядків інтерпретатора.
>>> сircle = Circle(2)
>>> сircle.radius = 3
>>> сircle.x = 12
>>> a = Circle(4, 5, 6)
>>> b = Circle(4, 5, 6)
>>> print(str(a))
(4, 5, 6)
>>> print(str(b))
(4, 5, 6)

369
>>> print(a == b)
True
>>> print(a == сircle)
False
>>> print(a == сircle)
True
>>> print(сircle.func())
12
>>> print(b.area())
50,2655
>>> print(b.circumference())
25,133
У прикладі 4.45 наочно показана можливість використання
поліморфізму у мові програмування Python. У даному випадку вона
проявляється в тому, що метод func(), який не визначений як
перевантажений у дочірньому класі Circle, запозичується із батьківського
класу Point. Ієрархія успадкування методів для прикладів 4.44, 4.45,
показана на рис. 4.6.

Circle
x
Point y
object x radius
__init__() y func()
__eq__() func() __init__()
__str__() __init__() area()
__eq__() circumference()
__str__() __eq__()
__str__()

Рис. 4.6 Наочна ілюстрація успадкування методів об’єктів object, Point та


Circle для прикладів 4.44 та 4.45

Розглянемо ще один приклад описання такого геометричного об’єкту, як


двовимірний вектор, з використанням засобів мови програмування Python [70].
370
Приклад 4.46 Створити з використанням кортежів двовимірний
вектор та реалізувати такі методи роботи з цим об’єктом, як додавання,
віднімання векторів та множення вектора на число.
Для реалізації цих арифметичних операцій над векторами
використаємо такі перевантажені функції мови програмування Python, як
__add__(), __sub__(), __mul__() та __rmul__(). Призначення цих
перевантажених функцій полягає у тому, що за їх допомогою можна
реалізовувати перевантажені арифметичні операції над об’єктами. Зрозуміло,
що функція __add__() відповідає операції «+», а функція __sub__() –
операції «–». Щодо функції __mul__() та __rmul__(), їх різниця полягає
у тому, що функція __mul__() відповідає множенню об’єкта на аргумент
функції справа, а функція __rmul__() – множенню зліва. Наприклад,
запис a.__mul__(5) означає a*5, а запис a.__rmul__(5) – 5*a. З
математичної точки зору ці вирази є еквівалентними, але для розшифрування
та розрахунку складного арифметичного виразу типу 4*(2*a – b*3)
порядок множення має суттєве значення [70].
З урахуванням описаних вище особливостей реалізації перевантажених
арифметичних операцій у мові програмування Python, код програми для
створення двовимірного вектора та для проведення арифметичних операцій з
ним як з об’єктом можна записати наступним чином [70].
Class Vec2D:
def __init__(self, tpl):
self.x = tpl[0]
self.y = tpl[1]
def print(self)
print (‘Vector = ’, self.x, self.y)
def __str__(self):
return ‘({},{})’.format(self.x, self.y)
def __add__(self, v):
return Vec2D(self.x + v.x, self.y + v.y)

371
def __sub__(self, v):
return Vec2D(self.x - v.x, self.y - v.y)
def __mul__(self, c):
return Vec2D(self.x*c, self.y*c)
def __rmul__(self, c):
return Vec2D(self.x*c, self.y*c)
Зверніть увагу на те, що коди функцій __mul__() та __rmul__() є
однаковими. Різниця полягає у тому, що під час розшифрування командного
рядка вони відповідають різним арифметичним операціям [70]. Розглянемо
результат роботи програми, наведеної у прикладі 4.46.
>>> a = Vec2D((1, 2))
>>> b = Vec2D((3, –1))
>>> a.print()
Vector = (1, 2)
>>> b.print()
Vector = (3, –1)
>>> z1 = a + b
>>> print(‘a + b =’, str(z1))
a + b = (4, 1)
>>> z2 = a – b
>>> print(‘a - b =’, str(z2))
a - b = (-2, 3)
>>> z3 = a*5
>>> z3.print()
Vector = (5, 10)
>>> z4 = 3*a
>>> z4.print()
Vector = (3, 6)
>>> z5 = 4*(2*a – b*3)
>>> z5.print()
Vector = (-28, 28)

372
Розглянуті у цьому підрозділі приклади 4.44 – 4.46 показують високу
ефективність використання кортежів для роботи з об’єктами двовимірної
графіки. Кортежі також можуть бути використані для побудови графіків
математичних функцій в різних системах координат. Відповідний приклад
для декартової системи координат буде наведений у підрозділі 5.4.3.2.

4.4 Словники у мові програмування Python та особливості роботи


з ними
Іншим цікавим структурованим типом даних мови програмування
Python є словник. Надамо відповідне визначення [24, 25].
Визначення 4.5 Словником у мові програмування Python називають
невпорядковану колекцію з двох елементів з довільними ключами. Елементи
словника можна змінювати.
Головні особливості роботи зі словниками закладені у самому
визначенні 4.4. Словник являє собою структурований тип даних, в якому
одній структурі відповідає інша. За цими значеннями які називаються
ключами, можна шукати елементи словника та відповідності, які були
встановлені між цими елементами. Сформулюємо головні правила роботи зі
словниками у мові Python [24, 25].
Правило 4.36 Порожній словник створюється з використанням
методу dict().
Правило 4.37 Для додавання до словника одного елементу
використовується синтаксична конструкція
Ім’я_словника [Змінна_1] = Змінна_2.
У цій синтаксичній конструкції Змінна_1 є ключем, а Змінна_2 –
його значенням. Використовуючи відповідну кількість операторів
присвоєння, аналогічних наведеному у правилі 4.37, можна поповнювати
створений словник новою інформацією.
Правило 4.38 Елементами словника можуть бути різня об’єкти,
зокрема: числові, рядкові дані, списки, множини та кортежі.
Правило 4.39 У разі перегляду словника через командний рядок

373
інтерпретатора його елементи відображаються у вигляді такої структурованої
сукупності даних:
{Ключ_1: Значення_1, Ключ_2: Значення_2, ... \
Ключ_n: Значення_n}
Правило 4.40 Ключі у словниках, на відміну від значень, не можуть
бути зміненими.
На рис. 4.7 показана узагальнена структура словника у вигляді діаграми
Вейля із встановленими відношеннями між двома множинами [42].

Ключ 1 Значеня 1
Ключ 2 Значеня 2

Ключ n Значеня n

Рис. 4.7 Структура словника з точки зору теорії множин

Розглянемо приклад створення простого словника згідно із наведеними


правилами 4.36 – 4.40.
Приклад 4.47 Створити словник, у якому значенню чисел від 0 до 10
відповідають назви цих цифр англійською мовою.
Відповідні командні рядки будуть мати наступний вигляд.
>>> dig2word = diсt()
>>> dig2word[‘0’] = ‘zero’
>>> dig2word[‘1’] = ‘one’
>>> dig2word[‘2’] = ‘two’
>>> dig2word[‘3’] = ‘three’
>>> dig2word[‘4’] = ‘four’
>>> dig2word[‘5’] = ‘five’
>>> dig2word[‘6’] = ‘six’
>>> dig2word[‘7’] = ‘seven’
>>> dig2word[‘8’] = ‘eight’

374
>>> dig2word[‘9’] = ‘nine’
>>> dig2word[‘10’] = ‘ten’
>>> dig2word
{‘10’: ‘ten’, ‘9’: ‘nine’, ‘8’: ‘eight’, ‘7’:
‘seven’, ‘6’: ‘six’, ‘5’: ‘five’, ‘4’: ‘four’,
‘3’: ‘three’, ‘2’: ‘two’, ‘1’: ‘one’, ‘0’: ‘zero’}
dig2word[‘4’]
‘four’
dig2word[‘4’, ‘6’]
{‘four’, ‘six’}
Розглянемо деякі інші правила роботи зі словниками.
Правило 4.41 Всі ключі словника мають бути унікальними.
Правило 4.42 Оскільки ключі словників є незмінними даними, для їх
створення можна використовувати кортежі.
Розглянемо відповідний приклад [24].
Приклад 4.48
>>> e = {}
>>> e[(4, 6)] = ‘1’
>>> e
{(4, 6): ‘1’}
Правило 4.43 Для словника може бути використаний оператор in.
Цей оператор повертає значення логічної змінної True, якщо задане
значення рядкової змінної є наявним серед ключів, або False у противному
випадку.
Розглянемо відповідний приклад.
Приклад 4.49
>>> dig2word = diсt()
>>> dig2word[‘0’] = ‘zero’
>>> dig2word[‘1’] = ‘one’
>>> ‘1’ in dig2word
True

375
>>> ‘4’ in dig2word
False
Із наведених у цьому підрозділі теоретичних відомостей зрозуміло, що
з теоретичної точки зору словник можна розглядати як список, у якому для
індексації елементів замість індексів використовуються ключі.
Розглянемо ще декілька прикладів створення словників, які
безпосередньо пов’язані із прикладами, що розглядалися раніше.
Приклад 4.50 За допомогою словника записати інформацію про
метали, яка наведена у прикладі 3.19.
Поставлене завдання можна розв’язати з використанням наступних
командних рядків.
>>> Metals = diсt()
>>> Metals[‘Вольфрам’] = [5.4e-8, 5.6e-8]
>>> Metals[‘Сталь’] = [1.3e-7, 1.5e-7]
Приклад 4.51 За допомогою словника записати інформацію про
одиниці вимірювання для прикладів 2.46 – 2.48.
Для розв’язування поставленого завдання можуть бути використані
наступні командні рядки.
>>> Units = diсt()
>>> Units [‘Температура’] = [‘Цельсій’, \
‘Фаренгейт’]
>>> Units [‘Тиск’] = [‘Паскаль’, \
‘Тор’]
>>> Units [‘Підсилення’] = [‘Рази’, \
‘Децибели’]
Будь-яку структуру, яка містить два елементи, наприклад, список або
кортеж, можна з використанням методу dict() перетворити на словник.
Розглянемо відповідний приклад [25].
Приклад 4.52
>>> lol = [[‘a’, ‘b’], [‘c’, ‘d’], [‘e’, ‘f’]]
>>> dict(lol)

376
{‘c’: ‘d’, ‘a’: ‘b’, ‘e’: ‘f’}
>>> lot = [(‘a’, ‘b’), (‘c’, ‘d’), (‘e’, ‘f’)]
>>> dict(lot)
{‘c’: ‘d’, ‘a’: ‘b’, ‘e’: ‘f’}
>>> tol = ([‘a’, ‘b’], [‘c’, ‘d’], [‘e’, ‘f’])
>>> dict(tol)
{‘c’: ‘d’, ‘a’: ‘b’, ‘e’: ‘f’}
>>> los = [‘ab’, ‘cd’, ‘ef’]
>>> dict(los)
{‘c’: ‘d’, ‘a’: ‘b’, ‘e’: ‘f’}
>>> tos = (‘ab’, ‘cd’, ‘ef’)
>>> dict(tos)
{‘c’: ‘d’, ‘a’: ‘b’, ‘e’: ‘f’}
Для роботи зі словниками також можна використовувати наступні
функції та команди, які аналогічні функціям та командам для роботи зі
списками, розглянутими у підрозділі 3.6.1 [25].
1. Команда del – видалення елементів за їхніми ключами. Ця команда
має наступний синтаксис.
del ім’я_словника(ключ)
2. Функція clear() – видалення всіх елементів, або очищення
словника. Метод clear() використовується до словника як до об’єкта,
тобто, відповідна команда має таку синтаксичну конструкцію.
ім’я_словника.clear()
3. Функція update() – об’єднати два словника. Синтаксична
конструкція для використання цієї функції має наступний вигляд.
ім’я_словника_1.update(ім’я_словника_2)
4. Функція keys() – отримати список всіх ключових елементів заданого
словника. Відповідна синтаксична конструкція має наступний вигляд.
ім’я_словника.keys()
Тобто, функція keys() також використовується як метод для об’єкту з
іменем ім’я_словника.

377
5. Функція copy() – функція копіювання словника. Ця функція
аналогічна відповідній функції для списків та їй відповідає така синтаксична
конструкція.
ім’я_словника_2 = copy(ім’я_словника_1)
Розглянемо наступний приклад, у якому використовуються ці функції
та команди.
Приклад 4.53
>>> dig2word_1 = diсt()
>>> dig2word_1 [‘0’] = ‘zero’
>>> dig2word_1 [‘1’] = ‘one’
>>> dig2word_2 = diсt()
>>> dig2word_2 [‘2’] = ‘two’
>>> dig2word_2 [‘3’] = ‘three’
>>> dig2word_2 [‘4’] = ‘four’
>>> dig2word_1
{‘1’: ‘one’, ‘0’: ‘zero’}
>>> dig2word_2
{‘4’: ‘four’, ‘3’: ‘three’, ‘2’: ‘two’}
>>> dig2word_1.update(dig2word_2)
>>> dig2word_1
{‘1’: ‘one’, ‘0’: ‘zero’, ‘4’: ‘four’,
‘3’: ‘three’, ‘2’: ‘two’}
>>> dig2word_1.keys()
dict_keys([‘1’, ‘0’, ‘4’, ‘3’, ‘2’])
>>> del dig2word_1[‘0’]
>>> dig2word_1
{‘1’: ‘one’, ‘4’: ‘four’, ‘3’: ‘three’, ‘2’: ‘two’}
>>> dig2word_2.clear()
>>> dig2word_2
{}
>>> dig2word_3 = copy(dig2word_1)

378
>>> dig2word_3
{‘1’: ‘one’, ‘4’: ‘four’, ‘3’: ‘three’, ‘2’: ‘two’}
>>> dig2word_1.clear()
>>> dig2word_1
{}
Цілком зрозуміло, що однією з ефективних можливостей використання
словників для розв’язування прикладних завдань програмування є
підрахунок кількості відповідних символів у структурі, яка аналізується.
Такою структурою може бути рядок, список або кортеж. Розглянемо приклад
такого використання словника [24].
Приклад 4.54
def histograms(s):
d = dict()
for c in s:
if c not in d:
d[c] = 1
else d[c] += 1
return d
Слід відзначити, що простота та ефективність цього програмного коду
обумовлена тим, що індексація елементів словника здійснюється не
числовим способом, а через самі елементи структури, яка аналізується. Саме
таке значення мають оператори присвоєння d[c] = 1 та d[c] += 1.
Оператор d[c] += 1 можна розглядати також як лічильник елементів.
Результат роботи наведеної функції histograms(s) для списку,
рядка та кортежу, буде наступним.
>>> histograms([2, 5, 6, 5, 4, 4, 4, 4, 3, 2, 2, \
2, 2])
{2: 5, 3: 1, 4: 4, 5: 2, 6: 1}
>>> histograms(‘rttyuyer’)
{‘r’: 2, ‘t’: 2, ‘y’: 2, ‘u’: 1, ‘e’: 1}
>>> histograms((5, 5, 6, 5, ‘h’, ‘5’))

379
{5: 3, 6: 1, ‘h’: 1, ‘5’: 1}
Із наведених у цьому підрозділі теоретичних відомостей зрозуміло, що
велике практичне значення словників, як структурованих типів даних мови
Python, полягає у можливості пошуку відповідної інформації не за індексом,
а за заданим ключовим словом. Таке завдання у дискретній математиці
розглядається як контекстний пошук, або пошук за зразком, і воно є значно
простішим, ніж пошук за індексом [42]. Зазвичай у разі обробки великої
кількості інформації для контекстного пошуку реалізують алгоритми,
пов’язані з формуванням класів лишків, які є досить простими та ефективно
виконується з використанням сучасних засобів комп’ютерної техніки [42].
Основними практичними завданнями програмування, для вирішення яких
ефективно можуть бути використані словники, є наступні.
1. Пошук інформації в тексті за заданим ключовим словом.
2. Переклад текстів з однієї мови на іншу.
3. Пошук інформації в електронних довідниках, наприклад, пошук
параметрів приладу за заданим маркування.
4. Кодування інформаційних повідомлень.
Зрозуміло, що саме розв’язування завдань такого типу є одним із
головних напрямків розвитку сучасних інформаційних технологій та роботи з
розподіленими додатками [12 – 14].

Контрольні питання та завдання до розділу 4


1. Що являють собою класи у мові програмування Python? Наведіть
власні приклади описання класу та поясніть їх.
2. Що являють собою об‘єкти у мові програмування Python? Наведіть
власні приклади описання об‘єктів та поясніть їх.
3. Поясніть визначення 4.1.
4. Як способи описання об’єктів та класів у мові програмування Python
пов’язані із загальними принципами об’єктно-орієнтованого програмування,
які були описані у розділі 1? Свою відповідь обґрунтуйте та наведіть власні
приклади такого взаємозв’язку.
380
5. Поясніть на прикладах, чому фахівці вважають Python мовою не
об’єктно-орієнтованого, а багатофункціонального програмування. Наведіть
власні приклади використання різних стилів програмування в мові Python.
6. Як у мові програмування Python можна створити порожній клас.
Наведіть власні приклади створення порожнього класу.
7. Поясніть приклад 4.1.
8. Як у мові програмування Python створюються об’єкти як екземпляри
класу? Наведіть власні приклади створення об’єктів.
9. Поясніть приклади 4.2 та 4.3.
10. Як і в яких випадках з використанням об’єктно-орієнтованого
підходу можна спростити програмний код? Наведіть власні приклади такого
спрощення програмного коду.
11. Поясніть приклади 4.4 та 4.5.
12. Що являють собою методи класів та як здійснюється посилання на
них через створені об’єкти? Наведіть власні приклади створення методів
класу та посилань на них.
13. Що являє собою системна змінна self та яке значення вона має в
методології об’єктно-орієнтованого програмування? Наведіть власні
приклади використання цієї змінної.
14. Поясніть приклад 4.6.
15. На основі прикладу 4.6 створить об’єкти класів Cat (кіт), Goat
(цап), Pig (свиня), Sheеp (вівця), Cow (корова), Cock (півень) та Fish
(риба).
16. На основі прикладу 4.6 створить об’єкт класу New_Animal (нова
тварина) та придумайте цікавий звук, який ця тварина буде говорити з
використанням методу voice().
17. Що являє собою конструктор об’єктів та як він реалізований в мові
програмування Python? Наведіть власні приклади використання
конструктора.
18. Поясніть приклади 4.7 та 4.8.

381
19. Поясніть визначення 4.2.
20. Поясніть приклади 4.9, 4.10, 4.11 та 4.12.
21. Як у мові програмування Python встановлюються властивості
об’єктів? Наведіть власні приклади встановлення властивостей об’єктів.
22. Поясніть приклади 4.13 та 4.14.
23. Як реалізований механізм інкапсуляції у мові програмування
Python? Наведіть власні приклади реалізації цього механізму для різних
класів.
24. Що являють собою приватні методи класу та як вони реалізовані у
мові програмування Python? Наведіть власні приклади створення приватних
методів класу.
25. Поясніть приклад 4.15, 4.16 та 4.17.
26. Що являє собою команда property() у мові програмування
Python та як вона використовується для формування приватних методів
класу? Наведіть власні приклади використання цієї команди.
27. Яку узагальнену синтаксичну конструкцію має команда
property() та як її можна використовувати у спрощеному вигляді?
Наведіть власні приклади використання узагальненої та спрощеної
конструкції цієї команди.
28. Поясніть приклади 4.18 та 4.19.
29. Як реалізований механізм успадкування класів у мові
програмування Python? Наведіть власні приклади реалізації цього механізму
для різних класів.
30. Як реалізований механізм множинного успадкування класів у мові
програмування Python? Наведіть власні приклади реалізації цього механізму
для різних класів.
31. Поясніть приклад 4.20.
32. Що являє собою системна функція super() та як вона
використовується для реалізації механізму успадкування класів? Наведіть
власні приклади використання цієї функції.

382
33. Поясніть приклади 4.21 та 4.22.
34. Як у мові програмування Python можна формувати та аналізувати
список із об’єктів визначеного класу? Наведіть власні приклади формування
та аналізу таких списків.
35. Поясніть приклади 4.23 та 4.24.
36. На основі прикладу 4.6 та виконання завдань 15, 16 та 17 створіть
батьківський клас, нащадками якого мають бути класи Cat, Goat, Pig,
Sheеp, Cow, Cock, Fish та New_Animal. Взявши за основу
класифікаційну діаграму, наведену на рис. 1.1 у першому розділі, побудуйте
класифікаційну діаграму для класу Animal.
37. Для батьківського класу Fish, створеного в результаті виконання
завдань 15, 17 та 36, створіть об’єкти, де опишіть властивості риб, яких Ви
знаєте. Які з цих властивостей є загальними для всіх риб, а які –
індивідуальними, притаманними лище даному екземпляру цього класу? Як
для створення екземплярів цього класу Ви використовували поліморфізм
об’єктів?
38. За результатами виконання завдання 37 побудуйте класифікаційну
діаграму об’єктів класу Fish, аналогічну анведеній на рис. 1.1.
39. Поясніть приклад 4.25 та зробіть порівняльний аналіз програм,
наведених у прикладах 3.19 та 4.25. Поясніть, чому введення класів та
об’єктів значно спрощує код програми, призначеної для визначення типу
метала за його електропровідністю.
40. Реалізуйте програму, наведену у прикладі 4.25, з використанням
списків без застосування засобів об’єктно-орієнтованого програмування.
Порівняйте написану програму із програмою, наведеною у прикладі 4.25.
Зробіть відповідні висновки про те, у яких випадках використання об’єктів та
класів є зручнішим, ніж стандартні методи структурного програмування
мови Python. Свою відповідь обґрунтуйте та наведіть доречні приклади таких
програм.
41. Поясніть блок-схему алгоритму, яка наведена на рис. 4.1.

383
42. Поясніть правила 4.1 – 4.17.
43. Зробіть порівняльний аналіз методів об’єктно-орієнтованого та
модульного програмування, реалізованих у мові Python. У яких випадках
краще та простіше використовувати об’єкти, а в яких – модулі? Свою
відповідь обґрунтуйте та наведіть власні приклади програм, написаних з
використанням об’єктів та модулів, які виконують однакові функції.
Порівняйте написані програмні коди та вкажіть їхні переваги та недоліки.
44. Як концепція об’єктно-орієнтованого програмування мови Python
пов’язана із філософськими принципами цієї мови, розглянутими у
підрозділі 1.5? Наведіть власні приклади програм, написаних з
використанням об’єктно-орієнтованого підходу, які відповідають цим
принципам, або, навпаки, суперечать їм.
45. Що являє собою поняття множини у мові програмування Python та
як воно пов’язане із визначенням множини у дискретній математиці?
Наведіть власні приклади описання множини у мові програмування Python.
46. Поясніть визначення 4.3.
47. За допомогою якого ключового слова описується множини у мові
програмування Python? Наведіть власні приклади описання множини.
48. Чи повинні елементи множини бути унікальними? Свою відповідь
обґрунтуйте.
49. Чи є елементи множини впорядкованими? Свою відповідь
обґрунтуйте.
50. Поясніть приклад. 4.26.
51. Поясніть рис. 4.2.
52. Поясніть правила 4.18 – 4.23.
53. Як можна створити множину із списку? Наведіть власні приклади
такого створення множини.
54. Поясніть приклад 4.27.
55. Як можна уникнути повторення елементів у списку через
використання множин? Наведіть власні приклади такого використання

384
множин.
56. Поясніть приклади 4.28 та 4.29.
57. Як можна уникнути повторення елементів у рядку через
використання множин? Наведіть власні приклади такого використання
множин.
58. Поясніть приклад 4.30.
59. Які головні операції над множинами реалізовані у мові
програмування Python? Наведіть власні приклади використання цих
операцій.
60. Поясніть приклади 4.31 та 4.32.
61. Поясніть діаграму Вейля, наведену на рис. 4.3.
62. Які додаткові операції над множинами реалізовані у мові
програмування Python? Наведіть власні приклади використання цих
операцій.
63. Поясніть приклад 4.33.
64. Поясніть діаграму Вейля, наведену на рис. 4.4.
65. Поясніть приклад 4.34.
66. Поясніть діаграму Вейля, наведену на рис. 4.5.
67. Як можна проаналізувати наявність відповідного елементу у
множині з використанням оператора циклу із заданою кількістю повторень?
Наведіть власні приклади такого аналізу.
68. Поясніть приклад 4.35.
69. Що являє собою поняття кортежу у мові програмування Python?
Наведіть власні приклади описання кортежів.
70. Поясніть визначення 4.4.
71. За допомогою якого ключового слова описується кортежі у мові
програмування Python? Наведіть власні приклади описання кортежів.
72. Поясніть правила 4.24 – 4.26.
73. Поясніть приклади 4.36 та 4.37.
74. Поясніть правила 4.27 та 4.28.

385
75. Поясніть приклад 4.38.
76. Поясніть правило 4.29 та приклад 4.39.
77. Як можна сформувати кортеж через створений список? Наведіть
власні приклади такого формування кортежів.
78. Поясніть правило 4.30 та приклад 4.40.
79. Як з використанням засобів програмування мови Python можна
об’єднати два створених кортежі? Наведіть власні приклади об’єднання
кортежів.
80. Поясніть правило 4.31 та приклад 4.41.
81. Поясніть правила 4.32 – 4.34.
82. Поясніть приклад 4.42.
83. Що являють собою іменовані кортежі у мові програмування Python?
Наведіть власні приклади іменованих кортежів.
84. За допомогою якого ключового слова визначається іменований
кортеж? Наведіть власні приклади формування іменованого кортежу.
85. Які способи звернення до елементів іменованого кортежу Вам
відомі? Наведіть власні приклади використання цих способів.
86. Чи можуть бути змінені елементи іменованого кортежу?
87. Поясніть правило 4.35.
88. У яких випадках під час написання програм зручніше
використовувати іменовані кортежі, а у яких – об’єкти? Наведіть власні
приклади програм, у яких замість об’єктів використовуються іменовані
кортежі.
89. Чому кортежі дуже зручно використовувати для описання
геометричних об’єктів? Наведіть власні приклади такого використання
кортежів.
90. Як у мові програмування Python для описання геометричних
об’єктів використовуються перевантажені функції? Наведіть власні приклади
такого використання перевантажених функцій.
91. Яке призначення у мові програмування Python мають перевантажені

386
методи __eq__() та __str__()? Наведіть власні приклади використання
цих перевантажених методів.
92. Як з використанням ієрархії наслідування класів мови
програмування Python можна описувати геометричні об’єкти? Наведіть
власні приклади такого описання геометричних об’єктів.
93. Поясніть приклади 4.44 та 4.45.
94. З використанням ієрархії наслідування класів, використовуючи
клас Point, створений у прикладі 4.44 як базовий, створити такі дочірні
класи, як трикутник, трапеція, паралелограм, прямокутник та шестикутник.
Створити відповідні методи для обчислення площі геометричної фігури та її
периметру, а також для порівняння геометричних фігур.
95. Поясніть ієрархічну діаграму успадкування геометричних об’єктів,
яка наведена на рис. 4.6.
96. Як для описання геометричних об’єктів використовуються операції
з кортежами? Наведіть власні приклади такого використання операцій з
кортежами.
97. Як для роботи з математичними об’єктами використовуються
перевантажені методи __add__() та __sub__()? Наведіть власні
приклади використання цих перевантажених методів.
98. Як для роботи з математичними об’єктами використовуються
перевантажені методи __mul__() та __rmul__()? Наведіть власні
приклади використання цих перевантажених методів.
99. Чому для реалізації перевантажених алгебраїчних операцій у теорії
програмування розрізняють операції лівого та правого множення? Наведіть
власні приклади, в яких продемонструйте, чим саме суттєво відрізняються ці
дві операції.
100. Поясніть приклад 4.46.
101. На основі прикладу 4.46 сформуйте новий клас «Тривимірний
вектор» та реалізуйте для об’єктів цього класу алгебраїчні операції
додавання, віднімання та множення вектора на число.

387
102. Що являє собою поняття словника у мові програмування Python?
Наведіть власні приклади описання словників.
103. Поясніть визначення 4.5.
104. За допомогою якого ключового слова описується словники у мові
програмування Python? Наведіть власні приклади такого описання словників.
105. Що являють собою ключі у словниках та як вони формуються?
106. Поясніть правила 4.36 – 4.40.
107. Що являють собою відношення між елементами словника?
108. Що являють собою елементи словника з точки зору теорії
множин?
109. Поясніть рис. 4.7.
110. Які дані та структури мови програмування Python можуть бути
елементами словника? Наведіть власні приклади формування словників з
такими елементами.
111. Поясніть приклад 4.47.
112. Чи можна змінювати ключі словника?
113. Які структури даних мови програмування Python можна
використовувати для створення ключів і чому?
114. Поясніть правила 4.41 та 4.42.
115. Поясніть приклад 4.48.
116. Як для аналізу словників може бути використаний оператор in.
Наведіть власні приклади такого використання цього оператора.
117. Поясніть правило 4.43 та приклад 4.49.
118. Чи можна з використанням словників зберігати довідникову
інформацію? Наведіть власні приклади такого використання словників.
119. Поясніть приклади 4.50 та 4.51.
120. Як можна створити словник із списку? Наведіть власні приклади
такого створення словника.
121. Як можна створити словник із рядка? Наведіть власні приклади
такого створення словника.

388
122. Як можна створити словник із кортежу? Наведіть власні приклади
такого створення словника.
123. Поясніть приклад 4.52.
124. Які функції мови програмування Python можуть бути використані
для роботи із словниками? Наведіть власні приклади такого використання
цих функцій.
125. Поясніть приклад 4.53.
126. Як для аналізу словників може бути використаний оператор циклу
із заданою кількістю повторень? Наведіть власні приклади такого
використання цього оператора.
127. Які практичні завдання програмування можуть бути розв’язані з
використанням словників? Свою відповідь обґрунтуйте.
128. Написати з використанням словника програму, призначену для
кодування інформації простим кодом та для декодування закодованого
повідомлення.
129. З використанням методів об’єктно-орієнтованого програмування
та словників на основі інформації, наведеної у практичному занятті 3,
створіть довідник з транзисторів та напишіть програму для визначення типу
транзисторо за його маркуванням.
130. З використанням довідника [62] та іншої довідникової літератури
створити програму, яка визначає властивості діодів та тиристорів за їхнім
маркуванням. Для написання програми застосовувати методи та засоби
об’єктно-орієнтованого програмування мови Python.

389
Мельник І.В.

Основи програмування на мові Python.


Комплексний навчальний посібник з курсів
«Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі»
для студентів-бакалаврів напряму підготовки
171 «Електронні пристрої та системи».
Том 2. Розвинені засоби мови програмування Python, призначені для
розв’язування складних інженерних та наукових завдань

Київ
Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»

2019
Рекомендовано до друку
Методичною радою Національного технічного університету України „ Київський
політехнічний інститут імені Ігоря Сікорського”, протокол № ____ від
___ грудня 2019 р.
Рецензенти:
В.Т. Лазурік, доктор технічних наук, професор, декан факультету
математики та інформатики Харківського національного універ-
ситету ім. В.Н. Каразіна
С.С. Забара, доктор технічних наук, професор, завідуючий ка-
федрою інформаційних технологій та програмування Інституту
комп’ютерних технологій Відкритого міжнародного університету
розвитку людини „Україна”, лауреат Державної премії СРСР, ла-
уреат Державної премії України
Мельник І.В.
Основи програмування на мові Python. Комплексний навчальний
посібник з курсів «Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі» для студентів-бакалаврів
напряму підготовки 171 «Електронні пристрої та системи». Том 2.
Розвинені засоби мови програмування Python, призначені для
розв’язування складних інженерних та наукових завдань. – 515 с.

Посібник містить великий обсяг теоретичного та практичного


матеріалу щодо програмування на мові Python, яка сьогодні
вважається однією із самих розвинених мов програмування,
призначених для вирішення завдань моделювання. У другому томі
посібника розглянуті засоби написання програм з віконним графічним
інтерфейсом та основи роботи з системою програмування Anacona,
яка вважається однією з найкращих для проведення науково-технічних
розрахунків. Особлива увага приділяється роботі з масивами, засобам
побудови двовимірної та тривимірної наукової гафіки, можливостям
симовльного процесора, способам обчислення інтегралів та способом
розв’язування диференціальних рівнянь. Окремо розглянуті засоби
мови програмування Python, призначені для створення клієнт-
серверних мережних додатків та для програмування мікроконтролерів.
Посібник призначений для студентів-бакалаврів, які навчаються за
напрямом «Електронні пристрої та системи», може бути корисним для
студентів інших напрямів.
© Мельник І.В., 2019

2
Розділ 5 Створення програм із віконними графічними
інтерфейсами
У цьому розділі розглядаються засоби мови програмування Python для
створення елементів графічного інтерфейсу користувача та їх
розташування на головному інтерфейсному вікні. Розглянута узагальнена
класифікація елементів інтерфейсу, а також способи їх створення та
визначення їхніх властивостей з використанням засобів програмування мови
Python. Як приклади програм із графічним інтерфейсом користувача
розглянуті прості лічильники кількості натиснень на кнопку, простий
калькулятор, калькулятор для проведення наукових розрахунків, конвертори
фізичних величин та програма для визначення типу матеріалу за його
електрофізичними властивостями. Розглянуті також способи розміщення в
інтерфейсному вікні графічних об’єктів.

5.1 Узагальнена структура програм із консольним та віконним


інтерфейсами
Всі фрагменти програм, які були розглянуті у попередніх розділах, були
переважно орієнтовані на реалізацію відповідних обчислювальних алгоритмів, а
введення та виведення даних здійснювалось у спрощеній формі через
командний рядок інтерпретатора. Такий підхід може бути використаний для
відлагодження програмного коду, але готові програмні продукти без зручного
графічного інтерфейсу користувача сьогодні не мають широкого попиту на
ринку комп’ютерних програм.
Вперше застосував термін графічний інтерфейс та зопропонував
маніпулятор типу миші для роботи з ним відомий американський інженер та
вчений Дуглас Карл Енгельбарт. Перша модель комп’ютерної миші була
розроблена Д.К. Енгельбартом у 1968 році [72]. Інший видатний вчений, Айвен
Едвард Сазерленд, почав ефективно застосовувати графічні засоби для роботи зі
своєю новою програмою Sketchpad починаючи ще з 1963 року. Він вперше
запропонував використовувати для введення графічної інформації в комп’ютер
такі електронні пристрої, як світлове перо та планшет [73, 74].
Програмні засоби для створення зручних віконних інтерфейсів почали
бурхливо розвиватися з початку дев’яностих років минулого століття із
появою операційної системи Windows, і сьогодні вони є загальним
стандартом для комерційного та вільного програмного забезпечення.
Узагальнені методи створення віконних інтерфейсів описані у посібниках
[16, 17]. Розглянемо їх у цьому розділі більш докладно.
3
Дуглас Карл Енгельбарт Айвен Едвард Сазерленд
(1925 – 2013) (нар. 1938)

У консольних програмних додатках, які працюють через командний


рядок, для введення та виведення даних використовується система
переривань [1]. З теоретичної точки зору переривання являють собою функції
операційної системи, призначені для здійснення елементарних операцій для
роботи з зовнішніми пристроями, наприклад таких, як введення символу з
клавіатури або виведення символу або точки заданого кольору на екран [1].
Зрозуміло, що зручний віконний інтерфейс створювати з використанням
таких засобів програмування вельми важко [16]. Тому зазвичай такі програми
створюються іншим чином, через формування посилань на елементи
графічного інтерфейсу та реалізацію алгоритмів обробки подій [16, 24].
Підпрограми обробки подій є біль складними функціями операційної
системи, ніж переривання, тому написання програм із розвиненими
графічними з використанням таких засобів програмування є значно
простішим. Але, у будь-якому разі, програми із графічними інтерфейсами
відрізняються від консольних лише способом введення та виведення даних,

4
тому відлагодження алгоритмів можна проводити і з використанням
консольного режиму роботи.
Блок-схема узагальненого алгоритму роботи консольної програми
наведена на рис. 5.1, а, а алгоритму роботи програми з віконним
інтерфейсом – на рис. 5.1, б [24].

Початок Початок 3

Відкриття вікна 4
Введення 1 графічного Є запит на
1 вхідних даних Ні
інтерфейсу 3 завершення 5
роботи?
Запуск циклу
2
2 Обробка даних обробки подій 5
Кінець
3
Виведення Є подія для Ні 4
3 результатів 2
обробки?

5 Обробка даних
Кінець 4

а) б)
Рис. 5.1 Узагальнені блок-схеми алгоритмів роботи програм із консольним
(а) та віконним (б) інтерфейсами

Тобто, для віконного інтерфейсу, на відміну від консольного, важливим


є наявність події. Такою подією може бути натиснення клавіші на клавіатурі,
натиснення кнопки миші, сигнал від будь-якого електронного приладу,
підключеного до комп’ютера, або зиіна властивостей будь-якого
інтерфейсного елемента [24, 25, 70].
Розглянемо у наступному підрозділі засоби мови програмування Python
для створення компонентів віконного інтерфейсу.
5
5.2 Створення та розташування компонентів віконного інтерфейсу
з використанням засобів програмування мови Python

5.2.1 Створення головного вікна для розташування елементів


віконного інтерфейсу та способи їхнього розташування
Загалом віконний інтерфейс програми, написаної мовою
програмування Python, формується згідно із алгоритмом, наведеним на рис.
5.1, б. Тобто, для написання віконного інтерфейсу необхідно послідовно
виконати наступні дії [24, 25].
1. Підключити відповідний модуль, в якому розташовані функції для
створення віконного інтерфейсу. Наприклад, в стандартний комплект
бібліотеки інтерпретатора Python версії 3 завжди входить модуль tkinter
[24, 25].
2. Викликати функцію створення головного вікна інтерфейсу. Для
цього створюється відповідний об’єкт window, через посилання на якій
потім створюються додаткові компоненти інтерфейсу. Якщо підключений
модуль tkinter, для створення головного вікна достатньо викликати
функцію window.Tk().
3. Для подальшої роботи з елементами віконного інтерфейсу,
розташованими на головному вікні, через аналіз та обробку відповідних
подій, необхідно викликати циклічну функцію обробки подій
window.mainloop() [24, 70].
Тобто, код програми для створення головного вікна інтерфейсу може
мати наступний вигляд [24].
Приклад 5.1
>>> # Підключення модуля, де розташовані об’єкти
>>> # для роботи з віконним інтерфейсом
>>> import tkinter
>>> # Виклик функції створення головного вікна
>>> window = tkinter.Tk()
>>> # Виклик функції обробки подій для головного вікна
6
>>> window.mainloop()
Як результат виконання командних рядків, наведених у прикладі 5.1, на
екрані монітора з’являється головне вікно графічного інтерфейсу, аналогічне
наведеному на рис. 5.2.

Рис. 5.2 Головне вікно графічного інтерфейсу, створене з використанням


засобів програмування мови Python

Тепер на полі головного вікна можна розташовувати елементи


графічного інтерфейсу, які також іноді в технічній літературі називають
запозиченим з англійської мови словом віджет (від англійського widget –
елемент інтерфейсу) [24]. Для розташування елементів інтерфейсу
створюються відповідні прямокутні області, які іноді в технічній літературі
називають запозиченим з англійської мови словом фрейм (від англійського
frame – кадр, рамка) [24]. Узагальнений принцип розташування елементів
інтерфейсу, зокрема кнопок та текстових вікон, показаний на рис. 5.3.

Корневе вікно

Область розташування текстових полів


Текстове поле 1 Текстове поле 2

Текстове поле 3 Текстове поле 4

Область розташування кнопок


Кнопка 1 Кнопка 2 Кнопка 3

Рис. 5.3 Елементи інтерфейсу та області їхнього розташування

7
Для спрощення розуміння та вивчення, а також для спрощення
написання програмного коду, у теорії програмування об’єкти графічного
інтерфейсу поділені на відповідні класи, які будуть розглянуті у наступному
підрозділі.

5.2.2 Класифікація елементів віконного інтерфейсу


Загалом розрізняють наступні класи елементів інтерфейсу [24, 69, 70].
1. Вікно відформатованого тексту (Text). Це прямокутний елемент
інтерфейсу, який дозволяє виводити, редагувати та форматувати текст з
використанням різних стилів. Можливості роботи із текстом визначаються
властивостями цього об’єкту. Подією вважається введення тексту в текстове
вікно або виконання операції збереження тексту.
2. Полотно (Canvas). Це прямокутний елемент інтерфейсу, у якому
відображуються примітивні графічні об’єкти.
3. Кнопка (Buttom). Звичайна кнопка графічного інтерфейсу для
виконання відповідних команд через наведення на неї курсору натиснення
лівої кнопки миші.
4. Селекторна кнопка (Radiobuttom). Обрання одного із пунктів
програмного меню через перемикання елементів списку за системою «АБО».
Тобто, цей елемент інтерфейсу дозволяє обрати лише один із альтернативних
варіантів запропонованого списку. В інтерфейсі, зробленому за стандартом
системи Windows, ці кнопки є круглими та відмічаються точкою [6, 7].
5. Прапорець (Checkbuttom). Кнопка обрання одного із пунктів
програмного меню через перемикання елементів списку за системою «І».
Тобто, цей елемент інтерфейсу дозволяє обрати декілька можливих пунктів із
списку, хоча такий елемент можк бути лише один. Повторне натиснення
відключає попередньо обраний компонент. В інтерфейсі, зробленому за
стандартом системи Windows, ці кнопки є квадратними та відмічаються
галочкою [6, 7].
6. Поля введення тексту (Entry). Горизонтальна смуга, до якої
вводиться текстовий рядок. Інформація, завантажена до поля введення
тексту, завжди сприймається комп’ютером лише як текстовий рядок. Якщо у
програмі, яка пишеться, маються на увазі числові дані, для проведення
подальших обчислень програмісту необхідно виконати відповідне

8
перетворення типів даних з використанням функцій, розглянутих у
підрозділі 2.4.3.
7. Рамка (Frame). Сукупність елементів інтерфейсу, розташованих в
одній області. Властивості фрейму визначаються властивостями
розташованому у ньому елементарних об’єктів через операцію наслідування.
8. Надпис (Label). Універсальний елемент інтерфейсу для виведення
текстових або графічних об’єктів.
9. Список (Listbox). Прямокутна область інтерфейсу зі списком компонент,
із яких користувач може обрати один через натиснення верхньої та нижньої
стрілочки. Якщо у списку стоїть натуральне число, стрілочка догори означає
його збільшення, а стрілочки вниз – відповідно, його зменшення. Такий список
також називається нумерованим списком, або лічильником (Spinbox).
10. Меню (Menu). Елемент інтерфейсу, за рахунок якого створюються
випливаючи та низпадаючи меню.
11. Кнопка-меню (Menubuttom). Кнопка із низпадаючим меню,
аналогічна показаній на рис. 2.15. Для операційної системи Windows цей
елемент не є загальним стандартом, але у програмах, написаних в
інтерпретаторі мови програмування Python, він іноді використовується.
12. Повідомлення (Message). Вікно для виведення великих текстових
повідомлень, яке, на відміну від текстових вікон (Text) та надпису (Label)
дозволяє передивлятися текст через елемент прокручування (листання) та
відображує лише частину тексту. За вимогою користувача розмір вікна
повідомлення та, відповідно, кількість символів тексту в ньому, може бути
зміненим. Цей елемент є особливо важливим для відображення вмісту
великих файлів та мережних повідомлень. Програма простого текстового
редактора із вікном повідомлення буде розглянута у підрозділі 5.3.4. Способи
надсилання та приймання мережних повідомлень з використанням засобів
програмування мови Python розглядатимуться у підрозділі 6.2.
13. Шкала (Scale). Цей елемент інтерфейсу дозволяє формувати у
заданому числовому діапазоні потрібне числове через переміщення
маркераабо повзунка.
14. Смуга прокрутки (Scrollbar). Елемент інтерфейсу, який дозволяє
відображати ту або іншу частину даних, які занесені до вікна. Цей елемент часто
використовується разом із елементом введення повідомлення (Message).
9
15. Вікно верхнього рівня (Toplevel), або головне вікно.
Наочно головні елементи графічного інтерфейсу показані на рис. 5.4.

Рис. 5.4 Головні елементи віконного інтерфейсу

Розглянемо у цьому розділі способи створення різних елементів


віконного інтерфейсу в межах головного вікна.

5.2.3 Способи формування простих текстових вікон


Згідно із загальною класифікацією об’єктів віконного інтерфейсу, яка
була наведена у підрозділі 5.2.2, а також із блок-схемою алгоритму,
наведеною на рис. 5.1, б, текстові вікна повинні мати наступні властивості.

10
1. Бути розташованими на головному вікні, що необхідно відобразити в
комп’ютерній програмі через механізм наслідування.
2. У разі зміни тексту через його введення з клавіатури відповідні зміни
мають бути відображені у текстовому вікні через механізм обробки подій.
Розглянемо найпростіший приклад створення текстового вікна, у якому
зміна виведеного тексту не передбачається. Для створення вікна виведення
тексту будемо використовувати універсальний об’єкт Label, призначений
для виведення текстової та графічної інформації [24].
Приклад 5.2
# Підключення модуля, де розташовані об’єкти
# для роботи з віконним інтерфейсом
import tkinter
# Виклик функції створення головного вікна
window = tkinter.Tk()
# Виклик функції створення універсального
# елемента інтерфейсу для виведення тексової
# інформації
label=tkinter.Label(window, text = ‘Це тек\
ст для виведення у вікно’)
# Відображуємо створений об’єкт на головному
# вікні з використанням функції pack()
label.pack()
# Виклик функції циклічної обробки подій для
# головного вікна
window.mainloop()
Результат роботи цих командних рядків показаний на рис. 5.5.

Рис. 5.5. Результат роботи програмного коду, наведеного у прикладі 5.2.


11
Розглянемо головні особливості коду програми, наведеного у прикладі 5.2.
1. Функція, призначена для створення текстового вікна Label(), має
два параметри.
2. Першим з цих параметрів є батьківський об’єкт, на якому має бути
розташований цей фрагмент інтерфейсу. У даному випадку це головне вікно
window, але пізніше ми побачимо, що так буває не завжди.
3. Другим параметром є безпосередньо той текст, який необхідно
виводити.
4. Для відображення об’єкту використовується функція pack() із
посиланням на об’єкт, який необхідно відобразити. Ця функція може бути
викликана без параметрів. Тобто, для відображення створеного текстового
вікна label слід написати командний рядок label.pack().
5. Як і у прикладі 5.1, для виконання циклічного процесу обробки подій
використана функція window.mainloop().
6. Можна легко помітити, що у прикладі 5.2 всі імена змінних, які
дають посилання на об’єкти віконного інтерфейсу, написані з малої літери, а
всі імена методів для роботи з цими об’єктами – з великої літери. Тобто,
label – це змінна, а Label() – функція. Цього правила, щодо написання
імен змінних та функцій, будемо дотримуватись у цьому посібнику і надалі.
Розглянемо більш складний приклад, у якому три текстових вікна
виводяться у заданій області вікна через формування фрейму [24].
Приклад 5.3
# Підключення модуля для роботи з графічним
# інтерфейсом
import tkinter
# Виклик функції створення головного вікна
window = tkinter.Tk()
# Виклик функції Frame() для створення

12
# фрейму на головному вікні
frame = tkinter.Frame(window)
# Відображуємо створену область на головному
# вікні з використанням функції pack()
frame.pack()
# Виклик функції для створення першого
# текстового вікна
first = tkinter.Label(frame, text = ‘Пер\
ше вікно’)
# Відображення першого текстового вікна
first.pack()
# Виклик функції для створення другого
# текстового вікна
second = tkinter.Label(frame, text = ‘Дру\
ге вікно’)
# Відображення другого текстового вікна
second.pack()
# Виклик функції для створення третього
# текстового вікна
third = tkinter.Label(frame, text = ‘Тре\
тє вікно’)
# Відображення третього текстового вікна
third.pack()
window.mainloop()
Результат роботи командних рядків, наведених у прикладі 5.3,
показаний на рис. 5.6.

Рис. 5.6. Результат роботи програмного коду, наведеного у прикладі 5.3

13
Розглянемо головні відмінності командних рядків, наведених у
прикладах 5.2 та 5.3.
1. Фрейм, створений з використанням командного рядку
frame = tkinter.Frame(window), відразу відображується у
головному вікні інтерфейсу з використанням функції frame.pack().
2. Надалі всі текстові вікна створюються із посиланнями не на головне
вікно, і на фрейм. Наприклад:
third = tkinter.Label(frame, text = ‘Третє вікно’)
3. Для відображення кожного із вікон використовується команда
pack() із посиланням на відповідний об’єкт. Наприклад: third.pack().
Узагальнений алгоритм створення віконного інтерфейсу із
розташуванням об’єктів у фреймі наведений на рис. 5.7.
Цікавим є те, що під час створення фрейму можна змінити його
властивості. Наприклад, можна вказати товщину граничної лінії
borderwidth та кольорову гаму для фону relief. Розглянемо спосіб,
яким це можна зробити, на наступному прикладі [24].
Приклад 5.4
import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
frame2 = tkinter.Frame(window, borderwidth = 4,\
relief = tkinter.GROOVE)
frame2.pack()
first = tkinter.Label(frame, text = ‘Пер\
ше вікно’)
first.pack()
second = tkinter.Label(frame2, text = ‘Дру\
ге вікно’)
second.pack()
third = tkinter.Label(frame2, text = ‘Тре\

14
тє вікно’)
third.pack()
window.mainloop()

Початок

Створення та відображення
1 головного вікна

Створення та відображення
2 фрейму із посиланням на
головне вікно

Створення та відображення
3 елементів інтерфейсу із
посиланням на фрейм

4 Формування циклу обробки


подій для головного вікна

Кінець

Рис. 5.7 Алгоритм створення віконного інтерфейсу із фреймом

Результат роботи командних рядків, наведених у прикладі 5.4,


показаний на рис. 5.8.

Рис. 5.8. Результат роботи програмного коду, наведеного у прикладі 5.4

15
Із наведених прикладів зрозуміло, що компоненти графічного
інтерфейсу можуть бути розташовані у фреймі автоматично, без
прив’язування до відповідних координат батьківського об’єкту та взагалі без
визначення позиції розташування. Нижче будуть розглянуті більш широкі
можливості щодо розташування компонент інтерфейсу з використанням
ефективних засобів програмування. Але слід відзначити, що автоматизоване
розташування компонент також є досить зручним для програмістів та значно
спрощує програмний код.
Розглянемо інший приклад, у якому відображення тексту у текстовому
вікні здійснюється дещо інакше, через формування рядкової змінної. У цьому
разі особливість полягає у тому, що ця рядкова змінні обов’язково має
належати до класу StringVar() модуля tkinter. Із подальшого розгляду
наведеного матеріалу буде зрозуміло, що саме такий спосіб створення
змінних у мові програмування Python забезпечує коректні зв’язки між
різними компонентами інтерфейсу. Якщо здійснюється виведення тексту у
текстове вікно елемента інтерфейсу Label через формування рядкової
змінної, необхідно виконати наступні дії [24, 69, 70].
1. Сформувати посилання на рядок через виклик функції
StringVar() модуля tkinter, не вказуючи розмір цього рядка. Ця
операція виконується з використанням звичайного оператора присвоєння
data = tkinter.StringVar().
2. З використання функції set() модуля tkinter змінній data
присвоюється відповідне значення. Наприклад:
data.set(‘Дані для виведення у вікно’)
3. Під час формування текстового вікна з використанням функції
tkinter.Label() через оператор присвоєння вказується посилання на
відповідну властивість об’єкта textvariable = data. Тоді виклик
функції формування текстового вікна має наступний вигляд:
label = tkinter.Label(window, textvariable = data)

16
4. Здійснюється відображення створеного текстового вікна на
головному вікні інтерфейсу з використанням команди label.pack().
Узагальнена блок-схема алгоритму виведення тексту у текстове вікно
через ініціалізацію рядкової змінної та присвоєння їй відповідного значення
наведена на рис. 5.9.
Тоді відповідний програмний код із формуванням текстового вікна з
використанням рядкової змінної можна записати наступним чином.
Приклад 5.5
import tkinter
window = tkinter.Tk()
data = tkinter.StringVar()
data.set(‘Рядок для виведення у вікно’)
label = tkinter.Label(window, textvariable = data)
label.pack()
window.mainloop()
Результат роботи цих програмних рядків показаний на рис. 5.10.

5.2.4 Узагальнена схема відображення компонентів віконного


інтерфейсу Модель – Вигляд – Контролер
Розглянемо інший приклад, у якому текст вводиться у вікно через зміну
властивостей елемента інтерфейсу класу Entry, та паралельно виводиться в
інше текстове вікно, яке створене на основі елемента інтерфейсу класу
Label. Такий програмний код є більш складним та працює за наступним
алгоритмом.
1. Створюється рядкова змінна data, яка належить до класу
StringVar.
2. Створюється текстове вікно Label, властивість якого визначається
змінною var. Відповідний оператор присвоєння має вигляд
textvariable = var.

17
Початок

Створення посилання на
рядкову змінну з
1 викорисанням оператора
data = StringVar()

Присвоєння текстовій змінній


відповідного значення через виклик
2 функції set() модуля tkinter:
data.set(‘Значення’)

Формування текстового вікна з


використанням функції
tkinter.Label()
3 через посилання на відповідну
властивість об’єкта
textvariable = data

Виведення текстового вікна на головне


інтерфейсне вікно або до фрейму з
4 використанням функції
pack()

Формування циклу обробки подій для


5 головного вікна з використанням функції
window.mainloop()

Кінець

Рис. 5.9 Блок-схема алгоритму виведення тексту у текстове вікно через


формування рядкової змінної

Рис. 5.10 Результат роботи програмного коду, наведеного у прикладі 5.5

18
3. Створюється текстове вікно Entry, властивість якого також
визначається змінною data. Відповідний оператор присвоєння також має
вигляд textvariable = var.
Розглянемо, як буде працювати програмний код, якщо властивості
текстових вікон визначені згідно із описаним вище алгоритмом. У
текстовому вікні класу Entry можна змінити значення змінної var.
Оскільки виконання програмного коду, призначеного для відображення
інтерфейсного вікна, циклічно продовжується через виконання команди
window.mainloop(), через певний час будуть змінені також властивості
вікна класу Label, які пов’язані з тією самою рядковою змінною var. Таким
чином, з урахуванням високої швидкодії сучасних комп’ютерів, введення
даних у текстове вікно класу Entry майже відразу змінює властивості вікна
класу Label, що впливає на зовнішній вигляд цього вікна. Реально обмін
даними здійснюється таким чином, що як тільки відповідний текст
з’являється у вікні редактора, він відображується у текстовому вікні Label,
хоча властивості цього вікна користувач безпосередньо не змінює.
Такий процес обміну даними між об’єктами інтерфейсу у комп’ютерній
літературі називається моделлю МВК, як абревіатура слів Модель – Вигляд
– Контролер (англійський термін – MVC, Model – View – Controller) [24,
25, 69, 70]. Компоненти цього ланцюжка мають наступні значення.
1. Модель являє собою спосіб збереження даних, наприклад, посилання
на відповідні змінні модуля tkinter, які визначають властивості об’єкта.
2. Вигляд – це спосіб відображення даних.
3. Контролер – це алгоритми та способи обробки даних.
Зв’язок між елементами цієї схеми обробки даних наочно показаний на
рис. 5.11 [24, 25].
У прикладі 5.6 наведений код програми, який реалізує описану та
наочно показану на рис 5.11 модель МВК для текстових вікон класів Entry
та Label.

19
Модель:
збереження даних як Вигляд:
властивостей об’єктів відображення об’єктів
через посилання на із заданими
змінні модуля властивостями через
аналіз значень змінних
tkinter

Контролер:
зміна властивостей
об’єктів після
відповідних подій в
інтерфейсному вікні

Рис. 5.11 Наочна ілюстрація взаємодії компонентів для моделі МВК [24]

Приклад 5.6
import tkinter
window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()
var = tkinter.StringVar()
label = tkinter.Label(frame, textvariable = var)
label.pack()
entry = tkinter.Entry(frame, textvariable = var)
entry.pack()
window.mainloop()
Результат роботи програмного коду, наведеного у прикладі 5.6,
показаний на рис. 5.12.

Рис. 5.12 Результат роботи програмного коду, наведеного у прикладі 5.6

20
5.2.5 Розташування кнопок як елементів віконного інтерфейсу та
способи аналізу події натиснення на кнопку

5.2.5.1 Методи розташування кнопок та визначення їхніх


властивостей
Розглянемо тепер методи створення та розташування кнопок як
елементів інтерфейсу, які існують в мові програмування Python. Створити
кнопку досить легко. Для цього достатньо звернутися до об’єкту Button
модуля tkinter, тобто, написати командний рядок [24, 25, 69, 70]:
btm = tkinter.Button(‘Властивості’, ‘Метод’)
Серед властивостей кнопки обов’язковими є дві.
1. Батьківський об’єкт, на якому розташований цей елемент
інтерфейсу. Як і для текстового вікна, таким елементом може бути головне
вікно або фрейм.
2. Текст, який має бути розташований на кнопці. Ця властивість
визначається оператором присвоєння через рядкову змінну text. Наприклад,
text = ‘Рахувати’.
Іншими властивостями кнопки, які можуть визначатися за
замовченням, є колір фону, колір тексту, тип та розмір шрифту, геометричні
розміри кнопки та координати її розташування відносно батьківського
об’єкту [24, 25, 69, 70].
Проте метод для обробки події натиснення на кнопку має бути
вказаним обов’язково. Саме цей параметр виклику функції
tkinter.Button() визначає, яка діє буде виконана у разі натиснення на
кнопку. Зрозуміло, що ця дія визначається не лише наявністю самої події
натиснення на кнопку як елемент інтерфейсу, але й станом головного вікна
на цей момент. Тобто, для визначення методу, який має бути підключеним,
зазвичай необхідно провести аналіз значень всіх активних текстових вікон, а
у багатьох випадках також інших змінних, які є результатом проведення

21
попередніх обчислень. Формування методів обробки події натиснення на
кнопку є окремим завданням теорії та практики програмування та їх загальна
класифікація буде окремо розглянута у підрозділі 5.2.5.2. Проте, у будь-
якому разі, цей метод у разі створення кнопки має бути визначеним.
Розглянемо спочатку спосіб створення простої кнопки, натиснення на
яку відповідає події виходу із програми. Ця подія описується однією простою
функцією модуля tkinter destroy(). Метод destroy() завжди
визначається для головного інтерфейсного вікна, а викликається від через
присвоєння значення імені цієї функції змінній з іменем command. Також
зрозуміло, що для головного вікна інтерфейсу необхідно виконати всі дії,
визначені у блок-схемі алгоритму формування віконного інтерфейсу,
наведеній на рис. 5.7. Тут відсутніми можуть бути лише фрейми, але лише
тоді, колли інтерфейс формується безпосередньо на головному вікні, як у
прикладі 5.2.
Розглянемо приклад простої програми із однією кнопкою для виходу з
неї [70].
Приклад 5.7
import tkinter
window = tkinter.Tk()
btn = tkinter. Button(window, text = ‘Вихід’, /
command = window.destroy)
btn.pack()
window.mainloop
Результат роботи цієї програми показаний на рис. 5.13.

Рис. 5.13 Результат роботи програмного коду, наведеного у прикладі 5.7

22
Важливими є також параметри розташування кнопки, які визначаються
або відносно головного вікна, або відносно фрейму, де вона розташована. У
мові програмування Python існує три методи для розташування елементів
віконного інтерфейсу, а саме: pack(), grid() та place(). У попередніх
прикладах для виведення текстових вікон ми використовували лише метод
pack() без параметрів, що відповідає автоматичному розташуванню
компонентів, які виводяться. Такий метод створення інтерфейсу є найбільш
простим, але не завжди зручним, оскільки програміст може мати своє
уявлення про естетичні особливості оформлення віконного інтерфейсу.
Дійсно, згідно із першим філософським принципом мови програмування
Python, сформульованому у підрозділі 1.5, «Красиве є кращим, ніж
виродливе». Метод розташування pack() має один параметр side, який
визначається через присвоєння йому значення рядкової змінної та може мати
два значення: side = ‘left’ – розташувати ліворуч та side =
‘right’ – розташувати праворуч.
Розглянемо приклад формування інтерфейсного вікна з двома
кнопками, одна з яких виводить у командне вікно інтерпретатора текст
«Прийшов студент Потапенко», а інша закриває головне інтерфейсне вікно.
Можна також змінити наступні параметри головного вікна.
window.title() – заголовок, який пишеться у верхній частині вікна.
Як видно із попередніх наведених екранних копій, за замовченням це рядкова
змінна tk.
window.geometry() – геометричні розміри вікна в міліметрах.
Приклад 5.8
import tkinter
window = tkinter.Tk()
# Зміна заголовку вікна

23
window.title(‘Потапенко’)
# Зміна геометрії вікна
window.geometry(‘280x80’)
# Описання функції Message
def Message(event):
# Виведення текста у вікно інтерпретатора
print(«Прийшов студент Потапенко»)
# Надпис на кнопці ‘Натисни мене’
btn = tkinter.Button(window, text = ‘Натис/
# Ширина кнопки width та її висота heigh /
ни мене’, width = 20, heigh = 4, /
# Колір надпису – чорний. Колір фону – білий.
bg = ‘white’, fg = ‘black’)
# Об’єкт <Button-1> прив’язаний до функцій
# Message через метод bind(). Це означає, що
# ця функція буде виконуватись у разі натиснення
# кнопки btn
btn.bind (‘<Button-1>’, Message)
# Розміщення кнопки на головному вікні ліворуч
btn.pack(side = ‘left’)
# Формування другої кнопки
btn2 = tkinter.Button(window, text = ‘Завер/
# Ширина кнопки width та її висота heigh /
шення’, width = 20, heigh = 4, /
# Колір надпису – червоний. Колір фону – зелений.
bg = ‘green’, fg = ‘red’,
# Команда на закриття вікна
command = window.destroy)
# Розміщення кнопки на головному вікні праворуч
btn2.pack(side = ‘right’)

24
window.mainloop
Результат роботи цієї програми наведений на рис. 5.14.

Рис. 5.14 Результат роботи програмного коду, наведеного у прикладі 5.8

Програмний код, наведений у прикладі 5.8, має наступні особливості.


1. На головному інтерфейсному вікні створюються дві кнопки. Перша
призначена для виведення текстової інформації у командне вікно
інтерпретатора, а друга – для завершення роботи з програмою. Ці кнопки, як
об’єкти віконного інтерфейсу, мають різні властивості. Головними з них є
наступні [70].
2. На кнопці, призначеній для виведення інформації, написаний текст
«Натисни мене», а на кнопці, призначеній для завершення роботи з

25
програмою – слово «Завершення». Ці параметри кнопок визначаються
значенням змінної text.
3. Перша кнопка розташована у лівій частині інтерфейсного вікна, а
друга – у правій. Параметри розташування для методу pack()
визначаються значенням рядкової змінної side.
4. Кнопки мають різне оформлення. На першій кнопці тест написаний
чорними літерами на білому фоні, а для другої – червоними літерами на
зеленому фоні. Колір тексту під час створення кнопки визначається
рядковою змінною fg, а колір фону – рядковою змінною bg.
5. Натиснення на першу та на другу кнопки вважаються різними
подіями, і тому кожна із цих подій описуються своєю функцією. Задати
функцію, яка виконується у разі натиснення на кнопку, можна двома
способами. Для першої кнопки це зроблено через використання методу
bind(), а для другої – через значення змінної command.
Іншими параметрами кнопок, які суттєво впливають на зовнішній
вигляд віконного інтерфейсу, є наступні [70].
1. fill – заповнення кнопкою усього інтерфейсного вікна за
довжиною у разі значення fill = ‘x’ або за висотою у разі значення
fill = ‘y’.
2. expand – заповнення кнопкою усієї площини інтерфейсного вікна
за умови значення expand = 1. У цьому випадку змінній fill
присвоюється значення fill = ‘both’.
Нижче розглянуті приклади виконання команд fill та expand для
трьох кнопок.
Приклад 5.9
import tkinter
window = tkinter.Tk()
btn1 = tkinter.Button(window, text = ‘Кнопка 1’)
btn2 = tkinter.Button(window, text = ‘Кнопка 2’)

26
btn3 = tkinter.Button(window, text = ‘Кнопка 3’)
btn1.pack(side = ‘left’, fill = ‘y’)
btn2.pack(side = ‘right’, fill = ‘x’)
btn3.pack(side = ‘right’, fill = ‘x’)
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.9,
показаний на рис. 5.15.

а) б)
Рис. 5.15 Результат роботи програмного коду, наведеного у прикладі 5.9
після відображення другої (а) та третьої (б) кнопки

Також важливими для розташування кнопок в інтерфейсному вікні є


параметри ipadx, ipady, padx та pady. Команди ipadx та ipady
визначають мінімальну відстань від надписи до границі інтерфейсного
елементу, а команди padx та pady – мінімальну відстань між
інтерфейсними елементами [70].
Для іншого методу grid() вказуються параметри розташування
об’єкту через номер відповідного рядка та стовпчика. Нумерація рядків та
стовпчиків здійснюється, на відміну від нумерації елементів списку,
починаючи з одиниці. Параметрами функції є наступні.
1. row – номер рядка, числове значення.
2. column – номер стовпчика, числове значення.
3. columnspan – кількість рядків та стовпчиків, які займає даний
елемент.
Тобто, у разі використання методу grid() елементи інтерфейсу
розташовуються вздовж дискретної координатної сітки, яка схожа на

27
таблицю. Зокрема, такий спосіб розташування текстових вікон є дуже
зручним для введення елементів матриці.
Для кращого розуміння цього способу розташування кнопок
розглянемо наступний програмний код.
Приклад 5.10
from tkinter import *
window = Tk()
Button(window, text = ‘Кнопка 1’).grid(row = 1, \
column = 1, padx = 12, pady = 12, ipadx = 12,\
ipady = 12)
Button(window, text = ‘Кнопка 2’).grid(row = 1, \
column = 2)
Button(window, text = ‘Кнопка 3’).grid(row = 1, \
column = 3)
Button(window, text = ‘Кнопка 4’).grid(row = 2, \
column = 1, columnspan = 2)
Button(window, text = ‘Кнопка 5’).grid(row = 2, \
column = 3)
window.mainloop
Особливість написання програмного коду, наведеного у прикладі 5.10,
полягає у тому, що у першому рядку програми здійснений імпорт відразу
всіх функцій модуля tkinter через командний рядок
from tkinter import *
Такий спосіб є досить ефективним, оскільки, з одного боку,
імпортуються всі функції модуля, а з іншого, для виклику відповідної
функції не треба вказувати ім’я модуля, достатньо вказати лише ім’я функції.
Єдиний недолік такої моделі роботи із модулями полягає в тому, що у разі
використання перевантажених функцій, котрі мають однакові імена, але
розташовані у різних модулях, можуть виникати серйозні помилки роботи
програмного коду. Приклади невірного виклику перевантажених функцій

28
досконало розглядалися в підрозділі 2.5. Наприклад, для модулів math та
cmath такий спосіб імпортування використовувати не варто, оскільки майже
всі функції цих модулів є перевантаженими.
Результат роботи командних рядків, наведених у прикладі 5.10,
показаний на рис. 5.16.

Рис. 5.16 Результат роботи програмного коду, наведеного у прикладі 5.10

Метод place() для розташування елементів інтерфейсу є дуже


ефективним з тієї точки зору, що всі елементи мають заданий розмір та
розташовуються у вікні за заданими координатами. Такий спосіб
розташування елементів інтерфейсу варто використовувати для складних
програм, які мають велику кількість кнопок та текстових вікон та їх розмір та
розташування є вкрай важливими для забезпечення зручності роботи з
програмою. Зрозуміло, що за такої умови автоматичне розташування
елементів зазвичай не приводить до бажаного результату. Такі інтерфейси
зазвичай пишуться професіональними програмістами, які не лише добре
знають способи створення програмного коду, але й вміють через вдале
розташування елементів інтерфейсу у текстовому вікні зробити програму
зручною для роботу користувачів.
Метод place() у загальному випадку має наступні чотири
аргументи.
1. Горизонтальна координата розташування об’єкта x.
2. Вертикальна координата розташування об’єкта y.
3. Ширина об’єкта width.

29
4. Висота об’єкта heigh.
Наприклад, з використанням методу place() розташувати чотири
кнопки можна наступним чином.
Приклад 5.11
from tkinter import *
window = Tk()
Button(window, text = ‘Кнопка 1’).place(x = 10, \
y = 20, width = 100, heigh = 25)
Button(window, text = ‘Кнопка 2’).place(x = 120, \
y = 20, width = 100, heigh = 25)
Button(window, text = ‘Кнопка 3’).place(x = 10, \
y = 100, width = 100, heigh = 25)
Button(window, text = ‘Кнопка 4’).place(x = 120, \
y = 100, width = 100, heigh = 25)
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.11,
показаний на рис. 5.17.

Рис. 5.17 Результат роботи програмного коду, наведеного у прикладі 5.11

З використанням методу розташування кнопок place() написані


інтерфейси для програм простого та інженерного калькуляторів, які
розглядатимуться у підрозділі 5.3.5.

30
Слід відзначити, що більшість методів та властивостей, розглянутих у
цьому підрозділі для кнопок як елементів інтерфейсу, можуть бути
використані і для інших його елементів. Це пов’язано із властивістю
поліморфізму для об’єктів визначеного класу, яка була розглянута у
підрозділі 1.2 та описана визначенням 1.13. Дійсно, для елементів інтерфейсу
зазвичай важливими є лише зовнішні властивості, як-то розміри, колір,
положення тощо, а їх внутрішня структура описується окремо та для
загального завдання побудови віконного інтерфейсу вона часто не має
суттєвого значення [16].
Відповідні способи створення інших елементів віконного інтерфейсу
будуть розглянуті у підрозділі 5.2.6. У наступному підрозділі розглянемо
більш досконало методи аналізу події натиснення на кнопку, які тісно
пов’язані із теорією скінченних автоматів.

5.2.5.2 Методи аналізу події натиснення на кнопку


Після аналізу можливостей зміни властивостей об’єктів та вивчення
різних методів їхнього розташування на головному вікні, повернемося до
моделі МВК, наведеної у підрозділі 5.2.4, та розглянемо можливості її
використання для аналізу події натиснення на кнопку.
Загальний алгоритм роботи такого віконного інтерфейсу є наступним.
1. Визначення відповідної події у циклі mainloop. Це можна зробити
з використанням властивості command або методу bind() для об’єкту
класу Button. Приклади зміни цієї властивості та використання цього
методу розглядалися у підрозділі 5.2.5.1.
2. Аналіз властивостей текстових вікон за відповідною подією. Для
здійснення цієї операції використовується метод get() із посиланням на
відповідний об’єкт інтерфейсу.
3. Зміна властивостей текстових вікон після проведення обчислень за
відповідними алгоритмами. Для здійснення цієї операції використовуються
методи set() або config() із посиланням на відповідний об’єкт
інтерфейсу. Використання методів set() та config() залежить від того,
як проводиться зміна властивостей об’єкта, яким зазвичай є вікно виведення
31
тексту класу Label. Якщо зміна властивостей здійснюється через відповідні
обчислення без аналізу текстового вікна, може бути використана функція
set(). Порядок роботи з цією функцією є наступним [24].
1. Посилання на клас tkinter.IntVar() або
tkinter.DoubleVar(), залежно від типу змінної, яка створюється. Метод
IntVar() використовується для посилання на змінну типу int, а метод
DoubleVar() – для посилання на змінну типу float.
2. Проведення ітераційних обчислень з використанням методів get()
та set(), які застосовуються до змінної відповідного класу.
3. Присвоєння властивості об’єкта класу Label значення обчисленої
змінної.
Для здійснення операції зміни властивості об’єкта класу Label через
аналіз текстового вікна Entry зручніше використовувати метод config(),
оскільки він працює безпосередньо із текстовою змінною без необхідності
перетворення типів.
У будь якому разі, якщо коректно використовувати функції
перетворення типів даних, можна використовувати обидва методи зміни
властивостей об’єктів інтерфейсного вікна, проте кожен з них має свої
особливості. У цьому підрозділі розглядатимуться коди програм, в яких
застосовується метод config(), а особливості використання методу set()
будуть проаналізовані у підрозділі 5.3.1.
Зрозуміло, що розглянутий алгоритм роботи віконного інтерфейсу
цілком відповідає теорії скінченних автоматів [2]. Відповідна схема
скінченного автомату у вигляді мережі Петрі наведена на рис. 5.18.

Подія натиснення на
кнопку Стан
Завершення роботи
вікна

Рис. 5.18 Програма із віконним інтерфейсом як спрощена схема скінченного


автомату

32
Алгоритм обробки події натиснення на кнопку аналогічний
узагальненому алгоритму роботи віконного інтерфейсу, блок-схема якого
наведена на рис 5.1. Блок-схема алгоритму обробки події натиснення на
кнопку наведена на рис. 5.19.

Початок 5 6 3

Аналіз події Проведення об-


1 натиснення на 4 числень за зада-
кнопку ним алгоритмом

2 Зміна стану вікна через


застосування методів
Кнопка Ні
6 5 set() або config()
натиснена?
до елементів віконного
інтерфейсу

Аналіз поточного 2
стану вікна з вико- 1
3 ристанням методу
get() 6
Є запит на Ні
завершення 1
4 роботи?

Кінець

Рис. 5.19 Узагальнена блок-схема алгоритму обробки події натиснення на


кнопку віконного інтерфейсу

Іншими можливостями використання кнопок у віконному інтерфейсі є


стандартні операції, призначені для роботи з елементами інтерфейсу, які
визначаються спеціальними функціями. Серед таких операцій слід
відзначити наступні.
1. Завершення роботи програми.
2. Очищення всіх текстових вікон.
Перша операція вже була розглянута у прикладі 5.7, вона здійснюється
методом destroy(). Щодо другої операції, її легко виконати через

33
присвоєння всім текстовим змінним значення None.
Розглянемо приклади, у яких команди натиснення на кнопку віконного
інтерфейсу використовуються для виведення текстової інформації.
Приклад 5.12 Написати програму, в якій текст, введений у текстове
вікно, переписується в іншому вікні після натиснення кнопки «Друк».
Передбачити можливість виконання функцій очищення вікна, призначеного
для виведення тексту, а також виходу із програми, через натиснення
відповідних кнопок.
Відповідний програмний код буде мати наступний вигляд.
from tkinter import *
def click1():
label.config(text = entry.get())
def click2():
label.config(text = '')
window = Tk()
frame = Frame(window)
frame.pack()
entry = Entry(frame)
entry.pack()
label = Label(frame)
label.pack()
btn1 = Button(frame, text = 'Друк', \
command = click1)
btn2 = Button(frame, text = 'Очистити', \
command = click2)
btn3 = Button(frame, text = 'Вихід', \
command = window.destroy)
btn1.pack()

34
btn2.pack()
btn3.pack()
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.12,
показаний на рис. 5.20.

а) б)
Рис. 5.20 Результат роботи програмного коду, наведеного у прикладі 5.12,
після натиснення кнопок «Друк» (а) та «Очистити» (б)

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


текстове вікно класу Entry вводиться дійсне число, а у текстовому вікні
класу Label виводиться значення синуса цього числа.
Приклад 5.13 Написати програму, яка за введеним значенням
дійсного числа в іншому вікні після натиснення кнопки «Обчислити»
виводить значення синуса цього числа. Як і в попередньому прикладі,
передбачити можливість виходу з програми та очищення вікна виведення
тексту через натиснення відповідних кнопок.
Відповідний програмний код буде мати наступний вигляд.
from tkinter import *
from math import sin
def click1()
label.config(text = str(sin(float(entry.get()))))
def click2():

35
label.config(text = '')
window = Tk()
frame = Frame(window)
frame.pack()
entry = Entry(frame)
entry.pack()
label = Label(frame)
label.pack()
btn1 = Button(frame, text = 'Обчислити', \
command = click1)
btn2 = Button(frame, text = 'Очистити', \
command = click2)
btn3 = Button(frame, text = 'Вихід', \
command = window.destroy)
btn1.pack()
btn2.pack()
btn3.pack()
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.13,
показаний на рис. 5.21.

а) б)
Рис. 5.21 Результат роботи програмного коду, наведеного у прикладі 5.13,
після натиснення кнопок «Обчислити» (а) та «Очистити» (б)

36
Зрозуміло, що код програми, наведений у прикладі 5.13, майже
повністю відповідає коду, наведеному у прикладі 5.12. Відмінності є
наступними.
1. На початку програми з модуля math імпортується функція sin.
2. В функції click1() здійснене перетворення типів даних,
обчислення значення функції синуса та виведення остаточно сформованого
рядка у текстове вікно label з використанням метода config().

5.2.5.3 Описання методів для роботи з елементами віконного


інтерфейсу з точки зору теорії подійного моделювання
У попередньому підрозділі були розглянуті способи описання події
натиснення на кнопку як елемент графічного інтерфейсу. Зокрема, як два
таких можливих способи розглядалися властивість ‘command’ та метод
bind(). Також були розглянуті методи аналізу та зміни значення числових
та текстових змінних get()та set(), через які можна формувати
повідомлення для виведення у текстове вікно. Зрозуміло, що виведення
повідомлення у текстове вікно також можна вважати реакцією інтерфейсної
системи на відповідну подію.
У теорії програмування методи подійного моделювання інтерфейсних
об’єктів розглядаються окремо, і такий підхід значно спрощує розуміння
концепції побудови віконного інтерфейсу [16, 70]. Розглянемо концепцію
подійного моделювання для методу bind(). Формат цієї команди має
наступний вигляд [70]:
bind(event, ім’я процедури, ‘+’)
Значення цих параметрів є наступними.
event – описання відповідної події.
ім’я процедури – процедура, виконання якої розглядається як
реакція на відповідну подію.

37
‘+’ – необов’язковий аргумент, який визначає, що процедура обробки
події, яка описується, додається до вже існуючих.
Події для методу bind() можуть бути описані з використанням
наступних зарезервованих рядків.
1. ‘<Button-1>’, або <1> – натиснення на ліву кнопку миші.
2. ‘<Button-2>’, або <2> – натиснення на середню кнопку миші,
або, для сучасних моделей мишей – на колесико.
3. ‘<Button-3>’, або <3> – натиснення на праву кнопку миші.
4. ‘<Double-Button-1>’ – подвійне натиснення на ліву кнопку
миші.
5. Літера у лапках – натиснення клавіші із відповідною літерою на
клавіатурі, наприклад, ‘U’.
6. ‘Return’ – натиснення клавіші ‘Enter’.
7. ‘Space’ – натиснення пробілу.
8. ‘Key’ – натиснення будь-якої клавіші на клавіатурі.
9. Сполучення функціональних клавіш записується через тире,
наприклад: ‘Control – Shift’, ‘Control – z’.
Надалі ці способи описання подій будуть використовуватися для
написання відповідних програмних кодів, призначених для формування
віконного інтерфейсу.

5.2.6 Створення та розташування інших елементів віконного


інтерфейсу
Перед вивченням цього підрозділу необхідно повторити розділ 3.
5.2.6.1 Головні елементи віконного інтерфейсу
Розглянемо тепер особливості створення інших елементів віконного
інтерфейсу, описаних у підрозділі 5.2.2, серед яких виділимо наступні.
1. Checkbutton() – функція вибору однієї опції, або прапорець.
Вона дозволяє через встановлення прапорця обрати відповідну опцію, за
якою далі буде працювати програма. Зазвичай ця кнопка в віконному
інтерфейсі є квадратною та помічається «галочкою».
2. Radiobutton() – функція вибору із кількох варіантів. На відміну
від функції Checkbutton(), вона дозволяє обирати один із кількох
38
можливих варіантів. Цей елемент також називають селекторною кнопкою
[16, 70].
3. Listbox() – список. Цей елемент віконного інтерфейсу дозволяє
виводити на екран список можливих варіантів для обрання одного з них.
4. Spinbox() – лічильник, або список із заданим набором
натуральних чисел.
5. Scale() – шкала, або лінійка з повзунцем. Важливий елемент
інтерфейсного вікна, призначений для подання аналогових величин в
цифровій формі.
Деякі з перелічених елементів інтерфейсу показані на рис. 5.4. У цьому
підрозділі розгянемо можливостs створення та відображення цих інтерфейсних
елементів з використанням засобів програмування мови Python.

5.2.6.2 Кнопка вибору


Для створення об’єкту класу Checkbutton використовується метод
Checkbutton() модуля tkinter. Головними властивостями цього
об’єкту є наступні [70].
1. Базовий батьківський об’єкт – тобто вікно або фрейм, на якому буде
розташований об’єкт класу Checkbutton.
2. text – рядкова змінна, яка визначає надпис, що буде розташований
біля цього елемента інтерфейсу.
3. variable – змінна, яка визначає стан вибору для цього об’єкту. Ця
змінна може мати значення 1, якщо прапорець встановлений, або 0, якщо він
не встановлений. Ця властивість встановлюється через оператор присвоєння
variable = var,
де var – ім’я змінної.
4. onvalue – значення булевої змінної var у разі, якщо опція вибрана.
За замовченням onvalue = 1.
5. offvalue – значення булевої змінної var у разі, якщо опція не
вибрана. За замовченням offvalue = 0.

39
6. command – функція обробки події обрання опції цього елементу
інтерфейсу. Тут вказується посилання на ім’я функції, яка аналізує стан
цього елементу інтерфейсу.
Зрозуміло, що властивості onvalue та offvalue можуть бути
встановлені за замовченням.
Серед властивостей об’єкту Checkbutton найбільш важливою є
змінна variable, яка визначає його стан. Ініциалізувати змінну var можна
через звернення до методів IntVar() або DoubleVar() модуля tkinter, а
аналіз та встановлення значення цієї змінної здійснюється з використанням
методів get()та set() цього модуля. Відповідні способи роботи з
властивостями об’єктів віконного інтерфейсу розглядалися у підрозділі 5.2.5.2 та
відображені у вигляді блок-схеми алгоритму на рис. 5.19.
У загальному вигляді набір команд для формування об’єкту
Checkbutton може бути записаний наступним чином [70].
str1 = StringVar()
var1 = IntVar()
check = Checkbutton(frame, text = ‘Встановлення \
прапорця’, variable = var1, command = fcb)
var1.set(1)
check.pack()
У наведеному коді для обробки події обрання прапорця
використовується функція fcb(). У цій функції необхідно з використанням
методу var.get() проаналізувати значення змінної var, а після цього,
відповідно до значення цієї змінної, змінити хід виконання програми та
властивості відповідних об’єктів інтерфейсного вікна [70]. Наприклад,
програмний код функції fcb() може мати наступний вигляд.
def fcb ()
if var1.get() == 1:
str1 = ‘Прапорець встановлений’
else:
40
str1 = ‘Прапорець не встановлений’
Після виконання цих командних рядків змінна str1 може бути
використана для виведення даних в текстовому вікні класу Label з
використанням методу label.config(), спосіб використання цього
методу був розглянутий у підрозділі 5.2.5.2.
Розглянемо наступний приклад, у якому здійснюється аналіз
встановлення прапорця в об’єкті класу Checkbutton, а стан прапорця
виводиться у тому самому інтерфейсному вікні до текстового вікна класу
Label.
Приклад 5.14
from tkinter import *
def fcb ():
if var1.get() == 1:
str1 = ‘Прапорець встановлений’
else:
str1 = ‘Прапорець не встановлений’
label.config(text = str1)
window = Tk()
frame = Frame(window)
frame.pack()
str1 = StringVar()
var1 = IntVar()
check = Checkbutton(frame, text = ‘Встановлення \
прапорця’, variable = var1, command = fcb)
var1.set(1)
check.pack()
label = Label(frame)
label.pack()
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.14,
показаний на рис. 5.22.

41
а) б)
Рис. 5.22 Результат роботи програмного коду, наведеного у прикладі 5.14, у
разі встановленого (а) та не встановленого (б) прапорця

Розглянутий у прикладі 5.14 об’єкт обрання варіанту за системою «І»,


або кнопка вибору, є найпростішим із об’єктів здійснення вибору, але
наведений алгоритм роботи з ним є досить універсальним та
використовується для всіх об’єктів інтерфейсу із визначенням варіантів
роботи програми. Запишемо цей алгоритм у вигляді тезових формулювань.
1. Створення об’єкту інтерфейсу для здійснення функції вибору. Згідно
з розглянутими вище теоретичними відомостями, це може бути об’єкт, який
належить до класів Checkbutton, Radiobutton, Listbox або
Spinbox.
2. Розташування створеного об’єкту в інтерфейсному вікні або у
фреймі.
3. Визначення імені змінної, яка характеризує стан об’єкту. Для цього
використовується властивість створеного об’єкту variable.
4. Визначення метода для аналізу стану об’єкту у циклі аналізу
властивостей інтерфейсного вікна window.mainloop. Посиланню на ім’я
цього методу відповідає властивість створеного об’єкту command.
5. Читання у методі аналізу властивості об’єкту значення змінної, яка
описує його поточний стан.
6. Зміна у методі аналізу властивості об’єкту відповідних змінних, які
визначають хід виконання програми та відповідають за стан інших елементів
інтерфейсу. Наприклад, можна змінити стан текстового вікна класу Label з
використанням методу label.config(), як це зроблено у прикладі 5.14. Ця

42
зміна здійснюється через аналіз значення змінної, яка описує властивість
об’єкту.
Блок-схема описаного узагальненого алгоритму створення та аналізу
властивостей об’єкту із вибором варіантів наведена на рис. 5.23.

3
Початок
Визначення мето-
4 да для аналізу ста-
Створення об’єкту
ну об’єкту
інтерфейсу для
1 здійснення
функції вибору
Читання значення
змінної, яка описує
5 поточний стан
Розташування
об’єкту
2 створеного
об’єкту

Зміна значень змінних,


Визначення імені які визначають хід
3 змінної, яка характе- 6 виконання програми та
різує стан об’єкту відповідають за стан
інших елементів
інтерфейсу
4

Кінець

Рис. 5.23 Блок-схема алгоритму формування та аналізу властивостей об’єкту,


який містить елементи для обрання різних варіантів

5.2.6.3 Селекторна кнопка


Розглянемо приклад створення та аналізу властивостей об’єкта
Radiobutton, або селекторної кнопки, із трьома варіантами вибору.
Завдання цього прикладу полягає у тому, щоб виводити обраний варіант із
списку об’єкта Radiobutton до текстового вікна класу Label. Будемо
писати відповідний програмний код за шаблоном програми із прикладу 5.14,
де необхідно було виводити у текстове вікно стан об’єкту Checkbutton.
Для цього спочатку необхідно розглянути спосіб описання можливих

43
властивостей об’єкта Radiobutton через значення змінної variable.
Наприклад, припустимо, що через обрання кнопок об’єкта Radiobutton
можна задати три значення, які умовно назвемо «Перший варіант», «Другий
варіант» та «Третій варіант». Тоді можливими значеннями змінної
variable можуть бути числа 1, 2 та 3. Ці числа також необхідно вивести на
екран як окремі компоненти об’єкта Radiobutton. Після формування цих
елементів необхідно розташувати їх в інтерфейсному вікні з використанням
методу pack() модуля tkinter, або будь-якого іншого з методів
розташування інтерфейсних об’єктів, які були описані у підрозділі 5.2.5.1.
Відповідний алгоритм формування об’єкта Radiobutton можна
записати наступним чином.
1. Визначення кількості кнопок n в об’єкті Radiobutton, який
формується.
2. Встановлення номера початкового елементу i = 1.
3. Формування фрейму для розташування всіх кнопок об’єкта
Radiobutton. Площина для розміщення кожного елементу розраховується
відповідно до їхньої кількості n.
4. Формування елемента об’єкта Radiobutton та визначення його
властивостей через значення змінних text та variable. Зрозуміло, що
змінна text визначає надпис над кнопкою, а значення variable відповідає
номеру елемента i.
5. Розташування елемента i об’єкта Radiobutton.
6. Якщо i < n – збільшення значення i на 1 перехід до пункту 4
алгоритму, а у противному випадку – завершення роботи щодо розташування
елементів та перехід до пункту 5.
7. Кінець формування об’єкта Radiobutton.
Блок-схема описаного алгоритму формування об’єкта Radiobutton
наведена на рис. 5.24.
Важливою особливістю формування елементів об’єкта Radiobutton

44
є те, що через змінну variable окремо визначається ім’я змінної, через яку
визначається номер обраної кнопки, а через змінну value задається
значення цієї змінної для поточного елемента об’єкта, який формується [70].
Відповідно з цим, програмний код для формування та розташування
елементів об’єкта Radiobutton, буде мати наступний вигляд.

3 7 6
Початок

Визначення кіль- Визначення властивос-


тей елемента i об’єкта 7 i=i+1
1 кості елементів
об’єкта n 4 Radiobutton через
значення змінних
text та variable 4
Формування фрей-
му для розташу-
2 вання об’єкта
Розташування 5
Radiobutton 5 елемента i об’єкта
Radiobutton
6
3 i=1 i < n? 7
6
Ні
4 Кінець

Рис. 5.24 Блок-схема узагальненого алгоритму формування об’єкта


Radiobutton

frmradio.place(x = 120, y = 0, width = 120,\


height = 34)
var_rad = IntVar()
rb1 = Radiobutton(frmradio, text=‘1’, variable=\
var_rad, value=1, command=arb)
rb2 = Radiobutton(frmradio, text=‘2’, variable=\
var_rad, value=2, command=arb)
rb3 = Radiobutton(frmradio, text=‘3’, variable=\

45
var_rad, value=3, command=arb)
rb1.pack(side = left)
rb2.pack(side = left)
rb3.pack(side = left)
Особливості написаного програмного коду полягають у тому, що
спочатку формується фрейм для розташування елементів селекторної кнопки
Radiobutton, а потім, через визначення властивостей text, variable,
value та command, описуються окремі елементи цього об’єкту, які
задаються змінними rb1, rb2 та rb3. Наприкінці програмного коду всі
елементи селекторної кнопки розташовуються у фреймі з використанням
методу pack() з параметром side = left.
Тепер залишається лише написати функції аналізу властивості об’єкту
Radiobutton. Головними завданнями, які необхідно виконати під час
написання цієї функції з наперед визначеним іменем arb(), є наступні.
1. Визначення обраного елементу селекторної кнопки через значення
змінної var_rad.
2. Виведення у текстове вікно класу Label повідомлення про те, який

елемент обраний. Наприклад, повідомлення може бути таким: «Обраний


третій елемент». Зрозуміло, що ці повідомлення формуються через
визначення значення відповідної рядкової змінної str1 з використанням

умовного оператора, а вікно класу Label змінюється у циклі mainloop з

використанням методу config().

Тоді програмний код функції arb(), аналогічно коду функції fcb()

для прикладу 5.14, можна написати наступним чином.


def fcb():
if var_rad.get() == 1:
str1 = ‘Обраний перший елемент’

46
elseif var_rad.get() == 2:
str1 = ‘Обраний перший елемент’
else:
str1 = ‘Обраний третій елемент’
label.config(text = str1)
Враховуючи наведені вище фрагменти програмного коду, а також
програму для тестування роботи кнопки-перемикача, наведену у прикладі
5.14, закінчений фрагмент програми для тестування роботи селекторної
кнопки можна записати у наступному вигляді.
Приклад 5.15
from tkinter import *
def arb():
if var_rad.get() == 1:
str1 = ‘Обраний перший елемент’
elif var_rad.get() == 2:
str1 = ‘Обраний другий елемент’
else:
str1 = ‘Обраний третій елемент’
label2.config(text = str1)
window = Tk()
window.title(‘Тестування селекторної кнопки’)
frmradio = LabelFrame(window, text=‘Кнопки вибору’)
frmradio.place(x = 120, y = 0, width = 120,\
height = 34)
frmedit = Frame(window)
frmedit.pack()
str1 = StringVar()
var_rad = IntVar()
label1=Label(window, textvariable = ‘Оберіть но\
мер елемента’)
label1.place(x = 4, y = 4, width = 100, height = 20)
rb1 = Radiobutton(frmradio, text=‘1’, variable=\
var_rad, value=1, command=arb)
47
rb2 = Radiobutton(frmradio, text=‘2’, variable=\
var_rad, value=2, command=arb)
rb3 = Radiobutton(frmradio, text=‘3’, variable=\
var_rad, value=3, command=arb)
var_rad.set(1)
rb1.pack(side = ‘left’)
rb2.pack(side = ‘left’)
rb3.pack(side = ‘left’)
label2 = Label(frmedit)
label2.pack()
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.15,
показаний на рис. 5.25.

а)

б)

в)
Рис. 5.25 Результат роботи програмного коду, наведеного у прикладі 5.15, у
разі обрання першого (а), другого (б) та третього (в) елемента селекторної
кнопки Radiobutton

48
Зверніть особливу увагу на те, що для виведення на інтерфейсне вікно
всіх елементів селекторної кнопки у прикладі 5.15 замість об’єкта Frame
використаний об’єкт LabelFrame, який від фрейму відрізняється лише тим,
що він може бути підписаним, а текст підпису задається через опцію text.

5.2.6.4 Список як елемент віконного інтерфейсу


Розглянемо тепер інший базовий елемент віконного інтерфейсу для
здійснення вибору – це список, або Listbox. Як було сказано у підрозділі
5.2.2, цей елемент віконного інтерфейсу являє собою випливаючий список, із
якого користувач зазвичай може обрати лише один компонент. Є можливість
такого налаштування цього елементу інтерфейсу, коли дозволяється обрання
двох та більшої кількості компонентів списку, але ця можливість зазвичай
оговорюється окремо [70]. У мові програмування Python функція формування
списку Listbox() має параметр selectmode, який визначає можливу
кількість елементів для вибору зі списку та за замовченням має значення
SINGLE (один).
Для роботи зі списками як елементами графічного інтерфейсу в мові
програмування Python зручно використовувати списки як структуровані типи
даних. Цей тип даних та головні функції роботи з ним були розглянуті у
підрозділі 3.6.
Будемо розглядати задачу формування списку як елемента інтерфейсу
на основі прикладу 5.15. Тобто, вважатимемо, що необхідно здійснити вибір
з трьох елементів, які умовно назвемо «Перший», «Другий» та «Третій». Це і
буде наша упорядкована структура. Її можна сформувати з використанням
простого оператора присвоєння:
lst = [‘Перший’, ‘Другий’, ‘Третій’]
Припустимо тепер, що список вже сформований. Доречи, це досить
легко зробити з використанням функції Listbox модуля tkinter
наступним чином [70]:
iflist = LabelFrame(window, text=‘Список’,\
49
borderwidth = 2, relief = SUNKEN, height = 70)
lstbox = Listbox(iflist, borderwidth = 3, height = 3)
За умови такої організації даних у програмі далі необхідно створити
новий список lstbox, який буде посилатися на елементи списку lst. З
використанням оператора циклу, розглянутого у підрозділі 3.7, це можна
зробити наступним чином [70]:
for elem in lst:
lstbox.insert(END, elem)
Параметр END вказує позицію, на яку необхідно добавити відповідний
елемент , а змінна elem, згідно із організацією циклу, відповідає самому
елементу.
Далі необхідно виділити будь-який елемент списку, наприклад,
нульовий. Це можна зробити з використанням наступної команди [70]:
lstbox.selection_set(first = 0)
Ще одна проблема полягає у тому, що конструктор Listbox() у мові
програмування Python не має параметра command. У цьому випадку для
автоматичної обробки події обрання елемента елементу списку можна
використовувати лише метод bind, розглянутий у підрозділі 5.2.5.1. Для
уникнення необхідності написання додаткової функції обробки події у
даному випадку можна застосувати анонімну лямбда-функцію, яка
розглядалася у підрозділі 3.7.8. Тоді відповідні командні рядки будуть мати
наступний вигляд [70].
str1 = ‘Обраний ’
str2 = ‘ елемент списку.’
fnlstbox = lambda ev: label2.config(text = str1 \
+ str.lower(lstbox.get(lstbox.curselection())) + str2)
lstbox.bind(‘ListboxSelect’,fnlstbox)
У розглянутому програмному коді метод lstbox.curselection()
визначає індекс виділеного елемента списку, а метод lstbox.get(index) –
рядок списку, який відповідає цьому індексу. Ім’я label2 відповідає текстовому

50
вікну, у яке виводиться значення обраного елемента списку. Функція lower(),
розглянута у підрозділі 2.6, призначена для заміни всіх літер тексту на малі.
Слід відзначити, що, на відміну від способу аналізу обраного елемента
селекторної кнопки, описаний спосіб аналізу обраного елемента списку не
містить умовного оператора. Це пов’язано з тим, що всі елементи списку
впорядковані як структуровані дані та кожному індексу відповідає лише один
елемент списку.
Блок-схема узагальненого алгоритму створення списку та аналізу
обраного елемента наведена на рис. 5.26, а. Код програми, написаній на мові
програмування Python, в якій реалізований цей алгоритм, наведений у
навчальному посібнику [70].
Іншим ефективним способом обробки події, пов’язаної з обранням
елемента списку, є введення до віконного інтерфейсу додаткової кнопки, яку
назвемо «Аналіз». Тоді функція fnlstbox() може бути визначена як
зовнішня у тому самому модулі, а виклик цієї функції здійснюється через
відповідний параметр кнопки command. Як і у випадку використання
анонімної лямбда-функції, зміна вмісту текстового вікна Label виконується
з використанням метода config(). Відповідний спосіб зміни вмісту
текстового вікна був розглянутий у прикладах 5.12 та 5.13, наведених у
підрозділі 5.2.5.2.
Блок-схема алгоритму обробка події обрання елемента списку через
аналіз події натиснення на інтерфейсну кнопку, представлена на рис. 5.26, б,
а код програми, який відповідає цьому алгоритму, наведений у прикладі 5.16.
Приклад 5.16
def fnlstbox():
str_n=str1 + str.lower(lstbox.get(lstbox.\
curselection())) + str2
label2.config(text = str_n)
from tkinter import *
window = Tk()
window.title('Тестування списку')

51
Початок Початок

Формування фрей- Формування фрей-


1 му для розташу- 1 му для розташу-
вання списку вання списку

Розташування Розташування
2 2
списку списку

Розташування Розташування
3 3
текстового вікна текстового вікна

Формування Розташування
4
структурованої кнопки
послідовності із
4 елементів списку Формування
з використанням структурованої
опеартора циклу послідовності із
5 елементів списку
з використанням
Визначення обрано- опеартора циклу
го елементу списку
5 та зміна тексту у
текстовому вікні з Обробка події
використанням натиснення на
лямбда-функції 6 кнопку через по-
силання на зов-
нішню функцію
Обробка події
обрання елемен-
6 ту списку з вико- Визначення обрано-
ристанням мето- го елементу списку
ду bind() 7
та зміна тексту у
текстовому вікні

Кінець
Кінець

а) б)
Рис. 5.26 Блок-схеми алгоритмів аналізу обраного елемента списку з
використанням методу bind() (а) та через аналіз події натиснення на
кнопку (б)

52
iflist = LabelFrame(window, text='Список', \
borderwidth = 2, relief = SUNKEN, \
height = 70)
iflist.pack()
lstbox = Listbox(iflist, borderwidth = 3, \
height = 3)
lstbox.pack()
str_n=StringVar()
lst = ['Перший', 'Другий', 'Третій']
for elem in lst:
lstbox.insert(END, elem)
lstbox.selection_set(first = 0)
str1 = 'Обраний '
str2 = ' елемент списку.'
label2 = Label(iflist, text = str_n)
label2.pack()
btn = Button(window, text = 'Аналіз', \
command = fnlstbox)
btn.pack()
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.16,
показаний на рис. 5.27.
Суттєво відмінність двох підходів до створення інтерфейсу
користувача, показаних у вигляді блок-схем алгоритмів на рис. 5.26, полягає
у тому, що у разі використання алгоритму, наведеного на рис. 5.26, а,
обрання елемента списку вважається подією, яка може змінити конфігурацію
головного вікна через метод bind(). Навпаки, для алгоритму, наведеного на
рис. 5.26, б, зміна обрання елемента списку змінює лише параметри
поточного інтерфейсного вікна, а саме вікно змінюється лише у разі
виникнення події натиснення на кнопку «Аналіз». Перший підхід, коли

53
подією, через яку здійснюється коректування всього вікна, вважається зміна
будь-якого із елементів інтерфейсу, раніше використовувався рідко та більш
притаманний новітнім програмним засобам, у той час як зміна вмісту
інтерфейсного вікна лише через подію натиснення на кнопку є більш
класичним варіантом [16]. У будь-якому разі, обрання першого або другого
способу створення віконного інтерфейсу залежить лише від власних
вподобань програміста. Пишучи програми з віконним інтерфейсом, завжди
пам’ятайте про перший, другий та третій принципи філософії мови
програмування Python, сформульований у підрозділі 1.5: «Красиве є
кращим, ніж виродливе», «Явне є кращим, ніж побічне», «Просте є
кращим, ніж складне».

а) б)

в)
Рис. 5.27 Результат роботи програмного коду, наведеного у прикладі 5.16, у
разі обрання першого (а), другого (б) та третього (в) елемента списку після
натиснення кнопки «Аналіз»

54
5.2.6.5 Нумерований список
Іншим елементом вибору, який часто використовується у віконному
інтерфейсі, є список-лічильник, або нумерований список Spinbox.
Параметрами цієї функції є наступні [70].
1. Місце розташування цього елемента інтерфейсу. Цей параметр
відповідає посиланню на батьківський об’єкт, фрейм або вікно, на якому
розташований нумерований список.
2. values – подання значення елементів нумерованого списку у
вигляді структурованого. Наприклад: values = [1, 5, 3, 5, 7, 4].
Цей параметр є необов’язковим. У разі, якщо елементи нумерованого списку
задаються зростаючою послідовністю натуральних чисел, можна замість
параметра values використовувати параметри from_ , to та increment.
3. from_ – початкове значення першого елемента впорядкованого
списку натуральних чисел.
4. to – кінцеве значення останнього елемента впорядкованого списку
натуральних чисел.
5. increment – крок зміни елементів для впорядкованого списку
натуральних чисел. За замовченням значення цього параметру дорівнює 1.
Наведемо приклад створення списка-лічильника у фреймі
інтерфейсного вікна [70].
ifspin = LabelFrame(window,\
text=‘Список-Лічильник’,\
borderwidth = 2, relief = SUNKEN, height = 54)
ifspin.pack()
lblspin = Label(ifspin, font = ‘Arial 10’, width = 12,\
text = ‘Оберіть число’)
lblspin.place(x = 4, y = 4, width = 100, height = 20)
spb = Spinbox(ifspin, from_ = 0, to = 10, width = 16, \

55
borderwidth = 4, font = ‘Arial 10’)
spb.place(x = 180, y = 0, width = 60, height = 30)
getspbvalue = lambda: lblRez.config(text = spb.get())
spb[‘command’] = getspbvalue
Зрозуміло, що такий програмний код працює за алгоритмом, наведеним
на рис. 5.26, а, з використанням анонімної лямбда-функції. Відмінність
полягає у тому, що замість методу bind() використана команда
spb[‘command’] = getspbvalue. Для аналізу властивостей списку
лічильника використано метод spb.get(), а виведення значення
здійснюється до текстового вікна, яке належить до класу Label. Ця операція
реалізована через посилання на властивість text змінної lblRez. Для зміни
властивості цього вікна, як і в інших розглянутих прикладах,
використовується метод config().
Розглянемо інший приклад, у якому для визначення обраного елемента
списку-лічильника використовується кнопка «Аналіз». Програмний код
будемо писати за шаблоном прикладу 5.16.
Приклад 5.17
def fnspinbox():
str_n = str1 + str2 + str(spb.get())
label2.config(text = str_n)
from tkinter import *
window = Tk()
window.title('Тестування списку-лічильника')
ifspin = Label(window, text='Список-Лічильник')
ifspin.place(x = 4, y = 4)
lblspin = Label(window, font = 'Arial 10', \
width = 12, text = 'Оберіть число:')
lblspin.place(x = 4, y = 20, width = 100,\

56
height = 20)
spb = Spinbox(window, from_ = 0, to = 15, \
width = 16, borderwidth = 4, font = 'Arial 10')
spb.place(x = 120, y = 20, width = 60, height = 30)
str_n=StringVar()
str1 = 'Обраний '
str2 = 'елемент списку-лічильника '
btn = Button(window, text = 'Аналіз', \
command = fnspinbox)
btn.place(x = 200, y = 20)
label2 = Label(window, text = str_n)
label2.place(x = 0, y = 50)
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.17,
показаний на рис. 5.28.

а) б)

в)
Рис. 5.28 Результат роботи програмного коду, наведеного у прикладі 5.17, у
разі обрання різних елементів списку-лічильника. а) – обраний нульовий
елемент, б) – обраний п’ятий елемент, в) – обраний десятий елемент

57
5.2.6.6 Лінійка з повзунцем
Нарешті, розглянемо особливості формування та аналізу роботи лінійки з
повзунцем як елемента віконного інтерфейсу, який у мові програмування Python
описується як об’єкт Scale (Шкала). Цей елемент є вкрай важливим для
створення імовірнісних та статистичний моделей та для моделювання
комп’ютерного особливостей роботи аналогових електронних приладів [26].
Головними параметрами лінійки з повзунцем є її геометричні
параметри, а також параметри, аналогічні розглянутим вище для
нумерованого списку [70]. Розглянемо та проаналізуємо ці параметри.
1. length – довжина лінійки в умовних пікселях.
2. orient – горизонтальна або вертикальна орієнтація лінійки, які
позначаються значеннями HORIZONTAL та VERTICAL.
3. from_ – початкове значення шкали лінійки.
4. to – кінцеве значення шкали лінійки.
5. tickinterval – інтервал між позначками шкали в інтерфейсному
вікні.
6. resolution – крок переміщення повзунця вздовж лінійки.
Нижче наведений приклад програмного коду, у якому лінійка з
повзунцем створюється у фреймі інтерфейсного вікна [70].
ifscale = LabelFrame(window,\
text=‘Лінійка-Повзунець’,\
borderwidth = 2, relief = SUNKEN, height = 80)
ifscale.pack()
lblscale = Label(ifscale, font = ‘Arial 10’, width = 12,\
text = ‘Встановлення Повзунця’)
lblscale.place(x = 4, y = 4, width = 100, height = 20)
sci = Scale(ifscale, orient = HORIZONTAL, \
length = 236, from_ = 0, to = 100, \

58
tickinterval = 10, resolution = 1, relief = SUNKEN)
sci.set(50)
sci.place(x = 4, y = 1)
getscalevalue = lambda: lblRez.config(text = scl.get())
spb[‘command’] = getscalevalue
Тепер, за шаблонами прикладів 5.16 та 5.17, з урахуванням розглянутих

вище параметрів лінійки з повзунцем як елемента віконного інтерфейсу,

розглянемо приклад програмного коду, призначеного для визначення

встановленого значення повзунця з через натиснення на кнопку «Аналіз».

Приклад 5.18
def fnscale():

str_n = str1 + str(sci.get())

label2.config(text = str_n)

from tkinter import *

window = Tk()

window.title('Тестування лінійки-повзунця')

ifscale = Label(window, text = 'Лінійка\

- Повзунець', borderwidth = 2, relief = SUNKEN)

ifscale.place(x = 0, y = 0)

lblscale = Label(window, font='Arial 10', \

text = 'Встановіть повзунець:')

lblscale.place(x = 10, y = 20)

sci = Scale(window, orient = HORIZONTAL, \

length = 236, from_ = 0, to = 100, \

tickinterval = 10, resolution = 1, relief = SUNKEN)

sci.set(50)

59
sci.place(x = 150, y = 20)

str_n=StringVar()

str1 = 'Встановлене значення становить '

btn = Button(window, text = 'Аналіз', \

command = fnscale)

btn.place(x = 400, y = 20)

label2 = Label(window, text = str_n)

label2.place(x = 170, y = 80)

window.mainloop

Результат роботи командних рядків, наведених у прикладі 5.18,

показаний на рис. 5.29.

а)

б)

Рис. 5.29 Результат роботи програмного коду, наведеного у прикладі 5.18, у

разі встановлення різних позицій повзунця вздовж лінійки: а) – встановлене

значення 38, б) – встановлене значення 52

60
5.2.6.7 Формування інформаційного рядка про успішність студента

через заповнення елементів інтерфейсного вікна

Розглянемо інший приклад, в якому звичайні та нумеровані списки

використовуються для введення інформації про студентів, а через аналіз

введеної інформації у текстовому вікні формується відповідне інформаційне

повідомлення.

Приклад 5.19 Написати з використанням засобів програмування

мови Python програму, у якій в текстовому вікні вводити прізвище студента,

через список-лічильник – його вік, через спливаюче меню списку – групу, де

він навчається, ДЕ-71 або ДЕ-72, через інше спливаюче меню списку – його

середню оцінку за всіма дисциплінами, «відмінно», «добре» або

«задовільно». Після введення відповідної інформації через натиснення

кнопки «Формування звіту» виводити в текстове вікно повідомлення за

шаблоном: «Студент Потапенко, 18 років, група ДЕ-72, навчається добре».

Передбачити також можливість очищення текстового вікна, до якого

виводиться повідомлення, через натиснення кнопки «Очистити».

Програмний код, призначений для розв’язування поставленого

завдання, наведений у додатку А.

Особливостями написання наведеного програмного коду є наступні.

1. Для виведення інформації у текстове вікно використана функція

f_r, а для очищення цього вікна – функція clr_r.

2. Вік студентів, згідно із способом формування списку-лічильника,

становить від 17 до 28 років.

61
3. У функції f_r передбачений контроль написання слова «рік» у

множині залежно від віку студента з використанням умовного оператора.

Наприклад: «21 рік», «23 роки», «18 років».

4. У разі натиснення кнопки текстове вікно btn1 у текстове вікно

label2 виводиться рядок str_n, в якому сформоване інформаційне

повідомлення за заданим шаблоном.

5. Для створення спливаючих списків, аналогічно прикладу 5.16,

використаний спосіб формування структурованих даних з використанням

оператора for.

6. Елементи інтерфейсу для введення інформації розташовані у фреймі

if_rep, а відповідні елементи для здійснення виведення інформації – у

фреймі if_out.

7. Для розташування великої кількості елементів інтерфейсу у фреймі

if_rep використаний метод place(), а для розташування двох кнопок та

текстового вікна у фреймі if_out – відповідно метод автоматичного

розташування pack().

Для обрання групи студента використаний список із випливаючим

меню, а для обрання успішності – селекторна кнопка Radiobutton.

Аналіз обраного елемента селекторної кнопки здійснюється у функції

def f_r() з використанням умовного оператора, а читання властивості

цього об’єкта реалізовано через виклик методу var_rad.get(). На основі

цього аналізу визначається значення рядкової змінної str6.

Результат роботи командних рядків, наведених у додатку А, показаний

на рис. 5.30, а – в.

62
а)

б)

в)
Рис. 5.30 Результат роботи програмного коду, наведеного у прикладі 5.19, у
разі формування звіту для різних студентів (а, б) та за умови натиснення
кнопки «Очищення» (в)

63
У прикладі 5.19 розглянута проста, але закінчена програма із різними
елементами віконного інтерфейсу, якими як текстове вікно, вікно
редагування тексту, список спливаючого меню та селекторна кнопка. Аналіз
значень, введених в цих елементах, будь то ручним способом або
автоматично, дозволяє формувати відповідну звітну документацію. Такий
спосіб обробки інформації є дуже простим та зручним, тому він часто
використовується для роботи з сучасними базами даних [12, 23].
Приклади створення інших елементів віконного інтерфейсу можна
знайти у підручниках та навчальних посібниках [24, 25, 70] та на сторінках
Інтернет [65]. У підрозділі 5.3.4 будуть розглянуті об’єкти віконного меню
для роботи з файлами на прикладі створення текстового редактора, а у
підрозділі 5.4 – особливості роботи з графічними об’єктами у віконному
інтерфейсі.
Приклади закінчених програм, написаних з використанням розглянутих
у цьому підрозділі елементів віконного інтерфейсу, розглядатимуться у
підрозділі 5.3.

5.3 Приклади закінчених програм із віконним інтерфейсом

5.3.1 Однобічний лічильник


Часто на сайтах Інтернет, в ігрових додатках та в інших комп’ютерних
програмах із віконним інтерфейсом, використовуються однобічні та двобічні
лічильники натиснень на кнопку. Різниця між однобічним та двобічним
лічильниками полягає у тому, що однобічний рахує лише загальну кількість
натиснень на відповідну кнопку, а двобічний може як збільшувати, так і
зменшувати поточне значення, залежно від натисненої кнопки. Крім того, у
таких лічильниках часто передбачається додаткова функція онулення, яка
може виконуватись або ручним способом через натиснення на відповідну
кнопку, або автоматично у разі, якщо значення лічильника перевищує
наперед задане граничне значення. Такі програми-лічильники є дуже

64
важливим елементом Інтернет-сторінок та ігрових додатків, вони
використовуються для ведення статистики [26].
Приклади простих однобічного та двобічного лічильника наведені у
підручнику [24]. З урахуванням теоретичного матеріалу, наведеного у
підрозділі 5.2, дещо ускладнимо ці програмні коди, додавши до цих
лічильників функцію онулення.
Розглянемо спочатку приклад програмного коду для однобічного
лічильника.
Приклад 5.20 Написати з використанням засобів програмування
мови Python однобічний лічильник. Для збільшення значення лічильника на 1
використати кнопку «+». Передбачити можливість очищення лічильника або
через натиснення кнопки «0», або у разі, якщо натиснена кнопка «+», а
поточне значення лічильника становить 999. Передбачити також можливість
виходу із програми через натиснення кнопки «Вихід».
Відповідний код програми може бути написаний наступним чином.
def click():
if counter.get()<999:
counter.set(counter.get()+1)
else:
counter.set(0)
def clear():
counter.set(0)
from tkinter import *
window = Tk()
window.title(‘Простий лічильник’)
counter = IntVar()
counter.set(0)
frame = Frame(window)
frame.pack()
btn1 = Button(frame, text = ‘+’, command = click)
btn2 = Button(frame, text = ‘0’, command = clear)

65
btn3 = Button(frame, text = ‘Вихід’, \
command = window.destroy)
btn1.grid(row = 0, column = 0)
btn2.grid(row = 0, column = 1)
btn3.grid(row = 1, column = 0, columnspan = 2)
label2 = Label(window, textvariable = counter)
label2.pack()
window.mainloop
Головними особливостями програмного коду, наведеного у прикладі
5.20, є наступні.
1. Для спрощення виведення кнопок в інтерфейсне вікно та збереження
за цієї умовии красоти та органічності створюваного віконного інтерфейсу,
розташування кнопок у фреймі здійснюється з використанням методу
grid().
2. Оскільки кнопка «Вихід» має більш довгий надпис, ніж кнопки «+»
та «0», вона розташована в іншому рядку та займає дві колонки.
3. Для читання значення лічильника counter використаний метод
get(), а для встановлення його значення – метод set(). Теоретичні
відомості щодо способів роботи з цими методами для читаття та
встановлення властивостей різних об’єктів були розглянуті у підрозділі 4.1.3.
4. Для аналізу події натиснення на кнопку «+» використана внутрішня
функція click(), для аналізу події натиснення на кнопку «0» – внутрішня
функція clear(), а вихід із програми здійснюється з використанням
стандартного метода window.destroy().
5. Ініціалізація змінної counter здійснюється з використанням
стандартного метода IntVar().
6. Оскільки значення змінної counter є не текстовим, а числовим, для
зміни тексту у текстовому вікні зроблено посилання не на властивість text,
а на властивість textvariable.
Результат роботи командних рядків, наведених у прикладі 5.20,
показаний на рис. 5.31.
66
а) б)
Рис. 5.31 Результат роботи програмного коду, наведеного у прикладі 5.20, у
разі натиснення на кнопки «+» (а) та «0» (б) , якщо початкове значення
лічильника становить 12

5.3.2 Двобічний лічильник


На основі коду програми, наведеного у прикладі 5.20, напишемо
програмний код двобічного лічильника. Як було відмічено у підрозділі 5.3.1,
такий лічильник відрізняється від однобічного тим, що має додаткову кнопку
«–» для зменшення значення показання лічильника на 1.
Приклад 5.21 Написати з використанням засобів програмування
мови Python двобічний лічильник. Для збільшення значення лічильника на 1
використати кнопку «+», а для зменшення на 1 – кнопку «–». Передбачити
можливість очищення лічильника або через натиснення кнопки «0», або у
разі, якщо натиснена кнопка «+», а поточне значення лічильника становить
999. У разі, якщо поточне значення лічильника становить 0 та натиснена
кнопка «–», це значення зберігається. Передбачити також можливість виходу
із програми через натиснення кнопки «Вихід».
Відповідний код програми може бути написаний наступним чином.
def click_plus():
if counter.get()<999:
counter.set(counter.get()+1)
else:
counter.set(0)
def click_minus():
if counter.get()>0:

67
counter.set(counter.get()-1)
else:
counter.set(0)
def clear():
counter.set(0)
from tkinter import *
window = Tk()
window.title(‘Двобічнийий лічильник’)
counter = IntVar()
counter.set(0)
frame = Frame(window)
frame.pack()
btn1 = Button(frame, text = ‘+’, \
command = click_plus)
btn2 = Button(frame, text = ‘-’, \
command = click_minus)
btn3 = Button(frame, text = ‘0’, command = clear)
btn4 = Button(frame, text = ‘Вихід’, \
command = window.destroy)
btn1.grid(row = 0, column = 0)
btn2.grid(row = 0, column = 1)
btn3.grid(row = 0, column = 2)
btn4.grid(row = 1, column = 0, columnspan = 3)
label2 = Label(window, textvariable = counter)
label2.pack()
window.mainloop
Результат роботи командних рядків, наведених у прикладі 5.21,
показаний на рис. 5.32.
68
а) б) в)
Рис. 5.32 Результат роботи програмного коду, наведеного у прикладі 5.21, у
разі натиснення на кнопки «+» (а), «–» (б) та «0» (в), якщо початкове
значення лічильника становить 12

5.3.3 Реакція на події із затримкою та приклад створення


багатофункціонального годинника із секундоміром та звуковим
сигналом
Окремим цікавим завданням, пов’язаним із програмуванням
інтерфейсів, є реакція на події із затримкою. Саме таким способом
створюється сучасне програмне забезпечення із зміною малюнків в
реальному часі, з анімацією та із звуковим супроводженням [12, 60].
У мові програмування Python для реалізації часової затримки на зміну
елементів інтерфейсного вікна використовується системна функція
after() [70]. Загальна синтаксична конструкція цієї функції, або методу
роботи з об’єктом інтерфейсного вікна, записується у наступному вигляді:
object_name.after(time_ms, function())
де object_name – ім’я об’єкта, для якого виконується затримка події,
time_ms – час затримки в мілісекундах, function()– ім’я функції, яка
виконується після визначеної затримки.
Часто разом із функцією after() використовується також функція
after_idle(function). У такому разі функція after() переноситься
до функції користувача function(), яка викликається після виконання всіх
дій функцією after_idle(function).
Розглянемо приклад створення з використанням цих функцій простого
комп’ютерного годинника. Для цього, крім стандартних методів модуля
tkinter, розглянутих у підрозділі 5.2, нам знадобиться також функція
69
strftime() модуля time. Ця функція повертає значення поточного часу,
встановленого на таймері комп’ютера, у форматі H:M:S. Для цього формату
подання часу на години, хвилини та секунди виділено по дві позиції, а
відділяються ці позиції двокрапкою [70]. Відповідний програмний код можна
записати наступним чином.
Приклад 5.22
from tkinter import *
import time
def tick():
label['text'] = ime.strftime('%H:%M:%S')
label.after(200,tick)
window = Tk()
window.title('clock')
label = Label (font='sans 20')
label.pack()
label.after_idle(tick)
window.mainloop
Результат роботи програмного коду, наведеного у прикладі 5.22,
показаний на рис. 5.33.

Рис. 5.33 Результат роботи програмного коду, наведеного у прикладі 5.22

Іншою важливою функцією подійного моделювання, яку часто


використовують програмісти для сигналізації про наявність помилки або про
безпомилкове завершення програми, є подання комп’ютером відповідного звукового
сигналу. У мові програмування Python сформувати звуковий сигнал можна досить
просто з використанням системної функції Beep(freq, duration) модуля
winsound, де freq – частота звукового сигналу у Герцах, а duration – його

70
тривалість в мілісекундах. Відповідний програмний код для формування сигналу з
частотою 440 Гц на протязі однієї секунди має наступний вигляд [71].
Приклад 5.23
import winsound
duration = 1000 # millisecond
freq = 440 # Hz
winsound.Beep(freq, duration)
Слід відзначити, що такий спосіб формування простого звукового
сигналу є стандартним та використовується в різних мовах програмування [3,
5, 8 – 10, 17, 39, 40].
Приклад 5.24 На основі прикладів 5.22 та 5.23 створити програму із
віконним інтерфейсом для багатофункціонального годинника, який може
виконувати функцію секундоміра та подавати звуковий сигналу у визначений
користувачем час.
На секундомір будемо виводити час у форматі M:S.D через кожні
100 мс, де D – десяті долі секунди, але починати рахувати час будемо з нуля.
Передбачимо також кнопки «Старт» та «Стоп», які дають можливість
запускати та зупиняти секундомір, та кнопку «Онулення» для онулення
показника секундоміра. Будемо також вважати, що для годинника кнопки
«Старт», «Стоп» та «Онулення» не працюють. Перевірку події натиснення
на кнопки «Стоп» та «Старт» будемо проводити через значення змінної CT з
використанням методів get() та set(). Якщо секундомір зупинений,
змінна CT приймає значення 0, а якщо запущений – значення 1. Для аналізу
подій натиснення на кнопки «Стоп» та «Старт» використаємо функції
runtime() та stoptime(), а для аналізу події натиснення на кнопку
«Онулення» – функція cleartime(). Обрання функції відображення
годинника або секундоміра будемо робити з використанням селекторної
кнопки із надписами «Годинник» та «Секундомір».
Передбачимо також можливість визначення частоти та тривалості
звукових сигналів, тривалості паузи між цими сигналами та кількості

71
сигналів. Для визначення частоти та тривалості використаємо лінійки з
повзунцем, а для визначення кількості сигналів – нумерований список із
значеннями від 1 до 20. Перебачимо також кнопку-перемикач «Ввімкнення
звукового сигналу» для реалізації функції вмикання звукового сигналу, а
вимикання його будемо робити окремою кнопкою, функціональне
призначення якої буде описане пізніше. Будемо вважати, що значення
частоти сигналу може змінюватись в діапазоні від 100 Гц до 8 кГц із кроком
10 Гц, а значення тривалості звукового сигналу та паузи між сигналами – від
1 с до 10 с з кроком 0,1 с. Функції годинника, пов’язані із формуванням та
поданням звукового сигналу, реалізуємо у програмному коді у функції
sound().
У разі включення секундоміра замість годинника у текстовому вікні
класу Label спочатку замість поточного часу встановлюються нульові
значення, які потім змінюються через кожні 100 мс, або 0,1 с. Тобто,
розрахунок проводиться до десятих долів секунди із відповідною затримкою
зміни текстового вікна. Як було відмічено, формат виведення часу у цьому
випадку становить M:S:D, де D – десяті долі секунди. У цьому разі
розрахунок показників секундоміра проводиться із заніманням з одного
розряду до іншого. Тобто, якщо значення D дорівнює 9, наступне значення
цього розряду буде дорівнювати 0, але значення секунд збільшується на 1.
Якщо значення секунд дорівнює 59, наступне значення цього показника буде
дорівнювати 0, але значення хвилин збільшується на 1. Секундомір
проводить вимірювання в межах однієї години. Якщо показник хвилин
становить 59, а необхідно збільшити його на 1, значення секундоміра
автоматично онулюється.
Блок-схема алгоритму роботи програми, яка реалізує описаний
багатофункціональний годинник, наведена на рис. 5.34, а блок-схема
алгоритму роботи секундоміра – на рис. 5.35.
Програмний код, у якому реалізований описаний алгоритм роботи
багатофункціонального годинника, наведений у додатку Б.

72
Початок 7

1
Включений Ні
8
годинник?

2
Годинник Ні
7
запущений?

Відображувати по-
3
точне значення часу

4
Звуковий сигнал Ні
7
включений?

5
Час подавання звуково- Ні
го сигналу відповідає 7
поточному

Подати звуковий
6
сигнал 2 4 5 8

7
Є команда на Ні
завершення роботи 1
програми?
1

Кінець 8
Секундомір Ні
7
запущений?

Відображення підрахо-
9 ваного значення часу

4
Рис. 5.34 Блок-схема алгоритму роботи багатофункціонального годинника

73
Початок 3

Встановлене почат- Відображення


1 кове значення часу 8 поточного
00:00.0 12 значення часу

2 M = 0; S = 0; D = 0 7 8 3

3
Є команда на зміну Ні
8
показань? 3

4 D=D+1 9 D = 0; S = S + 1

5 Ні 10 Ні
9 6
D < 10? S < 60?

10 12
Формування та 11 S = 0; M = M + 1
6 відображення
рядка M:S.D
12 Ні
6
M < 60?
7
Є команда на Ні
завершення роботи 3
2
програми?

Кінець

Рис. 5.35 Блок-схема алгоритму роботи секундоміра

Результат роботи програмного коду, наведеного у додатку Б, показаний


на рис. 5.36. Рис. 5.36, а, відповідає випадку включення годинника, а
рис. 5.36, б – випадку включення секундоміра.
Спосіб подання звукового сигналу, використаний у прикладі 5.24,
потребує окремого обговорення. Розглянемо алгоритм роботи програми,
наведений у вигляді блок-схеми на рис. 5.34, більш досконало. Згідно з цим
алгоритмом спочатку проводиться зчитування значення поточного часу з
системного блоку комп’ютера для годинника або формування цього значення

74
для секундоміра, а потім, у разі, якщо поточний час співпадає із заданим,
подається звуковий сигнал. Недолік такого способу обробки цих двох
одночасних подій полягає у тому, що виконуються вони послідовно. З точки
зору організації логіки роботи програми це означає, що під час подання
звукового сигналу рядок відображення часу у текстовому вікні тимчасово не
змінюється. Така послідовна обробка одночасних подій притаманна
більшості сучасних комп’ютерних систем, винятком є лише найсучасніші
системи паралельних обчислень [12 – 14].

Рис. 5.36 Результат роботи програми, описаної у прикладі 5.24, у разі


включення годинника (а) та секундоміра (б)

Тоді виникає інше питання. Яким чином на сучасних комп’ютерах


здійснюється обробка звуку та зображень у режимі реального часу, і чому тут
ніякої затримки не спостерігається? Річ у тому, що в сучасних комп’ютерних
системах відображення одночасних подій та одночасне функціонування
програмного забезпечення здійснюється через формування на рівні
75
програмування інформаційних потоків. Якщо комп’ютеру надана команда
сформувати відповідну кількість потоків, дані у цих потоках обробляються
одночасно або майже одночасно. Обробку потоків можна роботи двома
способами. Якщо для розв’язування поставленого завдання, поділеного на
потоки, передбачене використання лише одного центрального процесора,
тоді такі потоки розподіляються за часом. Тобто, у якісь невеликі моменти
часу виконується частина завдання одного потоку, потім – другого, після
цього процесор знову переключається не перший потік, і так далі, поки всі
завдання обох потоків не будуть повністю виконані. Зважаючи на те, що
перемикання інформаційних потоків здійснюється за вкрай малі проміжки
часу, користувач не помічає цієї внутрішньої організації обчислювального
процесу, йому здається, що всі завдання комп’ютер виконує швидко та
затримки не існує. Іншим способом виконання завдань, поділених на потоки,
є розподілення цих потоків на різні процесори багатопроцесорної системи.
Сьогодні іноді в таких системах використовуються обчислювальні
можливості потужних віддалених серверів [12 – 14]. Слід відзначити, що
технологія поділення завдань із одночасними подіями на потоки була
придумана та реалізована ще в сімдесятих-вісімдесятих роках ХХ століття,
наприклад, ця технологія складає основу операційної системи UNIX.
Операційна система Windows, як багатозадачна система, також основана на
ідеології поточного виконання складних обчислювальних завдань [4, 5, 16]. У
сучасних обчислювальних системах паралельна обробка потоків
відеоінформації із звуковою доріжкою зазвичай здійснюється через
перенесення завдання обробки зображень на відеопроцесор, а завдання
обробки та відтворення звуку – на процесор звукового адаптера [12 – 14]. У
разі такого розподілення єдиного відеопотоку на потік зображення та
звуковий потік, його відтворення в режимі реального часу значно
спрощується.

76
Зрозуміло, що у сучасній мові програмування Python також існують
засоби, призначені для формування інформаційних потоків [24 – 26], але у
простій програмі, наведеній у прикладі 5.24, вони не були використані. Для
формування звукового сигналу написана окрема процедура sound(), у якій
кількість повторень задається через глобальну змінну i з використанням
оператора циклу із заданою умовою:
while (i.get() < int(spb4.get())):
де змінній spb4 відповідає обране значення списку-лічильника, який
розташований у нижній частині віконного інтерфейсу, зображеного на
рис. 5.36.
Для формування паузи між сигналами використаний звук із високою
частотою 100 кГц, яка людським вухом не сприймається [50].
Іншою відмітною рисою програми, наведеної у прикладі 5.24, є
наявність окремої кнопки «Вимкнути звуковий сигнал». Річ у тому, що
оскільки події відображення часу та подання звукового сигналу є
одночасними, переведення перемикача «Подати звуковий сигнал» у
виключений стан є недостатнім для стирання інформації про нього із пам’яті
комп’ютера. Необхідно також надати змінній i значення 0. У разі натиснення
на кнопку «Вимкнути звуковий сигнал», яка також розташована в нижній
частині віконного інтерфейсу, виконується процедура sound_out(), яка
має наступний простий програмний код.
def sound_out():
i.set(0)
chk.set(0)
Незважаючи на вказаний вище недолік, пов’язаний із відсутністю
ділення завдань, які повинні виконуватись одночасно, на окремі
інформаційні потоки, написана програма є достатньо простою, проте
функціональною та ефективною.

77
5.3.4 Створення стандартних елементів віконного меню
текстового редактора
Перед вивченням цього підрозділу необхідно повторити підрозділ 2.6.5
Одним із найважливіших сучасних практичних завдань, пов’язаних із
створенням програмного забезпечення із віконним інтерфейсом, є написання
текстових редакторів [8 – 10, 16]. Загальновідомо, що головними елементами
віконного інтерфейсу текстового редактора є наступні [16].
1. Система меню для роботи з файлами.
2. Вікно відображення тексту, який вводиться з клавіатури.
3. Діалогові вікна для відкриття та збереження файлів.
4. Лінійка прокручення набраного тексту для послідовного
відображення його фрагментів.
Система меню текстового редактора у найпростішому варіанті має дві
опції, Файл та Допомога. За загальноприйнятими стандартами опція меню
Файл повинна мати принаймні чотири головні команди для роботи з
файлами: створити новий файл – «Новий», відкрити файл – «Відкрити»,
зберегти файл – «Зберегти», закрити файл – «Закрити» та вийти з
редактора – «Вихід», а опція меню Допомога зазвичай має лише одну
команду «Про програму», за якою виводиться інформація про розробника
програми та про її головні функції.
Розглянемо головні засоби та функції мови програмування Python, з
використанням яких можна створити текстовий редактор із віконним
інтерфейсом.
Зрозуміло, що команди опції меню Файл тісно пов’язані із командами
мови програмування Python, призначеними для роботи з файлами, які
розглядалися у підрозділі 2.6.5. Єдина різниця полягає в тому, що ці команди
тепер необхідно реалізувати з використанням графічних засобів побудови
віконного інтерфейсу. Розглянемо головні методи мови програмування
Python, призначені для роботи з файлами через віконний інтерфейс, та опції
для виклику цих методів, які визначають властивості відкритого файлу [70].
78
Всі опції, які відповідають цим методам, розташовані у функції
filedialog модуля tkinter. Перелічимо головні з них [70].
1. askopenfile() – запит на відкриття файлу.
2. asksaveasfile() – запит на збереження файлу.
Щодо допомоги до програми, вона відображується за допомогою
функції showinfo метода messagebox модуля tkinter. У зв’язку із
сказаним вище, першими рядками програми текстового редактора мають
бути наступні [70].
from tkinter import *
from tkinter.filedialog import askopenfile, \
asksaveasfile
from tkinter.messagebox import showinfo
Під час виконання команд askopenfile та asksaveasfile
відкриваються діалогові вікна для роботи з файлами, а налаштування опцій
для роботи з файлами виконується через наступні параметри
конструктора [70].
1. filetypes – типи файлів, які можуть бути відкритими. Можливі
значення цього параметру:
filetypes = (‘Текстові файли’, ‘.txt’)
filetypes = (‘Файли інтерпретатора мови \
Python’, ‘.py’)
filetypes = (‘Всі файли’, ‘*.*’)
У цих опціях перша рядкова змінна визначає рядок, який пишеться у
діалоговому вікні у випливаючому списку «Тип файлів», а друга змінна –
розширення файлів, які відображуються у діалоговому вікні.
Описані вище методи роботи з файлами askopenfile() та
asksaveasfile() відповідають об’єктам fopen та fsave, що
безпосередньо пов’язані з файлами, з якими виконується відповідна
операція [70]. З об’єктом fopen пов’язаний метод str = fopen.read(),
а з об’єктом fsave – метод fsave.write(str). Відповідні методи
79
читання та запису файлів розглядалися у підрозділі 2.6.5. Функція
fopen.read() повертає рядок, який містить відповідний текст, прочитаний
із файлу через функцію операційної системи, а функція
fsave.write(str) приймає як аргумент рядок, який записується до
текстового файлу із визначеним іменем. Якщо виконується операція читання
файлу – цей рядок необхідно вставити до елементу інтерфейсу Text. Для
цього виконується наступний програмний код [70].
text.delete(0.0, END)
text.insert(END, str)
Слід відзначити, що у разі натиснення у діалоговому вікні замість
кнопки «Open» або «Save» кнопки «Cancel», методи askopenfile() та
asksaveasfile() повертають значення None. У цьому разі вихід із
функції читання або записування файлу здійснюється з використанням
умовних операторів наступним чином [70].
if fopen == None: return
if fsave == None: return
Слід відзначити, що вікна відкриття та збереження файлу є об’єктами
операційної системи, тому надписи на кнопках цих вікон залежать від мови
системи, встановленої на вашому комп’ютері. Щодо розглянутих вище
надписів меню текстового редактора, вони виконуються програмістом під час
створення програми, тому їх мова може не відповідати мові операційної
системи.
Записування файлу здійснюється з використанням наступного набору
команд [70].
str = text.get(0.0, END)
fsave.write(str)
fsave.close()
Після описання головних функцій роботи з файлами перейдемо
безпосередньо до описання інтерфейсного вікна текстового редактора. Воно
має два елементи інтерфейсу: Text та Scrollbar. Елемент Text дозволяє

80
користувачу вводити текст до текстового вікна, а елемент Scrollbar
призначений для перегляду тексту через прокручення за допомогою лінійки.
Цей атрибут текстового редактора із графічним вікном є загальноприйнятим
стандартом [16].
Елемент інтерфейсу Text дозволяє вводити будь-яку кількість рядків
тексту. Головними властивостями цього об’єкта є наступні [70].
wrap – властивість, за допомогою якої задається спосіб відображення
довгих рядків тексту. У разі значення wrap = WORD текст у вікні
переноситься за словами, а у разі wrap = CHAR – за символами.
font – властивість, яка визначає тип шрифту.
У мові програмування Python атрибути тексту, зокрема тип шрифту,
можна застосовувати до уривків тексту, які у теорії програмування
називаються тегами (від англійського слова tag – позначка, ознака). Для
створення тегів використовується метод tag_add об’єкта Text, який має
наступний синтаксис:
text.tag_add(‘tag_name’, ‘first_row.first_char’, \
‘last_row.last_char’)
де tag_name – ім’я тегу, first_row – рядок, з якого починається тег,
last_row – рядок, яким закінчується тег, first_char – символ першого
рядку, з якого починається тег, last_char – символ останнього рядку,
яким закінчується тег [70]. Важливим є те, що нумерація рядків починається
з одиниці, а нумерація символів – з нуля. Наведемо приклад використання
команди text.tag_add().
text.tag_add(‘first’, ‘3.0’, ‘4.11’)
Ця команда означає, що тег з іменем first починається з першого
символу третього рядка, а закінчується дванадцятим символом четвертого
рядка.
Для створеного тегу можна змінити властивості тексту, зокрема колір
та розмір шрифту, з використанням метода config(). Головними

81
параметрами цього метода є наступні [70].
1. tag_name – ім’я тегу.
2. foreground – колір тексту.
3. background – колір фону.
4. font – тип та розмір шрифту. Цей параметр метода config()
записується у наступному форматі [70].
font = (‘font_type’, font_size)
де font_type – тип шрифту, font_size – його розмір.
Наведемо приклад використання команди config().
text.tag_config(‘first’, foreground = ‘red’, \
background = ‘black’, font = (‘times’, 14))
Для роботи з фрагментами тексту у вікні редактора використовуються
наступні методи [70].
1. get() – читання тексту. Ця команда має наступний синтаксис.
get(first_row.first_char, last_row.last_char)
Значення параметрів цієї функції було розглянуто вище. Слід
відзначити, що другий аргумент у зазначеному форматі команди get()
може мати значення end. Таке значення другого аргументу означає, що текст
треба читати до кінця. Зрозуміло, що метод get() повертає до присвоєної
змінної текстовий рядок.
2. insert() – вставка фрагмента тексту. Формат цієї команди має
наступний вигляд.
insert(row.char, string)
де row.char – номер рядка та номер символу у рядку, після якого треба
вставити текстовий фрагмент, визначений змінною string. Наведемо
приклад використання команди insert().
insert(3.14, ‘Студент Потапенко’)
Ця команда означає, що на позицію п’ятнадцятого символу третього
рядка необхідно вставити фрагмент тексту ‘Студент Потапенко’.

82
3. delete() – видалення текстового фрагменту. Формат цієї команди
співпадає із форматом команди get().
delete (first_row.first_char, last_row.last_char)
Наприклад, команда text.delete(0.0, END), яка була розглянута
нами вище, призначена для видалення всього тексту, написаного у вікні
редактора.
Як було відмічено раніше, для перегляду тексту у вікні редактора
використовується елемент графічного інтерфейсу Scrollbar. Для
здійснення прокручення тексту у вікні необхідно виконати дві наступні
операції [70].
1. Для елемента інтерфейсу Text встановлюється опція
yscrollcommand = scrollbar.set.
2. Для елемента інтерфейсу Scrollbar встановлюється опція
command = text.yview.
У цих двох командах літера y вказує координату, за якою здійснюється
перегляд тексту. Тобто, значення y вказує на горизонтальну смугу
прокручення. Для встановлення вертикальної смуги слід використовувати
опції xscrollcommand та xview [70].
У зв’язку з сказаним вище, команди мови програмування Python,
призначені для встановлення смуги прокручення у вікні текстового
редактора, мають наступний вигляд [70].
text = Text(window, height = 3, width = 40)
text.pack(side = ‘left’, fill = ‘both’, \
expand = ‘yes’)
scrollbar = Scrollbar(window, command = text.yview)
text.configure(yscrollcommand = scrollbar.set)
scrollbar.pack(side = ‘right’, fill = Y)
Після створення головного інтерфейсного вікна та розташування в
ньому текстового вікна та лінійки прокручування з використанням
розглянутих вище команд, необхідно сформувати у віконному інтерфейсі
83
рядок меню для роботи з текстовим редактором. Для цього використовується
елемент віконного інтерфейсу Menu. Цей об’єкт використовується як для
створення рядка меню головного вікна, так і для випадаючих та випливаючих
меню [70]. За існуючим стандартом меню головного вікна розташовується
зверху, під заголовком вікна. Як було відмічено вище, у текстовому
редакторі це меню містить дві головні команди, Файл та Допомога. Опція
меню Файл повинна мати випливаюче меню з п’яти команд: «Новий»,
«Відкрити», «Зберегти», «Закрити» та «Вихід», а опція Допомога для
програми, яка створюється, буде мати лише один елемент спливаючого
меню, який матиме назву «Про програму».
Меню верхнього рівня із опціями Файл та Допомога створюється
досить просто з використанням метода Menu() із посиланням на кореневе,
або батьківське вікно window. Тобто, ім’я батьківського вікна window має
бути аргументом функції Menu(). Приклад написання такої команди може
бути наступним [70].
menubar = Menu(window)
де menubar – ім’я змінної, яке дає посилання на створений об’єкт класу
Menu.
Але однієї цієї команди недостатньо, оскільки об’єкт menubar
створений, але не розташований в інтерфейсному вікні. Розташовується цей
об’єкт автоматично в верхній частині інтерфейсного вікна window з
використанням наступної команди [70].
window.config(menu = menubar)
Тепер створений об’єкт menubar є батьківським для інших об’єктів
інтерфейсвного меню, які будуть створюватися далі. Тобто, всі наступні
об’єкти меню будуть створюватись або із посиланням на об’єкт menubar,
або із посиланням на його нащадків з використанням концепції
успадкування, описаної у підрозділі 1.2.
Можна відразу створити спливаюче меню для команди Файл із

84
посиланням на об’єкт menubar, для цього використовується розглянутий
нами вище метод Menu(). Відповідна команда має наступний вигляд [70].
filemenu = Menu(menubar, tearoff = 0)
У цій команді параметр tearoff = 0 відключає опцію відображення
пунктирної лінії на початку списку команд меню.
Але, як і в попередньому випадку, об’єкт filemenu поки лише
створений, але не розташований в інтерфейсному вікні. Це можна зробити з
використанням методу add_cascade(), який має наступні аргументи
виклику [70].
1. label – назва відповідного пункту меню, наприклад,
label = ‘Файл’ .
2. underline – номер символу, який підкреслюється. Через клавішу
цього символу, разом із натисненою клавішею Alt, забезпечується доступ до
відповідної команди меню. Значенню underline = 0 відповідає перший
символ.
3. menu – посилання на батьківський об’єкт. Наприклад,
menu = filemenu.
Згідно із визначеними параметрами, приклад написання команди
menubar.add_cascade() може бути наступним [70].
menubar.add_cascade(label = ‘Файл’, underline = 0, \
menu = filemenu)
Тепер можна описати рядки спливаючого меню із посиланням на
функції, які виконують відповідні команди меню. Для цих об’єктів
батьківським також є об’єкт filemenu, а функція, яка викликається у разі
вибору відповідного елемента меню, задається звичайним чином через опцію
command. Для такого описання елементів випливаючого меню
використовується метод add_command(), який має бути зв’язаним із
об’єктом, до якого він застосовується. Наприклад, запис
filemenu.add_command() означає, що метод add_command()

85
зв’язаний із об’єктом filemenu. Наведемо приклад написання команди
add_command(), який може бути безпосередньо використаний для
написання текстового редактора [70].
filemenu.add_command(label = ‘Новий’, \
underline = 0, command = newfile)
Крім цього, в методі add_command() може бути використаний
параметр accelerator, який дозволяє виконати відповідну команду
файлового меню через описану комбінацію клавіш. Способи описання
комбінацій клавіш у мові програмування Python були наведені у
підрозділі 5.2.5.3. Наведемо приклад написання команди add_command() із
параметром accelerator.
filemenu.add_command(label = ‘Новий’, \
underline = 0, accelerator = ‘Ctrl + n’ \
command = newfile)
На основі наведених у цьому підрозділі теоретичних відомостей
розглянемо приклад створення текстового редактора.
Приклад 5.25 Створити текстовий редактор із функціями меню
Файл та Допомога, до опції меню файл включити пункти спливаючого
меню «Новий», «Відкрити», «Зберегти», «Закрити» та «Вихід». Опція
меню Допомога повинна мати лише один пункт спливаючого меню – «Про
програму». Передбачити можливість використання для виконання команд
меню наступних гарячих клавіш:
«Новий» – ‘Ctrl + N’ ; «Відкрити» – ‘Ctrl + O’ ;
«Зберегти» – ‘Ctrl + S’ ; «Вихід» – ‘Ctrl + Q’ ;
«Про програму» – ‘Ctrl + H’ .
Згідно із наведеними у цьому підрозділі теоретичними
відомостями, відповідний код програми, написаний на мові
програмування Python, наведений у додатку В.
На рис. 5.37 показаний результат роботи програмного коду, наведеного
у додатку В, для вікна текстового редактора. На рис. 5.38, а, відображена

86
структура опції меню Файл, а на рис. 5.38, б – вікно системи допомоги. На
рис. 5.39, а, показано вікно відкриття файлу, а на рис. 5.39, б – вікно
збереження файлу.

Рис. 5.37 Віконний інтерфейс текстового редактора. Результат роботи


програми, наведеної у прикладі 5.25

а)

б)
Рис. 5.38 Спливаюче меню команди Файл (а) та вікно системи допомоги (б)
для програми, наведеної у прикладі 5.25

87
а)

б)
Рис. 5.39 Вікна відкриття (а) та збереження (б) файлу для програми,
наведеної у прикладі 5.25

88
5.3.5 Програми для простого та інженерного калькулятора

5.3.5.1 Простий калькулятор


Перед вивченням цього підрозділу необхідно повторити підрозділи 2.4 та 3.7.8
Приклад 5.26 З використанням засобів мови програмування Python
написати програму простого калькулятора з графічним інтерфейсом, який
повинен виконувати наступні функції обробки дійсних чисел.
1. Арифметичні операції додавання, віднімання, множення та ділення.
2. Операцію збільшення або зменшення записаного числа на задану
величину.
3. Функцію взяття остачі від ділення.
4. Функцію обчислення модуля заданого числа.
5. Функцію пошуку відсотків одного числа відносно іншого.
6. Функцію округлення дійсного числа до найменшого цілого, до
найбільшого цілого та до найближчого цілого.
7. Функцію факторіала.
8. Функцію піднесення до степені, логарифмічну функцію,
експоненціальну функцію та функцію обчислення квадратного кореня.
9. Тригонометричні функції та введення числа π.
10. Зворотні тригонометричні функції.
У разі, якщо результат операції не визначений, виводити у вікно
результату повідомлення «Невизначена операція», а у разі, якщо заданий
невірний аргумент функції – виводити повідомлення «Неправильний
аргумент». Операцією із невизначеним результатом будемо вважати
операцію ділення на 0, а неправильним аргументом – такі значення
аргументу, для яких задана функція не може бути обчислена. Крім цього,
передбачимо виведення такого повідомлення про помилку обчислень, як
«Занадто велике значення». Будемо вважати, що повідомлення це

89
повідомлення виводиться у разі x > 10100 .

Передбачити також наявність десяти комірок пам’яті для записування


результатів обчислень та відповідні функціональні кнопки на калькуляторі.
Для розв’язування поставленого завдання спочатку сформуємо
концепцію віконного інтерфейсу калькулятора. Оскільки операції додавання,
віднімання, множення, ділення та піднесення до степені потребують
використання двох операндів, над якими виконується арифметична дія, у
верхній частині калькулятора розташуємо два текстових вікна для введення
даних та одне вікно для виведення результату обчислень. Операцію, яка
здійснюється над одним операндом, наприклад функцію sin, будемо писати
перед першим операдном, а операцію, яка здійснюється над двома
операндами, наприклад, операцію додавання, множення або ділення – між
вікном першого та другого операнда. Між вікнами першого та другого
операндів та вікном результату виконання операції поставимо знак «=».
Праворуч від вікна виведення результату розташуємо кнопку «Очистити»,
натиснення якої має відповідати запису нулів у вікна, де розташовані перший
та другий операнди, а також у вікно результату обчислень. Всі ці елементи
розташуємо у верхній частині головного інтерфейсного вікна та зробимо над
ними загальний заголовок «Блок проведення обчислень».
Під блоком елементів інтерфейсу, призначеним для проведення
обчислень, розташуємо кнопки для вибору математичних функцій, які
розіб’ємо на наступні блоки.
1. Арифметичні операції.
2. Функції округлення.
3. Степеневі, логарифмічна та експоненціальна функції.
4. Тригонометричні функції.
5. Зворотні тригонометричні функції.

90
6. Операції з пам’яттю.
Операція збільшення та зменшення числа, занесеного до першого
вікна, на величину, задану у другому вікні, віднесемо для блоку
арифметичних операцій. Ці операції є вкрай важливими для проведення
ітераційних розрахунків
Залишається визначити операції з пам’яттю.
У теорії програмування існує два типи таких операцій: операції із
прямою та із посередньою адресацією. У разі прямої адресації адреси
комірок пам’яті вказуються в окремих регістрах. У моделі калькулятора,
який розробляється, цю операцію зручно робити з використанням списків-
лічильників.
Посередню адресацію для вікон калькулятора будемо проводити
наступним чином. У разі натиснення на кнопку М(В1) => М(В2) число, яке
знаходиться у вікні з номером, що вказаний у першому вікні, переноситься
до вікна з номером, який вказаний у другому вікні. Нумерацію вікон будемо
проводити наступним чином.
Вікно В1 – перший операнд, або крайнє ліве вікно у блоці проведення
обчислень.
Вікно В2 – другий операнд, середнє вікно у блоці проведення
обчислень.
Вікно В3 – результат обчислень.
Вікна 4 – 13 – додаткові вікна пам’яті, розташовані праворуч від блоку
проведення обчислень та функціональних кнопок калькулятора.
Наведемо приклад роботи із пам’яттю калькулятора. Припустимо, що,
для проведення подальших обчислень, необхідно перенести отриманий
результат до першого вікна. Тоді до першого вікна необхідно занести цифру
3, до другого – цифру 1, та натиснути кнопку М(В1) => М(В2). У теорії
програмування такий спосіб роботи з пам’яттю називається неявною
адресацією [1].
Кнопку М(В1) => М(В2) розташуємо у нижній частині вікна у блоці під
назвою «Блок операцій з пам’яттю».
Узагальнена схема запропонованого та описаного вище віконного

91
інтерфейсу калькулятора наведена на рис. 5.40.
Код програми для калькулятора з описаними вище функціональними
можливостями, написаний з використанням засобів мови програмування
Python, наведений у додатку Г.
Програма, яка наведена у додатку Г, містить велику кількість рядків та,
напевно, є найскладнішою для аналізу із програм, наведений у цьому посібнику.
Тому розглянемо її та проаналізуємо особливості її написання більш досконало.

Головне вікно інтерфейсу калькулятора

Блок проведення обчислень Очистити Пам’ять


Оп. Вікно 1 Оп. Вікно 2 = Вікно 3 Вікно 4

Вікно 5
Блок арифметичних операцій

Вікно 6

Блок операцій округлення Вікно 7

Вікно 8
Блок степеневих, логарифмічної та
експоненціальної функції Вікно 9

Вікно 10
Блок тригонометричних функцій
Вікно 11

Блок зворотних тригонометричних функцій Вікно 12

Вікно 13

Блок операцій з пам’яттю

Вихід

Рис. 5.40 Проект віконного інтерфейсу простого калькулятора для прикладу 5.26

92
По-перше, головною причиною великою кількості рядків у цій програмі є
високі функціональні можливості калькулятора, який містить 27 кнопок з
математичними функціями, упорядкованих за функціональними блоками. Всі ці
математичні функції вам відомі. Вони розташовані у базовій бібліотеці
інтерпретатора Python та у бібліотеці math та були розглянуті у підрозділі 2.4.
Структура калькулятора побудована таким чином, що заповнені текстові вікна В1
та В2 містять вхідні параметри всіх визначених математичних функцій. Тому
обробка подій натиснення на кнопки математичних функцій пов’язана лише з
аналізом вмісту цих текстових вікон на значення дійсного або цілого числа та із
виконанням відповідних математичних операцій, коли тип числа є правильним. У
противному випадку у вікно результату В3 виводиться повідомлення «Перевірте
числові значення». Перевірка коректності операцій перетворення типів даних
виконана у функціях is_digit() та is_int() з використанням оператора
мови Python try, розглянутого нами у підрозділі 3.7.9. Цей оператор пробує
виконати вставлені у його тіло команди, але у разі хибного їх виконання не
видається повідомлення про помилку у вікно інтерпретатора. Якщо функція
is_digit() виконана правильно, вона повертає значення True, а у
противному випадку – значення False [24 – 27, 70]. Нижче наведений
програмний код функцій is_digit() та is_int().
def is_digit():
try:
W1.set(float(et1.get()))
W2.set(float(et2.get()))
return True
except ValueError:
pass
return False
def is_int():
try:

93
W1.set(int(et1.get()))
W2.set(int(et2.get()))
return TRUE
except ValueError:
pass
return False
Якщо відповідна математична функція має не два, а один аргумент,
перевіряється лише значення, яке знаходиться у вікні В1. Така перевірка
виконується у функції is_digit1().
У наведеній програмі калькулятора найпростішою є обробка події
натиснення на кнопку «Очистити» обчислювального блоку. За цією подією
числові значення у вікнах значення В1, В2 та В3 онуляються, а замість імен
виконаних функцій, які стояли перед кнопками В1 або В2, ставляться початкові
вказівники на ці функції «F1» та «F2». Імена функцій пишуться у текстових вікнах
класу Label та для зміни вмісту цих вікон використовується добре відомий нам
метод label.config(). Текстовому вікно, яке стоїть ліворуч, перед першим
вікном введення даних, відповідає ім’я label2, а вікну, яке розташоване між
першим та другим вікнами введення даних – ім’я label4.
Більш складною є процедура очищення текстових вікон класу Edit, в які
заносяться числові дані. Річ у тому, що у мові програмування Python для об’єктів,
в яких редагується текст, не визначений метод set() [24 – 27, 70]. Тому
автоматична зміна текстової інформації в таких об’єктах може бути виконана, як
для будь-якого текстового редактора, лише з використанням методів insert()
та delete(). Відповідний спосіб очищення вікна текстового редактора
розглядався у підрозділі 5.3.4. Якщо вікну В1 відповідає змінна et1, а вікну В2 –
змінна et2, випис у ці вікна нульових значень можна зробити з використанням
наступних команд.
et1.delete(0,END)
et2.delete(0,END)
et1.insert(0,'0')
94
et2.insert(0,'0')
Нижче наведений код процедури clear(), призначеної для очищення
вікон В1, В2, а також текстових вікон label2 та label4, до яких в процесі
роботи виводяться коди виконаних операцій, та label7, де записаний результат
виконання останньої операції. Тобто, ім’я label7 відповідає вікну В3.
def clear():
et1.delete(0,END)
et2.delete(0,END)
et1.insert(0,'0')
et2.insert(0,'0')
label7.config(text = '0')
label4.config(text='F2:')
label2.config(text='F1:')
У математичних функціях, які є методами, що обробляють події натиснення
на кнопки математичних операцій, виконуються наступні дії.
1. Перевірка значень, введених у вікнах В1 та В2, на належність до
відповідного класу чисел, дійсних або цілих. Із комплексними числами
калькулятор не працює.
2. Перевірка введеного діапазону числових значень. У разі, якщо заданий
невірний аргумент функції або занадто велике число, у вікно результату В3
виводиться відповідне повідомлення.
3. Якщо перевірки за пунктами 1 та 2 дали негативний результат, він
виводиться у вікно результату В3 та виконання математичної функції вважається
завершеним.
4. Якщо функція, яка виконувалась, має один аргумент, ім’я цієї функції
пишеться перед вікном В1, а якщо 2 аргументи – між вікнами В1 та В2.
Нижче, для прикладу, наведені коди функцій для виконання операцій
множення, обчислення факторіалу та квадратного кореня з написаного вище
програмного коду. Узагальнений алгоритм обробки події натиснення на кнопку
математичної функції наведений на рис. 5.41.
# Функція множення
def multiply():
95
Початок
2

Читання рядків із
1 теекстових вікон В1 Формування пові-
та В2 7 домлення «Перевірте
числові значення»

2
Ні Кінець
Рядки є числами? 7

3
3
Аргументи функції Ні Формування пові-
відповідають області 8 8 домлення «Непра-
визначення? вильний аргумент»

Кінець
4
Числа є занадто вели-
кими для проведення 9
4
обчислень?

Ні Формування пові-
9 домлення «Занадто
Обчислення зна-
5 чення функції великі значення»

Кінець
Формування рядка
6 для виведення у
теекстове вікно В3

Кінець

Рис. 5.41 Алгоритм обробки події натиснення на кнопку математичної функції для
моделі простого калькулятора, яка розглядається у прикладі 5.26

ChkDig=is_digit()
if (ChkDig==TRUE) and (abs(W1.get())<1e30) and \
(abs(W2.get())<1e30):
RES=float(et1.get())*float(et2.get())
RES_TXT=str(RES)

96
elif ((abs(W1.get())>=1e30) and \
(abs(W2.get())>=1e30)):
RES_TXT='Занадто велике значення'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='*')
label2.config(text='')
# Функція факторіалу
def fakt():
ChkDig=is_int()
if (ChkDig==TRUE) and (0<W1.get()<100):
if (W1.get()<50):
RES=factorial(int(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT=str(float(factorial\
(int(et1.get()))))
elif W1.get()>=100:
RES_TXT='Занадто велике значення'
elif W1.get()<0:
RES_TXT='Невірний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='n!')
# Функція квадратного кореня
def fn_sqrt():
ChkDig=is_digit1()

97
if (ChkDig==TRUE) and (W1.get()>=0):
RES=sqrt((float(et1.get())))
RES_TXT=str(RES)
elif (W1.get()<0) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='sqrt')
У калькуляторі передбачені два режими роботи з пам’яттю – це режими
прямого доступу та посередньої адресації. У разі режиму прямого доступу адреси
пам’яті встановлюються на списках-лічильниках, розташованих у блоці роботи з
пам’яттю. У разі посередньої адресації джерело даних вказується у вікні В1, а
адреса області розташування даних – у вікні В2. Наприклад, якщо у вікні В1 стоїть
число 4, а у вікні В2 – число 13, необхідно скопіювати число, яке стоїть у комірці
вікна В4 до комірки вікна В13. Зрозуміло, що у разі посередньої адресації значення
числа у першому вікні має бути не менше, ніж 3, оскільки у першому та другому
вікнах зберігаються адреси відповідних комірок і ці значення не є результатами
розрахунків. Для режиму прямого доступу такого обмеження не існує.
Копіювання даних здійснюється наступним чином.
1. Читання чисел, які відповідають адресам джерела та приймача даних. У
разі прямої адресації це будуть числа, встановлені на списках-лічильниках, а у разі
посередньої адресації – числа у вінках В1 та В2. В обох випадках для здійснення
цієї операції використовується метод get(), наприклад:
spb1 = Spinbox(window, from_ = 0, to = 13, \
width = 16, borderwidth = 4, font = 'Arial 10')
spb1.place(x = 100, y = 410, width = 60,
height = 30)
spb1.get()

98
et2 = Entry(window, font='Arial 12', width = 15)
et2.insert(0,'0')
et2.place(x = 260, y = 60)
et2.get()
2. У разі посередньої адресації здійснюється перевірка введених числових
значень. Це повинні бути натуральні числа. Індекс джерела даних має лежати в
діапазоні від 3 до 13, а індекс приймача – в діапазоні від 1 до 13. У разі прямої
адресації значення обох списків-лічильників лежать в діапазоні від 1 до 13, і цей
діапазон встановлюється автоматично.
3. У разі, якщо не виконана умова 2, або значення адрес є однаковими, у
вікно результату В3 виводиться повідомлення «Перевірте числові дані», у
противному випадку – перехід до пункту 4.
4. Читання чисел із джерела та приймача даних. Якщо читання даних
здійснюється з вікна класу Edit, для цієї операції використовується описаний
вище метод get(), а якщо із вікна класу Label – ця операція виконується з
використанням методу cget(‘text’). Наприклад:
et4.get()
RES_TXT=label7.cget('text')
Проблема полягає у тому, що заздалегідь невідомо, з яких вікон буде
здійснюватись читання даних. У програмі, наведеній у додатку Г, текстовому
вікну класу Label відповідає лише вікно В3 з іменем об’єкту label7. Всі інші
вікна є об’єктами класу Edit, тому рядок et_n.get(), де n – номер вікна,
необхідно формувати автоматично в процесі роботи програми. Це можна зробити
двома способами. Перший з них полягає у тому, що всі текстові вікна описуються
однією змінною з індексацією через список. Наприклад:
et = [‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’,‘0’]
et[12] = Entry(window, font='Arial 12', width = 15)
et[12].insert(0,'0')
et[12].place(x = 650, y = 390)
с = et[12].get()

99
Інший спосіб полягає у тому, що цим об’єктам надаються імена змінних, які
закінчуються числовим значенням, наприклад et12. Тоді в процесі виконання
програми формується рядкова змінна ‘et12.get()’, а відповідний метод
роботи з об’єктом викликається як анонімна лямбда-функція через системну
функцію eval(). Відповідний спосіб виклику лямбда-функції був описаний у
підрозділі 3.7.8. Програмний код, в якому реалізований цей спосіб нумерації вікон
пам’яті, може бути записаний наступним чином.
n1=int(et1.get())
n2=int(et2.get())
if(n1!=n2):
if (n2==3):
func='et'+str(n1)+'.get()'
RES_TXT=memconf1(lambda: eval(func))
else:
RES_TXT='Перевірте числові значення'
def memconf1(lf):
label7.config(text = lf())
5. Запис даних до вікна, яке відповідає приймачу даних. Для вікна В3, яке
відповідає класу Label, ця операція здійснюється з використанням розглянутого
вище методу config(), а для інших текстових вікон класу Edit – з
використанням методів insert() та delete(), які для всіх текстових вікон є
однаковими та були розглянуті у підрозділі 5.3.4. Відповідний програмний код має
наступний вигляд.
str1 = ‘et’+str(n1)+‘.get()’
RES_TXT = memconf3(lambda: eval(str1))
srt2 = ‘et’+str(n2)+‘.delete(0,END)’
srt3 = ‘et’+str(n2)+‘.insert(0,RES_TXT)’
memconf2(lambda: eval(str2))
eval(str3)
def memconf2(lf):
lf()

100
Програмний код для організації роботи з пам’яттю у разі використання
прямої адресації реалізований у процедурі trans_mem_direct(), а для
посередньої адресації – у процедурі trans_mem(). Ці процедури є
складовими частинами програми калькулятора, наведеної у додатку Г.
Узагальнений алгоритм для всіх розглянутих методів роботи калькулятора із
пам’яттю наведений на рис. 5.42.

Початок 1

1 Читання адреси дже-


Ні рела n1 з вікна В1 та
Використана пряма 6 6
адресація? адреси приймача n2 з
вікна В2

Читання адреси дже- 7


2 рела n1 з лічильника Зчитані рядки є Ні
Л1 та адреси прийма- 5
натуральними числами?
ча n2 з лічильника Л2 9

3 8
Ні Ні
n1≠ n2? 5 3 ≤ n1 ≤ 13? 5

Перенести рядок 9
4 з вікна n1 до Ні
1 ≤ n1 ≤ 13? 5
вікна n2

3 7 8 9
Кінець
3
Формування пові-
5 домлення «Перевірте
числові значення»

Кінець

Рис. 5.42 Алгоритм роботи калькулятора із пам’яттю для прикладу 5.26 у разі
використання прямої або посередньої адресації

101
Окремо слід розглянути дві арифметичні операції над вікном В1, які
забезпечують ефективне проведення рекурентних обчислень. Це операції
збільшення числа, яка знаходиться у регістрі В1, на величину, що
знаходиться у вікні В2, та зменшення його на цю величину. На кнопках
калькулятора ці операції позначені відповідно як «+В2» та «– В2», а у вікні
описання коду операції, яка була виконана – як «В1 = В1+В2» та «В1 = В1 –
В2». Ефективність використання цих операцій полягає у тому, що у разі
необхідності обчислення заданої функції від сукупності табульованих
значень не треба зайвий раз натискати кнопку «Продовжити», яка копіює
результат обчислень з вікна В3 до вікна В1. Доречи, саме наявність цієї
кнопки робить розроблений калькулятор повноцінною розрахунковою
системою із трьома регістрами обчислювального блоку, яким відповідають
вікна В1, В2 та В3, та десятьма регістрами пам’яті, яким відповідають вікна
В4 – В13. Тобто, у разі виконання операцій «В1 = В1+В2» та «В1 = В1 – В2»
запис результату здійснюється до вікна В1 та вміст цього вікна автоматично
змінюється. Арифметична операція «В1 = В1+В2» виконується з
використанням функції incr(), а операція «В1 = В1 – В2» – з
використанням функції decr(). Зрозуміло, що в цих функціях для
записування результату обчислень замість команди
label7.config(text=RES_TXT)
використаний набір команд:
et1.delete(0,END)
et1.insert(0,RES_TXT)
Нижче наведений програмний код функції incr().
# Функція В1 = В1 + B2
def incr():
ChkDig=is_digit()

102
if (ChkDig==TRUE) and (W2.get()!=0):
RES=float(et1.get())+float(et2.get())
RES_TXT=str(RES)
et1.delete(0,END)
et1.insert(0,RES_TXT)
label2.config(text='В1=B1+B2')
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='В1=B1+B2')
Іншою відмінною рисою розробленого калькулятора є можливість
виконання п’яти головних математичних дій, а саме, операцій додавання,
віднімання, множення, ділення та піднесення до степені, не лише над вікнами
обчислювального блоку В1 та В2, але й над вікнами пам’яті В4 – В13. У
цьому разі для вибору коду операцій використовується селекторна кнопка
класу Radiobutton, а читання коду операції з цієї кнопки реалізується
через функцію var_rad.get(). Відповідний спосіб роботи з елементами
селекторної кнопки був описаний у підрозділі 5.2.6. Для визначення комірок
пам’яті, з якими проводяться арифметичні операції, використовуються ті самі
списки лічильники, що й для операції копіювання. Для реалізації відповідної
операції необхідно натиснути кнопку «Виконати». У разі виникнення події
натиснення на цю кнопку виконується програмний код, реалізований у
функції def mem_operations(). Передбачено також можливість
очищення комірок через натиснення кнопки «Очистити» у блоці роботи з
пам’яттю. Цій кнопці відповідає функція mem_clear().
Віконний інтерфейс розробленого калькулятора у разі виконання
різних операцій показаний на рис. 5.43.

103
104

а)
Рис. 5.43 Віконний інтерфейс калькулятора для прикладу 5.26. а – проведення обчислювальних операцій, б – очищення
арифметичного блоку, в – проведення операцій з пам’яттю, г – очищення блоку пам’яті, д – проведення ітераційних
обчислень з використанням кнопки «+В2»
105

б)
Рис. 5.43 (продовження)

105
106

в)
Рис. 5.43 (продовження)

106
107

г)
Рис. 5.43 (продовження)
107
108

д)
Рис. 5.43 (закінчення)

108
Із наведених теоретичних відомостей зрозуміло, що відмінними рисами
розробленої програми калькулятора є наступні.
1. Наявність окремого вікна результату обчислень В3, до якого
записуються результати виконаних арифметичних дій та обчислення функцій.
2. Наявність кнопки «Продовжити», яка дозволяє переносити результат
виконаних обчислень з вікна В3 до вікна В1 та проводити таким чином
ітераційні обчислення.
3. Можливість збільшення та зменшення вмісту вікна В1 на величину,
яка міститься в регістрі В2, через натиснення кнопок «+В2» та «–В2». Це
дозволяє проводити рекурентні обчислення для табульованих значень
аргументу без натиснення кнопки «Продовжити».
4. Наявність десяти додаткових вікон пам’яті та можливість
копіювання значень, які зберігаються у цих вікнах, з використанням прямої
та посередньої адресації.
5. Можливість виконання арифметичних дій безпосередньо з даними,
які зберігаються у вікнах пам’яті, через пряму адресацію вікон.
6. Відображення функціональних операцій, які виконуються, в
обчислювальному блоку калькулятора.
Головними перевагами розробленої моделі калькулятора є наочність
процесу проведення обчислень та висока функціональність, проте суттєвий
недолік такої наочної моделі полягає у тому, що у більшості випадків для
проведення ітераційних обчислень необхідно зайвий раз натискати кнопку
«Продовжити». У класичній моделі обчислювальних пристроїв, побудованої
на основі польського зворотного запису математичних виразів, результат
обчислень завжди відразу записується до головного регістру
обчислювального блоку, замість попереднього числа, над яким виконувалась
поточна операція [1, 2, 5]. Інший спосіб побудови калькулятора, оснований
на аналізі записаних математичних виразів як рядкових змінних, буде
описаний у наступному підрозділі.

109
5.3.5.2 Інженерний калькулятор
Перед вивченням цього підрозділу необхідно повторити підрозділи 3.7.8, 3.7.9
та 5.2.5.3.
Розглянемо іншу модель інженерного калькулятора, альтернативну
наведеній у підрозділі 5.3.5.1. Будемо вважати, що калькулятор має одне
вікно текстового редактора класу Edit, куди записується математичний
вираз з використанням функцій мови програмування Python, та одне текстове
вікно класу Label для виведення результатів розрахунків. Тобто, віконний
інтерфейс калькулятора аналогічний інтерфейсу для програм, розглянутих у
прикладах 5.6 та 5.13. Саме інтерфейсне вікно цілком подібне до вікна,
отриманого у прикладі 5.6, а алгоритм роботи програми аналогічний
програмі, наведеній у прикладі 5.13. Різниця полягає у тому, що у вікні
калькулятора, який розглядатиметься у цьому підрозділі, немає кнопки для
проведення розрахунків, а введення математичного виразу вважається
закінченим, коли натиснена клавіша «Enter». Крім цього, передбачимо вихід
із програми через натиснення комбінації клавіш «Ctrl + q». Тобто,
інтерфейсне вікно, порівняно із калькулятором, розглянутим у підрозділі
5.3.5.1, є вкрай спрощеним, а аналіз подій реалізований головним чином
через зчитування комбінацій гарячих клавіш. Для обробки таких подій
зазвичай використовується метод bind(). Способи аналізу подій
натиснення на кнопки клавіатури розглядалися у підрозділі 5.2.5.3.
Іншими відмінними рисами програмної реалізації такої моделі
калькулятора є те, що для проведення розрахунку за математичним виразом,
записаним у текстовому вікні, використовується вбудована функція eval,
розглянута у підрозділі 3.7.8, а для аналізу коректності введеного виразу
використовується оператор обробки виключних ситуацій try: except,
розглянутий у підрозділі 3.7.9.
Передбачимо також єдину кнопку «Очистити», у разі натиснення якої
видаляється числове значення з вікна результату, а у вікно введення
командного рядка записується значення 0.
Код програми для інженерного калькулятора із розглянутими вище
функціями наведений у прикладі 5.27 [70].

110
Приклад 5.27
from tkinter import *
from math import *
def clear_res():
res.config(text = 'Результат: ')
entry.delete(0,END)
entry.insert('0',0)
def evalute(event):
try:
res.config(text = 'Результат: ' + \
str(eval(entry.get())))
except ZeroDivisionError:
res.config(text = 'Ділення на нуль!')
except NameError:
res.config(text = 'Відсутня змінна!')
except SyntaxError:
res.config(text = 'Синтаксична помилка!')
except Exception:
res.config(text = 'Помилка введення!')
window = Tk()
window.title('Науковий калькулятор')
l1 = Label(window, text = 'Вираз:')
l1.pack(pady = 3)
entry = Entry(window)
entry.bind('<Return>', evalute)
entry.pack(fill = X, ipady = 3, padx = 6)
res = Label(window, relief = RIDGE, borderwidth = 4)
res.pack(fill = X, padx = 5, ipady = 3, pady = 3)
window.bind('Control-q', lambda event: \
window.destroy)
btn1 = Button(window, text = 'Очистити', \
width = 20, command = clear_res)
btn1.pack()
window.mainloop
Результат роботи програмних рядків, наведених у прикладі 5.27, для
різних функцій, введених у текстовому вікні, показаний на рис. 5.44, а – з

111
а) б)

в) г)

д) е)

ж) з)
Рис. 5.44 Результати роботи програми наукового калькулятора, наведеної у
прикладі 5.27, для різних математичних виразів, введених у вікно редактора:
а – обчислення значення виразу sin(0,4π) – cos(0,4π), б – обчислення значення

виразу 2log 2 (25) , в – обчислення значення виразу


1
,
arccos(0,5) + arcsin (0,5)
г – помилка ділення на 0, д – введення невизначеної змінної si, е – введення
функції sin без аргументу, ж – спроба обчислення квадратного кореня від
від’ємного числа, з – після натиснення кнопки «Очистити»

112
Вельми цікавим є результат, показаний на рис. 5.44, е. Дійсно, якщо у
вікні текстового редактора вказане ім’я математичної функції без її
аргументу, обчислення не проводяться, а у вікно результату виводиться
інформація про цю функцію. Відповідні теоретичні відомості про
особливості роботи інтерпретатора мови Python у разі виникнення цієї
виключної ситуації були розглянуті у підрозділі 2.3. У будь-якому разі
зрозуміло, що оператор обробки виключних ситуацій try: except у коді
програми, наведеному у прикладі 5.27, працює правильно.
Порівнюючи модель простого калькулятора, розглянуту у підрозділі
5.3.5.1, та інженерного калькулятора, розглянуту у цьому підрозділі, можна
сказати, що вагомою перевагою простого калькулятора є наочність
проведення математичних операцій та операцій із пам’яттю та простота
проведення обчислень через натиснення відповідних кнопок. На відміну від
цього, розглянута модель інженерного калькулятора є простішою з точки
зору невеликої кількості функціональних кнопок, але для того, щоб
ефективно працювати з калькулятором такого типу, необхідно досконало
знати правила запису математичних виразів у мові програмування Python, які
були розглянуті у підрозділі 2.4. З іншого боку, код програми, призначеної
для реалізації моделі інженерного калькулятора та наведений у прикладі 5.27,
є значно коротшим та простішим.

5.3.6 Створення віконного інтерфейсу для конвертору фізичних


величин
Перед вивченням цього підрозділу необхідно повторити підрозділ 2.5.6
У підрозділі 2.5.6, у прикладах 2.46 – 2.48, розглядалися програмні
коди для різних конверторів фізичних величин. Головним недоліком таких
програм є те, що введення та виведення даних в них організоване через
командне вікно інтерпретатора, що у певній мірі ускладнює роботу
користувача з ними. Тому, з урахуванням знань, отриманих у цьому розділі,
щодо створення елементів віконних інтерфейсів та написання відповідних
113
програмних кодів, поставимо завдання написати універсальний конвертор
фізичних величин із віконним інтерфейсом.
Приклад 5.28 Використовуючи коди програм, наведені у прикладах
2.46 – 2.48, написати конвертор з віконним інтерфейсом для перетворення
градусів Цельсія на градуси Фаренгейта, Паскалів на міліметри ртутного
стовпчика та разів на децибели. Тип перетворюваної величини визначається
за вибором користувача. Передбачити можливість здійснення прямого та
зворотного перетворення цих фізичних величин.
Спочатку побудуємо проект віконного інтерфейсу, який буде
створюватися. Для цього визначимо головні необхідні елементи інтерфейсу
та розташуємо їх у площині інтерфейсного вікна.
Будемо вважати, що інтерфейсне вікно містить наступні елементи.
1. Селекторну кнопку для обрання фізичної величини, яка
перетворюється, а саме: температура, тиск або підсилення.
2. Два вікна текстових редакторів ТВ1 та ТВ2, до одного з яких
вводиться значення величини, яка перетворюється, а у другому записується
результат перетворення. Вибір вікна, до якого записується вхідна величина,
здійснюється за бажанням користувача.
3. Вікна текстових редакторів підписуються з використанням
звичайних текстових вікон. У разі зміну типу перетвореної величини з
використанням селекторної кнопки автоматично змінюються підписи,
розташовані над вікнами текстових редакторів.
4. Під вікнами текстових редакторів розташуємо кнопки «Очистити» та
«Вихід».
Загальна структура інтерфейсного вікна з описаними вище елементами
наведена на рис. 5.45. Код програми конвертора фізичних величин,
написаний мовою програмування Python, наведений у додатку Д, а
результати роботи цієї програми у разі перетворення різних величин,
натиснення кнопки «Очищення», а також у випадку введення помилкових
даних, представлені на рис. 5.46.

114
Інтерфейсне вікно
Селекторна кнопка для обрання
фізичної величини, яка перетворюється

Вікна текстових редакторів


ТВ1 ТВ2

Кнопки для перетворення


Кнопка «Очистити» Кнопка «Вихід»

Рис. 5.45 Узагальнена структура інтерфейсу конвертора фізичних величин

Програма, наведена у додатку Д, побудована за модульним принципом


та містить наступні функції.
1. Головну функцію, у якій виконано описання всіх елементів
інтерфейсного вікна.
2. Функцію arb(), у якій, з використанням команди
label2.config(), змінюються підписи над текстовими вікнами залежно
від обраного елемента селекторної кнопки. Аналіз обраного елемента
реалізований через читання значення змінної var_rad з використанням
функції var_rad.get(). Функція arb() прив’язана до об’єкту rb1 класу
Radiobutton через значення параметру command.
3. Функцію trans_direct(), у якій реалізовані алгоритми прямого
перетворення фізичних величин. Тип обраної величини, як і для функції
arb(), визначається через значення змінної var_rad, і, залежно від цього,
проводяться відповідні обчислення. Для проведення нелінійного
перетворення із разів до децибелів на початку коду цієї функції здійснений
імпорт математичної функції log10() із модуля math. Для обробки
виключних ситуацій, як-то введення нечислових даних або неправильних
числових значень, всі математичні обчислення виконані з використанням
оператора try: except, розглянутого у підрозділі 3.7.9. В результаті
проведення обчислень формується рядкова змінна STF, значення якої
записується до вікна текстового редактора et2 з використанням наступної
послідовності команд.
115
а) б)

в) г)

д)
Рис. 5.46 Результат роботи конвертора фізичних величин у разі переведення
значень температури (а), тиску (б) та підсилення (в), а також у разі введення
нечислового значення (г) та натиснення кнопки «Очистити» (д)

et2.delete(0,END)
et2.insert(0,STF)
Відповідний спосіб зміни тексту у вікні текстового редактора був
розглянутий у підрозділі 5.3.6.
116
Алгоритми перетворення фізичних величин у функції
trans_direct() реалізовані з використанням співвідношень (2.20), (2.22)
та (2.24).
Функція trans_direct() прив’язана до кнопки btn1 через значення
параметру command. В інтерфейсному вікні цій кнопці відповідає надпис '=>'.
4. Функцію trans_inverse(), у якій реалізовані алгоритми
зворотного перетворення фізичних величин. В цілому структура коду цієї
функції аналогічна структурі коду функції trans_direct(). Алгоритми
зворотних перетворень фізичних величин реалізовані з використанням
співвідношень (2.21), (2.23) та (2.25). Для проведення нелінійного
перетворення із децибелів до разів, згідно із співвідношенням (2.25), на
початку коду функції trans_inverse() здійснений імпорт математичної
функції pow() із модуля math. Функція trans_inverse() прив’язана
через значення параметру command до кнопки btn2, в інтерфейсному вікні
цій кнопці відповідає надпис '<='.
5. Функцію clear_et() для очищення вікон обох текстових
редакторів через записування до них нулевих значень. Ця функція прив’язана
через значення параметру command до кнопки «Очистити».
Із наведеного вище описання коду програми конвертора фізичних
величин, представленого у додатку Д, зрозуміло, що він суттєво відрізняється
від кодів програм, наведених у прикладах 2.46 – 2.48 за своєю структурою та
за загальним принципом організації. Якщо у прикладах 2.46 – 2.48
модульність програмного коду була тісно пов’язана із відповідними
виконуваними перетворювальними алгоритмами, у програмі, наведеній у
додатку Д, всі функції прив’язані лише до елементів інтерфейсного вікна, а
алгоритми перетворення фізичних величин, оскільки вони є вкрай простими,
не діляться на окремі модулі. Вони реалізовані всередині умовних
операторів, що у деякій мірі спрощує читання та аналіз програмного коду.
Така структурна організація цілком відповідає загальному принципу

117
побудови програм із віконними інтерфейсами, який був описаний у
підрозділі 5.1. Тому аналогічну структуру має програма, призначена для
визначення типу матеріалу за його електрофізичними властивостями, яка
буде розглянута у наступному підрозділі.

5.3.7 Створення віконного інтерфейсу для програми, призначеної


для визначення матеріалів за їхніми електрофізичними
параметрами
Перед вивченням цього підрозділу необхідно повторити підрозділ 3.5
У підрозділі 3.5, в прикладах 3.19 – 3.22, розглядалися програмні коди
для визначення типу матеріалів за їхніми електрофізичними параметрами з
використанням умовного оператора. Зокрема, у прикладах 3.19, 3.20,
визначався тип провідникового матеріалу за його питомим електричним
опором або питомою електропровідністю, залежно від вибору користувача, а
у прикладах 3.21, 3.22 – тип ізоляційного матеріалу за його діелектричною
проникністю. Тепер, з урахуванням знань, отриманих у цьому розділі,
поставимо завдання написати універсальну програму з віконним інтерфейсом
для визначення типу матеріалів за їхніми електрофізичними параметрами.
Приклад 5.29 Використовуючи коди програм, наведені у прикладах
3.19 – 3.22, написати програму з віконним інтерфейсом для визначення типу
матеріалів за їхніми електрофізичними параметрами.
Як і у прикладі 5.28, почнемо роботу щодо створення такої програми з
визначення необхідних елементів графічного інтерфейсу та їхнього
розташування у головному вікні.
Для завдання програмування, яке розглядається, в інтерфейсному вікні
слід розташувати наступні елементи.
1. Селекторну кнопку для обрання електрофізичної величини, за якою
визначається речовина, а саме: питомий електричний опір, питома

118
електропровідність або діелектрична проникність.
2. Вікно текстового редактора, в яке вводиться значення цієї
електрофізичної величини. Для зручності роботи з графічний віконним
інтерфейсом розташуємо це вікно безпосередньо під селекторною кнопкою.
3. Текстове вікно, у якому виводиться результат роботи програми. Це
може бути або визначений матеріал, або повідомлення про помилку введення
даних.
4. Під вікнами текстових редакторів розташуємо кнопки «Визначити»,
«Очистити» та «Вихід».
Загальна структура інтерфейсного вікна з описаними вище елементами
наведена на рис. 5.47. Код програми, призначеної для визначення типу
речовини за її електрофізичними параметрами, написаний мовою
програмування Python, наведений у додатку Е. Результати роботи цієї
програми у разі обрання різних електрофізичних параметрів, натиснення
кнопки «Очищення», а також у випадку введення помилкових даних,
представлені на рис. 5.48.

Інтерфейсне вікно

Селекторна кнопка для обрання


електрофізиного параметру, за яким
визначається речовина

Вікно текстового редактора

Текстове вікно для виведення результату

Кнопка «Визначити» Кнопка «Очистити» Кнопка «Вихід»

Рис. 5.47 Узагальнена структура інтерфейсу програми, призначеної для


визначення речовини за її електрофізичними властивостями

119
а) б)

в) г)

д) е)

Рис. 5.48 Результати роботи програми, призначеної для визначення речовини за її


електрофізичними властивостями, наведеної у додатку Е: а – за питомим опором,
б – за питомою електропровідністю, в – за діелектричною проникністю, г – у разі
введення неправильного числового значення, д – у разі введення нечислового
значення, е – у разі натиснення кнопки «Очистити»
120
Комп’ютерна програма, наведена у додатку Е, має наступні
особливості. Оскільки у цій програмі обрання селекторної кнопки не
розглядається як подія, пов’язана зі зміною вигляду інтерфейсного вікна,
немає потреби створювати окрему функцію, призначену для обробки цієї
події. Таким чином, програма, яка розглядається, складається з трьох
процедур. У головній процедурі описані елементи графічного інтерфейсу,
включаючи особливості їх розташування та прив’язування до них
відповідних функцій. Функція def_mat() містить описання алгоритмів
визначення речовини, які розглядалися у підрозділі 3.5 та були реалізовані у
прикладах 3.19 – 3.22 через командне вікно інтерпретатора. Ця функція
прив’язана до кнопки «Визначити». Нарешті, функція clear_et()
призначена для очищення інтерфейсного вікна та прив’язана до кнопки
«Очистити». Результатом роботи цієї функції є записування нульового
значення до вікна текстового редактора та слова «Матеріал:» до вікна
результату роботи програми. Вигляд віконного інтерфейсу програми після
натиснення кнопки «Очистити» показаний на рис. 5.48, е.
Ще однією особливістю програмного коду функції def_mat() є те,
що з метою підвищення надійності роботи програми більшість операцій
порівняння перенесені до структури оператора обробки виключних ситуацій
try: except. В іншому структура умовних операторів аналогічна
операторам, наведеним у прикладах 3.19 – 3.22, проте використання
оператора try: except дозволяє уникнути помилки, пов’язаної з
введенням нечислових даних. Відповідний вигляд віконного інтерфейсу
програми показаний на рис. 5.48, д.
Якщо введене у текстове вікно значення є числовим, воно автоматично
присвоюється змінній з іменем VAL_AN та аналізується з використанням
умовного оператора. В результаті формується рядкова змінна STF, яка
виводиться до текстового вікна як результат обчислень. Якщо задане числове

121
значення не відповідає жодному матеріалу, змінній STF присвоюється
значення рядка «Введене неправильне значення».
В іншому код програми, наведений у додатку Е, є досить простим для
розуміння та не потребує зайвих додаткових пояснень.

5.4 Розміщення графічних елементів у віконному інтерфейсі

5.4.1 Об’єкти векторної графіки модуля tkinter та способи їхньої


побудови та розташування
У попередніх підрозділах були розглянуті лише елементи віконного
інтерфейсу, призначені для аналізу реакції на відповідні події та для введення
та виведення відповідної текстової інформації. Тому такі програми, хоча і є
складнішими, ніж консольні, які розглядалися у другому та третьому
розділах, але мало відрізняються від них за своїми функціональними
можливостями. Зрозуміло, що можливості сучасної комп’ютерної графіки є
значно ширшими.
Тому розглянемо у цьому підрозділі об’єкти векторної графіки модуля
tkinter, які безпосередньо не пов’язані із завданням побудови віконних
інтерфейсів комп’ютерних програм, але широко викоритсовуютсья
програмістами для виконання цього завдання. Насамперед це звичайні
геометричні об’єкти та фігури, як-то пряма лінія, ламана лінія, квадрат, коло,
еліпс, трикутник, чотирикутник, багатокутник тощо [70].
В модулі tkinter існують всі перелічені вище геометричні об’єкти,
та загальний спосіб їхньої побудови пов’язаний із формуванням в
інтерфейсному вікні полотна (англійський термін – Canvas) та
розташуванням на ньому цих об’єктів [70]. Сформувати полотно в межах
заданого головного вікна window можна з використанням наступної
команди [70]:
canvas = Canvas(window, width = 480,

122
height = 360, bg = ‘#fafff’, cursor = ‘pencil’)
Головними параметрами наведеної команди Canvas() є наступні.
1. window – головне вікно, на якому необхідно розташувати полотно.
2. width – ширина полотна.
3. height – висота полотна.
4. bg – колір фону, за замовченням – сірий.
5. cursor – тип курсору, наприклад, у вигляді олівця (‘pencil’).
Після цього, з використанням одного із розглянутих вище методів
розташування об’єктів, полотно необхідно розташувати у головному вікні.
Для цього може бути використаний метод pack(), grid() або place().
Наприклад:
canvas.pack()
canvas.place(x = 90, y = 150)
canvas.grid(row = 1, column = 2)
Після формування полотна та розташування його у головному вікні
можна рисувати на ньому геометричні об’єкти, вказуючи їхню позицію на та
розміри у декартових координатах. Як і для головного вікна, початок
координат на полотні, тобто, точка (0, 0), розташований у верхньому лівому
куті, вісь X направлена праворуч, а вісь Y донизу [70].
Для створення геометричних об’єктів на полотні використовується
стандартний метод creat(). Наприклад, команда canvas.create_line()
призначена для створення прямої, ламаної або гладкої лінії. Головними
параметрами цієї команди є координати точок (x, y), які з’єднуються.
Наприклад, для прямої лінії вказуються координати двох точок: (x1, y1, x2, y2).
Цілком зрозуміло, що координати точок (x1, y1) та (x2, y2) задаються для полотна
згідно з наведеним вище загальним правилом. Наприклад, команда
canvas.create_line(200, 50, 300, 50, 250, 100)

123
призначена проведення лінії між точками з координатами (200, 50), (300, 50)
та (250, 100). Інші можливі параметри команди canvas.create_line()
[70]:
fill – колір лінії, наприклад, fill = ‘blue’.
smooth – спосіб проведення лінії. За умови smooth = 0 за
відліковими точками проводиться ламана лінія, а у разі smooth = 1
будується гладка крива, яка проходить між точками. Тобто, значення
smooth = 0 відповідає лінійній інтерполяції, а smooth = 1 –
поліноміальній апроксимації. Відповідні теоретичні відомості про
інтерполяцію та апроксимацію наведені у практичному занятті 9.
arrow – наявність стрілки на початку та в кінці лінії. Можливі
значення цього параметра:
FIRST – стрілка на початку лінії;
LAST – стрілка в кінці лінії;
BOTH – стрілка з обох кінців лінії.
Приклад формування команди canvas.create_line():
canvas.create_line(200, 50, 300, 50, 250, 100,
fill = ‘blue’, smooth = 1, arrow = LAST)
Із наведених вище теоретичних відомостей зрозуміло, що ця команда
призначена для рисування гладкої лінії (smooth = 1) блакитного кольору
(fill = ‘blue’) із стрілкою на кінці (arrow = LAST) між трьома
точками з координатами (200, 50), (300, 50) та (250, 100).
Товщина лінії у пунктах задається через значення параметра width.
Наприклад:
canvas.create_line(20, 50, 30, 50, \
fill = ‘black, smooth = 0, width = 2)
Для рисування прямокутників у модулі tkinter передбачений метод
create_rectangle(), який також пов’язаний із батьківським об’єктом
класу Canvas. Параметрами цієї команди є наступні змінні [70].

124
1. Координати двох точок (x1, y1) та (x2, y2). Перша точка є координатою
верхнього лівого кута прямокутника, а друга – його нижнього правого кута.
2. fill – колір заливки прямокутника.
3. outline – колір лінії, якою рисується контур прямокутника.
Наприклад:
canvas.create_rectangle(20, 50, 100, 100, \
fill = ‘blue’, outline = ‘black’)
Для рисування багатокутників використовується метод polygon(),
який також пов’язаний із батьківським об’єктом класу Canvas [70]. Метод
рисування багатокутника майже не відрізняється від відповідного метода для
прямокутника, але базові точки багатокутника зазвичай задаються у вигляді
списку із двох чисел, які являють собою координати вершини (x, y). Приклад
використання цієї команди:
canvas.create_polygon([20, 120], [200, 150], \
[80, 20], fill = ‘blue’, outline = ‘black’)
Слід відзначити, що квадратні дужки в координатах точок ставляться
лише для зручності читання програмного коду та можуть бути пропущеними.
У цьому випадку формат команд rectangle() та polygon() є майже
однаковим.
Для рисування багатокутника, як і для зобрапження ламаної лінії, може
бути використаний параметр smooth. У разі smooth = 1 контур
прямокутника рисується гладкою лінією. За замовченням використовується
параметр smooth = 0.
Для рисування еліпсу в модулі tkinter мови програмування Python
використовується метод oval() [70]. Геометричними параметрами цієї
функції є координати прямокутника, до якого вписаний еліпс, а також колір
лінії та колір заповнення його площини. Тому формат команди oval()
нічим не відрізняється від формату команди rectangle(). Приклад
використання цієї команди.
canvas.create_oval(360, 100, 460, 60, \
125
fill = ‘blue’, outline = ‘black’)
Сектор еліпсу або його дуга рисуються в модулі tkinter мови
програмування Python з використанням методу arc() [70]. Одним із
параметрів цієї функції є змінна style. За умови, якщо встановлене
значення style = ARC рисується дуга, а у разі style = CHORD – сектор
еліпсу. Іншими можливими параметрами команди arc() є наступні.
1. Координати двох точок (x1, y1) та (x2, y2), через які проводиться дуга.
2. Початковий кут дуги, який визначається в градусах числовим
значенням змінної start.
3. Кінцевий кут дуги, який визначається в градусах числовим значенням
змінної extent.
Як і для методів rectangle(), polygon() та oval(), для методу
arc() можуть бути визначені параметри width, fill та outline.
Наведемо приклади використання команди arc().
canvas.create_arc([200, 230], [270, 330], \
start = 10, extent = 135, style = CHORD, \
fill = ‘white’, outline = ‘black’, width = 2)
canvas.create_arc([150, 230], [250, 330], \
start = 100, extent = 135, style = ARC, \
outline = ‘black’, width = 2)
На полотні з графічними об’єктами також можуть бути розташовані
текстові фрагменти. Для цього використовується метод create_text()
модуля tkinter [70]. Головними параметрами цієї команди є координата
розташування текстового фрагменту (x, y) та значення змінної text, яка
визначає рядок, що виводиться на відповідну позицію полотна. За
замовченням координаті (x, y) відповідає середина текстового фрагменту. Для
зміщення розташування тексту використовуються параметри змінної
anchor (від англійського слова anchor – якір). Ця змінна може мати
наступні значення.
w – (від англійського слова west – захід).
e – (від англійського слова east – схід).
n – (від англійського слова north – північ).
s – (від англійського слова south – південь).

126
ne – північно-східний.
nw – північно-західний.
se – південно-східний.
sw – південно-західний.
Наприклад, якщо вказаний параметр w, текст розташовується праворуч
від точки з заданою координатою за довжиною. Якщо вказаний параметр n,
текст розташовується посередні за довжиною нижче заданої точки. Якщо
вказані дві літери, перша з них визначає прив’язку за довжиною, а друга – за
висотою [70].
Приклади використання команди create_text().
canvas.create_text(100, 100, text = ‘Приклад’)
canvas.create_text(100, 100, \
text = ‘Приклад’, anchor = ‘nw’)
Для розташування на полотні фотографій або малюнків, зроблених в
інших редакторах та збережених на комп’ютерному диску у графічних
файлах форматів BMP, GIF, TIF або JPG, необхідно виконати наступні дії
[70].
1. Зчитати файл із заданим іменем з відповідної директорії та присвоїти
йому ім’я рядкової змінної.
2. З використанням методу PhotoImage() записати інформацію з
цього файлу до структури даних типу список та надати їй відповідне ім’я.
3. Розташувати точки, зчитані із сформованої структури даних, на
полотні з використанням методу create_image(). Параметрами цієї
функції є координата верхнього лівого кута, в якому буде розташований
рисунок або фотографія, та ім’я змінної, визначеної з використанням методу
PhotoImage(). У даному випадку ім’я змінної зі зчитаними даними
використовується як параметр та його значення присвоюється змінній
image.
Відповідна послідовність команд наведена у прикладі 5.30.
Приклад 5.30
127
from tkinter import *
window = Tk()
canvas = Canvas(window, width = 600, \
height = 500, bg = 'gray', cursor = 'pencil')
photo = ".\\Graphics\\author.gif"
out_photo = PhotoImage(file = photo)
canvas.create_image(200, 200, image = out_photo)
canvas.pack()
label1 = Label(window,text = 'Мельник Iгор Вiталiйович')
label2 = Label(window,text = 'професор кафедри \
електронних приладів та пристроів')
label3 = Label(window,text = 'Національного \
технічного університету України')
label4 = Label(window,text = '"КПІ імені \
Ігоря Сікорського"')
label1.pack()
label2.pack()
label3.pack()
label4.pack()
У команді canvas.create_image() координати (200, 200)
відповідають місцю розташування центра фотографії [70].
Результат роботи цих командних рядків показаний на рис. 5.49.
У прикладі 5.31 показана можливість створення різнофарбного
малюнку з використанням описаних вище об’єктів модуля tkinter.
Результат роботи цієї програми показаний на рис. 5.50.
Приклад 5.31
from tkinter import *
window = Tk()
window.title('Приклад побудови геометричних фігур')
canvas = Canvas(window, width = 480, height = 360, \

128
Рис. 5.49 Результат роботи програмного коду, наведеного у прикладі 5.30

bg ='gray', cursor = 'pencil')


canvas.pack()
canvas.create_line(20, 150, 130, 250, \
fill = 'black', smooth = 0, width = 2)
canvas.create_oval(360, 100, 460, 60, \
fill = 'blue', outline = 'black')
canvas.create_arc([200, 330], [270, 150], \

129
start = 10, extent = 135, style = CHORD, \
fill = 'white', outline = 'black', width = 2)
canvas.create_arc([150, 330], [250, 150], \
start = 100, extent = 135, style = ARC, \
outline = 'black', width = 2)
canvas.create_rectangle(20, 50, 100, 100, \
fill = 'green', outline = 'black')
canvas.create_polygon([180, 120], [300, 150], \
[180, 20], fill = 'red', outline = 'black')
canvas.create_text(50, 20, text = 'Приклад', \
font = ('Arial', '14'))
window.mainloop

Рис. 5.50 Результат роботи програмного коду, наведеного у прикладі 5.31

130
Узагальнена класифікація графічних команд модуля tkinter та
відповідні параметри цих команд наведені у таблиці 5.1.

Таблиця 5.1 – Графічні функції модуля tkinter та їхні параметри

Функція Призначення Параметри


(x, y) – координати точок, які
Проведення
з’єднуються, fill – колір лінії,
line() прямої або
smooth – спосіб проведення
ламаної лінії
лінії, arrow – стрілки,
(x1, y1) та (x2, y2) – координати
верхнього лівого та нижнього
Рисування
rectangle() правого кутів прямокутника
прямокутника
fill – колір заливки,
outline – колір лінії
(x1, y1) ... (xn, yn) – координати
Рисування точок, через які проходить багато-
polygon ()
багатокутника кутник, fill, outline – як для
прямокутника
Рисування
еліпса,
oval() Як для прямокутника
вписаного до
прямокутника
(x1, y1) та (x2, y2) – координати
початкової та кінцевої точок дуги,
Рисування
style – тип об’єкту, дуга або
arc() дуги або
сектор, start – початковий кут,
сектора
extent – кінцевий кут, fill,
outline – як для прямокутника

131
Таблиця 5.1 (продовження)

Функція Призначення Параметри


(x, y) – координата точки, до якої
Відображення
прив’язаний текст, text –
на полотні
text() текстова змінна, яка виводиться,
текстового
anchor – параметри
фрагменту
вирівнювання тексту
Відображення (x, y) – координата точки, до якої
на полотні прив’язаний графічний об’єкт, що
image()
фотографії або завантажується із файлу,
малюнка image – ім’я файлу

5.4.2 Можливості зміни властивостей графічних об’єктів,


розташованих на полотні, для створення анімаційних фрагментів
Слід відзначити, що у мові програмування Python всі графічні методи
повертають посилання на об’єкт до ідентифікатору відповідної фігури. Ця
характерна особливість роботи з графічними об’єктами, притаманна мові
програмування Python, дозволяє після створення фігури звертатися до неї
через ідентифікатор, як до об’єкту, та змінювати її властивості або взагалі
видаляти фігуру з полотна [70].
Найпростіше за все видалити фігуру з полотна, для цього
використовується метод Canvas.delete(ім’я_змінної). Команда має
лише один параметр ім’я_змінної, який відповідає імені графічного
об’єкту, що видаляється. Крім цього, цей параметр може мати значення ALL,
що відповідає видаленню всіх фігур з полотна.
Розглянемо приклад, в якому для видалення нарисованих геометричних
фігур використовується команда delete().
Приклад 5.32
from tkinter import *

132
window = Tk()
canvas = Canvas(window, width = 480, \
height = 360, bg = ‘#fafff’, cursor = ‘pencil’)
canvas.pack()
rct = canvas.create_rectangle(20, 50, 100, 100, \
fill = ‘blue’, outline = ‘black’)
Canvas.delete(rct)
rct1 = canvas.create_rectangle(50, 50, 100, 100, \
fill = ‘blue’, outline = ‘black’)
rct2 = canvas.create_rectangle(70, 70, 100, 100, \
fill = ‘green’, outline = ‘black’)
Canvas.delete(ALL)
window.mainloop

Зрозуміло, що метод Canvas.delete() може бути використаний і

для видалення фотографій, після цього з використанням методу


create_image() можна на те саме місце завантажити іншу фотографію,

що робить інтерфейс користувача більш наочним та інформативним.


Розглянемо відповідний приклад, у якому використаємо цей спосіб для
поліпшення інтерфейсу програми конвертора фізичних величин, наведеної у
додатку Д.
Приклад 5.33 З використанням методів create_image() та

Canvas.delete() розташовувати в нижній частині інтерфейсного вікна

програми конверторів фізичних величин, наведеної у додатку Д, наступні


фотографії:
– для конвертора значення температури – фотографію, наведену на
рис. 2.21, а, відповідному файлу надати ім’я temp.gif;

133
– для конвертора значення тиску – фотографію, наведену на
рис. 2.23, а, відповідному файлу надати ім’я press.gif;

– для конвертора значення підсилення – фотографію, наведену на


рис. 2.25, а, відповідному файлу надати ім’я amp.gif.

У разі зміни типу конвертора з використанням селекторної кнопки


автоматично змінювати фотографію в нижній частині вікна.
Для виконання поставленого завдання необхідно виконати наступні дії.
1. В кінці програми, наведеної у додатку Д, перед командою
window.mainloop, зчитати вказані вище фотографії з диска та надати

зчитаним структурам даних імена відповідних змінних.


2. В функції arb(), призначеній для обробки події, пов’язаною із

зміною обраного елемента селекторної кнопки, автоматично міняти


фотографію. Для цього необхідно послідовно виконати дві опеарції: з
використанням методу Canvas.delete() видаляти розташовану

фотографію та з використанням методу create_image() розташовувати

на полотні нову.
Розглянемо послідовно командні рядки, які реалізують завдання,
поставлені в пунктах 1 та 2. Згідно із завданням, поставленим в пункті 1,
перед командою window.mainloop необхідно розташувати наступні рядки

програмного коду.
photo_temp = '.\\Graphics\\temp.gif'
photo_press = '.\\Graphics\\press.gif'
photo_amp = '.\\Graphics\\amp.gif'
out_photo_temp = PhotoImage(file = photo_temp)
out_photo_pres = PhotoImage(file = photo_press)
out_photo_amp = PhotoImage(file = photo_amp)

134
canvas = Canvas(window, width = 300, \
height = 300, bg = 'gray', cursor = 'pencil')
canvas.create_image(150, 150, \
image = out_photo_temp)
canvas.place(x = 10, y = 150)

Функцію arb() для виконання завдання, поставленого у пункті 2,

необхідно змінити наступним чином.


def arb():
def arb():
if var_rad.get()==1:
label2.config(text = 'Цельсій:')
label3.config(text = 'Фаренгейт:')
canvas.delete(ALL)
canvas.create_image(150, 150, \
image = out_photo_temp)
elif var_rad.get()==2:
label2.config(text = 'Паскаль:')
label3.config(text = 'Тор:')
canvas.delete(ALL)
canvas.create_image(150, 150, \
image = out_photo_pres)
else:
label2.config(text = 'Рази:')
label3.config(text = 'Децибели:')
canvas.delete(ALL)
canvas.create_image(150, 100, \
image = out_photo_amp)

135
Результат роботи наведених вище командних рядків для конвертору
фізичних величин у разі внесення відповідних змін до коду програми,
наведеної у додатку Д, показаний на рис. 5.51.

а) б) в)
Рис. 5.51 Конвертор фізичних величин, програмний код якого наведений у
додатку Д, у разі розташування в нижній частині вікна відповідних
фотографій: а – конвертор значення температури, б – конвертор значення
тиску, в – конвертор значення підсилення

Іншими можливостями роботи з графічними об’єктами, яка реалізована


в модулі tkinter, є переміщення об’єктів та зміна їх геометричних

параметрів. Переміщення об’єктів виконується з використанням методу


Canvas.move(), а зміна властивостей – з використанням методу

Canvas.itemconfig() [70]. Команда Canvas.move() має наступний

формат [70]:
Canvas.move(fig, deltaX, deltaY)

де fig – ім’я об’єкту, який переміщуються, deltaX – зміна

координати X, deltaY – зміна координати Y.

136
Команда Canvas.itemconfig() має формат:
Canvas.itemconfig(fig, [options])

де [options] – параметри об’єкта, які змінюються.

Приклад використання цієї команди:


ovl = cnvs.create_oval([20, 20], [120, 80], \
outline = ‘black’, width = 3)
Canvas.itemconfig(ovl, outline = ‘blue’, width = 5)

В результаті виконання наведених командних рядків колір зовнішньої


лінії нарисованого овалу змінюється з чорного на блакитний, а товщина цієї
лінії змінюється з трьох до п’яти пунктів.
Інший метод Canvas.coords() призначений для зміни координат

характеристичних точок фігури, наприклад, базових точок прямокутника.


Розглянемо приклад використання цієї команди.
rct = canvas.create_rectangle(20, 50, 100, 100, \
fill = ‘blue’, outline = ‘black’)
Canvas.coords(rct, 50, 50, 150, 150)

В результаті виконання цих командних рядків координати базових


вершин прямокутника змінюються зі значень (20, 50), (100, 100) на значення
(50, 50), (150, 150).
Розглянемо цікавий приклад роботи з графічними об’єктами, в якому
методи move(), itemconfig() та coords() використовуються для

створення анімаційних ефектів у разі натиснення відповідних клавіш [70].


Приклад 5.34 З використанням графічних засобів модуля tkinter

намалювати овал та реалізувати наступні функції щодо зміни геометричних


властивостей цього об’єкта та позиції його розташування.
1. З використанням клавіш переміщення курсору праворуч, ліворуч,

137
догори та донизу, переміщувати овал вздовж полотна.
2. З використанням комбінації клавіш Ctrl + F змінювати випадковим
чином колір зовнішньої лінії та її товщину.
3. З використанням комбінації клавіш Ctrl + S змінювати випадковим
чином розмір овалу.
4. Для зміни кольору та товщини зовнішньої лінії передбачити
можливість використання відповідної кнопки з надписом «Колір та
товщина», а для зміни розміру та форми овалу – кнопки з надписом «Розмір
та форма».
Відповідний програмний код можна записати наступним чином [70].
from tkinter import *
import random as rnd
def rndcolor():
bgr = '#'+'{0:02x}'.format(rnd.\
randrange(0,256,1))+'{0:02x}'.format(rnd.\
randrange(0,256,1))+'{0:02x}'.format(rnd.\
randrange(0,256,1))
return bgr
def moveoval(event):
if event.keysym == 'Right': cnvs.move(ovl,10,0)
elif event.keysym == 'Left': cnvs.\
move(ovl,-10,0)
elif event.keysym == 'Up': cnvs.move(ovl,0,-10)
elif event.keysym == 'Down': \
cnvs.move(ovl,0,10)
def cnfgeoval(event):
cnvs.itemconfig(ovl, outline = rndcolor(), \

138
width = rnd.randint(1,5))
def sizeoval(event):
crds = cnvs.coords(ovl)
crds[2] = crds[0] + rnd.randint(50,200)
crds[3] = crds[1] + rnd.randint(50,200)
cnvs.coords(ovl, tuple(crds))
window = Tk()
window.title('Зміна властивостей овалу')
cnvs = Canvas(window, width = 480, height = 360, \
bg = 'gray')
cnvs.pack(expand = 1, fill = 'both')
ovl = cnvs.create_oval([20,20],[120,80], \
outline = 'blue', width = 3)
butCnf = Button(cnvs, \
text = 'Колір та товщина', \
command = lambda: cnfgeoval(0))
cnvs.create_window(100, 340, window = butCnf, \
width = 110, heigh = 26, anchor = 'w')
butSize = Button(cnvs, \
text = 'Розмір та форма', \
command = lambda: sizeoval(0))
cnvs.create_window(270, 340, window = butSize, \
width = 110, heigh = 26, anchor = 'w')
window.bind('<Key>', moveoval)
window.bind('<Control-f>', cnfgeoval)
window.bind('<Control-s>', sizeoval)
window.bind('<Control-z>',(lambda:window.destroy))

139
window.mainloop

Результат роботи програмного коду, наведеного у прикладі 5.34,


показаний на рис. 5.52.

Рис. 5.52 Результат роботи програмного коду, наведеного у прикладі 5.34

Розберемо командні рядки для програмного коду, наведеного у


прикладі 5.34, більш досконало та послідовно [70]. Головні операції,
пов’язані з перетвореннями овалу, у цій програмі виконані через окремі
функції. Наприклад, функція rndcolor() через команду return bgr
повертає рядок – випадкове значення кольору, формоване у вигляді списку.
Це пов’язано з тим, що в комп’ютерній техніці колір формується з трьох
значень: червоної, зеленої та блакитної складової [16].
Далі ідуть функції, пов’язані з аналізом події натиснення на кнопку.
Якщо натиснена одна із клавіш переміщення курсору, а саме: переміщення
вгору, донизу, праворуч або ліворуч, тоді викликається метод переміщення

140
овалу вздовж полотна move(), який зміщує овал у потрібному напрямку.
Далі описана функція cnfgeoval(event), в якій з використанням метода
itemconfig(), прив’язаного до полотна cnvs, змінюється колір outline
та товщина width для лінії, яка являє собою границю еліпса.
Більш складною за своєю структурою є функція sizeoval(event),
яка змінює ширину та висоту прямокутника, до якого вписаний еліпс.
Спочатку за допомогою інструкції crds = cnvs.coords(ovl)
визначається список crds з чотирьох чисел, які являють собою координати
описаного прямокутника. Два останніх числа з цього списку коректуються
випадковим чином, у такий спосіб створюються структури crds[2] та
crds[3]. В кінці цієї функції овалу, як геометричному об’єкту,
присвоюються нові властивості з використанням команди
cnvs.coords(ovl, tuple(crds))
Тут необхідно звернути особливу увагу на те, що для створення списку
crds необхідною операцією є перетворення його до кортежу. Відповідні
теоретичні відомості щодо роботи з кортежами у мові програмування Python
були розглянуті у підрозділі 4.2.
Функції moveoval(), cnfgeoval() та sizeoval()
використовуються для обробки подій, пов’язаних із натисненням клавіш на
клавіатурі. Для функцій cnfgeoval() та sizeoval() також створені
анонімні лямбда-функції, які використовуються в опціях command
відповідних кнопок, розташованих під полотном. Для встановлення та
розташування кнопок «Колір та товщина» та «Розмір та форма»
використаний метод cnvs.create_window(), який за своїми
параметрами та функціональними можливостями дещо схожий на метод
place(), що часто використовувався нами в інших прикладах [70].
Головні графічні методи модуля tkinter, які дозволяють змінювати
властивості графічних об’єктів та переміщувати їх вздовж полотна, зведені у
таблиці 5.2.

141
Таблиця 5.2 – Методи модуля tkinter, призначені для видалення,
переміщення графічних об’єктів та зміни їхніх властивостей

Метод Призначення Параметри


Видалення об’єкта
delete(obj) Ім’я об’єкта obj
obj з полотна
Видалення всіх
delete(ALL) Змінна ALL
об’єктів з полотна
obj – ім’я об’єкта,
dX – зміщення у горизон-
move(obj, dX,
Переміщення об’єкта тальному напрямку,
dY)
dY – зміщення у вертикаль-
ному напрямку
itemconfig(obj, Зміна параметрів obj – ім’я об’єкта,
param) об’єкта obj param – нові параметри
Зміна координат
coords(obj, характеристичних obj – ім’я об’єкта,
param) точок, які задають param – нові параметри
форму об’єкта obj

Для закріплення теоретичного матеріалу, наведеного у цьому


підрозділі, необхідно виконати практичне заняття №9.

5.4.3 Можливості побудови графіків математичних функцій з


використанням графічних об’єктів модуля tkinter

5.4.3.1 Вкладенки як додатковий елемент віконного інтерфейсу


Перед тим, як починати вивчати простий спосіб побудови графіків
через проведення прямих ліній між точками із заданими координатами, варто
вивчити спосіб побудови ще одного елементу інтерфейсного вікна –

142
вкладенки. Вкладки, разом із кнопками та текстовими вікнами, також є
одним із стандартних елементів віконних інтерфейсів, які дозволяють робити
вікна прикладних програм більш інформативними за рахунок підвищення
степені систематизації інформації, яка в них розташовується [16]. З точки
зору спрощення аналізу графічних залежностей велику кількість графіків
варто розташовувати на різних вкладенках [70].
Вікну із вкладенками в інтерпретаторі мови програмування Python
відповідає об’єкт Notebook, який розташований в модулі tkinter.ttk.

Функція Notebook() із параметрами призначена для побудови вікна із

вкладенкою. Зазвичай головними параметрами цієї функції є ширина вікна


width та його висота height [70]. Для виведення вікна із вкладенкою на

екран може бути використаний будь-який із методів відображення елементів


інтерфейсу, розглянутих у підрозділі 5.2. Зазвичай для цього
використовується стандартний та простий метод pack(). Відповідна

послідовність команд має наступний вигляд.


from tkinter import *
from tkinter.ttk import *
window = Tk()
window.title(‘Побудова графіків функцій’)
nb = Notebook(width = 480, height = 360)
nb.pack(expand = 1, fill = ‘both’)

Далі необхідно наповнити створені вкладенки з іменем nb іншими

елементами графічного інтерфейсу. Зазвичай для цього використовується


контейнерне розташування елементів з використанням методу add().

Наприклад, для розташування полотен з метою подальшої побудови графіків


математичних функцій можуть бути використані наступні командні рядки [70].

143
cnvs = Canvas(nb, background)
nb.add(cnvs, text)
де nb – ім’я вкладенки, background – колір фону, cnvs – ім’я полотна,
text – назва відповідної вкладенки.
Додавання полотен до відповідних вкладенок можна виконати через
виклик окремої функції, яка у даному випадку буде мати наступний вигляд [70].
def makecanvas(txt, bgclr):
cnvs = Canvas(nb, background = bgclr)
nb.add(cnvs, text = txt, padding = 3)
return cnvs
Тоді виклик функції makecanvas() здійснюється з використанням
наступної послідовності команд [70].
cnvs1 = makecanvas(‘F1’, ‘f7ffff’)
cnvs2 = makecanvas(‘F2’, ‘fff7ff’)
cnvs3 = makecanvas(‘F3’, ‘fffff7’)
Цілком зрозуміло, що у поданих вище командних рядках першим
параметром є надпис на вкладенці, а другим – колір фону.
Для керування панелями класу Notebook як елементами віконного
інтерфейсу використовуються відповідні методи. Головним з них є метод
Notebook.selected(), який дозволяє працювати безпосередньо зі
вкладенкою, активною на даний момент. З іншими можливостями роботи зі
вкладенками можна ознайомитись в навчальній літературі [24 – 30, 70], або
через довідникову систему інтерпретатора.
У наступному прикладі наведений остаточний набір команд,
призначений для формування трьох вкладенок на одному інтерфейсному
вікні.
Приклад 5.35
from tkinter import *
from tkinter.ttk import *
def makecanvas(txt, bgclr):

144
cnvs = Canvas(nb, background = bgclr)
nb.add(cnvs, text = txt, padding = 3)
return cnvs
window = Tk()
window.title(‘Побудова графіків функцій’)
nb = Notebook(width = 480, height = 360)
nb.pack(expand = 1, fill = ‘both’)
cnvs1 = makecanvas(‘F1:’, ‘#f7ffff’)
cnvs2 = makecanvas(‘F2:’, ‘#fff7ff’)
cnvs3 = makecanvas(‘F3:’, ‘#fffff7’)
window.mainloop
Результат роботи цих командних рядків показаний на рис. 5.53.

Рис. 5.53 Результат роботи програмного коду, наведеного у прикладі 5.35

Надалі наведені у цьому підрозділі способи створення вкладенок та


засоби роботи з ними будуть необхідні для вивчення методів побудови
графіків математичних функцій з використанням стандартних графічних
об’єктів модуля tkinter.

5.4.3.2 Спосіб побудови графіків математичних функцій з


використанням прямих ліній як елементарних графічних об’єктів
Перед вивченням цього підрозділу необхідно повторити підрозділи 3.6 та 3.7
З використанням ліній як елементарних графічних об’єктів можна

145
формувати більш складні об’єкти інженерної та наукової графіки, зокрема,
будувати графічні залежності для заданих математичних функцій.
Розглянемо цю можливість більш досконало та сформулюємо узагальнений
спосіб побудови графіка математичної функції, який базується на проведені
прямих ліній між двома точками із заданими координатами [70]. Алгоритм
побудови графіка функції, заданої аналітичним виразом, можна
сформулювати у вигляді тез наступним чином.
1. Задається математичний вираз для функції y = f(x).
2. Задається діапазон значень аргументу x [xmin; xmax], для якого
необхідно обчислити значення функції f(x), та для подальшої побудови
графіка обчислюється довжина цього діапазону Dx = xmax – xmin.
3. Задається кількість базових точок n, які лежать у заданому в пункті 2
діапазоні та для яких необхідно обчислити значення функції f(x).
4. Перевіряється, чи всі точки заданого діапазону відповідають області
визначення функції f(x). Якщо існують точки, для яких не можна провести
відповідні обчислення, видається повідомлення про помилку.
5. Проводиться обчислення значень функції f(x) та визначаються пари
точок з координатами (xi, yi), i = 1…n, через які має проходити графік
функції.
6. Із визначених точок (xi, yi) з використанням методу append(), який

був розглянутий у підрозділі 3.6.1, формується список базових точок L.


7. Формується декартова система координат та визначається базова
сукупність дискретних точок D, через які буде проводитись графік функції f(x).
8. Через аналіз сформованого списку L знаходяться мінімальне та
максимальне значення функції f(x) ymin та ymax, та у такий спосіб визначається
діапазон значень y Dy = ymax – ymin для побудови графіка.

146
9. Через аналіз сукупності заданих дискретних точок D визначається

мінімальна та максимальна абсциси D xmax та Dxmin для діапазону точок

графічної площини та загальний діапазон для побудови графіка за віссю абсцис

D xdif = D xmax − D xmin .

10. Обчислюється коефіцієнт масштабування графіка kx, який зв’язує

діапазон реальних значень аргумента функції Dx з діапазоном абсциси Dxdif

на полотні. Відповідне співвідношення записується наступним чином:

D xdif
kx = . (5.1)
Dx

11. Через аналіз сукупності заданих дискретних точок D визначається

мінімальна та максимальна ординати D ymax та D ymin для діапазону точок

графічної площини та загальний діапазон для побудови графіка за віссю

ординат D dif max


y = Dy − D ymin .

12. Обчислюється коефіцієнт масштабування графіка ky, який зв’язує

діапазон реальних значень функції Dy з діапазоном ординати D dif


y на полотні.

Відповідне співвідношення записується наступним чином:

D dif
y
ky = . (5.2)
Dy

13. На основі сформованого списку L формується новий список Lg із


( ) ( [ ])
цілих значень xig , yig = [k x xi ], k y yi , який цілком відповідає декартовим

координатам полотна, через які необхідно проводити лінії для побудови


графіка функції y = f(x).
14. З використанням оператора циклу із заданою кількістю повторень

( ) ( )
через точки з координатами xig , yig , xig+1, yig+1 послідовно проводяться

147
прямі лінії, відповідна кількість ітерацій для цієї процедури складає n – 1.
15. Завершення операції виведення графіка на екран.
З теоретичної точки зору такий спосіб побудови графіків математичних
функцій оснований на методі лінійної інтерполяції, загальні основи якого
описані у практичному занятті 5.
Блок-схема алгоритму побудови графіка математичної функції з
використанням прямої лінії як елементарного графічного елемента наведена
на рис. 5.54.
Більш простим, але не чітко визначеним завданням, яке не має
загального розв’язку, є проведення координатних осей. В цілому для
визначення масштабу графіка достатньо ввести по дві відлікові точки на осі
абсцис та на осі ординат, і зазвичай однією з базових точок є початок
координат, тобто x = 0 та y = 0. Проте тут проблема полягає у тому, що не
завжди нульові значення входять до визначених діапазонів Dx та Dy. Тому за
існуючими стандартами оформлення науково-технічної документації частіше
осі графіка будують згідно із визначеними діапазонами значень за обома
координатами, а масштаби за осями задаються згідно із визначеною
кількістю базових точок. Зазвичай до цього набору базових точок входять
( ) (
чотири точки: (xmin, y(xmin)), (xmax, y(xmax)), x y= y , ymin та x y= y
min max
)
, ymax ,

які визначають прямокутну границю області побудови графіка. Наприклад,


такий спосіб побудови графіків реалізований у системі науково-технічних
розрахунків MatLab [6, 7] та у системі програмування Anaconda з
інтерпретатором IPython [26]. Можливості побудови графічних залежностей
в системі Anaconda розглядатимуться у підрозділі 6.1. У цьому підрозділі
розглянемо інший спосіб побудови графічних залежностей, в якому
реалізований алгоритм, блок-схема якого наведена на рис. 5.54, а однією з
базових точок вважається точка початку координат x = 0 та y = 0.

148
7
Початок

Введення значень xmin, 8 ymin = min( yi ) y ∈L


xmax, функції f(x) та i
1 кількості точок n

9 ymax = max( yi ) y ∈L
i
2
Діапазон [xmax, xmin] відповідає
4
області визначення функції f(x)?
Dx = xmax – xmin;
10
Dy = ymax – ymin
Ні
Формування пові-
3 домлення про Визначення значень
dif dif
помилку даних 11 Dx та D y для
діапазону точок
Кінець графічної площини

2
Dxdif D dif
y
12 kx = ; ky =
Dx Dy
4 i = 1, L =
7
i = 1K n ;

5 yi = f(xi)
13
(xig , yig )= ([kx xi ], [k y yi ])

6 L = L ∪ ( xi , yi ) 14
g g
(
З’єднання точок xi , yi )
прямими лініями

7 Кінець
Ні
i ≤ n? 5

Рис. 5.54 Узагальнений алгоритм побудови графіка аналітично заданої


функції з використанням прямої лінії як елементарного графічного елемента

149
Приклад 5.36 З використанням засобів програмування мови Python
написати універсальну функцію для побудови графічних залежностей за
алгоритмом, блок-схема якого наведена на рис. 5.54.
Відповідна послідовність командних рядків може мати наступний
вигляд [70].
from tkinter import *
def drawFunc(canvas, fun, a, b, kx, ky, \
exclude = None):
points = []
num = 500
for n in range(num):
x = a + ((b - a)/num)*n
if exclude != None:
if x in exclude: continue
y = fun(x)
pp = (xo + kx*x, yo - ky*y)
points.append(pp)
canvas.create_line(points, fill = ‘black’, \
smooth = 0, width = 3)
x_Axe = [(xo + a*kx,yo), (xo + b*kx,yo)]
canvas.create_line(x_Axe, fill = ‘black’, width = 2)
my = max([abs(e[1] - yo) for e in points])
y_Axe = [(xo, yo – my*1.05), (xo, yo + my*1.05)]
canvas.create_line(y_Axe, fill = ‘black’, width = 2)
maxy = min([e[1] - yo for e in points])
gor_Mark = [(xo - 5, yo + maxy), (xo + 5, \
yo + maxy)]

150
canvas.create_line(gor_Mark, fill = ‘black’, width = 1)
canvas.create_text(xo + 28, yo + maxy, \
text = ‘{0:.3f}’.format(-maxy/ky))
canvas.create_line([(kx, yo – 5), (kx, yo + 5)], \
fill = ‘black’, width = 1)
canvas.create_text(kx, yo - 10, text = ‘1.000’)
Спосіб використання наведеної вище функції побудови графіків
drawFunc() передбачає наступні кроки.
1. Визначення функцій, графіки яких необхідно побудувати.
2. Визначення на полотні базової точки початку координат xo, yo.
3. Визначення коефіцієнтів масштабування kx та ky.
4. Визначення набору особових точок визначених функцій, для яких не
можуть бути проведені математичні розрахунки.
5. Виклик функції drawFunc() із заданими параметрами.
Відповідна послідовність командних рядків, які розташовуються в
головній функції, має наступний вигляд [70].
import math
def g(x):
return math.sin(x)/x
def f(x):
return x*math.exp(-x**2)
xo, yo = 20, 180
drawFunc(cnvs1, math.sin, 0, 12, 35, 150)
xo, yo = 240, 180
drawFunc(cnvs2, g, -20, 20, 11, 150, [0])
drawFunc(cnvs3, f, -3, 3, 80, 350)
window.mainloop
Остаточний текст програми, призначеної для побудови графіків
математичних функцій, наведений у додатку Є, а результат роботи цієї
програми для графіків функцій, розташованих на різних вкладенках,
представлений на рис. 5.55.

151
а) б)

в)
Рис 5.55 Графіки функцій y(x)=ln(sin(x)2–cos(x) + 1,5) (а),

 
 sin ( x ) − 1  2
y ( x ) = ln  + 1,5  − 0,05 (б) та x ⋅ e − x (в), побудовані з
 π 
 x− 
 2 
використанням коду програми, наведеного у додатку Є

152
Головними особливостями написання коду програми, наведеного у
додатку Є, є наступні.
1. Обчислення значень всіх математичних функцій виконується в
окремих функціях програми, визначених як sc(x), g(x) та f(x). Імена цих

функцій використовуються як параметри функції drawFunc(), програмний

код якої безпосередньо призначений для виконання завдання побудови


графіка. Код цієї функції був розглянутий вище, у прикладі 5.36.
2. Графіки трьох функцій виконані на різних вкладенках. Для
розташування вкладенок, як елементів віконного інтерфейсу, на головному
вікні програми, використана функція makecanvas(), яка була розглянута у

прикладі 5.35. Єдиною відмінністю програмного коду цієї функції,


наведеного у додатку Є, є те, що назви вкладенок відповідають
математичним функціям побудованих на них графіків.
3. Параметрами виклику функції drawFunc() є наступні змінні.

– Ім’я вкладенки як об’єкту, на якому проводиться побудова


відповідного графіка.
– Ім’я функції, значення якої необхідно обчислити для побудови
графіка.
– Мінімальне значення аргументу функції a.

– Максимальне значення аргументу функції b.

– Коефіцієнт масштабування за віссю абсцис kx.

– Коефіцієнт масштабування за віссю ординат ky.

– Масив значень exclude, який відповідає точкам виключення заданої

функції, для яких не треба проводити розрахунки. За замовченням


вважається, що таких точок немає (exclude = None), проте, якщо масив

цих значень переданий, змінна exclude приймає задане значення. Такий

153
спосіб виклику функцій для обробки виключних ситуацій відповідає апарату
локальних та глобальних змінних мови програмування Python, який був
розглянутий у підрозділі 2.5.3.
4. Для обробки виключних ситуацій у тілі циклу побудови графіка
for n in range(num): використовується набір умовних операторів
if exclude != None:
if x in exclude: continue
Спосіб роботи оператора continue був розглянутий у підрозділі 3.7.7.
5. Обчислені значення функції y = f(x) записуються до списку points
у вигляді структури даних pp = (xo + kx*x, yo - ky*y) з
використанням процедури зчеплення структурованих даних
points.append(pp). Початковим значенням структури points , заданим
безпосередньо перед початком тіла циклу, призначеного для її формування,
є порожній елемент (points = []). Кількість точок для побудови графіка є
заздалегідь заданою величиною та складає num = 500. Спосіб побудови
складних структур даних з використанням методу append() був
розглянутий у підрозділі 3.6.1.
6. Проведення ліній через точки, задані у структурі points,
здійснюється за межами циклу формування цієї структури for n in
range(num): з використанням однієї графічної команди:
canvas.create_line(points, fill = 'black', \
smooth = 0, width = 3)
Цілком зрозуміло, що з використанням написаної функції drawFunc()
можна будувати графіки інших математичних функцій. Для цього необхідно
коректно обчислювати коефіцієнти масштабування kx та ky за умови відомих

значень D xdif , D dif


y , D x та D y . Для обчислення значень kx та ky слід

використовувати співвідношення (5.1) та (5.2). У будь-якому разі алгоритм


побудови графічної залежності, блок-схема якого наведена на рис. 5.54, є

154
універсальним. Пошук масиву виключних точок, для яких неможливо
обчислити значення заданої функції f(x) згідно із областю її визначення, є
окремим завданням обчислювальної математики.

5.5 Розширені бібліотеки елементів віконного інтерфейсу в


інтерпретаторі мови програмування Python

Весь цей розділ був присвячений способам побудови віконного


інтерфейсу для різних програмних засобів з використанням елементарних
графічних об’єктів модуля tkinter. Хоча можливості використання цих
об’єктів є вкрай широкими та дозволяють формувати досить функціональні
інтерфейси для різноманітних програмних засобів, у сучасних версіях
інтерпретатора мови Python існують також інші модулі, об’єкти яких, у разі
їх використання, можуть значно покращити функціональність віконного
інтерфейсу прикладної програми.
Тут в першу чергу слід звернути увагу на підмодуль ttk модуля
tkinter, в якому, насамперед, розташовані покращені версії таких
описаних вище стандартних інтерфейсних елементів, як кнопка (Button),
кнопка вибору (CheckButton), селекторна кнопка (RadioButton), вікно
для розташування текстового фрагменту (Label), вікно текстового
редактора (Entry), лінійка з повзунцем (Scale) та лінійка прокрутки
(Scrollbar). Крім цього, в підмодулі ttk модуля tkinter розташовані
деякі інші важливі елементи віконного інтерфейсу, яких немає у
програмному коді базової версії модуля tkinter. Серед них насамперед
слід відзначити такий об’єкт, як вкладенка (Notebook), який був
розглянутий у підрозділі 5.4.3.1 та використовувався для побудови графіків
математичних функцій у підрозділі 5.4.3.2. Серед інших важливих
елементарних об’єктів віконного інтерфейсу, які розташовані у підмодулі
ttk модуля tkinter, слід відзначити наступні: Combobox, Progressbar,

155
Separator, Sizegrip та Treeview [70]. Спосіб підключення бібліотеки
об’єктів віконного інтерфейсу із підмодуля ttk був розглянутий у підрозділі
5.4.3.1. Для імпорту функцій цього підмодуля необхідно вставити до
програмного коду наступну інструкцію.
from tkinter.ttk import *
З точки зору застосованих методів програмування об’єкти підмодуля
ttk відрізняються від стандартних об’єктів модуля tkinter насамперед
тим, що зміна вигляду об’єктів тут здійснюється не через посилання на
відповідні їхні властивості через параметри виклику методів, а іншим чином,
через використання відповідних тем [27 – 29 , 70]. Головними темами
підмодуля ttk є чотири: default, classic, alt та calm. Зовнішній
вигляд елементів інтерфейсу змінюється залежно від обраної теми. Слід
відзначити, що перелічені чотири теми є кросплатформеними та їх
використання не залежить від типу обраної операційної системи, що значно
підвищує функціональність виконання програмного коду у разі використання
різних системних платформ. Крім цього, для програмування під операційною
системою Windows розроблені три додаткові теми: winnative, xpnative
та vista [27 – 29, 70].
Іншою цікавою бібліотекою розширення графічних елементів модуля
tkinter є підмодуль tix. В ньому розташовано більше ніж 40 додаткових
елементів графічного інтерфейсу, які рідше використовуються в практиці
прикладного програмування, але також у значній мірі покращують
функціональність програмних засобів. Серед них найбільш важливими є такі
елементи, як Ballon, Buttonbox, CheckList, DirList, DirTree та
Master [27 – 29, 70].
Досконалий розгляд перелічених вище елементарних елементів
віконного інтерфейсу виходить за рамки цього посібника. З нами можна
ознайомитись в навчальній літературі [27 – 29], на сторінках Інтернет [31 –
38, 43, 44, 65, 71], або з використанням системи допомоги. Розглянемо
156
простий приклад, який дозволяє зрозуміти, як можна ефективно
використовувати систему допомоги інтерпретатора мови Python для пошуку
відповідних методів роботи з об’єктами.
Приклад 5.37 З використанням командного рядка інтерпретатора
мови Python знайти метод, який дозволяє зчитати текст з текстового вікна
класу Label.
Насамперед, необхідно підключити модуль tkinter, створити
головне вікно та текстове вікно класу Label із відповідним підписом.
Відповідна послідовність командних рядків має наступний вигляд.
from tkinter import *
window = Tk()
window.title('Тест')
label1 = Label (window,font='Arial 12',text = '123')
label1.pack()
window.mainloop
Тепер для створеного об’єкту label1 класу Label використаємо
команду dir(label1). Ця команда призначена для виведення на екран всіх
методів, які можна застосувати для об’єкту із заданим іменем. Результат
виконання цієї команди є наступним.
>>> dir(label1)
['_Misc__winfo_getint', '_Misc__winfo_parseitem',
'__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__',
'__setitem__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', '_bind',

157
'_configure', '_displayof', '_do', '_getboolean',
'_getconfigure', '_getconfigure1', '_getdoubles',
'_getints', '_grid_configure', '_name',
'_nametowidget', '_noarg_', '_options', '_register',
'_report_exception', '_root', '_setup',
'_subst_format', '_subst_format_str', '_substitute',
'_tclCommands', '_w', '_windowingsystem', 'after',
'after_cancel', 'after_idle', 'anchor', 'bbox', 'bell',
'bind', 'bind_all', 'bind_class', 'bindtags', 'cget',
'children', 'clipboard_append', 'clipboard_clear',
'clipboard_get', 'colormodel', 'columnconfigure',
'config', 'configure', 'deletecommand', 'destroy',
'event_add', 'event_delete', 'event_generate',
'event_info', 'focus', 'focus_displayof',
'focus_force', 'focus_get', 'focus_lastfor',
'focus_set', 'forget', 'getboolean', 'getdouble',
'getint', 'getvar', 'grab_current', 'grab_release',
'grab_set', 'grab_set_global', 'grab_status', 'grid',
'grid_anchor', 'grid_bbox', 'grid_columnconfigure',
'grid_configure', 'grid_forget', 'grid_info',
'grid_location', 'grid_propagate', 'grid_remove',
'grid_rowconfigure', 'grid_size', 'grid_slaves',
'image_names', 'image_types', 'info', 'keys', 'lift',
'location', 'lower', 'mainloop', 'master',
'nametowidget', 'option_add', 'option_clear',
'option_get', 'option_readfile', 'pack',
'pack_configure', 'pack_forget', 'pack_info',
'pack_propagate', 'pack_slaves', 'place',
'place_configure', 'place_forget', 'place_info',

158
'place_slaves', 'propagate', 'quit', 'register',
'rowconfigure', 'selection_clear', 'selection_get',
'selection_handle', 'selection_own',
'selection_own_get', 'send', 'setvar', 'size',
'slaves', 'tk', 'tk_bisque', 'tk_focusFollowsMouse',
'tk_focusNext', 'tk_focusPrev', 'tk_menuBar',
'tk_setPalette', 'tk_strictMotif', 'tkraise', 'unbind',
'unbind_all', 'unbind_class', 'update',
'update_idletasks', 'wait_variable', 'wait_visibility',
'wait_window', 'waitvar', 'widgetName', 'winfo_atom',
'winfo_atomname', 'winfo_cells', 'winfo_children',
'winfo_class', 'winfo_colormapfull',
'winfo_containing', 'winfo_depth', 'winfo_exists',
'winfo_fpixels', 'winfo_geometry', 'winfo_height',
'winfo_id', 'winfo_interps', 'winfo_ismapped',
'winfo_manager', 'winfo_name', 'winfo_parent',
'winfo_pathname', 'winfo_pixels', 'winfo_pointerx',
'winfo_pointerxy', 'winfo_pointery', 'winfo_reqheight',
'winfo_reqwidth', 'winfo_rgb', 'winfo_rootx',
'winfo_rooty', 'winfo_screen', 'winfo_screencells',
'winfo_screendepth', 'winfo_screenheight',
'winfo_screenmmheight', 'winfo_screenmmwidth',
'winfo_screenvisual', 'winfo_screenwidth',
'winfo_server', 'winfo_toplevel', 'winfo_viewable',
'winfo_visual', 'winfo_visualid',
'winfo_visualsavailable', 'winfo_vrootheight',
'winfo_vrootwidth', 'winfo_vrootx', 'winfo_vrooty',
'winfo_width', 'winfo_x', 'winfo_y']
>>>

159
Виданий список методів є досить довгим, але серед цих методів,
розташованих за абеткою, можна знайти метод cget(). Спробуємо
виконати команду label1.cget().
>>> label1.cget()
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
label1.cget()
TypeError: cget() missing 1 required positional
argument: 'key'
>>>
Інтерпретатор видає помилку, яка полягає у тому, що немає ключового
аргументу 'key'. Тепер завдання пошуку дещо змінилося. Необхідно знайти
цей параметр функції та правильно його записати.
Проте, якщо ще раз ретельно передивитися результат виконання
команди dir(label1), можна знайти серед списку команд команду
keys(). Скористаємося нею. Результат виконання цієї команди є
наступним.
>>> label1.keys()
['activebackground', 'activeforeground',
'anchor', 'background', 'bd', 'bg', 'bitmap',
'borderwidth', 'compound', 'cursor',
'disabledforeground', 'fg', 'font', 'foreground',
'height', 'highlightbackground', 'highlightcolor',
'highlightthickness', 'image', 'justify', 'padx',
'pady', 'relief', 'state', 'takefocus', 'text',
'textvariable', 'underline', 'width',
'wraplength']
>>>
Як бачимо, одним із можливих значень змінної 'key' є значення

160
'text', і можна припустити, що саме він і є правильним параметром для
читання тексту з текстового вікна. Тепер спробуємо використати цей параметр
для методу cget().
>>> label1.cget('text')
'123'
>>>
Цілком зрозуміло, що отримане значення '123' відповідає тексту,
введеному до текстового вікна. Тобто, тепер можна зробити остаточний
висновок, що зчитати текст з текстового вікна можна з використанням
команди label1.cget('text'), та вважати поставлене завдання
вирішеним.
Із наведеного прикладу зрозуміло, що зазвичай пошук відповідного
методу для роботи з об’єктом та параметрів його виклику є досить непростим
завданням, пов’язаним із глибоким знанням основ програмування мовою
Python. Деякі рішення приходиться приймати на інтуіційному рівні. Проте,
якщо програміст оволодів цим мистецтвом, ефективність написання програм із
віконним інтерфейсом значно підвищується.
Для застосування більш розвинених можливостей формування наукової
графіки та для розв’язування складних завдань математичного моделювання,
зокрема завдань математичної статистики, можна використовувати систему
науково-технічних розрахунків Anaconda, яка базується на версії IPython мови
програмування Python. Якщо можливості інтерпретатора Python версії 3 є
близькими до відповідних можливостей стандартних компіляторів з мов
програмування із графічною оболонкою [16], можливості пакету Anaconda є
значено ширшими та наближаються до засобів матричного програмування
системи науково-технічних розрахунків MatLab. Засоби роботи з бібліотеками
системи Anaconda, зокрема можливості інтегрування її відповідних модулів із
засобами програмування, об’єктами та методами розглянутої у цьому розділі
бібліотеки tkinter, будуть розглянуті у підрозділі 6.1.

161
Контрольні питання та завдання до розділу 5
1. Чому сьогодні всі програмні засоби комерційного призначення
мають віконний інтерфейс користувача? Свою відповідь обґрунтуйте та
наведіть власні приклади таких програмних засобів.
2. Чим суттєво відрізняються консольні програмні додатки від
програмних засобів, які мають графічний інтерфейс користувача? Свою
відповідь обґрунтуйте та наведіть власні приклади консольних програмних
додатків та програмних засобів із віконним інтерфейсом.
3. Поясніть блок-схеми алгоритмів, які наведені на рис. 5.1.
4. У якому модулі інтерпретатора мови Python версії 3 розташовані
головні об’єкти, які відповідають елементам віконного інтерфейсу?
5. Яка команда мови програмування Python використовується для
підключення модуля tkinter? Наведіть власні приклади використання цієї
команди.
6. Яким способом у мові програмування Python створюється головне
інтерфейсне вікно? Наведіть власні приклади команди, призначеної для
створення головного інтерфейсного вікна.
7. Як у мові програмування Python для головного інтерфейсного вікна
запускається цикл обробки подій? Наведіть власні приклади команди,
призначеної для створення циклу обробки подій для сформованого віконного
інтерфейсу.
8. Поясніть приклад 5.1 та рис. 5.2.
9. Як на головному вікні розташовуються елементи графічного
інтерфейсу? Поясніть рис. 5.3.
10. Які елементи віконного інтерфейсу Вам відомі? Наведіть власні
приклади таких елементів та поясніть їхнє призначення.
11. Що являє собою вікно відформатованого тексту (Text) як елемент
віконного інтерфейсу? Наведіть власні приклади використання вікна
відформатованого тексту в інтерфейсах прикладних програм.

162
12. Що являє собою кнопка (Buttom) як елемент віконного інтерфейсу?
Наведіть власні приклади використання кнопок в інтерфейсах прикладних
програм.
13. Що являє собою селекторна кнопка (Radiobuttom) як елемент
віконного інтерфейсу? Наведіть власні приклади використання селекторної
кнопки в інтерфейсах прикладних програм.
14. Що являє собою прапорець (Checkbuttom) як елемент віконного
інтерфейсу? Наведіть власні приклади використання прапорця в інтерфейсах
прикладних програм.
15. Що являє собою поле введення тексту (Entry) як елемент віконного
інтерфейсу? Наведіть власні приклади використання полів введення тексту в
інтерфейсах прикладних програм.
16. Що являє собою рамка (Frame) як елемент віконного інтерфейсу?
Наведіть власні приклади використання рамок в інтерфейсах прикладних
програм.
17. Що являє собою надпис (Label) як елемент віконного інтерфейсу?
Наведіть власні приклади використання надпису в інтерфейсах прикладних
програм.
18. Що являє собою список (Listbox) як елемент віконного інтерфейсу?
Наведіть власні приклади використання списку в інтерфейсах прикладних
програм.
19. Що являє собою Меню (Menu) як елемент віконного інтерфейсу?
Наведіть власні приклади використання меню в інтерфейсах прикладних
програм.
20. Що являє собою повідомлення (Message) як елемент віконного
інтерфейсу? Наведіть власні приклади використання повідомлень в
інтерфейсах прикладних програм.
21. Що являє собою шкала (Scale), або лінійка з повзунцем, як елемент
віконного інтерфейсу? Наведіть власні приклади використання шкали в
інтерфейсах прикладних програм.

163
22. Що являє собою смуга прокрутки (Scrollbar) як елемент віконного
інтерфейсу? Наведіть власні приклади використання смуги прокрутки в
інтерфейсах прикладних програм.
23. Поясніть елементи віконного інтерфейсу, які зображені на рис. 5.4.
24. Як з використанням засобів мови програмування Python
створюється просте текстове вікно із надписом класу Label? Наведіть
власні приклади створення такого вікна.
25. Поясніть приклад 5.2 та рис. 5.5.
26. Які способи розташування кількох текстових вікон із надписом в
одному інтерфейсному вікні, реалізовані в мові програмування Python, Вам
відомі? Наведіть власні приклади розташування кількох текстових вікон із
надписом.
27. Поясніть приклад 5.3 та рис. 5.6.
28. Поясніть приклад 5.4, блок-схему алгоритму, наведену на рис. 5.7,
та рис. 5.8.
29. Як здійснюється відображення тексту у текстовому вікні через
формування рядкової змінної? Наведіть власні приклади такого відображення
тексту у текстовому вікні.
30. Що являє собою метод StringVar() модуля tkinter та як він
використовується для формування надпису у текстовому вікні? Наведіть
власні приклади такого використання цього методу.
31. Що являє собою метод set() модуля tkinter та як він
використовується для формування надпису у текстовому вікні? Наведіть
власні приклади такого використання цього методу.
32. Поясніть приклад 5.5, блок-схему алгоритму, наведену на рис. 5.9,
та рис. 5.10.
33. Що являє собою процес обміну даними Модель – Вигляд –
Контролер та як він застосовується для формування віконного інтерфейсу?
Поясніть рис. 5.11 та наведіть власні приклади використання процесу
Модель – Вигляд – Контролер для формування віконного інтерфейсу

164
прикладних програм.
34. Поясніть приклад 5.6 та рис. 5.12.
35. Які методи створення та розташування кнопок як елементів
віконного інтерфейсу, реалізовані у мові програмування Python, Вам відомі?
Наведіть власні приклади використання цих методів для створення віконного
інтерфейсу прикладних програм.
36. Які властивості кнопок, як елементів віконного інтерфейсу,
необхідно вказувати обов’язково, а які можуть бути встановлені за
замовченням? Свою відповідь обґрунтуйте та наведіть власні приклади
визначення властивостей кнопок.
37. Що являє собою метод для обробки події натиснення на кнопку?
Наведіть власні приклади формування методу обробки події натиснення на
кнопку.
38. Чому під час формування кнопки як об’єкту віконного інтерфейсу
обов’язково має бути вказаним метод для обробки події натиснення на
кнопку? Свою відповідь обґрунтуйте.
39. Що являє собою метод destroy() та як він використовується під
час написання програм із віконним інтерфейсом? Наведіть власні приклади
використання цього методу.
40. Поясніть приклад 5.7 та рис. 5.13.
41. Які методи розташування кнопок, як елементів графічного
інтерфейсу, на головному інтерфейсному вікні, Вам відомі? Наведіть власні
приклади використання цих методів.
42. Що являє собою метод pack() та які він має переваги та недоліки?
Наведіть власні приклади використання цього методу для розташування
елементів віконного інтерфейсу.
43. Що являє собою метод grid() та які він має переваги та недоліки?
Наведіть власні приклади використання цього методу для розташування
елементів віконного інтерфейсу.
44. Що являє собою метод place() та які він має переваги та

165
недоліки? Наведіть власні приклади використання цього методу для
розташування елементів віконного інтерфейсу.
45. Які параметри має метод розташування елементів віконного
інтерфейсу pack()? Наведіть власні приклади використання цих параметрів
для розташування кнопки як елемента віконного інтерфейсу.
46. Які параметри має метод розташування елементів віконного
інтерфейсу grid()? Наведіть власні приклади використання цих параметрів
для розташування кнопки як елемента віконного інтерфейсу.
47. Які параметри має метод розташування елементів віконного
інтерфейсу place()? Наведіть власні приклади використання цих
параметрів для розташування кнопки як елемента віконного інтерфейсу.
48. Як методи розташування елементів віконного інтерфейсу пов’язані
із філософією мови програмуванні Python? Свою відповідь обґрунтуйте та
наведіть наочні приклади, які ілюструють цей зв’язок.
49. Які параметри має головне інтерфейсне вікно та які способи
визначення цих параметрів Вам відомі? Наведіть власні приклади визначення
параметрів головного інтерфейсного вікна.
50. Поясніть приклад 5.8 та рис. 5.14.
51. Поясніть приклад 5.9 та рис. 5.15.
52. Поясніть приклад 5.10 та рис. 5.16.
53. Поясніть приклад 5.11 та рис. 5.17.
54. Як методи get()та set() модуля tkinter використовуються
для зміни вигляду інтерфейсного вікна? Наведіть власні приклади такого
використання цих методів.
55. Що являють собою посилання на класи IntVar() та DoubleVar()
та як вони використовуються для проведення ітераційних обчислень під час
роботи з елементами інтерфейсного вікна? Наведіть власні приклади такого
використання методів IntVar() та DoubleVar().
56. Як метод config() використовується для зміни властивостей
текстового вікна класу Label? Наведіть власні приклади такого використання
166
цього методу.
57. Поясніть схему скінченного автомату, наведену на рис. 5.18, та блок-
схему алгоритму, наведену на рис. 5.19.
58. Поясніть приклад 5.12 та рис. 5.20.
59. Поясніть приклад 5.13 та рис. 5.21.
60. Які методи аналізу подій стосовно зміни станів елементів віконного
інтерфейсу Вам відомі? У чому полягають головні переваги та недоліки
кожного з цих методів? Свою відповідь обґрунтуйте.
61. Що являє собою параметр ‘command’ та як він використовується
для аналізу станів елементів віконного інтерфейсу? Наведіть власні приклади
такого використання цього параметру.
62. Що являє собою метод bind() та як він використовується для
аналізу станів елементів віконного інтерфейсу? Наведіть власні приклади
такого використання цього методу.
63. Які зарезервовані рядки можуть бути використані у мові
програмування Python для описання подій? Наведіть власні приклади такого
використання.
64. Як з використанням засобів програмування мови Python формується
кнопка вибору та аналізуються її властивості? Наведіть власний приклад
формування кнопки вибору та аналізу її властивостей.
65. Поясніть приклад 5.14 та рис. 5.22.
66. Поясніть блок-схему алгоритму, наведену на рис. 5.23.
67. Як з використанням засобів програмування мови Python формується
селекторна кнопка та аналізуються її властивості? Наведіть власний приклад
формування селекторної кнопки та аналізу її властивостей.
68. Поясніть блок-схему алгоритму, наведену на рис. 5.24.
69. Поясніть приклад 5.15 та рис. 5.25.
70. Як з використанням засобів програмування мови Python формується
список та аналізуються його властивості? Наведіть власний приклад
формування списку та аналізу його властивостей.

167
71. Як проводиться аналіз властивостей списку з використанням
методу bind() та через подію натиснення на кнопку як елемент графічного
інтерфейсу? Зробить порівняльний аналіз цих двох методів аналізу
властивостей списку та наведіть приклади їхнього практичного використання
під час створення інтерфейсів прикладних програм.
72. Поясніть блок-схеми алгоритмів, наведені на рис. 5.26.
73. Поясніть приклад 5.16 та рис. 5.27.
74. Як різні методи проектування графічного інтерфейсу прикладних
програм пов’язані з філософією мови програмування Python? Свою відповідь
обґрунтуйте з точки зору теорії програмування та з точки зору теорії
скінченних автоматів.
75. Як з використанням засобів програмування мови Python формується
нумерований список та аналізуються його властивості? Наведіть власний
приклад формування нумерованого списку та аналізу його властивостей.
76. Які параметри методу формування нумерованого списку
Spinbox() Вам відомі? Наведіть приклади використання цих параметрів.
77. Поясніть приклад 5.17 та рис. 5.28.
78. Як з використанням засобів програмування мови Python формується
лінійка з повзунцем як елемент графічного інтерфейсу та аналізуються її
властивості? Наведіть власні приклади формування лінійки з повзунцем та
аналізу її властивостей.
79. Які параметри методу формування лінійки з повзунцем Scale()
Вам відомі? Наведіть приклади використання цих параметрів.
80. Поясніть приклад 5.18 та рис. 5.29.
81. Поясніть приклад 5.19 та рис. 5.30.
82. Поясніть код програми, наведеної у додатку А.
83. Поясніть приклад 5.20 та рис. 5.31.
84. Поясніть приклад 5.21 та рис. 5.32.
85. Як у мові програмування Python під час подійного моделювання
реалізується часова затримка? Наведіть власні приклади формування часової

168
затримки.
86. Поясніть приклад 5.22 та рис. 5.33.
87. Як у мові програмування Python реалізована функція формування
звукового сигналу та які вона має параметри? Наведіть власні приклади
використання цієї функції.
88. Поясніть приклад 5.23.
89. Як з використанням засобів мови програмування Python можна
написати прикладну програму з віконним інтерфейсом, яка виконує функцію
багатофункціонального годинника? Опишіть принцип роботи такої програми
з точки зору теорії скінченних автоматів.
90. Поясніть блок-схеми алгоритмів, наведені на рис. 5.34 та 5.35.
91. Поясніть приклад 5.24 та рис. 5.36.
92. Поясніть код програми, наведеної у додатку Б.
93. Як у сучасних мультимедійних комп’ютерних програмах
проводиться одночасна обробка звука та зображення та як цей спосіб
обробки пов’язаний із відповідними засобами написання програмного коду?
94. Які головні елементи віконного інтерфейсу повинна мати програма
текстового редактора? Свою відповідь обґрунтуйте та наведіть приклади
таких текстових редакторів.
95. Які засоби та методи мови програмування Python, призначені для
створення віконного інтерфейсу текстового редактора, Вам відомі? Наведіть
власні приклади використання цих засобів для написання прикладних
програм.
96. Що являють собою методи askopenfile() та
asksaveasfile() та як вони використовуються для формування
спливаючого меню текстового редактора? Наведіть власні приклади
використання цих методів.
97. Що являють собою методи мови програмування Python
Text.delete() та Text.insert() та як вони використовуються для
роботи з текстовими вікнами? Наведіть власні приклади використання цих

169
методів.
98. Як у мові програмування Python реалізується операція збереження
файлу? Наведіть власні приклади виконання цієї операції.
99. Із яких елементів віконного інтерфейсу складається вікно
текстового редактора та які параметри мають ці об’єкти? Наведіть власні
приклади використання цих параметрів.
100. Що являють собою теги як атрибути тексту та як вони
використовуються для визначення властивостей тексту у текстовому
редакторі? Наведіть власні приклади такого використання тегів.
101. Які методи мови програмування Python використовуються для
роботи з фрагментами тексту? Наведіть власні приклади використання цих
методів.
102. Які методи та об’єкти мови програмування Python
використовуються для створення рядка меню текстового редактора? Наведіть
власний приклад створення рядка меню текстового редактора.
103. Поясніть приклад 5.25 та рис. 5.37, 5.38 та 5.39.
104. Поясніть код програми, наведений у додатку В.
105. Опишіть головні функціональні можливості простого
калькулятора, розглянутого у прикладі 5.26.
106. Поясніть рис. 5.40 та блок-схеми алгоритмів, які наведені на
рис. 5.41 та 5.42.
107. Поясніть код програми, наведений у додатку Г, та рис. 5.43.
108. Опишіть головні функціональні можливості інженерного
калькулятора, розглянутого у прикладі 5.27.
109. Поясніть код програми, наведений у прикладі 5.27, та рис. 5.44.
110. Поясніть приклад 5.28 та рис. 5.45.
111. Поясніть код програми, наведений у додатку Д, та рис. 5.46.
112. Поясніть приклад 5.29 та рис. 5.47.
113. Поясніть код програми, наведений у додатку Е, та рис. 5.48.
114. Що являє собою полотно як елемент графічного інтерфейсу та які

170
параметри має команда формування полотна Canvas()? Наведіть власні
приклади використання цих параметрів.
115. Які способи та методи створення геометричних об’єктів на полотні
Вам відомі? Наведіть власні приклади використання цих методів та способів.
116. Що являє собою метод побудови лінії create_line() та які він
має параметри? Наведіть власні приклади використання цих параметрів.
117. Що являє собою метод побудови прямокутника
create_rectangle() та які він має параметри? Наведіть власні приклади
використання цих параметрів.
118. Що являє собою метод побудови багатокутника
create_polygon() та які він має параметри? Наведіть власні приклади
використання цих параметрів.
119. Що являє собою метод побудови овалу create_oval() та які
він має параметри? Наведіть власні приклади використання цих параметрів.
120. Що являє собою метод побудови сектора або дуги еліпса
create_arc() та які він має параметри? Наведіть власні приклади
використання цих параметрів.
121. Що являє собою метод виведення текстової інформації на полотно
create_text() та які він має параметри? Наведіть власні приклади
використання цих параметрів.
122. Як з використанням графічних засобів мови програмування Python
можна розмістити у віконному інтерфейсі фотографію або малюнок?
Наведіть власні приклади розміщення фотографії або малюнку у віконному
інтерфейсі.
123. Поясніть приклад 5.30 та рис. 5.49.
124. Поясніть приклад 5.31 та рис. 5.50.
125. Поясніть графічні функції модуля tkinter, які описані у
таблиці 5.1.
126. Які методи та засоби мови програмування Python можуть бути
використані для зміни властивостей об’єктів, розташованих на полотні?
171
Наведіть власні приклади такого використання цих методів та засобів.
127. Що являє собою метод Canvas.delete() та як він
використовується для роботи з об’єктами? Наведіть власні приклади
використання методу Canvas.delete().
128. Поясніть приклад 5.32.
129. Поясніть приклад 5.33 та рис 5.51.
130. Що являє собою метод Canvas.move() та як він
використовується для роботи з об’єктами? Наведіть власні приклади
використання методу Canvas.move().
131. Що являє собою метод Canvas.itemconfig() та як він
використовується для роботи з об’єктами? Наведіть власні приклади
використання методу Canvas.itemconfig().
132. Що являє собою метод Canvas.coords() та як він
використовується для роботи з об’єктами? Наведіть власні приклади
використання методу Canvas.coords().
133. Поясніть приклад 5.34 та рис. 5.52.
134. Поясніть методи модуля tkinter, призначені для переміщення
графічних об’єктів та зміни їхніх властивостей, які наведені у таблиці 5.2.
135. Як з використанням методів графічної бібліотеки модуля
tkinter можна побудувати трикутник? Наведіть власні приклади побудови
трикутника.
136. Як з використанням методів графічної бібліотеки модуля
tkinter можна побудувати паралелограм? Наведіть власні приклади
побудови паралелограма.
137. Як з використанням методів графічної бібліотеки модуля
tkinter можна побудувати ромб? Наведіть власні приклади побудови
ромба.
138. Як з використанням методів графічної бібліотеки модуля
tkinter можна побудувати правильний шестикутник? Наведіть власні

172
приклади побудови правильного шестикутника.
139. Як з використанням методів графічної бібліотеки модуля
tkinter можна побудувати ламану лінію? Наведіть власні приклади
побудови ламаної лінії.
140. Що являє собою вкладенка як елемент графічного інтерфейсу та
які засоби мови програмування Python використовуються для побудови
вкладенок? Наведіть власні приклади побудови вкладенок.
141. Поясніть приклад 5.35 та рис. 5.53.
142. Як з використанням ліній як елементарних об’єктів можна
побудувати графіки математичних функцій? Наведіть власні приклади
реалізації такого способу побудови графіків математичних функцій.
143. Поясніть співвідношення (5.1) та (5.2) та наведіть власні приклади
використання цих співвідношень.
144. Поясніть блок-схему алгоритму, яка наведена на рис. 5.54.
145. Поясніть приклад 5.36 та графічні залежності, які наведені на рис. 5.55.
146. Поясніть код програми, наведений у додатку Є.
147. З використанням коду програми, наведеного у додатку Є,
побудувати графіки наступних математичних функцій та дослідити їх
поведінку на заданому числовому інтервалі зміни аргументу.

x 2 − sin ( x ) x 2 − 15
а) х∈ [0,10], f ( x ) = ; б) х∈ [–5,5], f ( x ) = .
( )
cos x + 1 + cos( x )
3

( )
atan ln x 4 + 1 

arcsin x 2 − 20 x + 15 
 
в) х∈ [–5,5], f (x ) = .
 3  3  
ln x + 1 + exp x − 10 x + 25  
  

arccos x3 − 20 x 2 + 15 x − 5 
г) х∈ [–2,2], f (x ) =   .
 
ln x3 + 2 x + 1 + exp x3 − 10  
  

173
arccos x3 − 5  + arcsin x3 + 5 
д) х∈ [1,15], f (x ) =    .
sin  x3 + 2 x + 1  + cos x3 − 10 
   

sh  x3 − 10  + ch x 2 + 5 
е) х∈ [0,5], f (x ) =    .
 x3 + 1  + ch x3 − 10 
   
   

ch x3 − 3 x + 5  + sh  x 2 − 3 x + 10 
є) х∈ [–2,2], f (x ) =    .
 x3 + 1  + ch x3 − 1 
   
   

sin  x3  + cos x 2 − 3 
ж) х∈ [0,5]; f (x ) =     .
cos x3 + 1  + sin  x3 − 1 
   
 
sin   x3  + cos x 2 − 3  
з) х∈ [0,10]; f (x ) =    
.
 3   3  
cos  x + 1  + sin  x − 1  
   

cos nx3  + exp nx 2 + 3 


і) х∈ [0,1]; f (x ) =     .
sin  nx3 + 1  + exp nx3 − 1 
   
148. В яких ще модулях інтерпретатора мови програмування Python, крім
модуля tkinter, зберігаються графічні об’єкти, призначені для побудови
віконного інтерфейсу користувача? Наведіть власні приклади таких об’єктів
із зазначенням модулів, в яких вони розташовані.
149. Які графічні об’єкти, призначені для побудови віконного
інтерфейсу, зберігаються у підмодулі ttk модуля tkinter? Наведіть власні
приклади таких об’єктів із зазначенням можливостей їхнього використання.
150. Чим суттєво відрізняються об’єкти підмодуля ttk від об’єктів
модуля tkinter з точки зору методології програмування?
151. Що являють собою теми та як вони використовуються для
описання об’єктів підмодуля ttk модуля tkinter?

174
152. Які головні теми об’єктів підмодуля ttk Вам відомі та під якими
операційними системами вони можуть бути використані?
153. Що являють собою бібліотеки підмодуля tix модуля tkinter та як
компоненти цих бібліотек можуть бути використані для побудови віконного
інтерфейсу? Наведіть власні приклади такого використання цих компонент.
154. Поясніть приклад 5.37.
155. З використанням засобів мови програмування Python написати
програму із віконним інтерфейсом, яка розраховує резонансну частоту fp,
добротність Q та смугу пропускання ∆f послідовного індуктивно-ємнісного
фільтру за відомими співвідношеннями:
1 1 L fp
fp = , Q= , ∆f = . (5.3)
2π LC R C Q
де R – опір у схемі фільтру, С – ємність, L – індуктивність [60].
Передбачити можливість введення значень елементів фільтру R, С та L
через задані дискретні значення списку-лічильника та через зміну положення
повзунця на лінійці. Для обрання способу введення значень елементів
фільтру використати селекторну кнопку.
Для заданого діапазону значень елементів фільтру R, С та L з
використанням графічних засобів модуля tkinter побудувати графічні
залежності f p (L ), f p (C ) , Q(R ) , Q(L ) , Q(C ) , ∆f (R ) , ∆f (L ) , ∆f (C ) .

У нижній частині інтерфейсного вікна розташувати рисунок


принципової схеми фільтру, наведеної на рис. 5.56.
C L

Uвх R
Uвих

Рис. 5.56 Принципова схема послідовного індуктивно-ємнісного фільтру

175
Розділ 6 Розширені можливості мови Python для розв’язування
прикладних завдань програмування та складних інженерних та
наукових завдань
У цьому розділі розглядаються можливості використання мови
програмування Python для розв’язування практичних завдань наукової та
інженерної діяльності в області сучасної електроніки. Насамперед тут слід
звернути увагу на систему програмування Anaconda, яка побудована на
основі одного з різновидів мови Python, що має назву IPython. Головною
відмінністю базової системи програмування мови IPython від класичної версії
інтерпретатора, яка розглядалася раніше, є наявність такого об’єкта, як
масив даних. Масиви орієнтовані на ефективну математичну обробку
структур числових даних та з цієї точки зору вони суттєво відрізняються
від списків, розглянутих у підрозділі 3.6 цього посібника. Система Anaconda
має розвинені засоби для роботи з науковою графікою, значно більш
ефективні, ніж графічні можливості базової версії інтерпретатора,
розглянуті у розділі 5. Також у цьому розділі окремо розглянуті можливості
використання мови програмування Python для розв’язування сучасних
інженерних завдань прикладної електроніки та інформаційних технологій.
Зокрема розглядаються засоби програмування розподілених додатків для
локальних та глобальних комп’ютерних мереж, а також наявні засоби
програмування сучасних мікроконтролерних та мікрокомп’ютерних
пристроїв.
6.1 Можливості використання пакету Anaconda для розв’язування
завдань математичного моделювання та наукових завдань
6.1.1 Описання головних можливостей пакету Anaconda,
призначених для розв’язування інженерних та наукових завдань
Однією з найсучасніших реалізацій інтерпретатора мови Python, яка
орієнтована на інженерів та науковців та призначена для розв’язування
прикладних наукових завдань, є пакет програм Anaconda, створений на

176
основі мови програмування IPython (абревіатура англійського
словосполучення Interactive Python) [26, 70]. Початкове ознайомлення з
можливостями цього пакету із розширеними математичними бібліотеками
було проведене у розділі 2.1, там же були наведені посилання на сторінки
Інтернет, де можна знайти інсталяції цього пакету, які відповідають
апаратним обчислювальним можливостям Вашого комп’ютера та
встановленій операційній системі [35, 36].
Головним новим об’єктом, реалізованим у версії IPython, якого немає у
базовій версії інтерпретатора, є масив. Робота з цим об’єктом реалізована
через бібліотеку математичних функцій numpy [26, 70]. Іншими важливими
бібліотеками пакету Anaconda є бібліотеки matplotlib, sympy та scipy.
Функції бібліотеки matplotlib призначені для роботи з науковою
двовимірною та тривимірною графікою, включаючи можливість створення
анімаційних ефектів. У бібліотеці sympy реалізовані функції для проведення
аналітичних перетворень та для спрощення алгебраїчних виразів [70].
Наявність такої бібліотеки у значній мірі відрізняє інтерпретатор IPython від
більшості інших сучасних мов програмування, які не є складовою частиною
автоматизованих комп’ютерних систем для проведення наукових
розрахунків. Наочним прикладом такої системи є система науково-технічних
розрахунків MatLab [6, 7]. У бібліотеці scipy реалізовані спеціальні функції
для проведення складних наукових розрахунків, зокрема, для чисельного
обчислення інтегралів та для розв’язування диференціальних рівнянь [70].
Окрему зацікавленість для фахівців-математиків та фізиків-
експериментаторів, які працюють в галузі проведення статистичних
обчислень та математичної статистики, являє собою бібліотека Pandas,
орієнтована на обробку великих масивів статистичних даних з
використанням сучасних комп’ютерних технологій та методів машинного
навчання [26].
Тобто, пакет Anaconda – це дійсно потужний та ефективний сучасний
засіб, який дозволяє розв’язувати складні інженерні та наукові завдання з
використанням засобів комп’ютерного моделювання та наукової графіки.
177
Чим саме відрізняється система Anaconda від класичної версії
інтерпретатора мови Python, основи роботи з якою були описані в попередніх
підрозділах? Головною відмінною рисою мови програмування IPython є
описання масивів як структур числових даних, над якими можна проводити
відповідні математичні операції. Масив, як об’єкт, суттєво відрізняється від
списків, основи роботи з якими були розглянуті у підрозділі 3.6. Для масивів
використовуються зовсім інші методи, орієнтовані на роботу з числовими
даними. Наприклад, можна поелементно скласти два масиви з використанням
операції додавання або перемножити їх з використанням операції множення.
Результатом таких операцій буде додавання та множення всіх елементів двох
початкових масивів, які повинні мати однакову розмірність. Розглянемо
відповідний приклад.
Приклад 6.1 Знайти поелементну суму та поелементний добуток

двох двовимірних масивів: A = 1 2 та B = 5 6 .


3 4 7 8
Результати поелеменного додавання та множення цих двох масивів
числових даних будуть такими.

A + B = 1 2 + 5 6 =  6 8  . A ⋅ B = 1 2 ⋅ 5 6 =  5 12  .
3 4 7 8 10 12 3 4 7 8 21 32
Такі операції у теорії програмування називаються матричними
макроопераціями та являють собою основи теорії матричного
програмування [5, 6]. Як було відмічено у підрозділі 1.1, вперше ввів поняття
матричного програмування та теоретично розглянув його розширені
потенціальні можливості у 1961 році відомий американський математик
К.Ю. Айверсон. Сьогодні на концепції матричного програмування цілком
базується система науково-технічних розрахунків MatLab [6, 7].
У навчальній літературі з системи науково-технічних розрахунків
MatLab [6, 7] обґрунтовано, що у разі ефективного використання методів
матричного програмування можна реалізовувати алгоритми низької та
середньої степені складності взагалі без використання умовних операторів та

178
циклічних структур, що часто у значній мірі спрощує розуміння програмного
коду. Замість умовних операторів використовуються арифметико-логічні
вирази описані у підрозділі 3.3, а замість циклів – матричні макрооперації.
Тобто, можна сказати, що засоби програмування системи Anaconda, основані
на введені поняття масивів та матричних макрооперацій над
структурованими числовими даними, цілком відповідають концепції
матричного програмування, реалізованій у системі науково-технічних
розрахунків MatLab [6, 7]. Підводячи підсумок сказаному, сформулюємо
головні відмінні риси, які відрізняють систему програмування Anaconda від
стандартної версії інтерпретатора мови програмування Python.
1. Введення поняття масиву та засобів матричного програмування,
притаманних системі науково-технічних розрахунків MatLab [6, 7].
Відповідні об’єкти та методи для роботи з ними реалізовані в бібліотеці
numpy [25, 70].
2. Розвинені функції для роботи з науковою комп’ютерною графікою,
зокрема, функції двовимірної, тривимірної графіки та анімації. Ці графічні
засоби також розроблені на основі стандартів системи науково-технічних
розрахунків MatLab [6, 7] та реалізовані в бібліотеці matplotlib [26, 70].
3. Функції для проведення аналітичних розрахунків, реалізовані в
бібліотеці sympy [26, 70]. Такі можливості реалізовані в багатьох пакетах
програм, призначених для проведення науково-технічних розрахунків,
зокрема MathCAD, Maple, MatLab, Mathematica, але у більшості систем
програмування зазвичай вони відсутні.
4. Функції для проведення інженерних та наукових обчислень, зокрема,
обчислення інтегралів та розв’язування диференціальних рівнянь, реалізовані
у бібліотеці scipy [70]. Більшість із цих функцій також запозичені з системи
науково-технічних розрахунків MatLab [6, 7].
5. Функції для проведення статистичних розрахунків, реалізовані в
бібліотеці Pandas [26].
Система Anaconda є досить обширною, і повний розгляд її

179
можливостей виходить за рамки цього посібника, який головним чином
орієнтований на вивчення базових функцій та концепцій мови програмування
Python. Більш досконале описання всіх функцій системи Anaconda можна
знайти у посібниках [26 – 29, 70]. Крім цього, більшість функцій системи
Anaconda, призначених для роботи з масивами, співпадають із відповідними
функціями системи науково-технічних розрахунків MatLab [6, 7]. Тому
достатньо знати синтаксис запису цих функцій, який відповідає розглянутим
у попередніх підрозділах принципам програмування мови Python. Зазвичай
імена цих функцій записуються як методи, які відносяться до об’єкту класу
array бібліотеки numpy.
Слід відзначити, що для роботи з цими засобами систему Anaconda
встановлювати на комп’ютері не обов’язково. Сьогодні існують також версії
інтерпретатора мови Python, до яких включені відповідні бібліотеки numpy,
matplotlib, sympy та scipy [26, 70].
У наступному підрозділі розглянемо поняття масиву, способи описання
масивів та функції для роботи з ними. Із наведеного вище описання
зрозуміло, що це поняття взагалі є базовим для реалізації концепції
матричного програмування.

6.1.2 Масиви та операції з ними в системі програмування


Anaconda

6.1.2.1 Визначення масивів та основні правила роботи з ними

Перед вивченням цього підрозділу необхідно повторити підрозділи 2.5 та 3.6


Масиви у системі програмування Anaconda, як і в системі науково-
технічних розрахунків MatLab [6, 7], відповідають визначенню матриці у
дискретній математиці та у лінійній алгебрі [42], тому, на відміну від списків,
елементами масиву можуть бути лише числові дані. Для того, щоб створити
масив, згідно із загальними принципами програмування мови Python
необхідно виконати наступні дії [26, 70].

180
1. Підключити модуль бібліотеки numpy. Відповідні засоби
програмування мови Python, які використовуються для роботи з модулями,
були описані у підрозділі 2.5.
2. Викликати функцію array() бібліотеки numpy. Ім’я цієї функції
зазвичай записується після імені бібліотеки через крапку, але можливі і інші
форми запису, які є стандартними для синтаксису програмування мови
Python та були розглянуті у підрозділі 2.5.
3. Єдиним параметром функції array() має бути масив, який
необхідно створити. Масиви у мові програмування Python записуються
аналогічно спискам, які розглядалися у підрозділі 3.6. Відмінності полягають
у тому, що всі елементи масиву мають бути числовими даними, а кількість
елементів у всіх рядках має бути однаковою.
4. Для перегляду елементів введеного масиву достатньо послатися на
змінну, якій відповідає його ім’я. Відповідний спосіб роботи зі змінними був
розглянутий у підрозділі 2.1.
5. Іншим способом перегляду елементів масиву є використання базової
функції print(), способи роботи з якою розглядалися у підрозділі 2.6.4.
Розглянемо простий приклад формування масивів.
Приклад 6.2
>>> import numpy as np
>>> a = np.array([0., 2.5, 5.4])
>>> a
array([0., 2.5, 5.4])
>>> print(‘a = ’, a)
a = [0. 2.5 5.4]
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>> b
array([1, 2, 3],
[4, 5, 6])
5. Для аналізу окремих елементів масивів та для роботи з ними

181
використовуються індекси. У мові програмування Python існує два способи
запису індексів елементів масиву. Перший з них відповідає індексації
елементів списків та був розглянутий у підрозділі 3.6. Тобто, номери рядків
та стовпчиків двовимірного масиву записуються після посилання на його
ім’я. Індекси пишуться підряд, але кожний у своїх квадратних дужках.
Наприклад: b [0] [1]. Інший спосіб індексації елементів масивів
запозичений із системи науково-технічних розрахунків MatLab [6, 7]. Індекси
елементу пишуться в квадратних дужках та розділяються комою. Наприклад
: b [0, 1]. У будь-якому разі, завжди виконуються два наступних правила.
Правило 6.1 Нумерація індексів елементів масиву на всіх ієрархіях
починається з нуля.
Правило 6.2 Для двовимірних масивів спочатку іде номер рядка, а за
ним – номер стовпчика.
Розглянемо приклад звернення до елементів масивів, який оснований
на прикладі 6.2.
Приклад 6.3
>>> b [0] [1]
2
>>> b [1] [2]
6
Під рівнем ієрархії у правилі 6.1 мається на увазі рівень розташування
елементу у багатовимірному масиві. Наприклад, одновимірний масив має
лише один рівень ієрархії – рядок, двомірний – рядок та стовпчик, а
тривимірний – рядок, стовпчик та сторінку [5, 6]. Розглянемо приклад
формування одновимірного, двовимірного та тривимірного масиву.
Приклад 6.4
>>> import numpy as np
# Одновимірний масив
>>> a = np.array([0., 2.5, 5.4])
# Двовимірний масив

182
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
# Тривимірний масив
>>> с = np.array([[1, 2, 3], [4, 5, 6]], \
[[7, 8, 9], [10, 11, 12]])
Всі головні математичні операції, призначені для роботи з масивами,
реалізовані як методи об’єктів класу array та будуть розглянуті у
наступному підрозділі. Окремо будуть розглянуті математичні функції,
призначені для реалізації елементарних матричних макрооперацій та
операцій лінійної алгебри.

6.1.2.2 Головні атрибути масивів та методи для роботи з ними


Як було відмічено у підрозділі 6.1.1, загалом більшість методів для
роботи з масивами, реалізованих у системі Anaconda, співпадають із
відповідними функціями системи науково-технічних розрахунків MatLab [6,
7]. Крім методів для масивів, як і для будь-яких об’єктів, існують атрибути,
які повертають відповідне значення [70]. Систематизуємо ці атрибути та
методи за їхнім призначенням та розглянемо головні з них.
1. Атрибути та функції, призначені для визначення розмірності
масиву та його розмірів за різними рівнями ієрархії.
ndim – розмірність масиву, або кількість рівнів ієрархії. Повертає
числове значення розмірності.
shape – розмір масиву, або кількість елементів на кожному з рівнів
ієрархії.
Різниця між поняттями розмірність та розмір масиву є
загальновживаною та розглядалася в навчальних посібниках [6, 7, 42].
size – загальна кількість елементів у масиві.
len() – функція, яка повертає значення розміру масиву за першим
рівнем ієрархії. Зрозуміло, що ця функція є перевантаженою, оскільки вона
існує також для інших структур даних, зокрема для рядків та списків.

183
Розглянемо приклади використання атрибутів та функцій, призначених
для визначення розмірності та розміру масиву.
Приклад 6.5
>>> import numpy as np
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>> b.ndim
2
>>> b.shape
(2, 3)
>>> b.size
6
>>> len(b)
2
2. Функції формування спеціальних матриць.
zeros(n) – формування матриці, всі елементи якої дорівнюють 0.
Параметр цієї функції n визначає розмір матриці та може бути числом або
масивом. Якщо n – числове значення, формується одновимірний масив із
заданим розміром, а якщо n – це масив, тоді він вказує розміри створюваної
матриці за всіма рівнями ієрархії. Наприклад:
zeros(5) – створення матриці з нулевими елементами із розмірністю
1 х 5. Часто в теорії програмування одновимірні масиви також називаються
векторами [6, 7].
zeros([2, 3]) – створення прямокутної матриці із розмірністю 2 х 3 з
нулевими елементами.
ones(n) – формування матриці, всі елементи якої дорівнюють 1.
Параметр цієї функції n визначається так само, як і для функції zeros().
eye(n) – формування діагональної одиничної матриці. Оскільки
діагональна матриця завжди є квадратною, у даному випадку параметр n

184
може бути лише цілим числом.
Розглянемо приклад використання функцій, призначених для
формування спеціальних матриць.
Приклад 6.6
>>> import numpy as np
>>> c = np.zeros(5)
>>> print(c)
[0, 0, 0, 0, 0]
>>> a = np.ones(2, 3)
>>> print(a)
[[1. 1. 1.]
[1. 1. 1.]]
>>> d = np.eye(3)
>>> print(d)
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
3. Атрибут визначення типу числових даних у масиві.
Типи числових даних, які можна визначати у мові програмування Python,
були описані у підрозділі 2.3. Це типи int16, int32, int64, float32,
float64. Визначити тип числових даних для сформованого масиву або задати
його ручним способом під час формування масиву можна через атрибут
dtype [70]. Для визначення атрибуту типу даних під час створення масиву
змінна dtype використовується як параметр об’єкта array(), а її значення
визначається через оператор присвоєння . Розглянемо відповідний приклад [70].
Приклад 6.7
>>> import numpy as np
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>> b.dtype
dtype(‘int32’)

185
>>> a = np.array([0., 2.5, 5.4])
>>> a.dtype
dtype(‘float64’)
>>> d = np.eye(3, dtype = int16)
>>> print(d)
[1 1 1]
4. Функції, призначені для формування табульованих послідовностей
чисел із заданим кроком на визначеному числовому інтервалі.
Відомо, що у системі науково-технічних розрахунків MatLab суттєве
значення мають вектори табульованих числових послідовностей із
визначеним кроком табуляції. Зокрема, такі типи структурованих даних дуже
зручно використовувати для побудови двовимірних та тривимірних
графічних залежностей [6, 7].
У системі Anaconda існують дві функції, призначених для побудови
одновимірних масивів із табульованими значеннями.
arangre (початкове_значення, кінцеве_значення, крок) –
формування числової послідовності від початкового до кінцевого значення з
заданим кроком. Послідовність закінчується, коли отримане число становиться
більшим за кінцеве значення, і останній результат до послідовності не
включається.
linspace(початкове_значення, кінцеве_значення,
кількість_елементів) – формування числової послідовності від
початкового до кінцевого значення з заданою кількістю елементів.
Розглянемо приклад, в якому використовуються ці функції.
Приклад 6.8
>>> import numpy as np
>>> a = np.arangre (0.5, 9.3, 2.5)
>>> print(a)
[0.5 3.0 5.5 8.0]
>>> b = np.linspace(0, 5, 6)

186
>>> print(b)
[0 1 2 3 4 5]
Для побудови тривимірних графіків у системах науково-технічних
розрахунків, зокрема у системі MatLab, використовуються масиви із рядками
та стовпчиками, які повторюються. У таких системах реалізовані спеціальні
функції для побудови відповідних матриць. Наприклад, у системі MatLab
такою є функція meshgrid [6, 7]. Аналогічна функція існує і в системі
Anaconda. Вона має такий формат запису:
meshgrid(M1, M2)
де M1 та M2 – одновимірні масиви, з яких створюється квадратна матриця.
Розглянемо приклад використання функції meshgrid().
Приклад 6.9
>>> import numpy as np
>>> x = np.linspace(–2, 2, 5)
>>> y = np.linspace(–2, 2, 5)
>>> print(y)
[–2. –1. 0. 1. 2.]
>>> X,Y = np.meshgrid(x, y)
>>> print(X)
[[–2. –1. 0. 1. 2.]
[–2. –1. 0. 1. 2.]
[–2. –1. 0. 1. 2.]
[–2. –1. 0. 1. 2.]
[–2. –1. 0. 1. 2.]]
>>> print(Y)
[[–2. –2. –2. –2. –2.]
[–1. –1. –1. –1. –1.]
[ 0. 0. 0. 0. 0.]
[ 1. 1. 1. 1. 1.]
[ 2. 2. 2. 2. 2.]]

187
Альтернативним варіантом функції meshgrid() у системі
програмування Anaconda є функція mgrid(), яка має наступний формат
запису [70].
mgrid(початкове_значення_1: кінцеве_значення_1:
крок_1, початкове_значення_2: кінцеве_значення_2:
крок_2)
Тобто, команда mgrid() відрізняється тим, що в ній числові значення
одновимірних масивів M1 та M2 задаються явно. Розглянемо приклад
використання цієї команди.
Приклад 6.10
>>> import numpy as np
>>> X1,Y1 = np.mgrid(0:8:2, –10:0:4)
>>> print(X1)
[[0 0 0]
[2 2 2]
[4 4 4]
[6 6 6]]
>>> print(Y1)
[[–10 –6 –2]
[–10 –6 –2]
[–10 –6 –2]
[–10 –6 –2]]
Зрозуміло, що функція np.mgrid() більше відповідає формату
функції meshgrid(), реалізованій у системі науково-технічних розрахунків
MatLab [6, 7].
5. Функції, призначені для формування масивів випадкових
числових значень та випадкового сортування елементів масиву.
Часто в практиці програмування для розв’язування інженерних та
наукових завдань необхідно формувати масиви значень випадкових чисел у
заданому числовому діапазоні [26, 70]. Наприклад, такі завдання є

188
важливими для статистичної обробки експериментальних даних. Для
розв’язування подібних завдань використовується функції системи
програмування Anaconda, розташовані в модулі numpy.random [70]. Слід
відзначити, що деякі функції з модуля numpy.random є перевантаженими з
функціями модуля random, призначеного для роботи з генератором
випадкових чисел. Відповідні функції з модуля random, зокрема функція
rand() та randint(), розглядалися у другому та третьому розділах,
зокрема, у прикладах, пов’язаних із формуванням послідовностей
випадкових чисел. Тому функції бібліотеки numpy.random слід
використовувати з урахуванням цього перевантаження методів [70].
Розглянемо декілька з цих функцій [70].
rand(n) – генерація одновимірного масиву із n випадкових дійсних
чисел, які лежать в діапазоні від 0 до 1.
rand(n, k) – генерація двовимірного масиву випадкових дійсних
чисел із розміром n х k. Числа лежать в діапазоні від 0 до 1.
randint(n, k, l) – генерація одновимірного масиву випадкових
цілих чисел із розміром l. Числа лежать в діапазоні від n до k, де n,
k, l – цілі числа, від n < k.
randint(n, k, (l, m)) – генерація двовимірного масиву
випадкових цілих чисел із розміром (l, m). Числа лежать в діапазоні від n
до k, де n, k, l, m – цілі числа, від n < k.
uniform(x0, x1, l) – генерація одновимірного масиву випадкових
дійсних чисел із розміром l. Числа лежать в діапазоні від x0 до x1.
uniform(x0, x1, (l, m)) – генерація двовимірного масиву
випадкових дійсних чисел із розміром (l, m). Числа лежать в діапазоні від x0
до x1.
shuffle(M) – випадкове перемішування елементів масиву M.
permutation(N) – створення масиву з випадково переміщених чисел із
діапазону 0 < n < N.

189
Розглянемо приклади використання цих функцій [70].
Приклад 6.11
>>> import numpy as np
>>> a = np.random.rand(3)
>>> print(‘a = ’, a)
a = [0.1238573 0.9587364 0.5938756]
>>> b = np.random.rand(2, 3)
>>> print(‘b = ’, b)
b = [[0.8475902 0.8395764 0.9108476]
[0.7389409 0.6765493 0.0192865]]
>>> c = np.random.randint(3, 8, 5)
>>> print(‘c = ’, c)
c = [5 7 4 6 5]
>>> d = np.random.randint(3, 8, (2, 4))
>>> print(‘d = ’, d)
d = [[4 5 6 7]
[5 6 5 3]]
>>> e = np.random.uniform(3, 8, 5)
>>> print(‘e = ’, e)
e = [5.34269801, 4.78560494, 6.78094765,
7.44769303, 5.67894756]
>>> f = np.random.uniform(3, 8, (2, 4))
>>> print(‘f = ’, f)
f = [[3.75869408, 5.76044156, 4.47657809, 7.94876756],
[3.75869408, 5.76044156, 4.47657809, 7.94876756]]
>>> z = np.arrange(8)
>>> print(‘z = ’, z)
z = [0 1 2 3 4 5 6 7]
>>> g = np.random.shuffle(z)
>>> print(‘g = ’, g)

190
g = [7 0 4 3 5 6 2 1]
>>> h = np.random.permutation(8)
>>> print(‘h = ’, h)
h = [7 0 4 3 5 6 2 1]

6.1.2.3 Реалізація матричних макрооперацій та інших алгебраїчних


операцій над масивами та окремими їхніми елементами
У бібліотеці numpy системи програмування Anaconda реалізована
низка функцій та операцій для роботи з масивами. Загалом ці функції та
операції побудовані на основі матричних макрооперацій над елементами
масивів та у деякій мірі відповідають аналогічним функціям, реалізованим у
системі науково-технічних розрахунків MatLab [6, 7]. Розглянемо головні з
них, а також особливості їхньої реалізації у системі програмування
Anaconda [26, 70].
1. Алгебраїчні операції між масивом та скаляром.
У системі програмування Anaconda реалізовані елементарні
арифметичні операції, тобто додавання, віднімання, множення та ділення,
між масивом та числом. Сутність цих матричних макрооперацій полягає у
тому, що до відповідна арифметична операція здійснюється над усіма
елементами масиву [26, 70].
Наведемо приклади виконання цих операцій.
Приклад 6.12
>>> import numpy as np
>>> a = np.array([1.0, 2.0, 3.0])
>>> b = a + 10
>>> print(b)
[11. 12. 13.]
>>> c = 5 * b
>>> print(c)
[55. 60. 65.]

191
>>> d = c – 5
>>> print(d)
[50. 55. 60.]
>>> e = d / 5
>>> print(e)
[10. 11. 12.]
Крім розглянутих вище чотирьох головних арифметичних дій,
можливим є піднесення всіх елементів масиву до степені з використанням
операції ** та виконання операцій складеного присвоєння типу +=, –=, *= та
/=, розглянутих у розділі 2 для роботи з числовими даними [26, 70].
Розглянемо приклади, в яких використовуються такі операції між масивом та
скаляром.
Приклад 6.13
>>> import numpy as np
>>> a = np.array([1.0, 2.0, 3.0])
>>> b = a**2
>>> print(b)
[1. 4. 9.]
>>> a += 10
>>> print(a)
[11. 12. 13.]
>>> c = np.array([1, 2], [3, 4])
>>> c += 10
>>> print(c)
[[11 12
[13 14]]
>>> c *= 10
[[110 120
[130 140]]
2. Матричні макрооперації над двома масивами.

192
У системі програмування Anaconda реалізовані поелеменнтні операції
між елементами двох масивів одного розміру. Головними з цих операцій є
чотири елементарні арифметичні та піднесення до степені. Для виконання
цих операцій між масивами одного розміру використовуються стандартні
символи +, –, *, / та ** [26, 70]. Крім цього, у системі Anaconda реалізовані
складені поелементні операції між двома масивами, як-то +=, –=, *= та /= [26,
70]. Розглянемо відповідний приклад.
Приклад 6.14
>>> import numpy as np
>>> a = np.array([1.0, 2.0, 3.0])
>>> b = np.array([10, 20, 30])
>>> c = a + b
>>> print(c)
[11. 22. 33.]
>>> d = a * b
>>> print(d)
[20. 40. 90.]
>>> e = b / a
>>> print(e)
[10. 10. 10.]
>>> f = b – a
>>> print(f)
[9. 18. 27.]
>>> g = b ** a
>>> print(g)
[10. 400. 27000.]
>>> b *= a
>>> print(b)
[20. 40. 90.]
>>> b /= a

193
>>> print(b)
[20. 20. 30.]
>>> b += a
>>> print(b)
[21. 22. 33.]
3. Поелементне порівняння двох масивів.
В навчальній літературі з системи програмування MatLab звертається
увага на те, що для ефективної реалізації концепції матричного
програмування важливим є можливість поелементного порівняння двох
структур однакового розміру [6, 7]. Оскільки умовний оператор системи
MatLab не дозволяє виконувати таку операцію над масивами, була
розглянута можливість альтернативної реалізації цієї операції інакше, з
використанням арифметико-логічних виразів [6, 7]. Базові поняття теорії
арифметико логічних виразів були розглянуті у підрозділі 3.3.
У системі програмування Anaconda реалізована досить проста
концепція порівняння елементів двох масивів, основана на понятті логічного
виразу у вузькому значенні цього слова, наведеному у підрозділі 3.2,
визначення 3.2. Формат оператора поелементного порівняння двох масивів
має наступний вигляд [26, 70].
Масив_3 = Масив_1 операція_порівняння Масив_2
Результатом виконання операцій порівняння двох масивів одного
розміру є масив такого ж розміру із відповідними значеннями булевої
змінної, які є результатом порівняння елементів двох масивів з однаковими
індексами.
Розглянемо відповідний приклад.
Приклад 6.15
>>> import numpy as np
>>> a = np.array([1.0, 2.0, 3.0])
>>> b = np.array([1.0, 4.0, 3.0])
>>> c = (a == b)

194
>>> print(c)
[True False True]
>>> d = (a != b)
>>> print(c)
[False True False]
>>> e = (b > a)
>>> print(e)
[False True False]
>>> f = (b >= a)
>>> print(f)
[True True True]
У теорії матричного програмування масиви, створені із логічних
змінних як результат виконання операції порівняння, називаються логічними
масивами [6, 7, 26, 70]. Надамо відповідне визначення.
Визначення 6.1 Масив, створений із значень логічної функції як
результат виконання операції порівняння, називається логічним масивом.
На основі логічних масивів формується поняття логічної індексації, яке
у теорії матричного програмування називається також множинною
індексацією [6, 7, 26, 70]. Надамо відповідне визначення.
Визначення 6.2 Індексація елементів масиву з використанням
значень іншого сформованого логічного масиву називається множинною, або
логічною індексацією.
Логічна індексація працює наступним чином. Припустимо, що
записаний оператор присвоєння A(L) = b, де A – числовий масив, L –
логічний масив такого ж розміру, як масив A, b – число або числова змінна.
Тоді, у разі, якщо елемент логічного масиву L дорівнює True, відповідному
елементу масиву A присвоюється значення b, а у противному випадку
значення елемента масиву A залишається незмінним.
Розглянемо приклади використання логічної індексації [70].
Приклад 6.16 Із заданого масиву із розміром 3 х 3 виділити всі

195
елементи, які є більшими за 2.
Будемо розв’язувати поставлену задачу в два етапи.
1. На основі заданих значень початкового масиву B сформуємо
логічний масив F, значення якого відповідають умові поставленої задачі.
2. Виділимо елементи масиву B, які відповідають заданій умові, з
використанням логічної індексації.
Відповідні рядки програмного коду можна записати наступним чином.
>>> import numpy as np
>>> B = np.array([4, –3, –1], [2, 7, 0], [–5, 1, 2])
>>> F = (B > 2)
>>> G = B(F)
>>> print(G)
[4 7]
Розглянемо ще один приклад використання логічної індексації
масивів [70].
Приклад 6.17
>>> import numpy as np
>>> A = np.arrange(1, 10).reshape(3, 3)
>>> print(A)
[[1 2 3]
[4 5 6]
[7 8 9]]
>>> B = np.array([8, 1, 6], [3, 5, 7], [4, 1, 2])
>>> print(B)
[[8 1 6]
[3 5 7]
[4 1 2]]
>>> C = (A <= B)
>>> print(C)
[[True] [False] [True]]

196
[False] [True] [True]
[False] [True] [False]]
>>> A(C) = 0
>>> print(A)
[[0 2 0]
[4 0 0]
[7 0 9]]
У прикладі 6.17 функція reshape() використовується для
реcтруктурізації масиву із зміною його розміру, елементи масиву в ході
виконання цієї операції не змінюються. Для прикладу, який розглядається, з
одновимірного вектора, створеного з дев’яти елементів з використанням
функції arrange(1, 10), створений двовимірний масив A із
розміром 3 х 3.
4. Функції транспортування матриці.
Важливою функцією роботи з числовими масивами в системах
матричного програмування є функція транспортування матриць [6, 7]. У
системі програмування Anaconda існує дві можливості виконання цієї
операції. Перша можливість відповідає перетворення вектора-рядка до
вектора-стовпчика. Ця операція є вкрай важливою для виконання матричних
макрооперацій. Таке перетворення у системі програмування Anaconda можна
зробити з використанням системної змінної None, призначення якої було
розглянуто у підрозділі 3.2 [70]. Розглянемо відповідний приклад.
Приклад 6.18
>>> import numpy as np
>>> y = linspace(-1., 1., 3.)
>>> print(y)
[–1 0 1]
>>> z = y[:, None]
>>> print(z)
[[–1]

197
[0]
[1]]
Іншим, більш універсальним способом створення транспонованої
матриці, є використання методу T() для функції array()[26, 70].
Розглянемо відповідний приклад.
Приклад 6.19
>>> import numpy as np
>>> A = np.array([8, 6], [3, 5]).T
>>> print(A)
[[8, 3]
[6, 5]]
Зрозуміло, що такі способи створення транспонованої матриці є значно
простішими, ніж спосіб, оснований на використанні списків, який був
розглянутий у прикладі 3.60.
5. Поелементні операції над масивами різного розміру.
У системі програмування Anaconda передбачена можливість виконання
поелементних операцій над масивами різного розміру. Такі операції
виконуються з використанням наступної обчислювальної схеми [26, 70]:
 M 21   M1 ⊕ M 21 
   
M1 ⊕ M 2 = M1 ⊕  M 22  =  M1 ⊕ M 22  . (6.1)
 L   L 
M M ⊕
 2n   1 M 2n 
де M1 – перший масив, M 2 – другий масив, M 21 , M 22 , ..., M 2n – елементи
другого масиву, ⊕ – код операції. Спосіб обробки масивів, згідно із схемою,
заданою співвідношенням (6.1), реалізований в системі програмування
Anaconda для операцій додавання, віднімання, множення, ділення та
піднесення до степені. Розглянемо приклади виконання цих операцій для
масивів різного розміру [70].
Приклад 6.20
>>> import numpy as np
>>> A = np.array([1, 2, 3])

198
>>> B = np.array([1, 2, 3], [4, 5, 6])
>>> C = A + B
>>> print (C)
[[2, 4, 6]
[5, 7, 9]]
>>> D = B – A
>>> print (D)
[[0, 0, 0]
[3, 3, 3]]
>>> E = B * A
>>> print (E)
[[1, 4, 9]
[4, 10, 18]]
>>> F = B / A
>>> print (F)
[[1, 1, 1]
[4, 2.5, 2]]
>>> F = B ** A
[[1, 4, 27]
[4, 25, 216]]
6. Обчислення елементів масивів з використанням функцій.
У системі Anaconda передбачена можливість формування масивів через
математичні операції над індексами їхніх елементів. Для цього
використовується метод fromfunction(), розташований в модулі numpy.
Формат запису цієї функції має наступний вигляд [26, 70].
ім’я_змінної = np.fromfunction(ім’я_функції, \
розмір масиву, тип_даних)
Розглянемо приклади формування масивів з використанням методу
fromfunction().
Приклад 6.21 З використанням засобів системи програмування

199
Anaconda створити одновимірний масив числових даних з п’яти елементів.
Значення елементів масиву обчислюються через їхні номери з використанням

співвідношення ci = 5i 2 .
Відповідний програмний код можна записати наступним чином.
>>> def g(i)
return 5*i**2
>>> import numpy as np
>>> a = np.fromfunction(g, (5,), dtype = int32)
>>> print (a)
[0 5 20 45 80]
Зверніть особливу увагу на те, що другий параметр функції
fromfunction(), який визначає розмір масиву, записується у вигляді
кортежу, тому кома у дужках після цифри 5 є обов’язковою. Способи
формування кортежів та методи для роботи з ними у мові програмування
Python були розглянуті у підрозділі 4.3.
Приклад 6.22 З використанням засобів системи програмування
системи Anaconda побудувати двовимірний масив числових даних із
розміром 3 х 3. Значення елементів масиву обчислюються через їхні номери з

використанням співвідношення M i = i 2 + j 2 , де i – номер рядка, j – номер


стовпчика.
Відповідний програмний код можна записати наступним чином.
>>> def f(i, j)
return i**2 + j**2
>>> import numpy as np
>>> a = np.fromfunction(f, (3,3), dtype = int)
>>> print (a)
[[0 1 4]
[1 2 5]
[4 5 8]]
Для проведення обчислень елементів масиву, крім функцій
200
користувача, можуть бути використані анонімні лямбда функції, основи
роботи з якими розглядалися у підрозділі 3.7.8. Тоді формат запису функції
fromfunction() дещо змінюється та має наступний вигляд.
ім’я_змінної = np.fromfunction(lambda \
імена_змінних: функція, розмір масиву, тип_даних)
Розглянемо приклад використання анонімної лямбда функції для
формування масиву.
Приклад 6.23 З використанням засобів системи програмування
Anaconda побудувати двовимірний масив числових даних із розміром 3 х 3.
Значення елементів масиву обчислюються через їхні номери з використанням

співвідношення M i = 2i 2 + 3 j 2 , де i – номер рядка, j – номер стовпчика.


Відповідний програмний код можна записати наступним чином.
>>> import numpy as np
>>> a = np.fromfunction(lambda i, j: 2*i**2 + \
3*j**2, (3,3), dtype = int)
>>> print (a)
[[0 3 12]
[2 5 14]
[8 11 20]]
Розглянуті у цьому підрозділі поелементні операції над масивами як
структурами числових даних, реалізовані в системі програмування Anaconda,
показують, що масиви суттєво відрізняються від списків, головні функції для
роботи з якими були розглянуті нами у підрозділі 3.6. Наприклад, якщо для
списків операція «+» означає об’єднання елементів двох визначених списків
до одного, для масивів вона відповідає операції поелементного сумування.
Для списків операція множення означає повторення елементів списку
відповідну кількість разів, а для масиву – поелементне множення його
елементів на задане число. Тобто, якщо перевантажені операції базової версії
інтерпретатора мови Python більше відповідають правилам роботи зі
структурованими даними в класичних мовах структурного програмування [3,
201
12, 39], засоби програмування для роботи з масивами в системі Anaconda
головним чином побудовані на концепції матричного програмування, яка
була запропонована К.Ю. Айверсоном та реалізована у системі науково-
технічних розрахунків MatLab [6, 7]. Порівняння описаних методів роботи з
масивами із реалізацією матричних операцій через роботу зі списками,
розглянутою у прикладах 3.60 та 3.61, дозволяють зробити висновок про те,
що засоби матричного програмування, призначені для роботи з структурами
числових даних, є значно більш простим та ефективним інструментом
програмування.

6.1.2.4 Використання математичних функцій для роботи з


масивами
У системі науково-технічних розрахунків MatLab з використанням
засобів матричного програмування ефективно реалізований механізм
застосування математичних функцій для опрацювання масивів [6, 7]. Цей
механізм є вкрай простим та працює наступним чином. Будь-яка
математична функція може бути використана для поелементної обробки
масиву числових даних і результатом виконання цієї поелементної операції є
масив того самого розміру, що й початковий, всі елементи якого
обчислюються як задана функція від елементів початкового масиву [6, 7].
Такий простий механізм дійсно є дуже зручним та у багатьох випадках
дозволяє уникнути використання циклів для проведення обчислень із
структурованими числовими даними. Тому аналогічний механізм для роботи
із масивами реалізований і в системі програмування Anaconda, але його
реалізація в цій системі має певні особливості, які розглядатимуться у цьому
підрозділі.
В системі Anaconda реалізовані кілька способів поелементної обробки
числових даних, поданих як масиви. Розглянемо головні з них [26, 70].
1. Векторізація функцій математичної бібліотеки.
Функції бібліотеки math, які були розглянуті у підрозділі 2.4,
безпосередньо не призначені для опрацювання масивів, але для них може
202
бути виконана функція векторізації. Надамо відповідне визначення.
Визначення 6.3 Векторізацією називається логічне перетворення,
яке дозволяє використовувати функцію, призначену для опрацювання
скалярних величин, для виконання матричних макрооперацій.
В системі програмування Anaconda для виконання операції векторізації
використовується функція vectorize() модуля numpy, яка має наступний
формат.
нове_ім’я_функції = vectorize(попеерднє_ім’я_функції)
Розглянемо простий приклад, в якому функція vectorize() із
бібліотеки numpy використовується для роботи із функцією sin() модуля
math.
Приклад 6.24 З використанням матричної макрооперації обчислити
π π π 3π
значення функції y(x) = sin(x) для значень x = 0, x = , x= , x= , x= ,
6 4 2 4
x = π . Для розрахованого масиву y(x) знайти значення зворотної функції
x(y) = arcsin(y).
Відповідний програмний код буде мати наступний вигляд.
>>> import numpy as np
>>> from math import (sin, pi)
>>> my_sin = np.vectorize(sin)
>>> x = np.array([0, math.pi/6, math.pi/4, \
math.pi/2, 3*math.pi/4, math.pi])
>>> y = my_sin(x)
>>> print(y)
[0 0.5 0.7071 1. 0.7071 0.0]
>>> my_asin = np.vectorize(asin)
>>> x_n = my_asin(y)
>>> print(x_n)
[0 0.5236 0.7854 1.5708 0.7854 0.0]
Тобто, виконання операції векторізації над функціями математичної

203
бібліотеки дозволяє використовувати ці функції для виконання матричних
макрооперацій над елементами масивів.
Розглянемо інші можливості використання функції векторізації
vectorize() [26, 70].
2. Векторізація функцій користувача.
Функція vectorize()може мати своїм аргументом не лише
математичні функції, але й визначені у програмі імена функцій користувача.
Розглянемо відповідний приклад, побудований на основі прикладу 6.24.
Приклад 6.25 З використанням матричної макрооперації обчислити
π π π
значення функції y(x) = sin2(x) + x для значень x = 0, x = , x= , x= ,
6 4 2

x= , x = π.
4
Відповідний програмний код буде мати наступний вигляд.
>>> import numpy as np
>>> from math import (sin, pi)
>>> def f(x):
return sin(x)**2 + x
>>> f_vect = np.vectorize(f)
>>> x = np.array([0, math.pi/6, math.pi/4, \
math.pi/2, 3*math.pi/4, math.pi])
>>> c = f_vect(x)
>>> print(c)
[0 0.7736 1.2854 2.5708 2.8562 3.1416]
3. Векторізація анонімної лямбда-функції.
Функція vectorize() також може бути використана для роботи з
анонімними лямбда-функціями. Розглянемо відповідний приклад.
Приклад 6.26 З використанням матричної макрооперації та
анонімної лямбда-функції обчислити значення функції y(x) = x2 + x + 1 для

значень x з матриці  2 5  .
 1 8
Відповідний програмний код буде мати наступний вигляд.
>>> import numpy as np

204
>>> g = lambda x: x**2 + x + 1
>>> m = np.array([2, 5], [1, 8])
>>> g_vect = np.vectorize(g)
>>> c = g_vect(m)
>>> print(c)
[[7 31]
[3 73]]
Слід відзначити, що у модулі numpy розташована бібліотека
перевантажених математичних функцій, які написані вже з урахуванням
можливості їхнього використання для роботи з масивами. У разі
використання цих функцій відпадає необхідність застосування методу
векторізації. Проте у цьому разі слід пам’ятати про особливості опрацювання
перевантажених функцій інтерпретатором мови Python, відповідні теоретичні
відомості були наведені у підрозділі 2.6.
4. Опрацювання масивів з використанням арифметико-логічних
функцій.
Зрозуміло, що для опрацювання масивів з використанням арифметико-
логічних функцій може бути використана векторізація функції (3.1) у явному
вигляді, відповідні приклади для числових даних були наведені у підрозділі
3.3. Проте у системі програмування Anaconda такі поелементні операції над
масивами даних можуть бути виконані значно ефективніше з використанням
функції piecewise() модуля np. Формат цієї функції має наступний вигляд.
ім’я_змінної = piecewise(x, \
[список_умов], [список_функцій])
У разі, якщо кількість умов становить більше за дві, для опрацювання
масивів необхідно використовувати поелементні логічні функції із бібліотеки
numpy. Наведемо список цих функцій [26, 70].
logical_and() – поелементна логічна операція «І».
logical_or() – поелементна логічна операція «АБО».
logical_not() – поелементна логічна операція «НІ».
logical_xor() – поелементна логічна операція «ВИКЛЮЧНОГО
АБО».

205
Наведемо приклад використання функції picewise() разом із
поелементними логічними функціями.
Приклад 6.27 З використанням анонімної лямбда-функції та
матричної макрооперації для масиву значень (− 3,5, 2,2, − 5,1, 4,3, 6,8, − 8,4 )
обчислити значення функції y(x), заданої на різних інтервалах числової осі
наступним чином:
− x , якщо x < −3;
 2 якщо 4 > x ≥ −3;
y(x ) =  x ,
 x + 100, якщо 6 > x ≥ 4;
 x , якщо x ≥ 6.
Відповідний програмний код можна записати наступним чином.
>>> import numpy as np
>>> x = np.array([–3.5, 2.2, 5.1, 4.3, 6.8, –8.4])
>>> Y = piecewise(x, [x<-3, \
np.logical_and(x>=-3, x<4), \
np.logical_and(x>=4, x<6), \
x>=6] \
[lambda t: –t, \
lambda t: t**2, \
lambda t: t + 100, \
lambda t: t**0.5])
>>> print(Y)
[3.5 4.84 5.1 104.3 2.6077 8.4]
5. Додаткові бібліотечні функції для здійснення матричних
макрооперацій над масивами.
Слід відзначити, що хоча розглянуті вище програмні засоби є досить
ефективними та дозволяють розв’язувати дуже складні задачі програмування,
пов’язані із обробкою масивів числової інформації, системи матричного
програмування зазвичай містять свої розвинені математичні бібліотеки, які
значно спрощують постановку та розв’язування прикладних інженерних
завдань [6, 7]. Існують такі функції і в системі програмування Anaconda [26,
70], і вони в значній мірі відповідають функціям системи науково-технічних
розрахунків MatLab. Список деяких із таких функцій наведений у таблиці 6.1.
Зрозуміло, що коди всіх цих функцій також розташовані у модулі numpy.

206
Таблиця 6.1 – Основні математичні функції системи Anaconda,
призначені для роботи з масивами
Функція Призначення
sum() Сума всіх елементів масиву
prod() Добуток всіх елементів масиву
Кумулятивна сума, або накопичення елементів.
Обчислюється як сума всіх елементів масиву, які стоять
cumsum() перед поточним, з урахуванням поточного елементу.
Останній елемент масиву накопичення являє собою суму
всіх елементів початкового масиву, який обробляється
Обчислення різниці між елементами масиву. Результатом
diff() цієї операції є масив, розмір якого є на 1 меншим, ніж
розмір початкового масиву
Максимальне значення серед елементів одновимірного
max()
масиву
Мінімальне значення серед елементів одновимірного
min()
масиву
Індекси максимальних елементів двовимірного масиву за
argmax(0)
стовпчиками, результат операції – одновимірний масив
Індекси максимальних елементів двовимірного масиву за
argmax(1)
рядками, результат операції – одновимірний масив
Індекси мінімальних елементів двовимірного масиву за
argmin(0)
стовпчиками, результат операції – одновимірний масив
Індекси мінімальних елементів двовимірного масиву за
argmin(1)
рядками, результат операції – одновимірний масив
Функція округляє значення масиву раціональних чисел M
M.round(n)
до кількості цифр n
mean() Середнє значення серед елементів одновимірного масиву
Середньоквадратичне значення серед елементів
одновимірного масиву, яке обчислюється за
std() a12 + a22 + K + an2
співвідношенням: S = , де a1, a2, …,
n
an – елементи масиву, n – кількість елементів [6, 7].

207
Слід відзначити, що функції, призначенні для опрацювання
одновимірного масиву, можуть також бути використані для роботи з
двовимірними масивами. У цьому разі рядки двовимірного масиву
розглядаються як окремі структури, а результатом операції є не число, а
одновимірний масив [26, 70]. Слід відзначити, що такий підхід до
опрацювання структурованих масивів даних реалізований також у системі
науково-технічних розрахунків MatLab [6, 7].
Розглянемо приклади використання функцій, призначених для
опрацювання масивів, наведених у таблиці 6.1 [70].
Приклад 6.28
>>> import numpy as np
>>> b = np.array([1, 2, 3], [4, 5, 6])
>>> b.sum()
21
>>> b.prod()
720
>>> b.max()
6
>>> b.mean()
3.5
>>> b.std()
1.7078
>>> a = np.array([1, 2, 3], [4, 5, 6], [7, 8, 9])
>>> a.sum()
45
# Сумування за стовпчиками
>>> c = a.sum(0)
>>> print(c)
[12 15 18]
# Сумування за рядками

208
>>> d = a.sum(1)
>>> print(d)
[6 15 24]
# Мінімальні елементи за рядками
>>> e = a.min(1)
>>> print(e)
[1 4 7]
# Максимальні елементи за стовпчиками
>>> f = a.max(0)
>>> print(f)
[7 8 9]
>>> a1 = np.array([2, –1, 5], [7, 3, –2], [3, 5, 9])
>>> a1.argmin()
5
>>> a1.argmax()
7
# Індекси мінімальних елементів за стовпчиками
>>> g = a1.argmin(0)
>>> print(g)
[0 0 1]
# Індекси мінімальних елементів за рядками
>>> h = a1.argmin(1)
>>> print(h)
[1 2 0]
>>> a2 = np.array([–1, 3, 2, –4, 5])
>>> k = np.cumsum(a2)
>>> print(k)
[–1, 2, 4, 0, 5]
>>> a3 = np.array([1, 3, 8, 25], [3, 4, 5, 6])
>>> l = diff(a3)

209
>>> print(l)
[–1, 2, 4, 0, 5]
[[2 5 17]
[1 1 1]]
>>> a4 = np.array([–3.546, 2.215, –5.149, 4.375])
>>> m = x.round(2)
>>> print(m)
[–3.55 2.22 –5.15, 4.38]
Інші функції бібліотеки numpy для поелементного опрацювання масивів
та приклади їхнього використання наведені у навчальних посібниках [26, 70].

6.1.2.5 Функції для виконання операцій лінійної алгебри


Незважаючи на те, що розглянуті у попередньому підрозділі
поелементні операції над масивами використовуються для розв’язування
прикладних інженерних завдань програмування значно частіше, ніж
спеціальні функції лінійної алгебри та матричного аналізу [42], виконання
операцій лінійної алгебри теж є важливим в інженерній практиці. Серед цих
операцій особливо важливе значення мають функції, які дозволяють
чисельно розв’язувати системи лінійних рівнянь [42]. Саме тому у системі
науково-технічних розрахунків MatLab функції лінійної алгебри та
матричного аналізу реалізовані окремо [6, 7].
В системі програмування Anaconda також існує реалізація функції
лінійної алгебри. Ці функції розташовані в двох бібліотечних модулях:
numpy.linalg та scipy.linalg [26, 70]. Більшість із функцій, які
реалізовані в цих модулях, дублюють одна одну, але зазвичай ефективніше
використовувати функції бібліотеки scipy.linalg. Це насамперед
обумовлено тим, що в них реалізовані більш швидкодійні алгоритми [70].
Крім цього, важливе значення для фахівців в галузі матричного аналізу має
модуль numpy.matlib, де реалізовані функції, які створюють не масиви, а
матриці. Тут слід відзначити, що у системі Anaconda масиви та матриці
розглядаються як різні об’єкти. Головна відмінність полягає у тому, що для
210
матриць матричні операції реалізовані не лише у вигляді методів, але й як
перевантажені арифметичні операції [26, 70]. Всі приклади використання
функцій лінійної алгебри, які будуть розглядатися у цьому підрозділі,
орієнтовані на використання бібліотечного модуля scipy.linalg. Слід
відзначити, що наведений у цьому підрозділі список матричних функцій
лінійної алгебри є досить стислим. Більше інформації про ці функції можна
знайти у навчальних посібниках [26, 70] та на сторінках Інтернет [35 – 38].
Головними функціями лінійної алгебри та матричного аналізу,
реалізованими в системі програмування Anaconda, є наступні.
1. det(M) – функція обчислення визначника матриці M.
2. norm(M) – функція обчислення евклідової норми матриці M [42].
3. inv(M) – функція обчислення матриці, зворотної до матриці M.
4. matmul(M1, M2) та dot(M1, M2) – функції для обчислення
добутку матриць M1 та M2. Ці функції реалізовані безпосередньо у бібліотеці
numpy та відрізняються лише тим, що функція matmul() є більш давньою
реалізацією, яка існувала вже в модулі numpy версії 1.10.
5. solve(M, V) – функція для пошуку вектора розв’язку X системи
лінійних рівнянь M · X = V, де M – квадратна матриця розміру n x n, V –
вектор із розміром n.
Розглянемо приклади використання функцій лінійної алгебри в системі
програмування Anaconda [70].
Приклад 6.29
>>> import numpy as np
>>> import scipy.linalg as la
>>> a = np.array([1, 2], [3, 4])
>>> print (a)
[[1 2]
[3 4]]
>>> b = la.det(a)
>>> print (‘det(a) = ’,b)
211
det(a) = –2
>>> c = la.norm(a)
>>> d = math.sqrt(1**2 + 2**2 + 3**2 + 4**2)
>>> f = (c == d)
>>> print(f)
True
>>> a_inv = la.inv(a)
>>> print(a_inv)
[[–2. 1.]
[1.5 –0.5]]
>>> g = np.matmul(a, a_inv)
>>> print(g)
[[1.00000000e+00 0.00000000e+00]
[8.81178420e–16 1.00000000e+00]]
>>> h = np.round_(np.dot(a, a_inv),10)
>>> print(h)
[[1. 0.]
[0. 1.]]
Тепер розглянемо приклад, у якому функції бібліотеки
scipy.linalg системи програмування Anaconda використовуються для
розв’язування системи лінійних рівнянь [70].
Приклад 6.30 З використанням засобів системи програмування

Anaconda розв’язати систему лінійних рівнянь  2 − 3  ⋅ X =  1  [70].


3 1   7
Відповідний програмний код можна записати наступним чином.
>>> import numpy as np
>>> import scipy.linalg as la
>>> a = np.array([2, –3], [3, 1])
>>> print (a)
[[2 –3]
[3 1]]
212
>>> b = np.array([1, 7])
>>> print (b)
[1 7]
>>> X = la.solve(a, b)
>>> print (X)
[2. 1.]

Тобто, розв’язком системи рівнянь  2 − 3 ⋅ X =  1  є вектор  2  . У


3 1   7  1
наступному прикладі перевіримо отриманий результат через обчислення
зворотної матриці.
Приклад 6.31 Перевірити результат розрахунків, отриманий у
прикладі 6.30, через обчислення зворотної матриці з використанням засобів
системи програмування Anaconda [70].
Відповідний програмний код можна записати наступним чином.
>>> import numpy as np
>>> import scipy.linalg as la
>>> a = np.array([2, –3], [3, 1])
>>> print (a)
[[2 –3]
[3 1]]
>>> b = np.array([1, 7])
>>> print (b)
[1 7]
>>> a_inv = la.inv(a)
>>> X = la.matmul(a_inv, b)
>>> print (X)
[2. 1.]
Тобто, результати, отримані у прикладах 6.30 та 6.31, співпадають.
У системі програмування Anaconda, крім узагальненої функції
solve() реалізовані також інші функції, призначені для розв’язування
систем лінійних рівнянь, які мають певні обчислювальні особливості.
Перевага цих функцій полягає у тому, що обчислення з їх використанням

213
проводяться швидше. Однією з таких функцій є функція solve_banded(),
призначена для роботи із матрицями з переважно діагональними
елементами [26, 70]. Особливості роботи з такими функціями описані у
навчальних посібниках [26, 70].

6.1.3 Графічні можливості системи Anaconda


6.1.3.1 Засоби для побудови двовимірної графіки
Головні засоби системи програмування Anaconda, призначені для
побудови двовимірної наукової графіки, розташовані в бібліотеці
matplotlib [70]. Слід відзначити, що ці графічні засоби і за зовнішнім
виглядом, і за реалізованими можливостями програмування, цілком
відповідають відомим графічним засобам системи науково-технічних
розрахунків MatLab [6, 7]. Розглянемо ці графічні засоби та методи роботи з
ними більш досконало.
Бібліотека matplotlib містить велику кількість модулів, серед яких
головним є модуль matplotlib.pyplot [26, 70]. Підключити цей модуль
можна з використанням наступної стандартної інструкції інтерпретатора
мови програмування Python [70]:
import matplotlib.pyplot as plt
Всі графічні засоби модуля matplotlib.pyplot організовані
ієрархічно, з використанням засобів об’єктно-орієнтованого програмування,
описаних у четвертому розділі. Об’єктом найвищого рівня бібліотеки
matplotlib є рисунок (Figure), на якому розташовані області рисування
(Axes), а також елементи оформлення рисунка, як-то заголовки, легенди,
підписи під осями та інші. Кожний об’єкт двовимірної графіки класу Axes
містить дві координатні осі, а головне призначення цього об’єкту пролягає у
тому, що на нього наносяться інші елементи, як-то графіки, діаграми,
легенди тощо [26, 70].
Створити об’єкт класу Figure можна з використанням наступної
інструкції інтерпретатора мови Python:

214
plt.figure()
Зрозуміло, що коректне виконання цієї інструкції можливе лише за
умови завантаження модуля matplotlib.pyplot під іменем plt.
Відповідна інструкція, яка виконує таке завантаження цього модуля, була
наведена вище.
Після створення рисунка, як екземпляра класу Figure, до нього
можна застосовувати відповідні графічні команди, але за цієї умови він ще не
буде відображений на екрані. Відображення рисунка здійснюється лише
після виконання графічної команди
plt.show()
Інші команди модуля matplotlib.pyplot призначені для
формування об’єктів двовимірної наукової графіки, як-то графік у
декартових координатах, графік у полярних координатах, сходинковий
графік, гістограма тощо [26]. Найбільш використовуваною із цих команд є
команда формування двовимірного графіка plot(), формат та способи
використання якої цілком відповідають функції plot системи науково-
технічних розрахунків MatLab [6, 7]. Для використання функції plot()
системи програмування Anaconda насамперед необхідно сформувати
структуру числових даних, які будуть відображені на графіку. Це можна
зробити з використанням списків або кортежів, але найбільш придатними для
цього є масиви числових даних, розглянуті у підрозділі 6.1.
Для початку домовимось про програмне середовище інтерпретатора
Python, де будуть виконуватись всі подальші приклади. У підрозділі 2.1 було
відмічено, що система програмування Anaconda побудована на основі
інтерпретатора IPython, а також були зроблені посилання на сторінки Інтернет,
де можна знайти безкоштовні інсталяції цієї системи [35, 36].
Зазвичай інсталяційні пакети системи програмування Anaconda містять
програму Spider, яка призначена для виконання графічних програмних додатків,
створених з використанням функцій бібліотеки matplotlib [26, 70].
Інтерфейсне вікно програми Spider показане на рис. 6.1 [70].
215
Рис. 6.1 Інтерфейсне вікно програми Spider

Як видно з рис. 6.1, інтерфейс користувача програми Spider містить


систему меню та три окремих вікна: два консольних, а у третьому вікні
відображується простір імен змінних. Тут можна подивитися значення будь-
якої введеної змінної. Зазвичай для роботи з графічною бібліотекою
matplotlib достатньо лівого вікна, де розташований інтерпретатор IPython.
Для початку роботи з графікою слід ввести в цьому вікні одну з наступних
команд [70]:
%matplotlib include
або
%matplotlib qt
Перша з цих команд призначена для виведення графіків всередині вікна
інтерпретатора IPython, а друга – в окремому графічному вікні. У всіх
подальших прикладах вважається що відповідний режим роботи з графікою в
програмі Spider вже встановлений.
Як видно з рис. 6.1, в інтерпретаторі IPython кожний рядок починається
не з трьох символів «більше» (>>>) , до чого ми вже звикли, працюючи з
інтерпретатором мови Python, а з ключового слова In та номера рядка в
квадратних дужках, наприклад, In [1]: . Тому надалі у цьому підрозділі ми
будемо дотримуватись саме такого стилю оформлення програмного коду.

216
Тепер розглянемо прості приклади використання команди plot()[70].
Приклад 6.32 З використанням засобів системи програмування
Anaconda побудувати графічну залежність для набору точок з координатами
[(1, 1), (3, 2), (2, 3), (4, 4)] [70].
Відповідний програмний код можна записати наступним чином [70].
In[1]: import matplotlib.pyplot as plt
In[2]: plt.plot([1, 3, 2, 4])
In[3]: plt.show()
В результаті виконання цього набору команд отримуємо графік, який
наведений на рис. 6.2, а.
Приклад 6.33 З використанням засобів системи програмування
Anaconda побудувати графік функції y(n) = sin(n) для натуральних значень
числа n від 0 до 16.
Відповідний програмний код можна записати наступним чином [70].
In [1]: import matplotlib.pyplot as plt
In [2]: from math import sin
In [3]: x = range(16)
In [4]: y = [sin(t) for t in x]
In [5]: plt.plot(list(x), y)
In [6]: plt.show()
В результаті виконання наведеного у цьому прикладі набору команд
отримуємо графік, який зображений на рис. 6.2, б.

а) б) в)
Рис. 6.2 Результати роботи функції plot() бібліотеки
matplotlib.pyplot системи програмування Anaconda для
прикладів 6.32, 6.33 та 6.34 [70]

Зрозуміло, що графік, наведений на рис. 6.2, б, не зовсім правильно

217
відображує поведінку функції y(x) = sin(x), оскільки він є результатом
лінійної інтерполяції цієї функції лише для дискретного набору значень
натуральних чисел. Але якщо збільшити кількість відлікових точок,
побудована ламана лінія майже не буде відрізнятися від гладкої кривої, яка
описує цю функцію. Розглянемо відповідний приклад.
Приклад 6.34 З використанням засобів системи програмування
Anaconda побудувати графіки функції y(x) = sin(x) та y(x) = cos(x) для 200
відлікових значень, заданих на інтервалі [–4, 4]. Для розв’язування цього
завдання використовувати структури числових даних, створені як масиви.
Відповідний програмний код можна записати наступним чином [70].
In [1]: import matplotlib.pyplot as plt
In [2]: import numpy as np
In [3]: X = np.linspace(–4, 4, 200)
In [4]: C,S = np.cos(X), np.sin(X)
In [5]: plt.plot(X, C)
In [6]: plt.show()
Результат роботи наведених у цьому прикладі команд системи
програмування Anaconda показаний на рис. 6.2, в.
Розглянемо більш досконало панель керування, яка розташована у
нижній частині графічного вікна. Іконки цієї панелі призначені для
подальшого опрацювання графіків із зміною їхнього зовнішнього вигляду.
Вигляд цієї панелі керування у збільшеному масштабі показаний на рис. 6.3.

Рис. 6.3 Іконки панелі керування для налаштування властивостей графіка,


сформованого з використанням засобів програмування бібліотеки matplotlib

218
Розглянемо послідовно призначення всіх іконок панелі керування,
показаної на рис. 6.3, починаючи з лівої та закінчуючи правою [70].
1. Перша іконка, на який намальований будинок, повертає графік, який
редагується, до початкового вигляду, яким він був безпосередньо після
відкриття графічного вікна.
2. Друга та третя іконка за стрілочками дозволяють передивлятися різні
модифікації графіка в процесі роботи над ним. Перша з цих іконок, зі
стрілочкою назад, відповідає переходу до попередньої версії графіка, а друга,
зі стрілочкою вперед – до наступної. Тобто, ці іконки відповідають
стандартним діям для систем програмування з графічним інтерфейсом:
«Відмінити операцію» – «Повторити операцію», або «Undo» – «Redo».
3. Четверта іконка, на який зображений хрестик, має подвійне
призначення. У разі натиснення на цю іконку вона зберігає свій активний
стан до події повторного натиснення, тобто, працює як перемикач. За умови,
що ця іконка є активною, можна змінювати стан графіка з використанням
миші. Якщо зробити цю іконку активною та натиснути ліву кнопку миші,
можна переміщувати графік у межах вікна. Якщо, за умови активності цієї
іконки, натиснути ліву кнопку миші, можна змінювати масштаб
зображення [70].
4. П’ята іконка, на якій зображені олівець та підписаний конверт,
призначена для збільшення та зменшення ручним способом розмірів
графічного вікна.
5. Шоста іконка, на якій зображений графік зі стрілками, призначена
для відкриття діалогового вікна, в якому можна ручним способом
налаштувати властивості графіка.
6. Сьома іконка, на якій зображений комп’ютерний диск, відкриває
інше діалогове вікно. З використанням елементів інтерфейсу цього вікна
можна зберігати отриманий графік до файлу, в якому буде міститися
відповідна графічна інформація.
Коли вікно із побудованим графіком є активним, замість описаних

219
вище іконок інтерфейсного меню можна використовувати наступні гарячі
клавіші [70].
h – повернення до початкового вигляду графіка, відповідає натиснення
першої іконки (перша літера англійського слова home – будинок).
c – відмінити операцію, відповідає натисненню на другу іконку.
v – повторити операцію, відповідає натисненню на третю іконку.
x – зміна масштабу графіка за повздовжньою координатою.
y – зміна масштабу графіка за поперечною координатою.
g – відображення координатної сітки на графіку (перша літера
англійського слова grid – сітка).
Для розглянутої функції plot() обов’язковими є два параметри, а
саме, набори числових значень, які відображаються за абсцисою та за
ординатою. Інші параметри цієї функції визначають властивості графіка, ці
прараметри під час його побудови задавати не обов’язково. Змінити
властивості графіка можна з використанням описаних вище іконок панелі
керування [70].
Проте розглянемо можливості використання функції plot() у
розширеному форматі із визначенням властивостей графіка. У загальному
випадку ця графічна команда має наступний вигляд [70].
plot(масив_значень_для_координати_х, \
масив_значень_для_координати_y, \
колір_лінії, стиль_лінії, товщина_лінії, \
стиль_маркера)
Колір лінії кодується через початкову літеру англійського слова, яке
визначає цей колір. Єдиною відмінністю є код чорного кольору k, який
відповідаю останній літері англійського слова blacK – чорний. Це пов’язано
лише з тим, що перша літера B в англійських назвах синього кольору (Blue) та
чорного (Black) є однаковою. Відповідний спосіб кодування кольорів, який
використовується в системі програмування Anaconda, проілюстрований у
таблиці 6.2. Спосіб кодування типу лінії в системі програмування Anaconda
описаний у таблиці 6.3, а спосіб кодування типу маркера – у таблиці 6.4.

220
Таблиця 6.2 – Спосіб кодування кольорів в системі програмування Anaconda

Українська
Жовтий Бузковий Блакитний Червоний
назва
Колір
Англійська
Yellow Magenta Cyan Red
назва
Код кольору y m c r
Українська
Зелений Синій Білий Чорний
назва
Колір
Англійська
Green Blue White blacK
назва
Код кольору g b w k

Таблиця 6.3 – Спосіб кодування типу лінії в системі програмування Anaconda

Тип лінії Суцільна Розривна Пунктирна Штрихпунктирна


Вигляд
лінії
-. (мінус та
Код - (мінус) -- (два знаки мінус) : (двокрапка)
крапка)

Таблиця 6.4 – Спосіб кодування типу маркера в системі програмування Anaconda

Тип маркера:
українською П’яти- Шести-
Квадрат Коло Ромб / Хрест Зірка Плюс
мовою / кутник / кутник /
/ Square / Oval Diamond / Cross / Star / Plus
англійською Pentagon Hexagon
мовою
Вигляд
маркера
x +
Код s o d p h x * +

221
Крім цього, можна задати товщину лінії в пунктах через параметр
linewidth, розмір маркера з пунктах через параметр markersize та колір
маркера через параметр markerfacecololr. Спосіб визначення кольору
маркера аналогічний способу визначення кольору лінії та відповідає системі
кодування кольорів, наведеній у таблиці 6.2. Наприклад, запис
markerfacecololr = ‘k’ означає обрання чорного кольору маркера.
Слід відзначити, що точно такі способи кодування кольорів, стилю лінії
та стилю маркера застосовується у графічних засобах системі науково-
технічних розрахунків MatLab [6, 7].
Розглянемо приклади використання графічної команди plot() із
параметрами, які визначають колір, товщину лінії та стиль маркера [70].
Приклад 6.35 З використанням засобів системи програмування
( )
Anaconda побудувати графіки функції y ( x ) = x 2 exp − x 2 в діапазоні значень
x [–3, 3] із кількістю відлікових точок 51 з використанням наступних стилів.
1. Стиль лінії – суцільна, товщина лінії – 3 пункти, розмір маркера – 10
пунктів, стиль маркера – коло.
2. Без лінії, розмір маркера – 20 пунктів, стиль маркера – шестикутник.
3. Без маркера, стиль лінії – пунктирна, товщина лінії – 3 пункти, колір
лінії – червоний.
Розв’язати поставлену задача можна з використанням наступного
програмного коду [70].
In [1]: import matplotlib.pyplot as plt
In [2]: import numpy as np
In [3]: x = np.linspace(–3, 3, 51)
In [4]: y = x**2*np.exp(-x**2)
In [5]: plt.plot(x, y, ‘–ko’, linewidth = 3,\
markersize = 10)
In [6]: plt.show()
In [7]: plt.plot(x, y, ‘–wh’, \
markersize = 20, markerfacecololr = ‘b’)
In [8]: plt.show()
222
In [9]: plt.plot(x, y, ‘–-r’, linewidth = 3)
In [10]: plt.show()
Результати роботи наведених вище командних рядків представлені на
рис. 6.4 [70].

а) б) в)

( )
Рис. 6.4 Графіки функції y ( x ) = x 2 exp − x 2 , побудовані з використанням різних
стилів подання: а) суцільна лінія товщиною 3 пункти, розмір маркера – 10 пунктів,
стиль маркера – коло; б) без лінії, розмір маркера –20 пунктів, стиль маркера –
шестикутник; в) пунктирна лінія без маркера, товщина лінії – 3 пункти

За допомогою команди plot() можна розміщувати декілька графіків


на одній координатній площині. Відповідний формат цієї команди має
наступний вигляд.
plot(перший_масив_значень_для_координати_х, \
перший_масив_значень_для_координати_y, \
колір_лінії, стиль_лінії, товщина_лінії, \
стиль_маркера, \
другий_масив_значень_для_координати_х, \
другий_масив_значень_для_координати_y, \
колір_лінії, стиль_лінії, товщина_лінії, \
стиль_маркера, \
........................................
останній_масив_значень_для_координати_х, \
останній_масив_значень_для_координати_y, \
колір_лінії, стиль_лінії, товщина_лінії, \
стиль_маркера)

223
Розглянемо приклад, у якому два графіка побудовані на одній
координатній площині [70].
Приклад 6.36 З використанням засобів системи програмування Anaconda
( ) ( )
побудувати графіки функцій y1 ( x ) = x exp − x 2 та y2 ( x ) = x 2 exp − x 2 на одній
координатній площині в діапазоні значень x [–3, 3] із кількістю відлікових точок 51.
Відповідні командні рядки можна записати наступним чином.
In [1]: import matplotlib.pyplot as plt
In [2]: import numpy as np
In [3]: x = np.linspace(–3, 3, 51)
In [4]: y1 = x*np.exp(-x**2)
In [5]: y2 = x**2*np.exp(-x**2)
In [6]: plt.plot(x, y2, ‘–k’, x, y1, ‘b-–’,
linewidth = 4)
In [7]: plt.show()
Результати роботи цих командних рядків показані на рис. 6.5.

( ) ( )
Рис. 6.5 Графіки функцій y1 ( x ) = x exp − x 2 та y2 ( x ) = x 2 exp − x 2 , побудовані на
одній координатній площині [70]

Розглянемо деякі додаткові можливості, які стосуються оформлення


графіків в системі програмування Anaconda [70]. Для цього насамперед

224
розглянемо функції, які дають можливість виводити на графіках текстову
інформацію. Це можуть бути заголовки, підписи на осях, анотації тощо.
Функція text() виводить в область графіка Axes будь-яку текстову
інформацію. Формат запису цієї функції є наступним [70].
text(x, y, текстова_інформація)
Положення текстової інформації на площині графіка Axes
визначається заданими у команді координатами x, y, враховуючи те, що
початку координат (0, 0) відповідає лівий нижній кут.
Важливим є формування посилання на об’єкт Axes, який
опрацьовується. Таке посилання легко отримати, використовуючи оператор
присвоєння ax = fig.gca(), де fig – посилання на батьківський об’єкт,
якому відповідає рисунок, а назва методу gca() відповідає абревіатурі
англійського словосполучення Get Current Axes – взяти поточні
координатні осі [70]. Важливими є також властивості тексту, які
визначаються з використанням наступних атрибутів. Атрибут
fontsize = n визначає розмір шрифту n, а атрибути
horizontalallignment та verticalallignment – горизонтальне та
вертикальне розташування тексту відносно координати базової точки
(x, y) [70].
Окрему проблему являє собою запис у тексті математичних формул,
які, для виведення на графік, повинні бути закодовані в форматі текстового
редактора ТЕХ [70]. Проте в системі програмування Anaconda ситуація
значно спрощується тим, що існує простий та ефективний спосіб
програмування математичної формули, записаної з використанням засобів
програмування мови Python, в код редактора ТЕХ. Для цього
використовується функція latex(), яка розташована у бібліотеці sympy.
Ця бібліотека призначена для проведення символьних обчислень з
використанням інтерпретатора мови IPython та головні її функції будуть
розглянуті у підрозділі 6.1.4. Функція latex() має наступний формат.
latex(S(‘математичний_вираз’, evaluate = False))

225
В результаті роботи цієї функції математичний вираз, записаний з
використанням засобів програмування мови Python, автоматично кодується в
форматі текстового редактора ТЕХ. Розглянемо приклади використання
функції latex() [70].
Приклад 6.37
In [1]: from sympy import latex, S
In [2]: c = latex(S(‘2*4 + 10’, evaluate = False))
In [3]: c
‘2 \\cdot 4 + 10’
In [4]: d = latex(S(‘exp(x*2)/2’, evaluate = False))
In [5]: d
‘\\frac{e^{2 x}} {2}’
Тобто, головна ідея використання функції latex() полягає у тому, що
код математичного виразу, записаний з використанням засобів
програмування мови Python, перекодується в рядок, який відповідає коду
цього виразу в текстовому редакторі ТЕХ, а сформований рядок після цього
може бути використаний для формування підписів на графіках.
Іншою важливою проблемою є те, що, на відміну від інтерпретатора
мови Python, бібліотека matplotlib за замовченням використовує шрифти,
які не підтримують символів кирилиці [70]. Серед шрифтів операційної
системи Windows, які використовують спосіб кодування UNICODE та
підтримують кирилицю, найбільш популярними є ‘Arial’, ‘Times New
Roman’, ‘Tahoma’ та ‘Courier New’. Тобто, для коректної роботи з текстами
необхідно підключити ці шрифти. Це можна зробити з використанням набору
команд, наведених у наступному прикладі [70].
Приклад 6.38
# -*- coding utf-8 -*-
In [1]: import matplotlib as mpl
In [2]: mpl.rcParams[‘font.family’] = ‘fantasy’
226
In [3]: mpl.rcParams[‘font.fantasy’] = ‘Arial’, \
‘Times New Roman’, ‘Tahoma’, ‘Courier New’
У наведеному прикладі перший рядок свідчить про те, що для текстової
інформації, яка виводиться, слід використовувати символи кирилиці. Після
цього створений набор шрифтів fantasy, який стає для бібліотеки
matplotlib головним, а до цього набору підключені відповідні шрифти. В
результаті виконання такого набору команд система Anaconda спочатку буде
намагатися використати шрифт, який іде у переліку першим, за умови його
відсутності буде використаний другий шрифт і так далі [70].
Розглянемо головні функції бібліотеки matplotlib, які дозволяють
змінювати вигляд графіків, а також відповідні лінгвістичні конструкції для
виклику цих функцій [70].
1. Функція matplotlib.pyplot.annote() дозволяє формувати у
полі графічного вікна примітки, які складаються з текстового повідомлення
та стрілки-вказівника. У загальному випадку ця функція має наступний
формат виклику [70].
annote(текст, (xa, ya), (xt, yt), shrink = r),
де
(xa, ya) – координати точки на графіку, на яку формується вказівник;
(xt, yt) – координати розташування текстового рядка;
shrink = r – параметр r визначає положення кінця стрілки відносно
тексту. Зазвичай обирається значення shrink = 0.5 [70].
2. Функції xlabel та ylabel використовуються для формування
підписів під віссю x та віссю y відповідно. Узагальнений формат виклику
цих функцій має наступний вигляд.
xlabel(‘текст’, [fontsize = ‘small’, \
verticalallignment = ‘top’ \
horizontalallignment = ‘center’ ])

227
У наведеному зразку командного рядка параметр fontsize визначає
розмір шрифту для підпису, а параметри horizontalallignment та
verticalallignment – горизонтальне або вертикальне розташування
тексту.
3. Функція matplotlib.pyplot.grid() використовується для
виведення сітки на площину графіка. За замовченням для формування сітки
використовуються базові відлікові точки графіка. Як видно з рис. 6.4 та 6.5, у
системі програмування Anaconda координатна сітка за замовченням не
формується. Для ввімкнення опції її формування слід подати команду
matplotlib.pyplot.grid(True)
Розглянемо приклад побудови графіка із використанням різних
функцій бібліотеки matplotlib для його оформлення [70].
Приклад 6.39
In [1]: # -*- coding utf-8 -*-
In [2]: % matplotlib qt
In [3]: import numpy as np
In [4]: import matplotlib as mpl
In [5]: import matplotlib.pyplot as plt
In [6]: from sympy import latex, S
In [7]: mpl.rcParams[‘font.family’] = ‘fantasy’
In [8]: mpl.rcParams[‘font.fantasy’] = ‘Arial’, \
‘Times New Roman’, ‘Tahoma’, ‘Courier New’
In [9]: str_math = ‘1./(sigma*sqrt(2*pi))*\
exp(-(x-mu)**2/(2*sigma**2)’
In [10]: out_m = latex(S(str_math, evaluate = False))
In [11]: out_math = ‘r$’ + out_m + ‘$’
In [12]: x = np.linspace(5, –5, 40)
In [13]: sigma = 1

228
In [14]: mu = 1
In [15]: y = 1./(sigma*np.sqrt(2*np.pi))*\
np.exp(-(x-mu)**2/(2*sigma**2)
In [16]: fig = plt.figure(facecolor = ‘white’, \
num = ‘Приклад оформлення гарфіка’)
In [17]: plt.plot(x, y, ‘-bo’, linewidth = 3, \
markersize = 10, label = out_math)
In [18]: plt.legend(fontsize = 18, \
loc = ‘upper left’)
In [19]: ax = fig.gca()
In [20]: plt.title(r‘$\mu = 1,\\sigma = 1$’)
In [21]: plt.text(0.58, .95, r‘$\varphi(x)$’, \
verticalallignment = ‘left’ \
horizontalallignment = ‘center’, \
transform = ax.transaxes, fontsize = 16)
In [22]: annote(‘Максимум’, xy = (1, 0.4), \
xytext = (–2, 0.25), arowprops = \
dict(facecolor = ‘green’, shrink = 0.05)
In [23]: plt.text(–0.9, 0.15, ‘Графік кривої’, \
rotation = 70, \
verticalallignment = ‘center’ \
horizontalallignment = ‘center’)
In [24]: plt.text(2.5, 0.3, out_math, fontsize = 24, \
bbox = dict(edgecolor = ‘w’, color = ‘cyan’), \
color = ‘black’)
In [25]: plt.xlabel(u‘X – вісь абсцис’, {‘fontname:\
Times New Roman’})
In [26]: plt.ylabel(r ‘$vapphi(x)$’ - ордината)
In [27]: plt.grid(True)
In [28]: plt.show()
229
Результат роботи програмного коду, наведеного у прикладі 6.39,
показаний на рис. 6.6.

Рис. 6.6 Результат роботи програмного коду, наведеного у прикладі 6.39

Крім розглянутих вище графіків в декартових координатах, засоби


програмування системи Anaconda дозволяють також будувати графіки в
полярних координатах та лінії однакового рівня. Ці графічні засоби є також
вкрай важливими для оформлення наукової документації [6, 7]. Розглянемо
відповідні програмні засоби системи Anaconda, призначені для отримання
таких графічних залежностей [26, 70].
Функція для побудови графіків у полярних координатах polar()
також розташована у бібліотеці matplotlib.pyplot та має досить
простий формат запису:
polar(кут, радіус)
де параметр кут відповідає масиву значень для кутів обертання точки, а
другий параметр радіус – масиву значень для радіусів, які відповідають
230
цим кутам [70].
Розглянемо деякі приклади, пов’язані з використанням функції
polar()[70].
Приклад 6.40
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: t = np.linspace(0, 4*np.pi, 100)
In[4]: plt.polar(t, t, linewidth = 4, color = ‘green’)
In[5]: plt.show()
In[6]: t2 = np.linspace(0, 2*np.pi, 100)
In[7]: r = [1 for a in t]
In[8]: plt.polar(t, r, linewidth = 4, color = ‘red’)
In[9]: plt.show()
In[10]: plt.polar(t, 2*np.cos(t), linewidth = 4, \
color = ‘red’)
In[11]: plt.show()
Результат роботи цих командних рядків показаний на рис. 6.7, а – в.

а) б) в)
Рис. 6.7 Графіки функцій y(t) = t (а), y(t) = 1 (б) та y(t) = 2cos(t) (в), побудовані
в полярних координатах з використанням функції polar(), розташованої в
бібліотеці matplotlib.pyplot системи програмування Anaconda [70]

Контурні графіки, які відображують лінії рівного рівня для


тривимірних поверхонь, у системі програмування Anaconda можна

231
побудувати з використанням функцій contour() та contourf(). Слід
відзначити, що оскільки контурні графіки будуються для функції від двох
аргументів та значення цих аргументів повторюються, для коректного
формування масивів даних у даному випадку слід використовувати функцію
meshgrid() модуля numpy, яка була розглянута у підрозділі 6.1.2.2.
Аналогічний спосіб розрахунку значень функцій від двох аргументів
реалізований у системі науково-технічних розрахунків MatLab [6, 7].
Аргументами функцій contour() та contourf() є двовимірні масиви
числових значень, сформовані з використанням функції meshgrid() із
одновимірних масивів, в яких задані діапазони значень для кожної змінної.
Єдина різниця між роботою функцій contour() та contourf()полягає у
тому, що функція contour() будує лінії рівного рівня для визначених
тривимірних поверхонь, а функція contourf() відображує залиті
відповідним кольором області між лініями рівного рівня [70].
Слід відзначити, що оскільки лінії рівного рівня зображені на
двовимірній площині та координати кожної точки такої лінії можна легко
обчислити, контурні графіки є дуже інформативними та використовуються
для оформлення результатів наукових досліджень частіше, ніж тривимірні
графіки поверхонь, які розглядатимуться у підрозділі 6.2.3.2. Наприклад, з
використанням контурних графіків описується розподіл електричних та
магнітних полів в аксіально-симетричних електродних системах [6, 7].
Розглянемо приклади побудови контурних графіків з використанням
функцій contour() та contourf() [70].
Приклад 6.41 З використанням засобів програмування системи
Anaconda побудувати лінії рівного рівня та залиті області між цими лініями
для функції f(x, y) = x4 – 2x2 + y4 – 2y2 + 1 в діапазонах значень змінних x та y
[–2, 2] із кількістю відлікових точок за кожною координатою 101.
Відповідний програмний код можна записати наступним чином [70].
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: def f(x, y):
232
return x**4 – 2*x**2 + y**4 – 2*y**2 + 1
In[4]: n = 101
In[5]: x = np.linspace(–2, 2, n)
In[6]: X, Y = np.meshgrid(x)
In[8]: Z = f(X, Y)
In[9]: fig1 = plt.figure(facecolor = ‘white’)
In[10]: fig1.contour(X, Y, Z, 40)
In[11]: fig1.show()
In[12]: fig2 = plt.figure(facecolor = ‘white’)
In[13]: fig2.contourf(X, Y, Z, 40)
In[14]: fig2.show()
У розглянутому прикладі параметр 40 вказує кількість ліній рівня на
графіках.
Результати роботи командних рядків, наведених у прикладі 6.41,
представлені на рис. 6.8.

а) б)
Рис. 6.8 Лінії рівного рівня (а) та зафарбовані області (б) для тривимірної
поверхні, заданої поліноміальним рівнянням f(x, y) = x4 – 2x2 + y4 – 2y2 + 1,
побудовані з використанням функцій contour() та contourf()
бібліотеки matplotlib.pyplot системи програмування Anaconda [70]

Задати палітру для відображення контурного графіка можна з


використанням атрибуту cmap методу contourf(). Можливими
233
значеннями цього атрибуту є наступні [26].
– jet – занадто високоякісна рівномірна карта кольорів, яка
використовувалась за замовченням у системі Anaconda до версії 2.0. Але
суттєвий недолік високоякісного подання кольорів полягає у тому, що
зазвичай вони некоректно відображують плавну зміну числових даних,
даючи нерівномірну яскравість вздовж шкали.
– virdis – нерівномірна карта кольорів, яка використовується за
замовченням у системі Anaconda, починаючи з версії 2.0. Зазвичай плавну
зміну числових даних нерівномірні карти кольорів відображують більш
коректно, ніж рівномірні.
– cubehelix – веселкова кольорова гама.
– RdBu – гама з темних та світлих відтінків двох кольорів, червоного та
блакитного, призначена для відображення зміни числових значень різного
діапазону, наприклад, додатних та від’ємних значень.
– gray – відтінки сірого кольору для чорно-білого друку.
Розглянемо приклад використання методу contourf() для
розв’язування важливого фізичного завдання, пов’язаного із формуванням
дифракційної картини Фраунгофера від точкового джерела світла [6, 7].
Приклад 6.42 Побудувати модель яскравості для точкового джерела
світла у разі розташування на шляху променя отвору малого розміру.
Вважати, що інтенсивність світла I(x, y) у координатній площині (x, y), після
проходження світловим променем отвору малого діаметра, згідно із моделлю
Фраунгофера, описується наступним співвідношенням [6, 7, 50]:

I ( x, y ) =
(sin( x ))2 (sin( y ))2
. (6.2)
x2 y2
Відповідний програмний код, у яком реалізовані розрахунки за
формулою (6.2) та побудова контурного графіка, можна записати наступним
чином.
In[1]: import numpy as np

234
In[2]: import matplotlib.pyplot as plt
In[3]: x = np.linspace(–2, 2, 1000)
In[4]: X, Y = np.meshgrid(x, x)
In[6]: Z = ((np.sin(X))**2/(X**2)*\
(np.sin(Y))**2/(Y**2))
In[7]: fig1 = plt.figure(facecolor = ‘white’)
In[8]: fig1.contour(X, Y, Z, 75, cmap = ‘gray’)
In[9]: fig1.show()
Результат роботи командних рядків, наведених у прикладі 6.42,
представлений на рис. 6.9.

Рис. 6.9 Результат моделювання дифракції Фрагунгофера, отриманий з


використанням командних рядків, наведених у прикладі 6.42

Іншою можливістю отримання контурного графіка є використання


функції imshow() бібліотеки matplotlib. Головна особливість
відображення контурних графіків з використанням цієї функції полягає у
тому, що початок координат за замовченням розташований у правому куті, а
осі координат спрямовані праворуч та донизу [70]. Щоб повернути графік та
придати йому звичайний вигляд, можна використати функцію flipud()
бібліотеки numpy [70].

235
Розглянемо відповідний приклад.
Приклад 6.43 З використанням засобів програмування системи
Anaconda побудувати контурний графік функції
 x
 4

( )(
f ( x ) = 1 − + x3 + y 3  exp − x 2 − y 2 x 2 − y − x

)
в діапазоні значень змінних x та y [–3, 3].
Відповідний програмний код можна записати наступним чином.
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: def f(x, y):
return (1 – x/4 + x**3 + y**3)*\
np.exp(- x**2 - y**2)*(x**2 – y - x)
In[4]: x = np.linspace(–3, 3, 121)
In[5]: Z = f(x, y)
In[6]: fig1 = plt.figure()
In[7]: plt.imshow(Z)
In[8]: fig1.gcf().set_facecolor(‘w’)
In[9]: fig1.gcf().gca().axis(image)
In[10]: fig1.axis(‘off’)
In[11]: fig1.show()
In[12]: fig2 = plt.figure()
In[13]: img = plt.imshow(np.flipud(Z))
In[14]: fig2.gcf().set_facecolor(‘w’)
In[15]: fig2.gcf().gca().axis(image)
In[16]: fig2.axis(‘off’)
In[17]: fig2.show()
In[18]: fig3 = plt.figure()
In[19]: img2 = plt.imshow(np.flipud(Z))
In[20]: fig3.gcf().set_facecolor(‘w’)
In[21]: fig3.gcf().gca().axis(image)
236
In[22]: fig3.axis(‘off’)
In[23]: fig3.gray()
In[24]: fig3.show()

Результати роботи програмного коду, наведеного у прикладі 6.43,


показані на рис. 6.10. Для графіків, наведених на рис. 6.10, а, б, за
замовченням використана палітра jet, а для графіка, наведеного на

рис. 6.10, в, примусово встановлена палітра gray. Видно, що палітра gray

більш чітко відображує плавну зміну значень функції f(x). Крім цього,
палітра gray більше пристосована для чорно-білого друку науково-технічної

документації.
Зрозуміло також, що для пригашення відображення координатних осей
на контурних графіках використаний відповідний набор команд [70].
fig2.gcf().gca().axis(image)
fig2.axis(‘off’)

а) б) в)
Рис. 6.10 Результати роботи командних рядків, наведених у прикладі 6.43,
для розташування початок координат контурного графіка у лівому верхньому
куті полотна (а) та у лівому нижньому куті (б, в) [70]

Іншим важливим завданням, пов’язаним із оформленням науково-

237
технічної документації, є суміщення кількох графіків із координатними
осями в межах одного рисунку з метою можливості порівняння отриманих
результатів [6, 7]. У системі програмування Anaconda існує два можливих
способи для такого оформлення графіків [26, 70].
1. Формування в межах створеного полотна кількох координатних
осей, масштаби на яких можуть бути однаковими або різними.
2. Автоматичне розділення полотна, на яке виносяться графіки, на
окремі пропорціональні частини з метою подальшого розташування
координатних осей на різних сформованих частинах розбитого полотна.
Розглянемо окремо програмні засоби, призначені для реалізації
першого та другого із наведених способів.
Якщо з використанням команди plt.figure() сформоване полотно
для виведення графіка, сформувати додаткову систему координат на цьому
полотні можна з використанням графічної команди add_axes() [26].
Формат цієї команди має наступний вигляд.
ім’я_полотна.add_axes([координати_розташування_та_
розмір_рисунка: x, y, ширина, висота], \
числові_границі_за_віссю_ординат)
де ім’я_полотна – посилання на полотно, де формується система
координат, x, y – координата нижнього лівого кута системи координат
відносно нижнього лівого кута сформованого полотна, ширина та
висота – ширина та висота системи координат відносно ширини та висоти
полотна. Всі чотири розміри вказуються у відносних одиницях. Наприклад,
запис [0.1, 0.5, 0.8, 0.4] означає, що система координат буде розташована з
відступами 0,1 за горизонтальним напрямком та 0,5 за вертикальним
відносно нижнього лівого кута полотна, де формується рисунок, а розміри
системи координат складають 0.8 від ширини та 0.4 від висоти цього
полотна. Як окремий параметр можуть бути вказані числові границі за віссю
ординат, але цей параметр може бути опущений, у цьому разі він
визначається системою автоматично.
238
Розглянемо приклад використання команди add_axes().
Приклад 6.44 З використанням засобів програмування системи
Anaconda побудувати графіки тригонометричних функцій y(x) = sin(x) та
y(x) = cos(x) на одному полотні в різних системах координат, для яких
масштаб за віссю абсцис є однаковим.
Відповідний програмний код можна записати наступним чином [26].
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: fig = plt.figure()
In[4]: ax1 = fig.add_axes([0.1, 0.5, 0.8, 0.4], \
xticklabels = [], ylim = (–1.2, 1.2))
In[5]: ax2 = fig.add_axes([0.1, 0.1, 0.8, 0.4], \
ylim = (–1.2, 1.2))
In[6]: x = np.linspace(0, 10)
In[7]: ax1.plot(np.sin(x))
In[8]: ax2.plot(np.cos(x))
Результат роботи командних рядків, які наведені у прикладі 6.44,
показаний на рис. 6.11.

Рис. 6.11 Графіки функцій y(x) = sin(x) та y(x) = cos(x) для прикладу 6.44

Згідно із параметрами команд fig.add_axes(), графіки розташовані


один під одним та мають однаковий масштаб, тому на верхньому графіку вісь
239
абсцис не підписана. Опції відсутності підпису на осі графіка відповідає
параметр xticklabels = [] команди fig.add_axes() [26].
Для розбиття області полотна на окремі підобласті однакового або різного
розміру, розташованими із заданою періодичністю в форматі таблиці, у системі
програмування Anaconda використовується команда subplot() [26, 70].
Формат цієї команди має наступний вигляд.
subplot(n, k, i)
де n – кількість рядків, у яких розташовуються підобласті, k – кількість
стовпчиків, i – порядковий номер елементу. Нумерація елементів у даному
випадку проводиться наскрізно, спочатку за стовпчиками, а потім за рядками.
Тобто, у разі, якщо стовпчик закінчений, здійснюється перехід на інший
рядок.
Слід відзначити, що команда subplot з аналогічними параметрами
існує також серед графічних засобів системи науково-технічних розрахунків
MastLab [6, 7].
Розглянемо приклад формування підобластей.
Приклад 6.45
In[1]: import matplotlib.pyplot as plt
In[2]: fig = plt.figure()
In[3]: for i in range (1, 7)
fig.subplot(2, 3, i)
plt.text(0.5, 0.5, str(2, 3, i), \
fohtsize = 18, \
horizontalallignment = ‘center’)
Результат роботи командних рядків, наведених у прикладі 6.45,
показаний на рис. 6.12, а.
Для налаштування розмірів полів між підобластями у системі
програмування Anaconda використовується команда
plt.subplot_adjust()

240
Формат цієї команди має наступний вигляд.
plt.subplot_adjust(hspace = a, wspace = b)

де a та b – поля за горизонтальною та вертикальною координатою у

відносних одиницях відносно площини підобластей. Наприклад, у разі


використання команди
fig.subplot_adjust(hspace = 0.4, wspace = 0.4)

підобласті, сформовані у прикладі 6.45 розташовуються дещо інакше [26].


Результат роботи відповідної послідовності командних рядків представлений
на рис. 6.12, б.

а) б)
Рис. 6.12 Розбиття області розташування графіків на підобласті за
замовченням (а) та із визначенням параметрів ширини та довжини
підобластей для вирівнювання полів (б)

Як було сказано вище, у цьому посібнику розглядаються лише головні


можливості системи програмування Anaconda. Більше інформації щодо
графічних засобів бібліотеки matplotlib, призначених для побудови та

налаштування властивостей двовимірних графіків, можна знайти у


навчальних посібниках [26, 70]. У наступному підрозділі будуть розглянуті
графічні засоби для побудови тривимірних графіків.

241
6.1.3.2 Засоби для побудови тривимірної графіки
Для побудови тривимірних графіків у системі програмування Anaconda
частіше за все використовуються функції бібліотеки, розташованої у
програмному модулі mpl_toolkits.mplot3d [26, 70]. Розглянемо у
цьому підрозділі деякі функції цієї бібліотеки, які найбільш часто
використовуються на практиці для оформлення науково-технічної
документації. Слід відзначити, що базовий набір функцій тривимірної
графіки системи програмування Anaconda, як і набір функцій двовимірної
графіки, схожий на відповідний набір функцій системи науково-технічних
розрахунків MatLab [6, 7].
У зв’язку з тим, що більшість функцій тривимірної графіки
розташовані в бібліотеці mpl_toolkits.mplot3d, зазвичай першими
рядками програм, призначених для побудови тривимірної графіки, є
послідовність рядків, які наведені у наступному прикладі [70].
Приклад 6.46
In[1]: %matplotlab qt
In[2]: import numpy as np
In[3]: import matplotlib as mpl
In[4]: import matplotlib.pyplot as plt
In[5]: from mpl_toolkits.mplot3d import Axes3D
Узагальнений список головних функцій тривимірної графіки системи
програмування з Anaconda наведений у таблиці 6.4.

Таблиця 6.4 – Головні функції системи програмування з Anaconda,


призначені для побудови тривимірних графіків та поверхонь
Функція Призначення
Axes3D() Формування тривимірної системи координат
plot(x, y, z) Функція для побудови тривимірної кривої лінії
plot_surface(x, y, z) Функція для побудови зафарбованої тривимірної
поверхні
plot_wireframe(x, y, z) Функція для побудови каркасної тривимірної
поверхні

242
Розглянемо приклади використання функцій тривимірної графіки, які
наведені у таблиці 6.4.
Приклад 6.47 З використанням засобів програмування системи
Anaconda побудувати графік гвинтової лінії, заданої параметрично з
використанням наступних співвідношень:

t2 t
r (t ) = + 1, x(t ) = r cos(t ) , y (t ) = r sin (t ) , z (t ) = . (6.3)
80 2π
Під час побудови графіка вважати, що значення параметра t лежать в
числовому діапазоні [− 4π,4π] .
Відповідний програмний код, у якому реалізовані розрахунки за
співвідношеннями (6.3) та побудова графіка гвинтової лінії у заданому
діапазоні числових значень параметра t, можна записати наступним чином [70].
In[1]: %matplotlab qt
In[2]: import numpy as np
In[3]: import matplotlib as mpl
In[4]: import matplotlib.pyplot as plt
In[5]: from mpl_toolkits.mplot3d import Axes3D
In[6]: fig = plt.figure()
In[7]: ax = Axes3D(fig)
In[8]: t = np.linspace(–4*np.pi, 4*np.pi, 100)
In[9]: r = t**2/80 + 1
In[10]: x = r*np.cos(t)
In[11]: y = r*np.sin(t)
In[12]: z = t/(2* np.pi)
In[13]: ax.plot(x, y, z, linewidth = 4)
Результат роботи командних рядків, наведених у прикладі 6.47,
показаний на рис. 6.13.
Розглянемо тепер приклад побудови зафарбованих та каркасних
тривимірних поверхонь.

243
Рис. 6.13 Результат роботи командних рядків, наведених у прикладі 6.47 [70]

Приклад 6.48 З використанням засобів програмування системи


Anaconda побудувати зафарбований та каркасний графіки тривимірної
поверхні, заданої наступними аналітичними співвідношеннями:
sin (r )
r = x2 + y 2 , z= . (6.4)
r
Під час побудови графіка вважати, що значення змінних x та y лежать в
числовому діапазоні [− 4π,4π] .
Відповідний програмний код, у якому реалізовані розрахунки за
співвідношеннями (6.4) та побудова графіків зафарбованої та каркасної
поверхонь у заданому діапазоні числових значень параметрів x та y, можна
записати наступним чином [70].
In[1]: %matplotlab qt
In[2]: import numpy as np
In[3]: import matplotlib as mpl
In[4]: import matplotlib.pyplot as plt
In[5]: from mpl_toolkits.mplot3d import Axes3D
In[6]: fig = plt.figure()
In[7]: ax = Axes3D(fig)
In[8]: u = np.linspace(–4*np.pi, 4*np.pi, 50)

244
In[9]: x, y = np.meshgrid(u, u)
In[10]: z = np.sin(r)/r
In[11]: surf = ax.plot_surface(x, y, z, \
rstride = 1, cstride = 1, cmap = mpl.cm.hsv)
In[12]: fig.colorbar(surf, shrunk = 0.75, acpect = 15)
In[13]: fig2 = plt.figure()
In[14]: ax2 = Axes3D(fig2)
In[15]: ax2.surf_w(x, y, z, rstride = 1, cstride = 1)
У прикладі 6.48 параметр задає rstride крок у створених
двовимірних масивах x та y за рядками, а параметр rstride – відповідно за
колонками. Значення rstride = 1 та cstride = 1 свідчать про те, що
необхідно брати всі елемента масиву u [70]. Команда
cmap = mpl.cm.hsv
задає відповідну палітру кольорів, яка має назву hsv [70].
Метод fig.colorbar() призначений для виведення праворуч від
графіка стрічки із позначеннями числових кодів кольорів.
Результати роботи командних рядків, наведених у прикладі 6.48,
показані на рис. 6.14.

а) б)
Рис. 6.14 Результат роботи командних рядків, наведених у прикладі 6.48.
а – розфарбований графік, б – каркасний графік [70]

245
Розглянемо ще один приклад побудови тривимірних поверхонь та
контурних графіків, у якому для розташування чотирьох графіків на одному
полотні використана розглянута у попередньому підрозділі функція
subplot()[70].
Приклад 6.49
In[1]: %matplotlab qt
In[2]: import numpy as np
In[3]: import matplotlib as mpl
In[4]: import matplotlib.pyplot as plt
In[5]: from mpl_toolkits.mplot3d import Axes3D
In[6]: fig = plt.figure(figsize = (8, 6), \
facecolor = ‘white’, num = ‘Приклади по\
будови графіків’)
In[7]: ax = fig.add_subplot(2, 2, 1, \
projection = ‘3d’)
In[8]: u = np.linspace(0, 2*np.pi, 51)
In[9]: v = np.linspace(-np.pi/2, np.pi/2, 51)
In[10]: x = np.outer(np.cos(u), np.cos(v))
In[11]: y = np.outer(np.sin(u), np.cos(v))
In[11]: ax.plot_surface(x, y, z, rstride = 2, \
cstride = 4, color = ‘0.75’)
In[12]: u = np.linspace(-4*np.pi, 4*np.pi, 50)
In[13]: X, Y = np.meshgrid(u, u)
In[14]: r = np.sqrt(X**2 + Y**2)
In[15]: Z = np.sin(r)/r
In[16]: ax = fig.add_subplot(2, 2, 2, \
projection = ‘3d’)
In[17]: ax.plot_surface(x, y, z, rstride = 1, \
cstride = 1, linewidth = 0, color = (0.5, 0.5, 1))
In[18]: pt = np.linspace(-3, 3, 31)

246
In[19]: X, Y = np.meshgrid(pt, pt)
In[20]: Z = X*Y*np.exp(X**2 + Y**2)
In[21]: ax = fig.add_subplot(2, 2, 3, \
projection = ‘3d’)
In[22]: ax.plot_wireframe(X, Y, Z, rstride = 1, \
cstride = 1, color = ‘k’)
In[23]: ax = fig.add_subplot(2, 2, 4)
In[24]: plt.counturf(X, Y, Z, cmap = ‘jet’)
In[24]: plt.axis(‘image’)
Результат роботи командних рядків, наведених у прикладі 6.49,
показаний на рис. 6.15.

Рис. 6.15 Результат роботи командних рядків, наведених у прикладі 6.49 [70]

Більш досконало засоби тривимірної графіки системи програмування


Anaconda описані у навчальних посібниках [26, 70]. Більшість з цих функцій
за своєї назвою та призначенням співпадають із відповідними функціями
системи науково-технічних розрахунків MartLab [6, 7]. У наступному
підрозділі розглядатимуться засоби програмування системи Anaconda,
призначені для створення анімаційних ефектів.

247
6.1.3.3 Засоби для створення анімаційних ефектів
Перед вивченням цього підрозділу необхідно повторити підрозділ 5.4.2
Як було відмічено у підрозділі 5.4.2, анімацією у теорії програмування
називається послідовність зображень, які швидко замінюють одне одне, через
що у спостерігача виникає уява про рух об’єкту [5, 6, 40, 60]. Засоби
програмування системи Anaconda, призначені для створення анімаційних
ефектів, розташовані у модулі matplotlib.animation. Серед цих засобів
найбільш важливими і поширеними у практичному використанні, є функції
FuncAnimation() та ArtistAnimation() [26, 70].
З практичної точки зору анімація створюється через багатократний
виклик функції користувача func(), призначенням якої є рисування кадрів.
У найпростішому випадку створення анімації параметр виклику frames
задає кількість кадрів, а функція func() приймає номер кадру як перший
аргумент. Параметр interval задає паузу між кадрами анімації у
мілісекундах. Можливим є також використання опції repeat = True, яка
задає режим повторення анімації [26, 70].
Розглянемо кілька прикладів, в яких анімаційні ефекти
використовуються для проведення інженерних та наукових досліджень [70].
Приклад 6.50 З використанням засобів анімації системи
 ix 
sin  
програмування Anaconda побудувати 100 графіків функції f ( x ) =   для
10
1 + x2
різних значень натурального числа i в діапазоні значень x ∈ [0,8] . Відобразити
побудовані графіки на анімаційному ролику з інтервалом між кадрами 50 мс.
Відповідний програмний код можна записати наступним чином [70].
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: import matplotlib.animation as ani
In[4]: fig = plt.figure(facecolor = ‘white’)

248
In[5]: ax = plt.axes(xlim = (0, 8), ylim = (–1, 1))
In[6]: line, = ax.plot([], [], lw = 3)
In[7]: ax.grid(True)
In[8]: def redraw(i):
x = np.linspace(0, 8, 200)
y = np.sin(i*x/10)/(1 + x**2)
line_set_data(x, y)
In[9]: anm = ani.FuncAnimation(fig, redraw, \
frames = 100)
In[10]: plt.show()
Об’єкт, який повертається до функції FuncAnimation(), повинен
існувати постійно під час роботи анімаційного ролика. Тому функції
FuncAnimation() присвоєна ім’я змінної, яка посилається на цей об’єкт.
Для коду програми, розглянутого у прикладі 6.50, це змінна anm.
Три різних анімаційних кадри, які є результатом роботи командних
рядків, наведених у прикладі 6.50, показані на рис. 6.16, а – в [70].

Рис. 6.16 Результати роботи командних рядків, наведених у прикладі 6.50,


для різних значень параметра i [70]

Розглянемо інший приклад анімації, в якому формується зображення


циклоїди. Як відомо з основ аналітичної геометрії, циклоїдою називається
крива, яка формується точкою кола, що котиться вздовж прямої лінії із
рівною лінійною швидкістю [45]. Циклоїди також мають важливе значення в
практичних задачах прикладної електронної оптики, оскільки вони
відповідають траєкторіям руху заряджених частинок в перехрещених

249
електричних та магнітних полях [50]. У загальному вигляді рівняння
циклоїди записується через параметричні функції x(t ) та y (t ) наступним
чином:
x(t ) = t − sin (t ) , y (t ) = 1 − cos(t ) (6.5)
Приклад 6.51 З використанням засобів анімації системи
програмування Anaconda відобразити коло, яке котиться вздовж прямої лінії,
фіксовану точку на цьому колі та траєкторію цієї точки, яка описується
рівнянням циклоїди (6.5).
Відповідний програмний код можна записати наступним чином [70].
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: import matplotlib.animation as ani
In[4]: from matplotlib.patches import Circle
In[5]: def initpict():
line1.set_data([], [])
line2.set_data([], [])
pc.center(xC, yC)
ax.add_patch(pc)
pc.center(xP, yP)
ax.add_patch(pp)
In[6]: def redraw(i):
global xC, xP, yP
n = i/10
t = np.linspace(0, 8, 200)
x = t – np.sin(t)
y = 1 – np.cos(t)
line1.set_data(x, y)
xC = n
pc.center(xC, yC)
xP = n – np.sin(n)

250
yP = 1 – np.cos(n)
pc.center(xP, yP)
line2.set_data([n, xP], [1, yP])
return pc, pp, line1, line2
In[7]: fig = plt.figure(facecolor = ‘white’)
In[8]: fig.set_dpi(100)
In[9]: a = 1; b = 3; dl = 1; dh = 0.25
In[10]: ax = plt.axes(xlim = (0, 12), ylim = (0, 3))
In[11]: ax.set_yticklabels([‘0’, ‘1’, ‘2’, ‘3’])
In[12]: line1, = ax.plot([], [], lw = 2)
In[13]: line2, = ax.plot([], [], ‘r’)
In[14]: xC = 0; yC = 1; xP = 0; yP = 0
In[15]: pc = plt.Circle((xC, yC), 1, fc = ‘c’)
In[16]: pc = plt.Circle((xP, yP), 0.1, fc = ‘k’)
In[17]: ax.set_aspect(‘equal’)
In[18]: anim = ani.FuncAnimation(fig, redraw, \
init_func = implict, frames = 120, \
interval = 50, blit = True)
In[19]: plt.show()
Особливістю виклику функції FuncAnimation() у прикладі 6.51 є
використання параметру blit = True. Встановлення цієї опції роботи з
анімаційним роликом гарантує, що під час побудови графіків оброблятися та
проходити сортування будуть лише ті значення числових масивів інформації,
які були змінені. Зрозуміло, що використання таких алгоритмів обробки
даних значно підвищує швидкість формування та відтворення
відеоінформації. У разі використання цієї опції функції користувача, які
формують зображення, повертають не окремі числові значення, а
структуровані дані, як-то списки або кортежі [70]. Тому у прикладі 6.51
робота функцій initpict() та redraw() організована саме через
передавання кортежів до головної програми.
Один з анімаційних кадрів, отриманий з використанням командних
рядків, наведених у прикладі 6.51, показаний на рис. 6.17.

251
Рис. 6.17 Анімаційний кадр, отриманий як результат роботи командних
рядків, наведених у прикладі 6.51 [70]

Для створення анімаційних кадрів використовуються також способи


формування тривимірних графічних зображень та контурних графіків,
розглянуті у підрозділах 6.1.3.1 та 6.1.3.2. Такі способи формування
зображень необхідні у тих випадках, коли кадрі анімації відображують
числові дані з двовимірних масивів, які були генеровані в ході виконання
програми. Розглянемо відповідний приклад, в якому анімаційні кадри
створюються з використанням функції imshow() [70].
Приклад 6.52
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: import matplotlib.animation as ani
In[4]: fig = plt.figure(facecolor = ‘white’)
In[5]: f = lambda x, y: np.sin(2*x) + np.sin(2*y)
In[6]: x = np.linspace(0, 2*np.pi, 100)
In[7]: y = np.linspace(0, 2*np.pi, 100).reshape(-1, 1)
In[8]: im = plt.imshow(f(x, y), cmap = ‘hot’, /
animated = True)
In[9]: def redraw(*args)
global x, y
x += np.pi/26
y += np.pi/20
im.set_array(f(x, y))
252
im.set_cmap(‘hot’)
return im
In[10]: anim = ani. FuncAnimation(fig, redraw, \
interval = 50, blit = True)
In[11]: plt.show()
Один з анімаційних кадрів, отриманих в результаті роботи програмного
коду, наведеного у прикладі 6.52, показаний на рис. 6.18.

Рис. 6.18 Анімаційний кадр, отриманий як результат роботи командних


рядків, наведених у прикладі 6.52 [70]

Функція ArtistAnimation() суттєво відрізняється від розглянутої


функції FuncAnimation() лише тим, що другим аргументом цієї функції є
не функція користувача, призначена для описання методів побудови
графічних фігур, а вже готові графічні об’єкти для анімаційного ролика. Ці
графічні об’єкти записується через значення кольорів та яскравості окремих
точок, із яких формуються відповідні масиви числових даних [70]. Інакше
кажучи, розглянута функція FuncAnimation() реалізує методи векторної
комп’ютерної графіки, а функція ArtistAnimation() – методи растрової
графіки. Методи векторної графіки потребують використання більш
потужного графічного процесора, а методи растрової графіки – більшого
об’єму відеопам’яті [5 – 7].
Розглянемо приклад, у якому для побудови растрових анімаційних
253
кадрів використовується функція pcolor(). Ця функція може бути
використана у двох можливих форматах, спрощеному та ускладненому.
Спрощений формат цієї функції вигляд:
pcolor(C)
де C – масив значень, яким відповідають яскравості та кольори точок.
Ускладнений формат запису цієї функції має наступний вигляд:
pcolor(X, Y, C)
де значення X та Y визначають координати (x, y) зафарбованих
чотирикутників, вершини яких розташовуються у точках:
(X[i, j], Y[i, j]), (X[i, j+1], Y[i, j+1]),
(X[i+1, j], Y[i+1, j]), (X[i+1, j+1], Y[i+1, j+1])
У наведеному нижче прикладі функція pcolor(X, Y, C)
використовується, разом із функцією об’єднання списків append(), для
формування змінної спискового типу imlest [70].
Приклад 6.53
In[1]: import numpy as np
In[2]: import matplotlib.pyplot as plt
In[3]: import matplotlib.animation as ani
In[4]: import copy
In[5]: fig = plt.figure(facecolor = ‘white’)
In[6]: ax = plt.axes(xlim = (–25, 25), \
ylim = (–25, 25), aspect = ‘equal’)
In[7]: x = np.arange(–25, 26)
In[8]: y = np.arange(–25, 26)
In[9]: X, Y = np.meshgrid(x, y)
In[10]: ZZ = np.sqrt(X**2 + Y**2)
In[11]: imlist = []
In[12]: for i in np.arrange(36):
Z = copy.deepcopy(ZZ) – i
Z[np.logical_and(Z < 0, Z > –2)] = (i – 17)*2
Z[np.logical_and(Z < 6, Z > 4)] = (17 – i)*2
In[13]: imlist.append(plt.pcolor(x, y, Z, \
norm = plt.Normalize(–35, 35)), ))

254
In[14]: anim = ani.ArtistAnimation(fig, imlist, \
intervqal = 50, repeat_delay = 100, \
blit = True)
In[15]:. Plt.show()
Деякі кадри анімації, отримані з використанням програмного коду,
наведеного у прикладі 6.53, представлені на рис. 6.19, а – г.

а) б)

в) г)
Рис. 6.19 Анімаційні кадри, отриманий як результат роботи командних
рядків, наведених у прикладі 6.53 [70]

Деякі інші приклади анімаційних програм, написаних в системі


програмування Anaconda, наведені у навчальному посібнику [70].

255
6.1.3.4 Можливості інтеграції графічних об’єктів модуля matplotlib
системи програмування Anaconda із об’єктами графічного
інтерфейсу модуля tkinter
Перед вивченням цього підрозділу необхідно повторити підрозділи 5.2 та 5.4
У підрозділі 5.4 були описані можливості модуля tkinter, призначені
для роботи з векторною графікою. Проте із матеріалу, наведеного у цьому
підрозділі, цілком зрозуміло, що можливості функцій, розташованих у модулі
matplotlib, є значно ширшими. Наприклад, побудувати графік функції від
одного аргументу з використанням програми, наведеної у додатку Є, значно
складніше, ніж з використанням функції plot() бібліотеки
matplotlib.pyplot, а засобів побудови тривимірної графіки в модулі
tkinter взагалі на існує.
З програмної точки зору ці можливості реалізовані з використанням
складеного полотна FigureCanvasTkAgg, спеціального класу, який
успадковує можливості графічного об’єкту Canvas модуля tkinter, але
дає додаткові можливості використання всіх графічних функцій модуля
matplotlib системи програмування Anaconda. Разом з цим класом
імпортується також клас NavigationToolbar2TkAgg, у якому міститься
панель керування графікою бібліотеки matplotlib, показана на рис. 6.3.
Проте підключення цієї панелі керування до графічного вікна, сформованого
з використанням засобів програмування модуля tkinter, не завжди є
обов’язковим [70].
Узагальнений алгоритм розміщення графічних об’єктів, сформованих з
використанням засобів програмування бібліотеки matplotlib, у вікні
графічного інтерфейсу, створеного на основі об’єктів модуля tkinter, є
наступним [70].
1. З використанням засобів програмування модуля tkinter
створюється вікно графічного інтерфейсу та розташовується на ньому
полотно, якому відповідає об’єкт frame.

256
2. З використанням засобів програмування бібліотеки matplotlib
створюється графічний об’єкт, який має бути розташований на полотні.
3. Створений графічний об’єкт відображується на полотні.
Для реалізації третього пункту описаного алгоритму слід виконати
наступні дії [70].
1. З використанням методу FigureCanvasTkAgg() створюється
об’єкт, який належить до класу складеного полотна FigureCanvasTkAgg.
Ця функція має наступний формат виклику.
FigureCanvasTkAgg(ім’я_об’єкту, ім’я_полотна)
де ім’я_об’єкту – ім’я графічного об’єкту, створеного з використанням
засобів бібліотеки matplotlib. Створений об’єкт розташовується на
полотні із іменем ім’я_полотна. Метод FigureCanvasTkAgg()
належить до бібліотеки matplotlib.backends.backend_tkagg.
2. З використанням команди show() бібліотеки matplotlib
включається функція відображення графічного об’єкта на полотні.
3. З використанням команди canvasAgg.get_tk_widget()
графічний об’єкт переноситься на полотно. Ця команда використовується без
параметрів.
4. З використанням функції pack() модуля tkinter графічний
об’єкт відображується у фреймі.
5. З використанням функції pack() модуля tkinter фрейм
відображується в інтерфейсному вікні.
6. З використанням функції mainloop() модуля tkinter
формується цикл для відображення інтерфейсного вікна. Призначення
функцій pack() та mainloop() було описано у підрозділах 5.2.3 та 5.2.1.
Розглянемо простий приклад, у якому в інтерфейсному вікні
розміщується графік синусоїдальної функції, побудований з використанням
засобів програмування бібліотеки matplotlib, описаних у
підрозділі 6.1.3.1 [70].

257
Приклад 6.54
In[1]: from tkinter import *
In[2]: import numpy as np
In[3]: import matplotlib.pyplot as plt
In[4]: from matplotlib.backends.backend_tkagg \
import FigureCanvasTkAgg
In[5]: window = Tk()
In[6]: frm = frame(window)
In[7]: x = np.linspace(0, 2*np.pi)
In[8]: fig = plt.figure(facecolor = ‘white’)
In[9]: ax = fig.add_subplot(1 1 1)
In[10]: ax.plot(x, np.sin(x), ‘–rh’, \
linewidth = 3, markerfacecolor = ‘b’, \
label = r‘$\sin x$’)
In[11]: ax.grid(color = ‘b’, linewidth = 1.0)
In[12]: plt.legend(fontsize = 12)
In[13]: canvasAgg = FigureCanvasTkAgg(fig, \
master = frm)
In[14]: canvasAgg.show()
In[15]: canvas = canvasAgg.get_tk_widget()
In[16]: canvas.pack(fill = BOTH, expsnd = 1)
In[17]: canvas.pack(fill = BOTH, expsnd = 1)
In[18]: frm.pack()
In[19]: window.mainloop()

Результати роботи програмних рядків, наведених у прикладі 6.54,


показані на рис. 6.20.

258
Рис. 6.20 Результат роботи програмного коду, наведеного у прикладі 6.54 [70]

Розглянемо тепер інший приклад, у якому графік функції будується з


використанням засобів бібліотеки matplotlib, а елементи графічного

інтерфейсу модуля tkinter використовуються для забезпечення введення

та виведення інформації та для обробки виключних ситуацій.


Приклад 6.55 З використанням засобів мови програмування Python
написати програму з віконним інтерфейсом, призначену для побудови
графічної залежності за заданим математичним виразом. Програма повинна
мати три текстових вікна, до першого з яких вводиться математичний вираз,
до другого – мінімальне значення аргументу функції, а до третього –
максимальне. Виведення графіка функції в інтерфейсне вікно здійснюється
після натиснення кнопки «Графік». Передбачити також обробку виключних
та помилкових ситуацій із виведенням повідомлення «Неправильний
математичний вираз або числові значення».
Ця програма є аналогом програми інженерного калькулятора,
розглянутої у підрозділі 5.3.5.2, приклад 5.27. Різниця полягає у тому, що в
інтерфейсне вікно замість результату обчислення значення математичної функції

259
необхідно виводити її графік на заданому числовому інтервалі.
Почнемо розв’язування цього завдання з побудови проекту віконного
інтерфейсу. У верхній частині інтерфейсного вікна розташуємо три
текстових вікна для введення інформації, під ними – область виведення
графіка, а у нижній частині вікна – кнопку з надписом «Графік».
Узагальнений вигляд такого віконного інтерфейсу показаний на рис. 6.21.

Підписи над текстовими вікнами


Математичний вираз: Початок інтервалу: Кінець інтервалу:

Вікно 1 Вікно 2 Вікно 3


Текстові вікна

Область виведення графіка

Кнопка «Графік»

Рис. 6.21 Узагальнений вигляд інтерфейсного вікна програми, призначеної


для побудови графіка функції за заданим математичним виразом

Для написання такої програми використовуються розглянуті у цьому


посібнику функції бібліотеки matplotlib та модуля tkinter. За

допомогою функцій бібліотеки matplotlib, розглянутих у підрозділі

6.1.3.2, будується графік функції, заданої математичним виразом, записаним


у першому інтерфейсному вікні. Ця функція у програмному коді описується
як анонімна лямбда-функція. Для обробки виключних ситуацій використаний
оператор try: except:. Відповідний теоретичний матеріал розглядався у

підрозділах 3.7.8 та 3.7.9. Для описання об’єктів віконного інтерфейсу

260
використані засоби програмування, розглянуті у підрозділі 5.2. Виведення
графіка в інтерфейсне вікно здійснюється з використанням розглянутого у
цьому підрозділі алгоритму, який дозволяє встановлювати взаємозв’язок між
об’єктами модулів matplotlib та tkinter. Код програми з віконним

інтерфейсом, призначеної для виведення на екран графіка заданої функції,


наведений у додатку Ж. Результат роботи цієї програми представлений на
рис. 6.22 [70].

Рис. 6.22 Результат роботи програмного коду, наведеного у додатку Ж [70]

261
6.1.4 Символьні обчислення в системі програмування Anaconda

6.1.4.1 Загальні основи символьних обчислень

Вже було відмічено, що більшість функцій системи програмування


Anaconda у значній мірі відповідає функціям системи науково-технічних
розрахунків MatLab. Наприклад, у бібліотеці sympy системи Anaconda
реалізований символьний процесор, функції якого у значній мірі схожі на
функції символьного процесору MatLab [6, 7].
Розглянемо у цьому підрозділі основи роботи з- символьним
процесором системи Anaconda. Насамперед зрозуміло, що для початку
роботи з ним необхідно імпортувати бібліотеку sympy. Після цього можна
оголосити символьні змінні та проводити з ними аналітичні обчислення, що у
багатьох випадках у значній мірі спрощує завдання програмування [6, 7]. У
системі Anaconda для створення списків символьних змінних
використовуються функції symbols() та var(). Слід зазначити, що будь-
яку змінну, наприклад x, не можна використовувати як символьну без
відповідного оголошення. У цьому функції бібліотеки sympy системи
Anaconda також у значній мірі схожі на функції системи MatLab та суттєво
відрізняються від функцій аналітичних комп’ютерних систем Maple та
Mathematica, де неоголошені змінні за замовченням вважаються
символьними [6, 7].
Розглянемо простий приклад, у якому оголошуються та
використовуються символьні змінні [70].
Приклад 6.56
>>> from sympy import *
>>> x, y, a, b = symbols(‘x y a b’)
>>> f = a**3*x + 3*a**2*x/2 + a*x**3 + x**4/4
Суттєва різниця між функціями оголошення символьних змінних
symbols() та var() полягає у тому, що функція symbols() дає лише
посилання на символьний об’єкт, який потім можна використовувати у
262
математичних виразах, як у прикладі 6.56. Навпаки, функція var() створює
символьну змінну відразу, без присвоєння. Розглянемо відповідний приклад [70].
Приклад 6.57
>>> from sympy import *
>>> var(‘Student’)
Student
>>> type(Student)
<class ‘sympy.core.symbol.Symbol’>
Під час створення символьних виразів, аналогічних виразу f,
наведеному у прикладі 6.56, слід дуже охайно обробляти числові дані.
Наприклад, вираз 1/2 інтерпретатор IPython може прочитати як число 0,5 та
не включити його до символьних перетворень. Щоб бути остаточно
впевненим, що числові дані у математичних виразах будуть інтерпретовані
як символьні, можна використовувати функцію символьного перетворення
S() [70]. Ця функція є синонімом функції simplify().
Важливою для проведення аналітичних обчислень та переходу до
числових значень символьних змінних є також функція subs(), призначена
для надання числових значень аналітичним змінним. Ця функція має
наступний формат запису [70].
subst(ім’я_символьної_змінної, числове_значення)
Розглянемо відповідний приклад.
Приклад 6.58
>>> from sympy import *
>>> x, y = symbols(‘x y’)
> ex = x**2 + sin(y) + S(1)/2
>>> ex
x**2 + sin(y) + /2
>>> type(1)
<class ‘int’>
>>> type (S(1))

263
<class ‘sympy.core.numbers.One’>
>>> type (S(x**2))
sympy.core.power.Pow
>>> (S(x**2)).subs(x, 3)
9
>>> simplify(0.5)
0.500000000000
>>> type (_)
<class ‘sympy.core.numbers.Float’>
>>> x**(1/2)
x**0.5
>>> x**(S(1)/2)
sqrt(x)
>>> x**(S(1)/2).subs(x, 4)
2
Символьні змінні в системі програмування Anaconda можна
оголошувати з індексом. У цьому разі замість змінної із заданим іменем,
наприклад x, формується список індексованих змінних x1, x2, x3, ... xn.
Тоді формат команди symbols() має наступний вигляд [70].
x = symbols(‘xn1:n2’)
де n1, n2 – натуральні числа. Число n1 відповідає початковому значенню
індексу, а число n2 – кінцевому. Якщо параметр n1 пропущений, вважається,
що він за замовченням дорівнює 0.
Інший спосіб автоматичного визначення набору символьних змінних
полягає у тому, що замість значень n1 та n2 записуються літери англійської
абетки. Наприклад, запис symbols(‘a:d’) означає створення символьних
змінних з іменами a, b, c та d . Для постійної роботи із символьною
математикою можна імпортувати стандартний намір символьних змінних із
модуля sympy.abc [70]. Перелік цих змінних можна подивитися з
використанням команди dir().

264
Можна також у явному вигляді задати тип символьної змінної у
форматі Тип_змінної = True. Часто таке визначення спрощує роботу
символьного процесора та дозволяє отримати необхідний результат без
додаткових аналітичних перетворень.
Розглянемо відповідний приклад [70].
Приклад 6.59
>>> from sympy import *
>>> x = symbols(‘x:5’)
>>> x
(x0, x1, x2, x3, x4)
>>> y = symbols(‘x5:10’)
>>> y
(y5, y6, y7, y8, y9)
>>> symbols(‘a:d’)
a b c d
>>> k, m, n = symbols(‘k m n’, integer = True)
>>> x = symbols(‘x’)
>>> sqrt(x**2)
sqrt(x**2)
>>> x = symbols(‘x’, positive = True)
>>> sqrt(x**2)
x
>>> import sympy.abc
>>> dir (sympy.abc)
[‘A’, ‘B’, ‘C’, ..., ‘a’, ‘alpha’, ‘b’, ‘beta’,
‘c’, ‘chi’, ...]
Для видалення символьної змінної із простору імен використовується
стандартна команда del(), розглянута у підрозділі 3.6. Розглянемо
відповідний приклад.
Приклад 6.60

265
>>> from sympy import *
>>> x, y = symbols(‘x y’)
>>> x
<class ‘sympy.core.symbol.Symbol’>
>>> del x, y
>>> x
ValueError: invalid literal for float: ‘x’
Головними правилами для роботи з символьними виразами є наступні [70].
Правило 6.3 Після запису виразу з символьними змінними
аналітичний процесор відразу спрощує його.
Правило 6.4 Для обчислення значення символьного виразу для
заданих числових значень змінних використовується команда символьного
процесора subst().
Правило 6.5 Аргументом функції subst() може бути словник із
параметрами {ключ: значення}. У цьому разі замість ключового слова
до виразу підставляється його значення. Наприклад, замість subst(x, 1)
можна писати subst({x:1}). Головні правила роботи зі словниками
розглядалися у підрозділі 4.4.
Правило 6.6 Замість символьної змінної можна підставляти до виразу
інший, більш простий математичний вираз. Наприклад, запис
subst(x, 1/x) означає, що у математичний вираз, до якого
застосовується заміна, замість символьної змінної x необхідно підставити
1/x.
Правило 6.7 Присвоєння відповідного значення символьній змінній
не впливає на аналітичні вирази, які були записані раніше.
Правило 6.8 Символьні обчислення можуть також проводитись над
числовими виразами, наприклад, під час роботи із раціональними дробами.
Розглянемо відповідні приклади, у яких наочно показано, як у роботі
символьного процесора системи програмування Anaconda виконуються
правила 6.3 – 6.8 [70].
266
Приклад 6.61
>>> from sympy import *
>>> a, b, c, d, x, y, z, u, v, w = symbols(‘a b c \
d x y z u v w’)
>>> x – 3 + 23 – z + 14 + sin(pi) + 2*z
x + 9
>>> f = a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4
>>> f.subst(a, 1)
x**4/4 + x**3 + 3*x**2/2 + x
>>> f.subst([(a, 1), (x, 2)])
20
>>> f = x*(1 + log(x))
>>> f.subs(x, pi),evalf()
6.73786765331895
>>> f = a**3*x + 3*a**2*x**2/2 + a*x**3 + x**4/4
>>> f.subs({x:1})
a**3 + 3*a**2/2 + a + 1/4
>>> expr = x**2 + 2*x + 1
>>> expr.subs(x, 1/x)
1 + 2/x + x**(–2)
>>> expr = x + 1
>>> x = 2
>>> print(expr)
x + 1
>>> S(1)/3 + S(2)/5
11/15
>>> 1/3 + 2/5
0.733333333333334
>>> sqrt(12)
2*sqrt(3)

267
>>> sqrt(12.0)
3.46410161513775
Для організації проведення символьних розрахунків важливими є
також аргумент args, який повертає кортеж із аргументів математичного
виразу, та метод as_operand_terms(), який повертає список
операндів [70]. Правила роботи з кортежами були розглянуті у підрозділі 4.3,
а правила роботи зі списками – у підрозділі 3.6. Базовим об’єктом для цього
аргументу та цього методу є символьний вираз, який аналізується, а
посилання на об’єкт здійснюється через змінну, яка йому відповідає. Загальні
правила щодо описання об’єктів та способи роботи з ними розглядалися у
підрозділі 4.1. Розглянемо відповідний приклад [70].
Приклад 6.62
>>> from sympy import *
>>> x, y, z = symbols(‘x y z’)
>>> z = x + y + 1
>>> z.args
(1, x, y)
>>> z.as_operand_terms()
[x, y, 1]
Однією з системних змінних модуля sympy є змінна oo, яка відповідає
знаку нескінченності ∞, що часто використовується у символьній математиці.
Розглянемо приклади використання цієї системної змінної.
Приклад 6.63
>>> from sympy import *
>>> oo + 1
>>> oo
>>> 10000000 < oo
True
>>> oo – 10000000
oo
>>> S(6)/S(0)
oo

268
>>> S(10000000) / oo
0
У системі науково-технічних розрахунків MatLab змінній oo відповідає
системна змінна Inf [6, 7].
У наступнгму підрозділі розглядатимуться головні функції символьної
алгебри, реалізовані в системі програмування Anaconda.

6.1.4.2 Аналітичні функції алгебраїчних перетворень


Головні функції системи програмування Anaconda, призначені для
здійснення символьних перетворень алгебраїчних виразів, наведені у
таблиці 6.5 [70].
Розглянемо головні правила, за якими в системі програмування
Anaconda здійснюються алгебраїчні символьні перетворення [70].
Правило 6.9 В системі програмування Anaconda символьні вирази
завжди розглядаються як об’єкти,
Наслідок правила 6.9 полягає у тому, що можливі різні форми звернення до
команд символьного процесора. Можна звертатися до відповідного об’єкта,
записуючи його як аргумент функції, наприклад, expand(z), а можна інакше,
посилаючись через ім’я об’єкта на відповідний метод, який інкапсульований до
нього, наприклад, z.expand(). Відповідні способи роботи з об’єктами у мові
програмування Python розглядалися у підрозділі 4.1.
Правило 6.10 Аналітичний процесор системи програмування
Anaconda розпізнає імена всіх математичних функцій без посилання на
модуль, в якому вони розташовані. В іншому запис аналітичних виразів
цілком відповідає синтаксису мови програмування Python.
Правило 6.11 Для запису символьних виразів можна
використовувати не лише математичні функції та арифметико-логічні вирази,
розглянуті у підрозділі 4.3, але й інші лінгвістичній конструкції мови Python,
як-то умовні оператори, оператори циклу та анонімні лямбда-функції.
Розглянемо приклади використання функцій символьних алгебраїчних
та тригонометричних перетворень для змінних, які відповідають класу
раціональних чисел [70]. Командні рядки, наведені у наступному прикладі,
написані з урахуванням правил 6.9 – 6.11.
269
Таблиця 6.5 – Головні функції системи програмування Anaconda,
призначені для здійснення алгебраїчних перетворень

Загальні функції для здійснення алгебраїчних перетворень


Функція Призначення
factor() Розкладання аналітичного виразу на множники
Подання математичного виразу, розкладеного на
expand() множники, у поліноміальній формі. Функція є зворотною
до функції factor()
Обчислення добутку заданих символьних аргументів
prod()
функції
Зведення в аналітичному виразі подібних членів, або
collect() сумування коефіцієнтів, що відповідають однаковим
степеням символьної змінної
Скорочення раціональних дробів та зведення їх до одного
cancel()
дробу із спільним знаменником
Розкладання складних дробів на елементарні прості
apart()
дроби. Функція є зворотною до функції cancel()
Аналітичний процесор системи Anaconda намагається
привести символьний математичний вираз до найбільш
simflify()
простої форми, використовуючи для цього всі можливі
методи аналітичних перетворень
Функції для здійснення тригонометричних перетворень
Функція Призначення
Зведення тригонометричних виразів до поліноміальної
форми. Всі тригонометричні функції записуються
expand_trig()
відносно символьної змінної без додаткових числових
множників
trigsimp() Спрощення тригонометричних виразів

270
Приклад 6.64
>>> from sympy import *
>>> x, y = symbols(‘x y’)
>>> factor(x**2 – y**2)
(x – y)*(x + y)
>>> factor(x**4 + 4)
(x**2 – 2*x + 2)(x**2 + 2*x + 2)
>>> expr = sum([x**i for i in range(0, 6)])
>>> expr
x**5 + x**4 + x**3 + x**2 + x + 1
>>> factor(expr)
(x + 1)*(x**2 – x + 1)*(x**2 + x + 1)
>>> f = (a + b)**3
>>> a, b = symbols(‘a b’)
>>> expand(f)
a**3 + 3*a**2*b + 3*a*b**2 + b**3
>>> expand((1 – x)*(1 + x + x**2 + x**3 + \
x**4 + x**5))
–x**6 +1
>>> expand(log(x*y))
(log(x*y))
>>> var(‘a’, ‘b’, positive = True)
(a, b)
>>> expand(log(a*b))
log(a) + log(b)
>>> expand(prod([(x – i) for i in range(1, 5)]))
>>> x**4 – 10*x**3 + 35*x**2 – 50*x + 24
>>> prod(range(1,5))
24
>>> x, y, z = symbols(‘x y z’)

271
>>> expr = x*y + x – 3 + 2*x**2 – z*x**2 + x**3
>>> collect(expr, x)
x**3 + x**2*(–z + 2) + x*(y + 1) – 3
>>> a, b, c, d = symbols(‘a b c d’)
>>> collect(a*x + b*x + c*y + d*y, x)
c*y + d*y + x*(a + b)
>>> collect(a*x + b*x + c*y + d*y, (x, y))
x*(a + b) + y*(c + d)
>>> cancel (a/b + c/d)
(a*d + b*c)/(b*d)
>>> cancel (x**2 + 2*x +1)/(x**3 + x**2)
(x + 1)/(x**2)
>>> cancel (x – 7)/(x – 3) – (x – 12)/(x – 2)
50/(x**2 + x – 6)
>>> apart((4*x**3 + 21*x**2 + 10*x + 12)/(x**4 +\
5*x**3 + 5*x**2 + 4*x))
(2*x - 1)/(x**2 + x + 1) – 1/(x + 4) + 3/x
>>> simplify(sin(x)**2 + cos(x)**2)
1
>>> a, b = symbols(‘a b’)
>>> z = simplify((a**4 – 2*a**2*b**2 + \
b**4)/(a – b)**2)
>>> z
a**2 + 2*a*b + b**2
>>> c = factor(z)
>>> c
(a + b)**2
>>> expr = sin(2*x) + cos(3*x)
>>> expand_trig(expr)
2*sin(x)*cos(x) + 4*cos(x)**3 + 3*cos(x)

272
>>> tr = expand_trig(cos(4*x) – 2*cos(x)*cos(3*x))
>>> tr
–2*(4*cos(x)**3 + 3*cos(x))*cos(x) + 8*cos(x)**4 –
8*cos(x)**2 +1
>>> trigsimp(tr)
2*(–cos(2*x) + 1)**2 + 3*cos(2*x) – cos(4*x) – 3
>>> simplify(tr)
–cos(2*x)
>>> trigsimp(sin(x)**4 – 2*cos(x)**2*sin(x)**2 + \
cos(x)**4)
cos(4*x)/2 + 1/2
>>> a, b, c, d, x, y, z, = symbols(‘a b c d x y z’)
>>> expr = 6 + 11*x – 3*x**2 – 2*x**3
>>> z = expr.factor()
>>> z
–(x – 2)*(x + 3)*(2*x + 1)
>>> z.expand()
–2*x**3 – 3*x**2 + 11*x + 6
>>> ((a + b + c)**2).expand()
a**2 + 2*a*b + 2*a*c + b**2 + 2*b*c + c**2
>>> w = a/b + c/d
>>> u = w.cancel ()
>>> u
(a*d + b*c)/(b*d)
>>> u.simplify()
a/b + c/d
>>> z = a*x + b*x + c*y + d*y
>>> z.collect(x)
c*y + d*y + x*(a + b)
>>> z.collect((x, y))
x*(a + b) + y*(c + d)

273
Символьний процесор системи програмування Anaconda може
опрацьовувати і математичні вирази з комплексними числами, для цього
необхідно у відповідному виразі посилатися на умовну одиницю з
використанням системної змінної I. Слід відзначити, що для роботи з
уявними числами можуть бути використані стандартні функції комплексної
арифметики, серед яких найбільш важливими є наступні [70].
re(z) – дійсна частина комплексного числа z.
im(z) – уявна частина комплексного числа z.
Abs(z) – модуль комплексного числа z.
arg(z) – аргумент комплексного числа z, який являє собою кут
нахилу вектора комплексного числа до осі абсцис.
conjugate(z) – обчислення числа, комплексно спряженого до числа z.
Основи арифметики комплексних чисел були розглянуті у
підрозділі 2.4.7. Зверніть особливу увагу на те, що функція Abs(z) в
аналітичних виразах, на відміну від командних рядків інтерпретатора мови
Python, пишеться з великої літери. Для роботи з комплексними числами
можуть бути використані будь-які функції алгебраїчних перетворень,
наведені у таблиці 6.5. Тобто, можна сказати, що робота з аналітичними
виразами із комплексними числами в системі програмування Anaconda не
має суттєвих особливостей.
Розглянемо приклад, у якому розв’язуються деякі завдання з
арифметики комплексних чисел [70].
Приклад 6.65
>>> from sympy import *
>>> sqrt(–1)
I
>>> I*I
–1
>>> a, b = symbols(‘a, b’, real = True)
>>> z = symbols(‘z’)

274
>>> z = a + b*I
>>> re(z)
a
>>> im(z)
b
>>> Abs(z)
sqrt(a**2 + b**2)
>>> arg(1 + 2*I)
atan(2)
>>> conjugate(z)
a – I*b
>>> z1, z2 = symbols(‘z1, z2’)
>>> z1 = 4 + 3*I
>>> z2 = 1 – 2*I
>>> z1 + z2
5 + I
>>> simplify(z1*z2)
10 – 5*I
>>> simplify(z1/z2)
–2/5 + 11*I/5
>>> var(‘w’)
>>> w = z**3
>>> collect(w, I)
a**3 – 3*a*b**2 + I*(3*a**2*b – b**3)
>>> simplify(re(w))
a*(a**2 – 3*b**2)
>>> simplify(im(w))
b*(3*a**2 – b**2)
Окремо слід розглянути способи відображення в системі
програмування Anaconda результатів алгебраїчних перетворень. Відомо, що в

275
системах аналітичних розрахунків розробники застосовують два різні
способи відображення математичних формул. У системі науково-технічних
розрахунків MatLab результати аналітичних перетворень відображаються
через командний рядок інтерпретатора, а у системах Maple та Mathematica – у
графічному режимі у зручному вигляді для читання користувачем.
Відображення інформації у зручному для користувача вигляді через
графічний інтерфейс має назву WYSIWYG (абревіатура англійського
словосполучення What You See Is What you Get – Ви отримуєте те, що
бачите). Технологія WYSIWYG останнім часом, особливо з появою
операційної системи Windows, стає все більш популярною серед
користувачів персональних комп’ютерів, оскільки вона значно спрощує
діалог між людиною та машиною [16]. Але, з іншого боку, для програміста
зазвичай зручніше отримувати аналітичний вираз у вигляді командного рядка
та відразу копіювати його у вікно текстового редактора, де він складає
програму [6, 7]. Оскільки Anaconda – це система програмування, розробники
передбачили можливість відображення результатів аналітичних розрахунків
обома цими способами. Змінювати режим відображення математичних
формул можна з використанням інструкції init_printing(). Ця функція
має один параметр і, як цей параметр, можна використовувати одну з
наступних логічних змінних [70].
pretty_print – виведення формул у якісному вигляді у графічному
режимі.
use_unicode – виведення формул в форматі стандарту Unicode.
use_latex – виведення формул в форматі стандарту TEX.
Розглянемо деякі можливості використання команди
init_printing() [70]. Інструкція
init_printing(pretty_print = False)
використовується для переходу до стандартного виведення математичних
формул у командний рядок. Інструкція
init_printing(use_latex = True)

276
переводить інтерпретатор до роботи із редактором Latex для виведення
математичних формул у графічному режимі. Розглянемо приклад
використання цих команд.
Приклад 6.66
>>> from sympy import *
>>> a, b, c, d = symbols(‘a b c d’)
>>> init_printing(use_latex = True)
>>> w = a/b + c/d
>>> u = w.cancel ()
ad + bc
bd
>>> init_printing(pretty_print = False)
>>> u
(a*d + b*c)/(b*d)
Можливість обрання різних форм подання та відображення
математичних виразів дозволяє користувачам системи Anaconda вкрай
ефективно працювати з її символьним процесором, використовуючи всі його
широкі можливості.
Як вже було відмічено, у цьому посібнику не описуються повністю всі
функції системи програмування Anaconda. Більш повну інформацію про
функції символьного процесора, призначені для здійснення алгебраїчних
перетворень, можна знайти в іншій навчальній літературі [26, 70].

6.1.4.3 Функції для аналітичного розв’язування алгебраїчних


рівнянь та їх систем
Іншою важливою алгебраїчною операцією, реалізованою у
символьному процесорі системи програмування Anaconda, є аналітичне
розв’язування лінійних та нелінійних рівнянь та їх систем. Для вирішення
цього завдання використовується певний набір функцій бібліотеки sympy.
Для записування алгебраїчних рівнянь у мові програмування IPython
використовується не декларативне об’явлення зі знаком рівності ==, а
відповідна логічна функція Eq() [70]. Ця логічна функція має наступний
формат
277
Eq(вираз_1, вираз_2)
Якщо значення символьних змінних вираз_1 та вираз_2 можна
порівняти, функція Eq() повертає значення True або False, залежно від
результату порівняння. У цій функції існує також опція
evaluate = False, використовуючи яку можна примусово відмінити
перевірку на рівність. Розглянемо деякі приклади використання функції
Eq() [70].
Приклад 6.67
>>> from sympy import *
>>> Eq(3, 4)
False
>>> x = 3
>>> Eq(3, x)
True
>>> Eq(3, 2 + 1)
True
>>> Eq(3, 4, evaluate = False)
Eq(3, 4)
>>> x, z = symbols(‘x y’)
>>> Eq(x, y)
Eq(x, y)
Всі функції символьного процесора системи програмування Anaconda,
призначені для розв’язування алгебраїчних рівнянь та їх систем,
використовують функцію Eq(), у якій автоматично вважається, що значення
другого виразу дорівнює 0 [70]. Тобто, формат цієї функції, у цьому,
конкретному випадку, має спрощений вигляд: Eq(вираз_1, 0).
Головні функції системи програмування Anaconda, які
використовуються для розв’язування алгебраїчних рівнянь, наведені у
таблиці 6.6. Параметрами цих функцій є наступні змінні.
1. Рівняння, яке розв’язується. Воно може бути записане як параметр
функції Eq(), але не обов’язково [70].
2. Змінна, відносно якої розв’язується рівняння.
3. Числова область пошуку рішення, яка визначається змінною domain
та записується як посилання на об’єкт S. Наприклад, domain = S.Reals,
domain = S.Complexes.

278
Таблиця 6.6 – Головні функції системи програмування Anaconda,
призначені для аналітичного розв’язування алгебраїчних рівнянь та їх систем

Функція Призначення
Аналітичне розв’язування рівняння відносно заданої
solveset()
змінної. Результат розрахунків повертається як множина
Функція повертає значення коренів рівняння у символьній
формі у вигляді словника у форматі {корінь:
roots()
кратність}. У разі встановлення опції dict = False
словник автоматично перетворюється на список
Функція повертає значення коренів заданого рівняння, які
real_roots()
лежать в області дійсних чисел
Функція повертає значення коренів заданого
nroots() поліноміального рівняння із заданою кількістю значущих
цифр
Головна функція символьного процесору системи
solve() Anaconda для розв’язування алгебраїчних рівнянь та їх
систем
linsolve() Функція для розв’язування систем лінійних рівнянь

Розглянемо приклади аналітичного розв’язування алгебраїчних рівнянь


та систем лінійних рівнянь з використанням функцій, наведених у
таблиці 6.6 [70].
Приклад 6.68
>>> from sympy import *
>>> solveset(Eq(x**2, 4), x)
{–2, 2}
>>> solveset(Eq(x**2 - 7*x + 12, 0), x)
{3, 4}
>>> solveset(Eq(x**2 - 5*x + 12, 0), x)
{5/2 – sqrt(23)*I/2, 5/2 + sqrt(23)*I/2}
>>> type(_)
279
<class ‘sympy.sets.sets.FiniteSet’>
>>> solveset(x**4 – 1, x)
{1, –1, –I, I}
>>> type(_)
<class ‘sympy.sets.sets.FiniteSet’>
>>> solveset(x**2 – x**2, x, domain = S.Reals)
{–oo, oo}
>>> type(_)
<class ‘sympy.sets.fancysets.Reals’>
>>> solveset(cos(x) – 1, x, domain = S.Reals)
ImageSet(Lambda(_n, 2*_n*pi), Integers())
>>> solveset(exp(x), x)
EmptySet
>>> x = S(‘x’)
>>> real_roots(x**2 – 4)
[–2, 2]
>>> p = (x – 3)**2*(x – 2)*(x – 1)*x*(x + 1)*\
(x**2 + x + 1)
>>> real_roots(p)
[–1, 0, 1, 2, 3, 3]
>>> real_roots(x**2 + x + 1)
[]
>>> a, b, c, x = symbols(‘a b c x’)
>>> roots(x**2 – c**2, x)
{–c: 1, c: 1}
>>> roots(x**3 – 5*x**2 + 3*x + 9, x)
{3: 2, –1: 1}
>>> factor(x**3 – 5*x**2 + 3*x + 9, x)
(x – 3)**2*(x + 1)
>>> nroots(x**2 – 2, 20)
[–1.4142135623730950488, 1.4142135623730950488]
>>> nroots(x**2 – 2, 5)

280
[–1.4142, 1.4142]
>>> x, y = symbols(‘x y’)
>>> solve(x**2 + x – 30, x)
[–6, 5]
>>> eq1 = Eq(a*x**2 + b*x + c, 0)
>>> solve(eq1)
[{a: –(b*x + c)/x**2}]
>>> solve(eq1, x)
[(–b + sqrt(–4*a*c+b**2))/(2*a),
–(b + sqrt(–4*a*c+b**2))/(2*a)]
>>> solve([x – 2*y, 3*x + y – 7], x)
{y:1, x:2}
>>> solve([Eq(x**2 – y**2, 0), Eq(x + y, 2)], \
x, y, dict = False)
[(1, 1)]
>>> solve(exp(x**2 + x – 6) – 1, x)
[–3, 2]
>>> solve(exp(x) + 1, x)
[I*pi]
>>> linsolve([x – 2*y, 3*x + y – 7], x, y)
{[2, 1]}
>>> linsolve(Matrix(([1, –2, 0], [3, 1, 7])), \
(x, y))
{[2, 1]}
У наведеному прикладі 6.68 досить повно показані функції
символьного процесора системи Anaconda щодо аналітичного розв’язування
алгебраїчних рівнянь та їх систем. Якщо рівняння не має аналітичного
розв’язку, необхідно використовувати інші функції бібліотеки scipy,
шукаючи відповідні чисельні алгоритми [26, 70].
Зверніть увагу на те, що функції системи програмування Anaconda,
наведені у таблиці 6.6, у значній мірі відповідають функціям системи
науково-технічних розрахунків MatLab, також призначених для
розв’язування алгебраїчних рівнянь та їх систем [6, 7].

281
6.1.4.4 Аналітичні функції матричної алгебри

В останній команді прикладу 6.68 використана команда символьного


процесора Matrix(), яка створює символьну матрицю та є однією з
головних серед символьних функцій матричного аналізу системи
програмування Anaconda. З одного боку, більшість цих функцій є
перевантаженими відносно функцій над числами, але оскільки матрична
алгебра має свої особливості [42], її функції зазвичай розглядають
окремо [70].
Відображення матриць аналітичним процесором у системі
програмування Anaconda також має свої певні особливості. Наприклад, якщо
перевести систему в режим відображення символьної математики в редакторі
Latex з використанням команди init_printing(use_latex = True),
всі матриці в цьому режимі коректно не відображуються. Проте для
коректного відображення в цьому режимі однієї матриці достатньо виконати
команду pprint(M), де M – ім’я матриці [70].
Головні функції символьного процесора системи Anaconda для роботи з
матрицями зазвичай співпадають із чисельними функціями матричної
алгебри, розглянутими у підрозділах 3.6.2 та 3.7.3. Список цих функцій
наведений у таблиці 6.7.
Таблиця 6.7 – Головні функції символьного процесора системи
програмування Anaconda, призначені для роботи з матрицями

Функція Призначення
Matrix() Створення із списку матриці для символьних перетворень
det() Формування аналітичного виразу для визначника матриці
M.T Функція транспортування матриці
Формування аналітичного виразу для матриці, зворотної
inv()
до заданої
eigenvals() Обчислення власних чисел матриці [42]
eigenvects() Обчислення власних векторів матриці [42]

Розглянемо приклади символьних перетворень над матрицями [70].

282
Приклад 6.69
>>> from sympy import *
>>> a, b, c, d = symbols(‘a b c d’)
>>> M = Matrix([a, b], [c, d])
>>> M[0, 0]
a
>>> v1 = Matrix([1, 2, 3])
>>> v1
Matrix([
[1],
[2],
[3]])
>>> M.det()
a*d – b*c
>>> M.T
Matrix([
[a, c]
[b, d]])
>>> B = simplify(M.inv())
Matrix([
[d/(a*d – b*c), –b/(a*d – b*c)]
[–c/(a*d – b*c), a/(a*d – b*c)]])
>>> M.eigenvals()
{5: 1, –1: 1}
>>> M.eigenvects()
[(–1, 1, [Matrix([[–2], [1]])]),
(5, 1, [Matrix([[1], [1]])])]
>>> x = symnbols(‘x:2:2’)
>>> x
(x00, x01, x10, x11)
>>> y = symnbols(‘y:2:2’)

283
>>> y
(y00, y01, y10, y11)
>>> A = Matrix([[x[0], x[1]], [x[2], x[3]]])
>>> A
Matrix([
[x00, x01],
[x10, x11]])
>>> B = Matrix([[y[0], y[1]], [y[2], y[3]]])
>>> B
Matrix([
[y00, y01],
[y10, y11]])
>>> A + B
Matrix([
[x00 + y00, x01 + y01],
[x10 + y10, x11 + y11]])
>>> A*B
Matrix([
[x00*y00 + x01*y10, x00*y01 + x01*y11],
[x10*y00 + x11*y10, x10*y01 + x11*y11]])
>>> A**2
Matrix([
[x00**2 + x01*x10, x00*x01 + x01*x11],
[x00*x10 + x10*x11, x01*x10 + x11**2]])
>>> A**(–1)
Matrix([
[1/x00 + x01*x10/x00**2*(x11 – x01*x10/x00),
–x01/(x00*(x11 – x01*x10/x00))],
[–x10/(x00*(x11 – x01*x10/x00)),
1/(x11 – x01*x10/x00)]])
>>> A = Matrix([1, 2], [3, 4])
>>> B = Matrix([1, –1], [–1, 3])
>>> A/B
284
Matrix([
[5/2, 3/2],
[13/2, 7/2]])
>>> A**(–1)
Matrix([
[–2, 1],
[3/2, –1/2]])
Слід відзначити, що з використанням матриць можна виконувати
досить складні алгебраїчні перетворення, тому вони часто використовуються
в задачах прикладного програмування [26, 70]. Деякі функції матричного
аналізу, реалізовані в системі програмування Anaconda, розглядалися в
підрозділі 6.1.2.5. Використання цих функцій разом із розглянутими у цьому
підрозділі функціями аналітичного процесора у значній мірі розширює
можливості розв’язування прикладних інженерних та наукових завдань з
застосуванням засобів матричного програмування [6, 7]. Наприклад,
матричні перетворення можна використовувати для аналізу електронних
схем [6, 7].

6.1.4.5 Аналітичні функції математичного аналізу


Головні функції символьного процесора системи програмування
Anaconda, призначені для виконання аналітичних операцій математичного
аналізу, наведені у таблиці 6.8.
Таблиця 6.8 – Функції символьного процесора, призначені для
виконання аналітичних операцій математичного аналізу
Функція Призначення
limit() Обчислення границі функції за заданих умов
diff() Обчислення похідної
Function() Визначення символьної функції
Інтегрування функцій, пошук невизначених та визначених
integrate()
інтегралів
summation() Пошук скінченних та нескінченних сум
series() Формування степеневих рядів та поліноміальні операції

285
Можливості символьного процесора системи програмування Anaconda
щодо виконання функцій математичного аналізу є досить широкими. Він
може обчислювати границю функції у заданій точці, зокрема з
використанням символу нескінченності, знаходити похідні та інтеграли від
аналітично заданих функцій, обчислювати скінченні та нескінченні суми та
формувати степеневі ряди [70].
Розглянемо приклади використання функцій символьного процесу
системи програмування Anaconda для виконання деяких операцій
математичного аналізу. Більш досконале описання цих функцій наведено у
навчальних посібниках [26, 70]
Приклад 6.70
>>> from sympy import *
>>> x, y, z = symbols(‘x y z’)
# Обчислення границць
>>> limit(sin(x)/x, x, 0)
1
>>> limit(x*log(x)/x, x, 0)
0
>>> expr = x**2*exp(–x)
>>> limit(expr, x, oo)
0
>>> limit((1+z/x)**x, x, oo)
exp(z)
>>> limit((sin(x + z) – sin(x))/z, z, 0)
cos(x)
# Обчислення похідної
>>> diff(sin(x)*exp(x), x)
exp(x)*sin(x) + exp(x)*cos(x)
# Обчислення похідної другого порядку
>>> diff(x**4, x, x)
12*x**2

286
# Обчислення похідної тртього порядку
>>> diff(x**4, x, 3)
24*x
>>> f = exp(x*y**2)
# Обчислення часткової похідної за змінними
# x та y
>>> diff(f, x, y)
2*y*(x*y**2 + 1)*exp(x*y**2)
>>> f = x**2 + y**2 + z**2
# Обчислення градієнту
>>> g = [diff(f, var) for var in [x, y, z]]
>>> g
[2*x, 2*y, 2*z]
# Обчислення часткової похідної d(f(x))/dx**2*dy
>>> f.diff(x, 2, y)
2*x**3*(x*y**2 + 2)*exp(x*y**2)
# Обчислення невизначених інтегралів
>>> integrate(1/x, x)
log(x)
>>> integrate(log(x), x)
x*log(x) – x
>>> _.diff(x)
log(x)
# Обчислення визначених інтегралів
>>> integrate(exp(x), (x, 0, oo))
1
>>> integrate(exp(–x**2), (x, –oo, oo))
sqrt(pi)
# Обчислення повторних невизначених
# та визначених інтегралів
>>> integrate(x*y, x, y)

287
>>> integrate(x*y, (x, 0, 1), (y, 0, 1))
1/4
>>> integrate(exp(–x**2 – y**2), \
(x, –oo, oo), (y, –oo, oo))
pi
>>> integrate(x**2*y), (y, 0, sqrt(1 – x**2)), \
(x, –1, 1))
2/15
>>> var (‘i, j, n’)
# Обчислення скінченних сум з числовими границями
>>> summation(2*i – 1, (i, 1, 12))
144
>>> summation((i + j)**2, (i, 1, 3), (j, 1, 4))
266
>>> summation(x**i/factorial(i), (i, 1, 7))
x**7/5040 + x**6/720 + x**5/120 + x**4/24 +
x**3/6 + x**2/2 + x
# Обчислення скінченних сум з символьними границями
>>> var (‘a, b’)
>>> s = summation(6*n**2 + 2**n, (n, a, b))
–2**a + 2**(b + 1) – 2*a**3 + 3*a**2 – a +
2*b**3 + 3*b**2 + b
>>> summation(i**2, (i, 1, n))
n**3/3 + n**2/2 + n/6
>>> summation(i**4, (i, 1, n))
n**5/5 + n**4/2 + n**3/3 – n/30
>>> factor(_)
n*(n + 1)*(2*n + 1)*(3*n**2 + 3*n – 1)/30
>>> simplify(summation((–1)**i*i/(4*i**2 – 1),\
(i, 1, n)))
((–1)**n – 2*n – 1)/(4*(2*n + 1))

288
# Обчислення нескінченних сум
>>> summation(1/i**2, (i, 1, oo))
pi**2/6
>>> summation(x**n/factorial(n), (n, 0, oo))
exp(x)
# Обчислення нескінченних степеневих рядів
>>> g = series(exp(x))
>>> g
1 + x + x**2/2 + x**3/6 + x**4/24 +
x**5/120 + O(x**6)
# Обчислення скінченних степеневих рядів
>>> sin(x).series(x, 0, 7)
x – x**3/6 + x**5/120 + O(x**7)
>>> log(x).series(x, 1, 4)
–1 – (x – 1)**2/2 + (x – 1)**3/3 +
O((x – 1)**4, (x, 1))
>>> sin(x).series(x, 0, 7).removeO()
x – x**3/6 + x**5/120
# Перераскладання поліному за степінню (x – a)
>>> P = x**5 + 2*x**4 – 3*x**3 + 6*x**2 – 12*x + 7
>>> P.series(x, 1, 5).removeO()
4*x + 7*(x – 1)**4 + 15*(x – 1)**3 + 19*(x – 1)**2 +7
# Алгебраїчні операції з поліномами
>>> f = series(sin(x))
>>> f
x – x**3/6 + x**5/120 + O(x**6)
>>> f + g
1 + 2*x + x**2/2 + x**4/24 + x**5/60 + O(x**6)
>>> simpify(f*g)
x + x**2 + x**3/3 – x**5/30 + O(x**6)
>>> simpify(g**2)

289
(120 + 120*x + 60*x**2 + 20*x**3 + 5*x**4 + x**5 +
O(x**6))**2/14400
>>> f.diff(x)
1 – x**2/2 + x**4/24 + O(x**5)
Розглянемо ще один приклад, в якому екстремум функції шукається
через обчислення її першої та другої похідної [70].

Приклад 6.71 Знайти максимум функції f ( x ) = x3 − x 2 + x .


Будемо розв’язувати цю задачу послідовно. Всі головні кроки її
розв’язування відмічені у коментарях до відповідних командних рядків.
# Визначення символьної змінної та аналітичного
# виразу для функції
>>> from sympy import *
>>> x = symbols(‘x’)
>>> f = x**3 – 2*x**2 + x
# Обчислення похідної від функції f(x)
>>> f1 = diff(f, x)
# Пошук коренів рівняння f’(x) = 0
>>> sls = solve(f1, x)
>>> sls
[1/3, 1]
>>> diff(f1, x).subs({x: sls[0]})
–2
>>> diff(f1, x).subs({x: sls[1]})
2
1
Оскільки у точці x = друга похідна функції f ( x ) є від’ємною
3
величиною, ця точна є точкою максимуму цієї функції [45]. Обчислимо
значення функції у цій точці.
>>> f.subs({x: sls[0]})
4/27
У багатьох випадках аналітичні перетворення для функцій математичного

290
аналізу зручніше аналізувати через подання результатів розрахунків в
графічному режимі з використанням редактора формул Latex. Розглянемо деякі
приклади таких символьних перетворень.
Приклад 6.72
>>> from sympy import *
>>> init_printing(use_latex = True)
>>> f = Function(‘f’)
>>> f(x).diff(x)
d
f (x )
dx
>>> f, g, h = symbols(‘f g h’, cls = Function)
>>> (f(x), g(x), h(x)).diff(x)
d d d
f ( x )g ( x ) h( x ) + f ( x )h( x ) g ( x ) + g ( x )h( x ) f ( x )
dx dx dx
>>> diff(f(x)/g(x), x)
d d
g (x ) f (x )
dx f (x ) + dx
g (x )
2 g (x )
>>> diff(exp(f(x)), x)

e f (x )
d
f (x )
dx
>>> f(x, y).diff(x, 2)

∂2
f ( x, y )
dx 2
>>> x, y, a, b = symbols(‘x y a b’)
>>> y = integrate((a + x**3), x)
>>> pprint(y)

3 3a 2 x 2 3 x
4
a x+ + ax + .
2 4
Деякі інші приклади використання символьного процесора системи
програмування Anaconda для здійснення аналітичних перетворень
математичного аналізу наведені у навчальному посібнику [70].
291
6.1.5 Приклади розв’язування прикладних завдань математичного
моделювання з використанням системи програмування Anaconda

6.1.5.1 Чисельне обчислення інтегралів

Модуль scipy містить великий набір функцій для розв’язування


завдань математичного моделювання з використанням чисельних методів.
Зокрема, тут реалізовані функції чисельного інтегрування та чисельного
розв’язування диференціальних рівнянь [70].
Список функцій чисельного інтегрування, реалізованих в бібліотеках
модуля scipy, наведений в таблиці 6.9.
Таблиця 6.9 – Функції чисельного інтегрування, реалізовані в модулі
scipy системи програмування Anaconda

Функція Призначення
quad() Однократне чисельне інтегрування
dblquad() Обчислення подвійного інтеграла
tplquad() Обчислення трійного інтеграла
nquad() Обчислення інтеграла кратності n
Обчислення невизначених інтегралів зі змінною верхньою
cumprapz()
границею
Розглянемо декілька прикладів чисельного обчислення визначених
інтегралів у системі програмування Anaconda.
Приклад 6.73 З використанням засобів системи програмування
1
Anaconda чисельно обчислити визначений інтеграл ∫ exp( x )sin ( x )dx .
−1
In[1]: from scipy.integrate import quad
In[2]: import numpy as np
In[3]: def f(x):
return np.exp(x)*sin(x)
In[4]: Iq = quad(f, –1, 1)
In[5]: print(Iq)

292
(–0.6634936666312413, 1.2783578503385453e–14)
Із прикладу 6.73 зрозуміло, що функція quad() повертає кортеж із
двох числових значень. Першим з них є безпосереднє значення обчисленого
інтегралу, а друге являє собою точність обчислень [70].
Із прикладу 6.73 також видно, що першим аргументом функції
інтегрування quad() є ім’я підінтегральної функції f(x). Слід мати на
увазі, що підінтегральна функція f(x, ...) може мати кілька аргументів, у
цьому випадку інтегрування проводиться за першим з них. Як параметр f у
функції quad() може бути використана анонімна лямбда-функція, основи
роботи з якою були описані у підрозділі 3.7.8.
Розглянемо відповідний приклад.
Приклад 6.74 З використанням засобів системи програмування
3
( )
Anaconda чисельно обчислити визначений інтеграл ∫ x 2 + y 2 dx за умови
0
y = 1.
In[1]: from scipy.integrate import quad
In[2]: import numpy as np
In[3]: f = lambda x, y: x**2 + y**2
In[4]: y, err = quad(f, 0, 1, args = (1,))
In[5]: print(y)
12.0
Для обчислення числового значення інтегралів, верхня або нижня
границя яких дорівнює нескінченності, у системі програмування Anaconda
використовується системна змінна numpy.inf. Якщо відповідний інтеграл
для перевірки результату чисельних розрахунків обчислюється аналітично,
тоді як символ нескінченності використовується набір символів oo.
Розглянемо відповідний приклад.
Приклад 6.75 З використанням засобів системи програмування

( )
Anaconda чисельно обчислити визначений інтеграл ∫ exp − x 2 dx .
0

293
In[1]: from scipy.integrate import quad
In[2]: import numpy as np
In[3]: I1 = quad(lambda x: np.exp(–x**2), 0, np.inf)
In[4]: print(I1)
(0.886226254527579, 7.1013183915439e–09)
In[5]: import sympy as smp
In[6]: x = smp.symbols(‘x’)
In[7]: s1 = smp.integrate(smp.exp(–x**2), \
(x, 0, smp.oo))
In[8]: print(s1)
sqrt(pi)/2
In[9]: print(s1.evalf())
0.886226254527578
Функція обчислення подвійного інтегралу dblquad() працює
наступним чином. Запишемо подвійний інтеграл у наступній математичній
формі:
b h( x )
∫ ∫ f ( x, y )dxdy , (6.6)
a g (x )

де функції g ( x ) та h( x ) – нижня та верхня границя інтегрування за змінною x,


a, b – нижня та верхня границя інтегрування за змінною y, f ( x, y ) –
підінтегральна функція. З урахуванням співвідношення (6.6) синтаксична
конструкція функції dblquad() має наступний вигляд [70].
scipy.integrate.dblquad(ffun, a, b, gfun, hfun)
де ffun – підінтегральна функція f ( x, y ) , a, b – нижня та верхня границя
інтегрування за змінною y, gfun, hfun – нижня та верхня границя
інтегрування за змінною x. Існує також особливість описання підінтегральної
функція f ( x, y ) , яка полягає у тому, що змінну y у переліку змінних потрібно
вказувати першою [70]. Це правило працює і у разі описання функції з
використанням декларації def:
def ffun(y, x)

294
і у разі її описання як анонімної лямбда-функції
lambda y, x: алгебраїчний_вираз
Також слід відзначити, що границі за змінною x для подвійного
інтеграла у команді виклику функції dblquad() завжди вказуються як
функції, навіть тоді, коли вони мають числові значення [70].
З урахуванням описаних особливостей розглянемо приклад чисельного
обчислення подвійного інтегралу [70].
Приклад 6.76 З використанням засобів системи програмування
Anaconda чисельно обчислити визначений подвійний інтеграл
1x
(
2 2
)
∫ ∫ x + y dydx .
00
In[1]: from scipy.integrate import dblquad
In[2]: f = lambda y, x: x**2 + y**2
In[3]: g = lambda x: 0
In[4]: h = lambda x: x
In[5]: I1 = dblquad(f, 0, 1, g, h)
In[6]: print(I1)
(0.333333333333333, 3.700743415417188e–15)
З іншого боку, аналогічний результат можна отримати з використанням
звичайної функції інтегрування quad(). У цьому разі ця функція
використовується двічі, як функція від функції. Відповідний спосіб роботи з
функціями у мові програмування Python був описаний у підрозділі 2.4.8. Тоді
відповідний програмний код можна записати наступним чином.
In[1]: from scipy.integrate import dblquad
In[2]: def f(y, u):
return y**2 + u**2
In[3]: def g(x):
return quad(f, 0, x, arg = (x,))[0]
In[4]: I1 = quad(g, 0, 1)
In[5]: print(I1)
(0.333333333333333, 3.700743415417188e–15)

295
Слід відзначити, що спосіб обчислення подвійних інтегралів з
використанням функції dblquad() зазвичай є більш ефективним, оскільки
програмний код цієї функції оптимізований саме для розв’язування задач
багатократного чисельного інтегрування. Аналогічно обчислюються потрійні
інтеграли та інтеграли кратності n [70].
Окремим завданням математичного аналізу є чисельне обчислення
невизначених інтегралів, або інтегралів зі змінною верхньою границею, які в
математичний формі записуються наступним чином [45]:
x
I ( x ) = ∫ f ( x )dx . (6.7)
a
Для обчислення інтегралів зі змінною границею у системі
програмування Anaconda використовується функція cumprapz().
Синтаксична конструкція функції cumprapz() має наступний вигляд [70].
scipy.integrate.cumprapz(y, x = None, axis = –1, \
initial = None)
де y – одновимірний масив значень функції, яка інтегрується, x –
одновимірний масив значень змінної, за якою проводиться інтегрування,
axis – координатна вісь, за якою проводиться інтегрування, initial –
значення, яке визначає перший елемент масиву y. Зазвичай стандартними
значеннями цих змінних є x = None та initial = None [70].
Аналізувати результат обчислення невизначеного інтегралу із змінною
верхньою границею зручніше за все через аналіз графіка функції I ( x ) . Таку
графічну залежність можна отримати з використанням графічних засобів
двовимірної графіки бібліотеки matplotlib, описаних у підрозділі 6.1.3.1.
Розглянемо приклад використання функції cumprapz() [70].
Приклад 6.77 З використанням засобів програмування системи
Anaconda чисельно обчислити інтеграл зі змінною верхньою границею
x
I ( x ) = ∫ cos 2 (t )dt та побудувати графік функції I ( x ) . Перевірити отриманий
0

296
x x sin (2 x )
результат, враховуючи, що ∫ cos 2 (t )dt = + [45].
0 2 4
Згідно з розглянутими теоретичними відомостями відповідний
програмний код можна записати наступним чином.
In[1]: from scipy.integrate import cumprapz
In[2]: import matplotlib.pyplot as plt
In[3]: import numpy as np
In[4]: x = np.linspace(0, 6, num = 25)
In[5]: y = np.cos(x)**2
In[6]: yint = cumprapz(y, x, initial = 0)
In[7]: exact = lambda x: x/2 + np.sin(2*x)/4
In[8]: [p1, p2] = plt.plot(x, exact(x), \
‘–b’, x, yint, ro)
In[9]: p1.set_linewidth(3)
In[10]: p2.set_markersize(8)
In[11]: fig = plt.gcf()
In[12]: fig.set_facecolor(‘white’)
In[13]: plt.show()
Результат роботи програмного коду, наведеного у прикладі 6.77,
показаний на рис. 6.23.

Рис. 6.23 Результат роботи програмного коду, наведеного у прикладі 6.77 [70]

Інші приклади обчислення інтегралів з використанням програмних


засобів системи програмування Anaconda можна знайти у навчальному
посібнику [70].
297
6.1.5.2 Чисельне розв’язування диференціальних рівнянь

У системі програмування Anaconda існують функції для розв’язування


звичайних диференціальних рівнянь. Розглянемо їх окремо.
Із основ математичного аналізу відомо [45], що задача Коші для
диференціального рівняння порядку n полягає у тому, що необхідно знайти
функцію ( )
f t , y, y ′, y ′′,K, y (n−1) , яка задовольняє головній умові, що
визначається рівністю:
(
y (n ) = f t , y, y ′, y ′′,K, y (n−1) , ) (6.8)
та початковим умовам:
y (t0 ) = y10 , y ′(t0 ) = y20 , ..., y (n ) (t0 ) = y n0 . (6.9)
Згідно із відомою з основ математичного аналізу теоремою Коші [45],
рівняння (6.8) завжди можна переписати у вигляді системи диференціальних
рівнянь першого порядку:
 dy1
 dt = f1 ( y1 , y 2 , K , y n , t );
 dy
 2 = f 2 ( y1 , y 2 , K , y n , t );
 dt (6.10)
KKKKKKKKKKK
 dy n
 = f n ( y1 , y 2 , K , y n , t ),
 dt
з початковими умовами
y1(t0 ) = y10 , y2 (t0 ) = y20 , ..., yn (t0 ) = yn0 . (6.11)
Зрозуміло, що рівняння (6.11) з математичної точки зору еквівалентні
рівнянням (6.9) [45, 70].
Модуль scipy.integrate містить дві функції, призначених для
розв’язування звичайних диференціальних рівнянь (ЗДУ) першого порядку із
заданими початковими умовами в одній точці – це функції ode() та
odeint(). У теорії диференціальних рівнянь ця задача називається задачею
Коші [45]. Різниця між функціями ode() та odeint() полягає в тому, що
функція ode() є більш універсальною та дозволяє розв’язувати складні
рівняння із високою степені жорсткості, проте функція odeint() має

298
простий інтерфейс та є придатною для розв’язування великої кількості
складних практичних інженерних завдань. Слід відзначити, що вказати
спосіб розв’язування диференціального рівняння у системі програмування
Anaconda неможливо, він визначається системою автоматично. З цієї точки
зору система Anaconda дещо поступається системі науково-технічних
розрахунків MatLab, де чисельний метод, який застосовується для
розв’язування рівняння, може бути заданий явно через обрання відповідної
функції [6, 7].
У цьому посібнику всі приклади орієнтовані на використання функції
odeint(). Спрощена лінгвістична конструкція для виклику цієї функції має
наступний вигляд [70].
odeint(func, y0, t, інші_параметри)
де func – це функція двох змінних, перша з яких є список, заданий у вигляді
[y1, y2, ..., yn], а друга змінна – незалежна. Аргумент y0 відповідає

масиву значень y10 , y20 ,K yn0 , а t – масив значень незалежної змінної t, для

якого розв’язується задача Коші. Значення y10 , y20 ,K yn0 відповідають системі
рівнянь (6.11), а значення y1, y2, ..., yn – це обчислені значення

y1 , y2 ,K yn у заданий момент часу.


Із сказаного вище зрозуміло, що в результаті своєї роботи функція
odeint() повертає двовимірний масив числових даних розмірності
r = len( y0 ) × len(t ) , (6.12)
де len (t ) – довжина вектора незалежної змінної t, len( y0 ) – довжина вектора
початкових значень змінної y0, яку необхідно обчислити [70]. В результаті
обчислений масив даних Y має наступний вигляд [70]:
 y1 (t0 ), y 2 (t0 ), K y n (t0 ) 
 ( ) y2 (t1 ), K y n (t1 )  .
Y =  y1 t1 , (6.13)
K K K K 
 y (t ), y 2 (t k ), K y n (t k ) 
 1 k
Зрозуміло, що для масиву Y, заданного формулою (6.13), len (t ) = k + 1 ,
len ( y0 ) = n . Оскільки дослідників, які розв’язують системи диференціальних
рівнянь, часто цікавлять графічні залежності для функцій yi (t0 ) для різних

299
значень змінної i, для побудови таких залежностей необхідно транспортувати
вектор yi з вектора-стовпця до вектора-рядка. Крім цього, часто дослідників
цікавлять залежності y j ( yi ) за умови j > i, які у науковій літературі з

диференціальних рівнянь називаються фазовими портретами [6, 7, 45]. Для


виконання алгебраїчної операції перетворення вектора-стовпця до вектора-
рядка в системі програмування Anaconda може бути використаний або
розглянутий вище оператор .T, або функція flattern() модуля np [70].
Іншими параметрами функції odeint(), які не є обов’язковими, можуть
бути відносна похибка обчислень rtol та абсолютна похибка atol. Зазвичай за
замовченням вважається, що rtol = atol = 1.49012e–8 [70]. Ці
параметри, а також деякі інші параметри обчислювального процесу інтегрування
диференціального рівняння, використовуються математиками та
кваліфікованими програмістами для ефективного керування роботою
обчислювальних алгоритмів функції odeint() [70].
Розглянемо деякі приклади використання функції odeint() для
розв’язування диференціальних рівнянь [70].
Приклад 6.78 З використанням засобів програмування системи
Anaconda чисельно розв’язати диференціальне рівняння y′ = − y5t 3 для
початкової умови y(–1,5) = 0,01 на відрізку значень змінної x [–1,5, 1,5]. На
заданому відрізку побудувати графік функції y(x) [70].
Відповідний програмний код можна записати наступним чином.
In[1]: from scipy.integrate import odeint
In[2]: import matplotlib.pyplot as plt
In[3]: import numpy as np
In[4]: def dydt(y, t)
return –5*t**3*y
In[5]: t = np.linspace(–1.5, 1.5, 31)
In[6]: y0 = 0.01
In[7]: y = odeint(dydt, y0, t)
In[8]: y_out = np.array(y).flattern()
In[9]: plt.plot(t, y_out, ‘–sr’, linewidth = 3)

300
Результат роботи програмного коду, наведеного у прикладі 6.78,
показаний на рис. 6.24 [70].

Рис. 6.24 Результат роботи програмного коду, наведеного у прикладі 6.78 [70]

Приклад 6.79 З використанням засобів програмування системи


Anaconda чисельно розв’язати диференціальне рівняння y′ + y = x для
початкової умови y(0) = 1 на відрізку значень змінної x [0, 4]. На заданому
відрізку побудувати графік функції y(x). На отриманий графічній залежності
порівняти отриманий результат чисельного розв’язку із відомим точним
рішенням y(x) = x – 1 + exp(–x). Знайти похибку чисельних розрахунків як
ε = yч − yт , де yч – чисельний розв’язок, yт – точне рішення. На основі

проведених розрахунків побудувати графічну залежність ε( x ) [70].


Відповідний програмний код можна записати наступним чином.
In[1]: from scipy.integrate import odeint
In[2]: import matplotlib.pyplot as plt
In[3]: import numpy as np
In[4]: def dydt(y, x)
return x – y
In[5]: x = np.linspace(0, 4, 41)
In[6]: y = odeint(dydt, y0, x)
In[7]: y_out = np.array(y).flattern()

301
In[8]: fig = plt.figure(facecolor = ‘white’)
In[9]: y_exact = x – 1+ 2*np.exp*(–x)
In[10]: ax = fig.gca()
In[11]: ax.plot(x, y_out, x, y_exact, ‘o’)
In[12]: ax.grid(True)
In[13]: y_diff = np.abs(y_out – y_exact)
In[14]: fig2 = plt.figure(facecolor = ‘white’)
In[15]: fig2.plot(x, y_diff, linewidth = 2)
In[16]: fig2.ylabel(‘Error’)
In[17]: fig2.title(‘Error in numeri\
cal integration’)
In[18]: fig2.grid(True)
Результати роботи програмного коду, наведеного у прикладі 6.79,
показані на рис. 6.25. На рис. 6.25, а, показаний графік аналітичного рішення
та точки, які відповідають чисельному розв’язку. Чітко видно, що результати
аналітичного рішення та чисельному розв’язку майже збігаються.
Розраховані значення похибки чисельних розрахунків відносно аналітичного
рішення показані на рис. 6.25, б. Як видно з наведених результатів,
абсолютне значення похибки не перевищує величини 5·10–8.

а) б)
Рис. 6.25 Результат роботи програмного коду, наведеного у прикладі 6.78. а –
чисельний та аналітичний розв’язки диференціального рівняння y′ + y = x для
початкової умови y(0) = 1, б – розрахована похибка чисельних обчислень [70]

302
Приклад 6.80 З використанням засобів програмування системи
1
Anaconda чисельно розв’язати диференціальне рівняння z′′ + z′ + z = 0 для
5
початкових умов z (0 ) = 0 , z′(0 ) = 1 на відрізку значень змінної x [0, 20]. На
заданому відрізку побудувати графік отриманої функції y1(x). Для отриманих
значень функцій y1(x) та y2(x) побудувати фазовий портрет y2(y1).
Оскільки розв’язується диференціальне рівняння другого порядку, для
чисельного розв’язування поставленої задачі необхідно спочатку звести її до
задачі Коші, заданої системою рівнянь (6.10), (6.11). Відповідна система
рівнянь записується у наступному вигляді [70].
dy1 dy 1
= y2 , 2 = − y2 − y1 , (6.14)
dt dt 5
y1(0) = 0 , y2 (0 ) = 1 . (6.15)
Програмний код, призначений для розв’язування системи рівнянь
(6.14) для початкових умов (6.15), можна записати наступним чином [70].
In[1]: from scipy.integrate import odeint
In[2]: import matplotlib.pyplot as plt
In[3]: import numpy as np
In[4]: def dydt(y, t)
Y1, y2 = y
return [y2, –0.2*y2 – y1]
In[5]: t = np.linspace(0, 20, 41)
In[6]: y0 = [0, 1]
In[7]: w = odeint(dydt, y0, 1)
In[8]: y1 = w[;, 0]
In[9]: y2 = w[;, 1]
In[10]: fig = plt.figure(facecolor = ‘white’)
In[11]: fig.plot(е, y1, ‘–o’, linewidth = 2)
In[12]: fig.grid(True)
In[13]: fig2 = plt.figure(facecolor = ‘white’)

303
In[14]: fig2.plot(y1, y2, linewidth = 2)
In[15]: fig.grid(True)
Результати роботи програмного коду, наведеного у прикладі 6.79,
показані на рис. 6.26. На рис. 6.26, а, зображений графік чисельного розв’язку
системи рівнянь (6.14) для початкових умов (6.15), а на рис 6.26, б – фазовий
портрет y2(y1) для цієї системи диференціальних рівнянь.

а) б)
Рис. 6.26 Часова залежність (а) та фазовий портрет (б) для функції z(t), яка є
1
розв’язком диференціального рівняння z′′ + z′ + z = 0 для початкових умов
5
z (0 ) = 0 , z′(0 ) = 1 [70]

На основі прикладу 6.80 розглянемо інший приклад, безпосередньо


пов’язаний із прикладними завданнями сильнострумної імпульсної
електроніки [6, 7]. Із загальної теорії коливань відомо, що у загальному
випадку нелінійні коливання у жорсткій системі описуються
диференціальним рівнянням Ван-дер-Пола другого порядку:

d2y
dt 2
(
− ε 1 − y2 )dydt + ω2 y = 0, (6.16)

де ω – частота коливань, ε – коефіцієнт жорсткості коливальної системи [6, 7].


З теорії колвань відомо, що рівняння (6.16) описує у загальному вигляді
роботу генераторів синусоїдальних коливань та мультивібраторів [6, 7].

304
Зведемо диференціальне рівняння другого порядку (6.16) до задачі
Коші, заданої системою рівнянь (6.10), (6.11). Відповідна система рівнянь для
початкових умов y1(0 ) = 0 , y2 (0 ) = 1 записується у наступному вигляді [6, 7]:

 y1′ = y2 ,

( )
2
 y2′ = ε 1 − y1 y2 − ω y1,
2
(6.17)
 y1(0 ) = 0, y2 (0 ) = 1.

У наступному прикладі розв’яжемо систему рівнянь (6.17).
Приклад 6.81 З використанням засобів програмування системи
Anaconda чисельно розв’язати систему диференціальних рівнянь (6.17) на
відрізку значень змінної t [0, 30] для значень ω = 1 , ε = 5 та ε = 0,1 .
Зрозуміло, що розв’язок цього завдання аналогічний розв’язку завдання
для прикладу 6.79, єдина відмінність полягає у написанні коду функції
dydt(y, t).
Відповідний програмний код можна записати наступним чином.
In[1]: from scipy.integrate import odeint
In[2]: import matplotlib.pyplot as plt
In[3]: import numpy as np
In[4]: def dydt(y, t)
Y1, y2 = y
return [y2, e*y1**2*y2 – y1]
In[5]: t = np.linspace(0, 30, 41)
In[6]: y0 = [0, 1]
In[7]: input (‘e =’, e)
e = 5
In[8]: w = odeint(dydt, y0, 1)
In[9]: y1 = w[;, 0]
In[10]: y2 = w[;, 1]
In[11]: fig = plt.figure(facecolor = ‘white’)
In[12]: fig.plot(е, y1, ‘–o’, linewidth = 3)
In[13]: fig.grid(True)

305
In[14]: fig2 = plt.figure(facecolor = ‘white’)
In[15]: fig2.plot(y1, y2, linewidth = 3)
In[16]: fig.grid(True)
Результати роботи програмного коду, наведеного у прикладі 6.79, для
значення ε = 5 показані на рис. 6.27, а для значення ε = 0,1 – на рис. 6.28.

а) б)
Рис. 6.27 Часова залежність (а) та фазовий портрет (б) для функції y(t),
заданої системою диференціальних рівнянь (6.17), за умови ε = 5 та ω = 1

а) б)
Рис. 6.28 Часова залежність (а) та фазовий портрет (б) для функції y(t),
заданої системою диференціальних рівнянь (6.17), за умови ε = 0,1 та ω = 1

Часові залежності та фазові портрети, аналогічні наведеним на


306
рис. 6.27 та 6.28, є важливими для аналізу особливостей роботи коливальних
імпульсних електронних схем залежно від коефіцієнту ε . Наприклад, за
законом, який описується системою диференціальних рівнянь (6.17),
працюють мультивібратори на потужних електронних лампах та на польових
транзисторах [6, 7].
Наведені у цьому підрозділі приклади свідчать про те, що у більшості
випадків для розв’язування різних диференціальних рівнянь зазвичай
достатньо змінити код функції для обчислення похідної, яку ми умовно
назвали dydt(), а решта командних рядків, у яких викликається функція
розв’язування рівняння odeint() та будуються відповідні графічні
залежності, залишаються незмінними. Інші цікаві приклади розв’язування
диференціальних рівнянь різних порядків з використанням засобів
програмування системи Anaconda наведені у навчальному посібнику [70].
Для закріплення теоретичного матеріалу, наведеного у цьому
підрозділі, необхідно виконати практичне заняття 10.

6.2 Функції інтерпретатора мови Python для програмування мережних


програмних додатків та приклади створення мережного програмного
забезпечення
6.2.1 Базові принципи програмування мережних додатків з
використанням функцій інтерпретатора мови Python
Загальна технологія програмування мережних програмних додатків є
єдиною для всіх мов програмування [12 – 14, 17, 20 – 24]. Вона полягає у
наступному. Якщо одному з комп’ютерів, який називається клієнтом,
необхідно передати дані іншому комп’ютеру, що підключений до тієї ж самої
локальної мережі та називається сервером, по перш за все необхідно
ідентифікувати ці комп’ютери через адреси мережного протоколу IP [20 –
22]. Інша проблема полягає у тому, що на комп’ютері, який приймає запит,
працює велика кількість програмних додатків, і ці додатки приймають різні
повідомлення. Наприклад, це можуть бути мережні новини, електронні

307
листи, запити на передавання файлів, запити до баз даних або запити на
інформацію в Інтернеті. Серед популярних сьогодні програм, які працюють з
мережними додатками, слід відзначити telnet, elm, Microsoft Outlook Express,
Microsoft Internet Explorer, Skype, Telegram та багато інших [12 – 14, 17, 22].
Оскільки всі ці мережні програми встановлені на більшості сучасних
комп’ютерів, насамперед серверу слід визначити, до якого саме мережного
додатку клієнт надіслав повідомлення. Для цього кожному додатку
присвоюється унікальний номер, який називається мережним портом. У разі
вирішення практичних завдань проектування комп’ютерних мереж часто
порти прив’язані не до конкретного програмного забезпечення, а до
відповідних мережних служб, наприклад, до протоколу підключення
оболонки командного рядка, до протоколу передавання файлів або до
протоколу електронної пошти [12 – 14, 20, 22].
Тобто, для організації надійного зв’язку між двома комп’ютерами у
мережі вкрай важливим для забезпечення безпомилкового передавання,
приймання та обробки повідомлень є взаємозв’язок між наборами числових
даних, які визначають мережну адресу та мережний порт. Такий
взаємозв’язок у технології програмування комп’ютерних мережних додатків
називається сокетом (англійській термін socket). У теорії комп’ютерних
мереж узагальнена лінгвістична конструкція для описання сокета має
наступний вигляд [17, 20, 22]:
Сокет = [мережна адреса: мережний порт].
Вперше ідея сокетів була реалізована в операційній системі Unix
FreeBSD на мові програмування С [17].
Розглянемо тепер різні моделі взаємодії між клієнтом та сервером [12 –
14, 24, 25].
1. Найпростішою та самою поширеною у використанні з них є модель
«запит – відповідь», яку розглядають також як діалог між клієнтом та
сервером. Ця модель взаємодії працює у синхронному режимі, тому
надіславши запит, клієнт відразу чекає відповіді від сервера.

308
2. Іншим поширеним шаблоном взаємодії між клієнтом та сервером є
модель «розгалуження на виході». Така модель відповідає принципу
передавання попереджень у разі появи небезпеки, який також називається:
«Всім, хто мене чує!».
3. Часто для організації зв’язку реалізується інша модель, яка
називається «розгалуження на вході». Тут, на відміну від попередньої моделі,
сервер одночасно приймає дані від кількох джерел та записує їх до
відповідного файлу з регістрацією повідомлень, який у літературі також
часто називають журналом повідомлень. Зазвичай за цим принципом
організується робота баз даних з розподіленим доступом [12 – 14].
4. Ще однією з поширених у використанні моделей взаємодії є модель
«розсилання – підписка». Ця модель відповідає надсиланню сформованих
повідомлень за заданою темою всім клієнтам, які на цю тему підписані. Із
всіх відомих стандартних способів зв’язку така модель найбільше схожа на
класичний спосіб підписування пересічених грамодян на державні та
комерційні періодичні видання, зокрема на газети, на журнали тощо.
5. Спрощена модель клієнт-серверної взаємодії, коли і програма клієнта
і програма сервера розташовані на одному комп’ютері. Ця модель є одним із
різновидів моделі «запит – відповідь». Тобто, нібито користувач комп’ютера
надсилає повідомлення сам собі. Проте слід відзначити, що у будь-якому разі
для організації взаємодії за цією моделлю програми клієнта та сервера
повинні бути різними, оскільки вони виконують різні функції [21]. Зазвичай
за такої умови вказується стандартна адреса для клієнта та сервера [17]:
localhost = 127.0.0.1.
Далі у цьому посібнику розглядатиметься лише п’ята модель
взаємодії. Для реалізації цієї моделі слід насамперед сформувати сокет, для
чого використовується вбудований модуль socket інтерпретатора мови
Python [24, 25].
Об’єкт класу socket створюється з використанням методу
socket(). Відповідна команда інтерпретатора мови програмування Python

309
має наступний синтаксис [24, 25].
Ім’я_змінної = socket.socket(socket.AF_INET, \
socket.SOCK_STREAM),
де AF_INET – мережна адреса, записана як рядкова змінна, SOCK_STREAM –
номер порту.
Для роботи з об’єктами класу socket використовуються наступні
методи, розташовані в модулі socket [24, 25].
1. bind() – прив’язування мережної адреси та номера порту до
відповідного об’єкта.
2. listen() – команда сервера для прослуховування мережі та
очікування запиту на з’єднання.
3. connect() – команда клієнта для формування запиту на з’єднання
з сервером.
Ця команда має наступний синтаксис [24, 25].
connect((HOST, PORT)),
де HOST – мережна адреса комп’ютера, до якого здійснюється з’єднання,
PORT – номер порту для з’єднання. У разі використання п’ятої моделі
взаємодії завжди використовується параметр мережної адреси
HOST = 127.0.0.1, або HOST = ‘localhost’.
4. accept() – команда сервера для прийняття запиту від клієнта та
формування нового сокета з метою організації з’єднання з клієнтом. Для
формування сокета використовується змінна із заданим іменем, а інша змінна
використовується для записування адреси клієнта. Формат команди
accept() має наступний вигляд [24, 25]:
Ім’я_сокету_для_з’єднання, Ім’я_для_записування_\
мережної_адреси = Ім’я_об’єкту.accept()
де Ім’я_об’єкту – посилання на ім’я сокета, попередньо створеного з
використанням методу socket().
5. send(‘Повідомлення’) – надсилання повідомлення.

310
6. recv(n) – прийняття повідомлення максимальною кількістю бітів
n, зазвичай встановлюється значення n = 1024.
7. close() – завершення з’єднання.
Робота сервера відрізняється від роботи клієнта тим, що клієнт формує
лише один сокет і здійснює через нього з’єднання з сервером, а серверу
необхідно сформувати також сокет для з’єднання з клієнтом, від якого
надіслано запит, з використанням методу accept().
Слід відзначити, що розмір пакету даних 1024 байти є максимальною
величиною за стандартом Ethernet [20, 22]. Якщо передається пакет даних із
меншим об’ємом, він надсилається та приймається автоматично без помилок.
Іншою важливою особливістю мережного передавання інформації є те,
що вона передається побітово, тому для коректного читання інформації на
приймальній стороні необхідно вказати спосіб кодування. Зазвичай з
використанням команди інтерпретатора мови Python встановлюється спосіб
кодування utf-8 [24, 25].
Часто для мережних додатків важливими параметрами роботи є час
встановлення з’єднання та час надсилання повідомлення [17, 21]. Для
коректного визначення цих параметрів використовуються процедури модуля
time інтерпретатора мови програмування Python [25].
6.2.2 Приклад створення простої мережної бази даних на основі
клієнт-серверної технології
Розглянемо деякі приклади написанням мережних програмних
додатків. Для простоти будемо вважати, що програмне забезпечення клієнта
та сервера встановлені на одному комп’ютері, тобто, реалізується п’ята
модель взаємодії.
Приклад 6.82 З використанням засобів програмування мови Python
написати мережне програмне забезпечення для формування повідомлень про
успішність студентів. Роботу клієнтської та серверної частин програмного
забезпечення реалізувати наступним чином. Викладач з програми клієнта
надсилає повідомлення «Як навчається студент С», де С – прізвище студента.

311
Секретар з програми сервера відповідає викладачеві з використанням
наступної системи кодування оцінок: 3 – задовільно, 4 – добре, 5 – відмінно.
В результаті у програмі клієнта формується відповідні повідомлення про
успішність студентів, наприклад: «Студент Потапенко навчається добре».
Для синхронізації роботи мережі та створення протоколів під час виведення
на екран запиту та відповіді обов’язково вказується час формування
повідомлення.
З використанням розглянутих вище теоретичних відомостей
відповідний програмний код для програми клієнта можна написати
наступним чином.
import socket as soc
import time as dt
HOST = '127.0.0.1'
PORT = 5000
i = 1
print('Список студентів:')
print('1 – Абраменко, 2 – Ігнатенко, /
3 – Костюченко')
print('4 – Потапенко, 5 – Хоменко, 6 – Шинкаренко')
while (i >=0 ):
inp=input('Введіть число від 1 до 6. С – перерв\
ати роботу ')
if (ord(inp)>ord('6')or(ord(inp)<ord('1')))and\
(inp!='С'):
continue
elif (inp=='С'):
break
elif (inp == '1'):
OutName = 'Abramenko'
elif (inp == '2'):
OutName = 'Ignatenko'
elif (inp == '3'):

312
OutName = 'Kostiuchenko'
elif (inp == '4'):
OutName = 'Potapenko'
elif (inp == '5'):
OutName = 'Homenko'
elif (inp == '6'):
OutName = 'Shinkarenko'
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.connect((HOST, PORT))
OutDate = dt.strftime('%d:%m:%Y')
OutTime = dt.strftime('%H:%M:%S')
SendString = OutDate + ' o ' + OutTime + ': \
How study the student ' + OutName + '?'
s.send(SendString.encode('utf-8'))
Resp=s.recv(1024)
RecDate = dt.strftime('%d:%m:%Y')
RecTime = dt.strftime('%H:%M:%S')
RecDT = RecDate + ' о ' + RecTime
Resp_Str = str(Resp)
Resp_Out = Resp_Str[2:len(Resp_Str)-1]
PrintStr = RecDT + ': Student ' + OutName +\
' study ' + Resp_Out
print(PrintStr)
s.close()
Відповідно, програмний код для серверної частини буде мати
наступний вигляд.
import socket as soc
import time as dt
HOST = '127.0.0.1'
PORT = 5000
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.bind((HOST, PORT))
print('Критерії оцінок:')
print('5 – відмінно, 4 – добре, 3 – задовільно')
313
s.listen(1)
conn, addr = s.accept()
RecvDate = dt.strftime('%d:%m:%Y')
RecvTime = dt.strftime('%H:%M:%S')
RecvDT = RecvDate + ' о ' + RecvTime
i = 3
print(RecvDT, ': отриманий запит від клієн\
та з адресою ', HOST)
while 1:
data = conn.recv(1024)
print(data)
if not data:
break
else:
while (i >=0 ):
inp=input('Введіть число від 3 до 5. ')
if ord(inp)>ord('5')or(ord(inp)\
<ord('3')):
continue
elif (inp == '5'):
OutMark = 'excellent'
break
elif (inp == '4'):
OutMark = 'good'
break
elif (inp == '3'):
OutMark = 'satisfactory'
break
conn.send(OutMark.encode('utf-8'))
SendDate = dt.strftime('%d:%m:%Y')
SendTime = dt.strftime('%H:%M:%S')
SendDT = SendDate + ' о ' + SendTime
print(SendDT, ': Клієнту з адре\
сою ', HOST, ' відправлено відпо\
відь на запит.')
s.listen(1)
conn, addr = s.accept()
conn.close()

314
Результат роботи програми клієнта та програми сервера для прикладу
6.82 показаний на рис. 6.29. Зрозуміло, що хоча здійснення запитів та
обробка даних проводиться на одному комп’ютері, програми клієнта та
сервера необхідно запускати у різних вікнах оболонки IDLE [24]. Спочатку
необхідно запустити додаток сервера, а після цього, запущений пізніше
додаток клієнта, встановлює з ним зв’язок.

Рис. 6.29 Вікна з результатами роботи програм сервера (зверху) та клієнта


(знизу) для прикладу 6.82, екранна копія

315
Оскільки через дрібний шрифт програмної оболонки IDLE текст на
рис.6.29 читати не досить зручно, нижче текстовий вміст вікон програм
сервера та клієнта роздрукований окремо.
Результати роботи програми клієнта.
>>> ======================= RESTART ==================
>>>
Список студентів:
1 – Абраменко, 2 – Ігнатенко, 3 – Костюченко
4 – Потапенко, 5 – Хоменко, 6 – Шинкаренко
Введіть число від 1 до 6. С – перервати роботу 4
23:07:2019 о 16:14:05: Student Potapenko study good
Введіть число від 1 до 6. С – перервати роботу 5
23:07:2019 о 16:14:26: Student Homenko study excellent
Введіть число від 1 до 6. С – перервати роботу 6
23:07:2019 о 16:14:58: Student Shinkarenko study
excellent
Введіть число від 1 до 6. С – перервати роботу 3
23:07:2019 о 16:15:12: Student Kostiuchenko study
satisfactory
Введіть число від 1 до 6. С – перервати роботу С
>>>
Результат роботи програми сервера.
>>> =================== RESTART ===============
>>>
Критерії оцінок:
5 – відмінно, 4 – добре, 3 – задовільно
23:07:2019 о 16:13:33 : отриманий запит від клієнта з
адресою 127.0.0.1
b'23:07:2019 o 16:13:33: How study the student
Potapenko?'

316
Введіть число від 3 до 5. 6
Введіть число від 3 до 5. 4
23:07:2019 о 16:14:05 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит.
b'23:07:2019 o 16:14:14: How study the student
Homenko?'
Введіть число від 3 до 5. y
Введіть число від 3 до 5. 5
23:07:2019 о 16:14:26 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит.
b'23:07:2019 o 16:14:49: How study the student
Shinkarenko?'
Введіть число від 3 до 5. 5
23:07:2019 о 16:14:58 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит.
b'23:07:2019 o 16:15:02: How study the student
Kostiuchenko?'
Введіть число від 3 до 5. 3
23:07:2019 о 16:15:12 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит.
Головними особливостями програмного коду, наведеного у прикладі
6.82, є наступні.
1. У програмі клієнта формування сокету та здійснення з’єднання з
сервером проводиться в циклі while (i>=0) лише тоді, коли повністю
сформований рядок із запитом до сервера. Для здійснення цих двох операцій
використаний наступний набір команд модуля socket.
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.connect((HOST, PORT))
2. Переривання з’єднання з боку клієнта здійснюється після отримання
відповіді від сервера на сформований запит за командою закриття сокета

317
s.close(). Для формування нового запиту створюється новий сокет.
3. Кількість запитів від клієнта до сервера може бути необмеженою,
оскільки цикл while (i>=0) у програмі клієнта може припинятися лише
примусово за командою користувача через натиснення на клавіатурі
української літери С.
4. Сервер відкриває з’єднання з клієнтом через прослуховування
мережі та встановлення зв’язку з ним у разі наявності запиту. Відповідний
набір команд розташований у циклі while (i>=0) у програмі сервера та
має наступний вигляд.
s.listen(1)
conn, addr = s.accept()
5. Дата та час формування та надсилання повідомлень визначаються
через звернення до системного годинника з використанням функції
strftime() модуля time [25]. Дата виводиться у форматі
Число:Місяць:Рік, а час – у форматі Часи:Хвилини:Секунди. Відповідні
формати команди strftime() мають наступний вигляд [25].
Для читання дати: Ім’я_змінної = dt.strftime('%d:%m:%Y')
Для читання часу: Ім’я_змінної = dt.strftime('%H:%M:%S')
6. Оскільки запити та відповіді формуються шляхом надсилання через
систему мережного зв’язку бітових послідовностей, для коректного читання
цих послідовностей слід вказувати тип кодування. Для цифр та літер
англійської абетки коректним є кодування UTF-8, а щодо повідомлень із
літерами національних абеток, тут тип кодування, особливо під операційною
системою Windows, може бути різним. Найчастіше для кодування літер
української абетки використовують або коди UTF-16, 1251 або cp-1252 [12 – 14,
24, 25]. Для уникнення помилок кодування та для спрощення програмного коду
всі повідомлення у прикладі 6.82 надсилаються англійською мовою.
Зрозуміло, що суттєвим недоліком програм, наведених у прикладі 6.82,
є те, що в них відповідь від сервера отримується через введення даних
секретарем з клавіатури. Такий підхід є аналогом спілкування між людьми

318
через мережу і він не дозволяє повністю оптимізувати процес формування
мережних повідомлень, що є вкрай важливим для уникнення помилок
введення інформації. А необхідність виводити інформацію на екран літерами
англійської абетки створює додаткові незручності.
Тому розглянемо тепер інший приклад, в якому сервер надсилає
клієнту коротке повідомлення із оцінкою студента, а відповідну інформацію
він знаходить через аналіз бази даних, сформованої на основі словника.
Методи та засоби для роботи зі словниками були розглянуті у підрозділі 4.4.
На основі отриманої інформації програма клієнта формує повідомлення про
успішність студента, а таке повідомлення вже без проблем виводиться на
екран з використанням символів кирилиці. В іншому підхід до організації
діалогу між клієнтом та сервером не відрізняється від базових принципів
програмування мережних додатків, які були розглянуті вище та використані
у прикладі 6.82.
Приклад 6.83 З використанням засобів програмування мови Python
написати мережне програмне забезпечення для формування повідомлень про
успішність студентів через звернення до серверної бази даних, створеної на
основі словника.
Для поставленого у цьому прикладі завдання код для програми клієнта
можна написати наступним чином.
import socket as soc
import time as dt
HOST = '127.0.0.1'
PORT = 5000
i = 1
print('Список студентів:')
print('1 – Абраменко, 2 – Ігнатенко, 3 – \
Костюченко')
print('4 – Потапенко, 5 – Хоменко, 6 – Шинкаренко')
while (i >=0 ):

319
inp=input('Введіть число від 1 до 6. \
С – перервати роботу ')
if (ord(inp)>ord('6')or(ord(inp)<ord('1')))and\
(inp!='С'):
continue
elif (inp=='С'):
break
elif (inp == '1'):
OutName = 'Abramenko'
OutName_UA = 'Абраменко'
elif (inp == '2'):
OutName = 'Ignatenko'
OutName_UA = 'Ігнатенко'
elif (inp == '3'):
OutName = 'Kostiuchenko'
OutName_UA = 'Костюченко'
elif (inp == '4'):
OutName = 'Potapenko'
OutName_UA = 'Потопенко'
elif (inp == '5'):
OutName = 'Homenko'
OutName_UA = 'Хоменко'
elif (inp == '6'):
OutName = 'Shinkarenko'
OutName_UA = 'Шинкаренко'
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.connect((HOST, PORT))
OutDate = dt.strftime('%d:%m:%Y')
OutTime = dt.strftime('%H:%M:%S')
SendString = OutDate + ' o ' + OutTime + '|'+ OutName
s.send(SendString.encode('utf-8'))

320
Resp=s.recv(1024)
RecDate = dt.strftime('%d:%m:%Y')
RecTime = dt.strftime('%H:%M:%S')
RecDT = RecDate + ' о ' + RecTime
Resp_Str = str(Resp)
Resp_Out = Resp_Str[2:len(Resp_Str)-1]
Resp_Num = int(Resp_Out)
if(Resp_Num == 3):
Resp_Prn = 'задовільно'
elif(Resp_Num == 4):
Resp_Prn = 'добре'
elif(Resp_Num == 5):
Resp_Prn = 'відмінно'
if(Resp_Num == 0):
PrintStr = RecDT + ': Студент ' + OutName_UA + \
' у списку не знайдений.'
else:
PrintStr = RecDT + ': Студент ' + OutName_UA + \
' навчається ' + Resp_Prn
print(PrintStr)
s.close()
Код програми сервера для цього прикладу буде мати наступний вигляд.
import socket as soc
import time as dt
HOST = '127.0.0.1'
PORT = 5000
Stud_List = dict()
Stud_List['Abramenko'] = '4'
Stud_List['Kostiuchenko'] = '3'
Stud_List['Potapenko'] = '4'
Stud_List['Homenko'] = '5'

321
Stud_List['Shinkarenko'] = '5'
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.bind((HOST, PORT))
print('Критерії оцінок:')
print('5 – відмінно, 4 – добре, 3 – задовільно')
s.listen(1)
conn, addr = s.accept()
RecvDate = dt.strftime('%d:%m:%Y')
RecvTime = dt.strftime('%H:%M:%S')
RecvDT = RecvDate + ' о ' + RecvTime
OutMark = '0'
i = 1
print(RecvDT, ': отриманий запит від клієнта з \
адресою ', HOST)
while 1:
while (i > 0):
data = conn.recv(1024)
print(data)
if not data:
break
else:
Rec_Str = str(data)
n = str.find(Rec_Str, '|')
Stud_Name = Rec_Str[(n + 1):len(Rec_Str)-1]
if ((Stud_Name in Stud_List) == True):
OutMark = Stud_List[Stud_Name]
Mess = 'Інформація про студента знайдена'
else:
OutMark = '0'
Mess = 'Інформація про студента не знайдена'
conn.send(OutMark.encode('utf-8'))

322
SendDate = dt.strftime('%d:%m:%Y')
SendTime = dt.strftime('%H:%M:%S')
SendDT = SendDate + ' о ' + SendTime
print(SendDT, ': Клієнту з адресою ', HOST, \
' відправлено відповідь на запит. ', Mess)
conn.close()
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
Нижче наведений текстовий вміст вікон програм сервера та клієнта для
прикладу 6.83.
Результати роботи програми клієнта.
>>> ================= RESTART ======================
>>>
Список студентів:
1 – Абраменко, 2 – Ігнатенко, 3 – Костюченко
4 – Потапенко, 5 – Хоменко, 6 – Шинкаренко
Введіть число від 1 до 6. С – перервати роботу q
Введіть число від 1 до 6. С – перервати роботу 1
24:07:2019 о 13:47:05: Студент Абраменко навчається добре
Введіть число від 1 до 6. С – перервати роботу 2
24:07:2019 о 13:47:19: Студент Ігнатенко у списку не
знайдений.
Введіть число від 1 до 6. С – перервати роботу 3
24:07:2019 о 13:47:36: Студент Костюченко навчається
задовільно
Введіть число від 1 до 6. С – перервати роботу 4
24:07:2019 о 13:47:42: Студент Потопенко навчається добре
Введіть число від 1 до 6. С – перервати роботу 5
24:07:2019 о 13:47:49: Студент Хоменко навчається

323
відмінно
Введіть число від 1 до 6. С – перервати роботу 6
24:07:2019 о 13:47:54: Студент Шинкаренко навчається
відмінно
Введіть число від 1 до 6. С – перервати роботу 8
Введіть число від 1 до 6. С – перервати роботу С
>>>
Результати роботи програми сервера.
>>> ================= RESTART ======================
>>>
Критерії оцінок:
5 – відмінно, 4 – добре, 3 – задовільно
24:07:2019 о 13:47:05 : отриманий запит від клієнта з
адресою 127.0.0.1
b'24:07:2019 o 13:47:05|Abramenko'
24:07:2019 о 13:47:05 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит. Інформація про студента
знайдена
b'24:07:2019 o 13:47:19|Ignatenko'
24:07:2019 о 13:47:19 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит. Інформація про студента
не знайдена
b'24:07:2019 o 13:47:36|Kostiuchenko'
24:07:2019 о 13:47:36 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит. Інформація про студента
знайдена
b'24:07:2019 o 13:47:42|Potapenko'
24:07:2019 о 13:47:42 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит. Інформація про студента
знайдена

324
b'24:07:2019 o 13:47:49|Homenko'
24:07:2019 о 13:47:49 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит. Інформація про студента
знайдена
b'24:07:2019 o 13:47:54|Shinkarenko'
24:07:2019 о 13:47:54 : Клієнту з адресою 127.0.0.1
відправлено відповідь на запит. Інформація про студента
знайдена
Зрозуміло, що функціональність програм, наведених у прикладі 6.83, є
значно вищою, ніж програм, наведених у прикладі 6.82. Головна перевага
програмного забезпечення, створеного у прикладі 6.83, полягає у тому, що сервер
тепер формує інформаційне повідомлення за запитом, поданим клієнтом, цілком
автоматично, що дозволяє уникнути помилок, які часто виникають у разі ручного
введення інформації. Єдиним недоліком клієнтської частини програмного
забезпечення, розглянутого у прикладі 6.83, є те, що введення та виведення
інформації здійснюється в консольному режимі, без використання зручних засобів
віконного інтерфейсу, розглянутих у п’ятому розділі. Проте, як було відмічено у
підрозділі 5.1, програми із віконним інтерфейсом відрізняються від консольних
лише способом введення та виведення даних. Тому, знаючи базові методи для
створення та налаштування головних елементів віконного інтерфейсу, розглянуті у
підрозділі 5.2.6, клієнтську частину програми, наведеної у прикладі 6.83,
нескладно переписати. Щодо серверної частини цього програмного забезпечення,
то оскільки задачею сервера тепер є лише формування відповідей на запити
клієнта та фіксування часу надходження цих запитів, він може працювати і в
консольному режимі. Більшість сучасних розподілених клієнт-серверних систем
працює саме за таким принципом [12 – 14].
Розглянемо приклад написання клієнтської частини мережного програмного
забезпечення з віконним інтерфейсом користувача.
Приклад 6.84 З використанням засобів програмування мови Python
переписати клієнтську програму, наведену у прикладі 6.83, передбачивши

325
можливість зручного введення та виведення інформації через елементи
віконного інтерфейсу користувача.
Розглянемо спочатку головні елементи, які мають бути розташовані в
інтерфейсному вікні такої програми. Будемо формувати проект віконного
інтерфейсу на основі програми для введення інформації про студента,
розглянутої у підрозділі 5.2.6.7, приклад 5.19, та наведеної у додатку А.
Згідно із логікою роботи клієнтської програми, код якої наведений у
прикладі 6.83, віконний інтерфейс такої програми повинен містити наступні
елементи.
1. Текстове вікно або випливаючий список для введення прізвища
студента. Використаємо для нашої програми випливаючий список,
вважаючи, що прізвища всіх студентів вже відомі та занесені до
інформаційної бази клієнтської програми. Такий підхід значно спрощує
створення програмного забезпечення для роботи з розподіленими базами
даних [12 – 14].
2. Над випливаючим списком розташуємо текстове вікно із підписом
«Прізвище студента».
3. Безпосередньо під випливаючим списком розташуємо текстове вікно
класу Label для виведення інформаційного рядка про успішність студента.
4. Над текстовим вікном, до якого виводиться інформація про студена,
розташуємо текстове вікно із незмінним підписом «Формування
інформаційного повідомлення».
5. Кнопку «Формування запиту», після натиснення якої здійснюється
формування запиту до сервера та заповнення текстового вікна.
6. Кнопку «Очистити» для очищення текстового вікна.
7. Кнопку «Вихід» для закінчення роботи з програмою.
Відповідний проект віконного інтерфейсу показаний на рис. 6.30.
Код програми клієнта із вікном графічного інтерфейсу, призначеної для
виконання поставленого завдання, наведений у додатку З, а результат роботи
цієї програми показаний на рис. 6.31.

326
Головне вікно

Випливаючий
список з
Кнопка «Вихід»
прізвищами
студентів

Текстове вікно для виведення


інфорамції про успішність студента

Кнопка «Формування запиту»

Кнопка «Очищення»

Рис. 6.30 Загальна структура інтерфейсного вікна програми клієнта для


прикладу 6.84

Рис. 6.31 Результати роботи програм клієнта та сервера для прикладу 6.84,
екранна копія
327
6.2.3 Приклад створення простої мережної обчислювальної
програми на основі клієнт-серверної технології
Розглянемо ще один приклад, в якому з використанням клієнт-
серверних технологій реалізується проведення мережних обчислень із
надсиланням запиту від клієнта та отримання відповіді від сервера. Сьогодні
такі технології організації мережних обчислень часто використовуються для
проведення складних наукових розрахунків, вони отримали назву хмарних
обчислень [12 – 14]. Зазвичай ефективність хмарних обчислень полягає у
тому, що складну обчислювальну роботу можна переносити на сервери, які
часто мають значно більшу швидкодію та обчислювальну потужність, ніж
персональні комп’ютери клієнтів.
Приклад 6.85 З використанням засобів програмування мови Python
написати програми клієнта та сервера для обчислення значень функцій
cos( x ) arcsin ( x )

sin ( x )  sin ( x ) 
f (x ) = e , f ( x ) = ln  та f ( x ) = e x −1 в області раціональних
 x +1 
чисел для заданого значення аргументу. Програму клієнта реалізувати з
використанням графічних засобів віконного інтерфейсу. У разі, якщо провести
обчислення неможливо, виводити у текстове вікно замість результату обчислень
відповідне повідомлення: «Неправильне числове значення», «Помилка ділення
на 0» або «Неправильно заданий аргумент функції».
Коди програм клієнта та сервера, призначені для виконання завдання
цього прикладу, наведені у додатку І. Розглянемо головні особливості
написання цих програм.
По-перше, відразу домовимось про те, що ми будемо передавати з
клієнта до сервера та з сервера до клієнта мінімальну кількість необхідної
інформації без тексту, написаного кириличним шрифтом. У зв’язку з цим для
формування запита з клієнта на сервер для прикладу, який розглядається,
необхідно передати лише номер функції та числове значення аргументу.
Тепер домовимось про головні необхідні елементи інтерфейсного
вікна. Оскільки клієнтська частина програмного забезпечення реалізується з
328
віконним інтерфейсом, функцію, яка розраховується, будемо вводити через
виплаваючий список, а значення аргументу функції – через текстове вікно.
Вигляд інтерфейсного вікна програми клієнта показаний на рис 6.32, а – г.
Також в інтерфейсному вікні програми клієнта необхідно розташувати два
окремих текстових вікна. Перше вікно призначене для виведення часу
отримання відповіді на запит, а друге – для виведення результату обчислення
значення функції, або відповідної інформації про помилку введення даних.

а) б)

в) г)
Рис. 6.32 Результати роботи програм клієнта для прикладу 6.85 у разі
cos( x )

sin ( x )
обчислення значення функції f ( x ) = e для помилкових (а, в, г) та
непомилкового (б) значень аргументу, екранна копія
329
Крім цього, у нижній частині інтерфейсного вікна розташовані кнопки
«Обчислити», «Очистити» та «Вихід». У разі натиснення кнопки
«Обчислити» через виклик функції req_serv() формується запит до
сервера.
Текстовий рядок для формування запиту від клієнта до сервера
створюється через читання системного часу, а також через аналіз введених
значень випливаючого списку lstb1 та текстова вікна з редагуванням тексту
et1. Формат цього текстового рядка має наступний вигляд.
[Дата запиту] о [Час запиту] | [Номер функції] \
# [Значення аргументу]
У наведеній лінгвістичній конструкції формати запису дати та часу
надсилання запиту відповідають стандарту, який використаний у функції
strftime модуля time та був розглянутий у прикладі 6.81.
Кнопка «Очистити» очищує обидва текстових вікна, призначених для
виведення результатів обробки запиту, а кнопка «Вихід» закриває віконний
інтерфейс клієнтської програми. Кнопці «Очистити» відповідає функція
clr_r() програми клієнта, а кнопці «Вихід» – стандартна функція
destroy() модуля tkinter, яка була розглянута у підрозділі 5.1.
Обробка запиту з боку сервера реалізована наступним чином. Спочатку
з використанням функцій обробки рядків, розглянутих у підрозділі 2.6, із
переданої клієнтом інформації виділяються дата та час передавання запиту,
номер функції та числове значення аргументу. Для розділення полів запиту
використовуються спеціально введені в нього символи логічного або (|) та
номеру (#). Таким способом формуються дві рядкових змінні: змінна
Num_Fun, яка відповідає номеру функції, та змінна Dig, яка відповідає
кінцевій частині переданого рядка, символи якої розташовані за символом #.
Але, враховуючи те, що значення аргументу функції, записане у текстовому
вікні клієнтської програми, через помилку користувача може бути не
числовим, початкова обробка змінної Dig із спробою перетворити її на

330
числове значення виконується у серверній програмі з використанням
оператору обробки виключної ситуації try: except:. Особливості роботи
цього оператора були описані у підрозділі 3.7.9. У тілі цього оператора
створюється рядкова змінна Calc_Result, за допомогою якої формується
результат проведення обчислень або повідомлення про відповідну помилку.
Наприклад, у разі, якщо значення змінної Dig не є числовим, змінній
Calc_Result присвоюється значення рядка 'Error'.
У разі, якщо значення змінної Dig є числовим, виконується команда
Dig_Num = float(Dig), яка розташована в тілі конструкції try:
оператора try: except:. Тепер подальша обробка виключної ситуації
здійснюється залежно від аргумента функції, яка обчислюється, через
послідовне використання низки умовних операторів. Якщо виникає помилка
ділення на 0, змінній Calc_Result присвоюється значення 'Inf', у разі
неправильного аргументу обчислюваної функції – значення 'NaN', а якщо
аргумент заданий правильно та функція може бути обчислена, тоді вона
обчислюється та змінній Calc_Result надається відповідне числове
значення. Для коректного звернення до математичних функцій, визначених у
цьому прикладі, а також для спрощення програмного коду, на початку
серверної програми стоїть команда
import math as m
В кінці серверної програми змінна Calc_Result передається до
клієнта з використанням команди
conn.send(Calc_Result.encode('utf-8'))
Головні особливості роботи цієї команди були розглянуті у підрозділі 6.2.1.
Зрозуміло, що на стороні клієнта читати повідомлення типу Inf, NaN
або Error користувачу було б вкрай незручно, тому на клієнтській стороні
відповідні повідомлення вже виводяться українською мовою: «Неправильне
числове значення», «Помилка ділення на 0» або «Неправильно заданий
аргумент функції». Для здійснення перетворення прийнятої від сервера

331
бітової змінної Resp_Out до рядкової змінної Resp_Out_Str, яка
виводиться у текстове вікно, у програмі клієнта використаний умовний
оператор. Відповідні екранні копії інтерфейсного вікна програми клієнта
наведені на рис. 6.32.
У командному вікні серверної програмі на екран виводяться відповідні
повідомлення про прийняті від клієнта запити та передані відповіді,
фіксується також час прийняття повідомлень та передавання відповідей. Таке
командне вікно для прикладу, який розглядається, показане на рис. 6.33.

Рис. 6.33 Командне вікно серверної програми для прикладу 6.85, екранна
копія

Із наведених прикладів зрозуміло, що для створення ефективних


мережних програмних додатків крім функцій модуля socket, розглянутих у
підрозділі 6.2.1, використовуються всі інші функції інтерпретатора мови

332
Python, розглянуті в цьому посібнику. Наприклад, у додатках для роботи з
базами даних ефективно використовуються списки та словники, а у
програмному забезпеченні, призначеному для розв’язування складних
інженерних та наукових завдань матепматичного моделювання в
розподілених обчислювальних мережах, важливим є використання функцій
математичного блоку, розглянутих у підрозділі 2.4.
У будь-якому разі, під час створення мережного програмного
забезпечення головним принципом є простота та лаконічність повідомлень,
які передаються. У разі необхідності передавання через мережу великої
кількості інформації, наприклад графічної інформації або відеороликів,
зазвичай використовуються ефективні цифрові методи її стиснення [12 – 14].
Для закріплення теоретичного матеріалу, наведеного у цьому
підрозділі, необхідно виконати практичне заняття 11.

6.3 Можливості використання інтерпретатора мови Python для


програмування мікроконтролерів
У мові програмування Python існують відповідні бібліотеки, призначені
для програмування сучасних мікроконтролерів. Для вирішення таких завдань
насамперед необхідно підключити мікроконтролер, функції для роботи з
яким існують в інтерпретаторі мови Python, до відповідного порту
передавання даних персонального комп’ютера. У загальному випадку це
може бути порт USB, LPT або COM [24]. Розглянемо один з таких прикладів,
для виконання якого Вам необхідно мати мікроконтролер Auderino Mega
2560, модуль датчика освітленості LM393 та рідиннокристаличний екран з
екранованим кабелем та клавішною панеллю (англійський термін LCD
Keypad Shield).
Приклад 6.86 З використанням засобів мов програмування С та Python
написати програмний код для відображення значення освітленості,
передавання їх через послідовний порт та зчитування з послідовного порту.
Для вимірювання освітленості у приміщенні використати мікроконтролер

333
Auderino Mega 2560 [24].
Нижче наведений код програми для мікроконтролера Auderino Mega
2560, написаний на мові програмування С [24]. Особливості написання таких
програм наведені у навчальному посібнику [5].
// Підключення коду бібліотеки
# include LicuidCrystal.h
// Ініциалізація функції lcd() та перелік номерів
// відповідних контактів
LicuidCrystal lcd(8, 9, 4, 5, 6, 7);
// Підключення аналогового сигнального контакта
const int analogSignal = A1;
// Підключення цифрового сигнального контакта
const int digitalSignal = 7;
// Змінна для збереження значення про наявність
// світла
boolean noLight
// Змінна для збереження значення освітленності
int lightness = 0
// Функція для встановлення режиму
// роботи мікроконтролера Auderino
void setup()
{
// 1. Встановлення режиму роботи контакта
pinMode(digitalSignal, INPUT)
// 2. Ініціалізація опслідовного порту
Serial.begin(9600)
// 3. Встановлення стовпчика та рядка для
// положення курсору на рідиннокристалічному
// моніторі
lcd.begin(16, 2)

334
}
// Функція циклу для зчитування
// значення освітленності
void loop()
{
// Чи є світло взагалі?
noLight = digitalRead(digitalSignal)
// Читання значення освітленності
lightness = analog.Read (analogSignal)
// Встановлення стовпчика та рядка для
// положення курсору на рідиннокристалічному
// моніторі
lcd.setCursor(0, 0)
// Виведення повідомлення на рідиннокристалічний
// монітор
// Друк повідомлення ‘There is ’
Serial.print(‘There is ’)
// Друк повідомлення ‘dark’ у разі відсутності
// світла
if (nolight)
{
Serial.print(‘dark.’)
lcd.print(‘dark.’)
}
// Друк повідомлення ‘lightly.’ у разі
// збільшення освітленності
else
{
Serial.print(‘lightly.’)
lcd.print(‘lightly.’)
}

335
// Друк повідомлення ‘value’
Serial.print(‘value: ’)
// Друк числового значення освітленості
Serial.print(lightness)
// Встановлення стовпчика та рядка для
// положення курсору на рідиннокристалічному
// моніторі
lcd.setCursor(0, 1)
// Виведення числового значення освітленості
// на рідиннокристалічний монітор
lcd.print(lightness)
// Затримка циклу вимірювання освітленості
// на 1 секунду
delay(1000)
}
Результат роботи цього програмного коду на платі мікроконтролера
Auderino Mega 2560 показаний на рис. 6.34 [24].

Рис. 6.34 Результат роботи програмного коду, наведеного у прикладі 6.86,


для мікроконтролера Auderino Mega 2560 [24]

336
Тепер, після занесення відповідного програмного коду, написаного мовою
програмування С, до пам’яті мікроконтролера, можна, з використанням засобів
бібліотеки pySerial інтерпретатора мови програмування Python, зчитувати
значення, які мікроконтролер Auderino Mega 2560 буде кожну секунду
надсилати на послідовний порт комп’ютера. Відповідний програмний код,
написаний мовою програмування Python, має наступний вигляд [24].
import serial as s
sr = s.Serial(‘/dev/ttyACM0’, 9600)
while True:
print(s.readline())
Результат роботи такого фрагмента програми в інтерпретаторі мови
програмування Python буде мати приблизно наступний вигляд [24].
b‘value: 116/r/n’
b‘There is lightly./r/n’
b‘value: 118/r/n’
b‘There is lightly./r/n’
b‘value: 0/r/n’
b‘There is dark./r/n’
b‘value: 0/r/n’
b‘There is dark./r/n’
b‘value: 114/r/n’
b‘There is lightly./r/n’
Зрорзуміло, що виведення даних на рідиннокристаличний монітор не
завжди є необхідним, що у деякій мірі спрощує постановку цього
навчального експерименту та його вартість. Проте наявність
мікроконтролера та датчика освітленості LM393 у будь-якому разі є
обов’язковою.
Із кодів програм, наведених у прикладі 6.86, можна зробити наступні
висновки щодо особливостей програмування мікроконтролерів з

337
використанням засобів мови програмування Python.
1. Для створення програмного забезпечення мікроконтролерів
використовується мова програмування С, яка є дуже гнучкою
низькорівневою мовою та дозволяє досить ефективно керувати
програмованою цифровою електронною апаратурою [3, 5].
2. Передавання даних через послідовний порт здійснюється побітово,
як і для клієнт-серверних технологій комп’ютерних мереж. Це пов’язано з
тим, що передавання даних між комп’ютерами та між комп’ютерним
програмним забезпеченням з теоретичної точки зору є одним із різновидів
взаємодії комп’ютера із зовнішнім пристроєм [20, 21].
Проте, у разі програмування мікроконтролерів завдання програмістів
зазвичай спрощується тим, що на них вкрай рідко передається текстова
інформація, у більшості випадків це або відповідні сигнали керування, або
числові значення. Однак, у будь-якому разі, програмне забезпечення
мікроконтролерів пишеться на мовах С та асемблер, тобто, якщо на
головному комп’ютері писати програму на мові програмування Python, таке
програмне забезпечення має бути різномовним.
Розглянемо більш простий приклад програмування мікроконтролера
Auderino, у якому реалізується не лише приймання інформації з
мікроконтролера, але й надсилання інформації до нього з метою
забезпечення керування його роботою. Для цього прикладу наявність датчика
та рідиннокристаличного монітору не потрібна, оскільки здійснюється
керування освітленістю світлодіода, який розташований безпосередньо на
платі мікроконтролера. Для надсилання інформації на мікроконтролер
використовується метод write() модуля pySerial [75]. Проте, на відміну від
попереднього прикладу, тут значна частина програмного коду буде реалізована
мовою програмування Python.
Приклад 6.87 З використанням засобів програмування мов С та Python
написати програмний код для вмикання та вимикання світлодіоду
мікроконтролера Auderino [75].

338
Відповідний програмний код буде мати наступний вигляд.
# Іпмортування модулів serial та time
import serial
import time
# Створення порту для обміну даними
# між комп’ютером та мікроконтролером
ArduinoSerial = serial.Serial(‘com18’,9600)
# Затримка на 2 секунди для встановлення зв’язку
time.sleep(2)
# Читання даних та виведення їх на монітор
# комп’ютера
print ArduinoSerial.readline()
inp = ‘’
# Цикл для реалізації подій ввімкнення та вимкнення
# світлодіоду за командами користувача комп’ютера
while (1):
# Введення 0 або 1. 0 – вимкнути, 1 – вмикнути
# світлодіод. S – завершити роботу з програмою.
while (inp != ‘0’) or (inp != ‘1’) or \
(inp != ‘S’):
input (‘Натисніть 1 для ввімкнення або \
0 для вимкнення світлодіода. S – завер\
шити роботу з програмою. ’)
if(inp == ‘S’) break
ArduinoSerial.write(var)
if (var == ‘0’):
print (‘Ви вимкнули світлодіод.’)
elif (var == ‘1’):
ArduinoSerial.write(var)
print (‘Ви ввімкнули світлодіод.’)

339
# Затримка на 1 секунду
time.sleep(1)
Код мікроконтролера Auderino, написаний мовою програмування С,
буде мати наступний вигляд [75].
void loop()
{
while (Serial.available())
{
data = Serial.read();
}
if (data == ‘1’)
digitalWrite (LED_BUILTIN, HIGH);
else if (data == ‘0’)
digitalWrite (LED_BUILTIN, LOW);
}
Результат роботи з програмним забезпеченням, наведеним у
прикладі 6.87, буде мати приблизно наступний вигляд.
Натисніть 1 для ввімкнення або 0 для вимкнення
світлодіода. S – завершити роботу з програмою. 1
Ви ввімкнули світлодіод.
Натисніть 1 для ввімкнення або 0 для вимкнення
світлодіода. S – завершити роботу з програмою. Y
Натисніть 1 для ввімкнення або 0 для вимкнення
світлодіода. S – завершити роботу з програмою. 0
Ви вимкнули світлодіод.
Натисніть 1 для ввімкнення або 0 для вимкнення
світлодіода. S – завершити роботу з програмою. S
Зрозуміло, що події ввімкнення та вимкнення світлодіода
мікроконтролера Auderino відповідають повідомленням, які надходять на
екран монітора.

340
Розглянемо тепер інший приклад, у якому ввімкнення та вимкнення
світлодіоду на мікроконтролері здійснюється комп’ютером автоматично у
відповідні моменти часу.
Приклад 6.88 З використанням засобів програмування мов С та Python
написати програмний код для автоматичного ввімкнення та вимикання
світлодіоду мікроконтролера Auderino. Передбачити 16 циклів ввімкнення та
вимикання. Спочатку вважати, що світлодіод вимкнений. Час ввімкнення
світлодіоду розраховувати як tвм = 3n + 8 від часу вимикання, а час
вимикання – як tвим = 2n + 3 від часу ввімкнення, де n – номер циклу.
Будемо писати програмний код для цього прикладу на основі прикладу
6.87. Зрозуміло, що код програми на мові С, написаної для мікроконтролера,
для цього прикладу залишається незмінним.
Тоді код комп’ютерної програми, написаною мовою програмування
Python, буде мати наступний вигляд.
import serial
import time
ArduinoSerial = serial.Serial(‘com18’,9600)
time.sleep(2)
print ArduinoSerial.readline()
for n in range (1, 16):
var = ‘0’
ArduinoSerial.write(var)
t_off = 3*n + 8
time.sleep(t_off)
var = ‘1’
ArduinoSerial.write(var)
t_on = 2*n + 3
time.sleep(t_on)
Для закріплення теоретичного матеріалу, наведеного у цьому
підрозділі, необхідно виконати практичне заняття 12.

341
Контрольні питання та завдання до розділу 6
1. Які головні бібліотеки, призначені для організації проведення
інженерних та наукових розрахунків, містить система програмування
Anaconda? Наведіть приклади використання модулів цих бібліотек.
2. Яка головна відмінна риса відрізняє інтерпретатор системи
програмування Anaconda від стандартного інтерпретатора мови Python?
Свою відповідь обґрунтуйте.
3. Які головні функції для проведення наукових розрахунків містить
бібліотека numpy системи Anaconda?
4. Які головні функції для проведення наукових розрахунків містить
бібліотека matplotlib системи Anaconda?
5. Які головні функції для проведення наукових розрахунків містить
бібліотека sympy системи Anaconda?
6. Які головні функції для проведення наукових розрахунків містить
бібліотека scipy системи Anaconda?
7. Які головні функції для проведення наукових розрахунків містить
бібліотека Pandas системи Anaconda?
8. Що являють собою матричні макрооперації над масивами числових
даних? Наведіть власні приклади проведення таких операцій.
9. Поясніть приклад 6.1.
10. Як описуються масиви числових даних у системі програмування
Anaconda та у якій бібліотеці розташовані відповідні класи та методи?
Наведіть власні приклади описання масивів числових даних.
11. Що являє собою функція array() бібліотеки numpy та як вона
використовується для створення масивів? Наведіть власні приклади
використання цієї функції.
12. Поясніть приклад 6.2.
13. Як у системі програмування Anaconda здійснюється індексація
елементів масиву? Наведіть власні приклади індексації елементів масиву.

342
14. Поясніть правила 6.1 та 6.2.
15. Поясніть приклад 6.3.
16. Що являє собою рівень ієрархії масиву з точки зору теорії
програмування? Наведіть власні приклади створення одновимірних,
двовимірних та тривимірних масивів з використанням засобів програмування
системи Anaconda.
17. Поясніть приклад 6.4.
18. Які головні атрибути масивів реалізовані у системі програмування
Anaconda? Наведіть власні приклади використання цих атрибутів.
19. Які головні методи для роботи з масивами реалізовані у системі
програмування Anaconda? Наведіть власні приклади використання цих
методів.
20. Що являє собою розмірність масиву та як вона визначається?
Наведіть власні приклади визначення розмірності масиву.
21. Що являє собою розмір масиву та як він визначається? Наведіть
власні приклади визначення розміру масиву.
22. Що являє собою атрибут масиву ndim та як він використовується
для визначення властивостей масивів? Наведіть власні приклади
використання цього атрибуту.
23. Що являє собою атрибут масиву shape та як він використовується
для визначення властивостей масивів? Наведіть власні приклади
використання цього атрибуту.
24. Що являє собою атрибут масиву size та як він використовується
для визначення властивостей масивів? Наведіть власні приклади
використання цього атрибуту.
25. Що являє собою метод len()та як він використовується для
визначення властивостей масивів? Наведіть власні приклади використання
цього методу.
26. Поясніть приклад 6.5.
27. Які функції формування спеціальних матриць реалізовані у системі

343
програмування Anaconda? Наведіть власні приклади використання цих
функцій.
28. Що являє собою функція zeros() та для формування яких
матриць вона використовується? Наведіть сласні приклади використання цієї
функції.
29. Що являє собою функція ones(n) та для формування яких
матриць вона використовується? Наведіть сласні приклади використання цієї
функції.
30. Що являє собою функція eye() та для формування яких матриць
вона використовується? Наведіть сласні приклади використання цієї функції.
31. Поясніть приклад 6.6.
32. Як у системі програмування Anaconda визначається тип числових
даних у масиві? Наведіть власні приклади такого визначення типу числових
даних.
33. Поясніть приклад 6.7.
34. Які функції, призначені для формування табульованих числових
послідовностей із заданим кроком на визначеному інтервалі, реалізовані в
системі програмування Anaconda? Наведіть власні приклади використання
цих функцій.
35. Що являє собою функція arangre() системи програмування
Anaconda та як вона використовується для формування числових
послідовностей? Наведіть власні приклади такого використання цієї функції.
36. Що являє собою функція linspace() системи програмування
Anaconda та як вона використовується для формування числових
послідовностей? Наведіть власні приклади такого використання цієї функції.
37. Поясніть приклад 6.8.
38. Що являє собою функція meshgrid() системи програмування
Anaconda та як вона використовується для формування матриць числових
послідовностей? Наведіть власні приклади такого використання цієї функції.
37. Поясніть приклад 6.9.
344
38. Що являє собою функція mgrid() системи програмування
Anaconda та як вона використовується для формування матриць числових
послідовностей? Наведіть власні приклади такого використання цієї функції.
39. Поясніть приклад 6.10.
40. Як пов’язані функції meshgrid() та mgrid() з відповідними
функціями системи науково-технічних розрахунків MatLab? Наведіть власні
приклади формування матриць числових послідовностей з використанням
програмних засобів систем Anaconda та MatLab. Порівняйте наведені
приклади з точки зору оцінки ефективності засобів програмування першої та
другої системи.
41. Які функції, призначені для призначені для формування масивів
випадкових числових значень, реалізовані в системі програмування
Anaconda? Наведіть власні приклади використання цих функцій.
42. Які функції, призначені для призначені для випадкового сортування
елементів масиву, реалізовані в системі програмування Anaconda? Наведіть
власні приклади використання цих функцій.
43. У якому модулі системи програмування Anaconda розташовані
функції, призначені для формування масивів випадкових числових значень та
чи є ці функції перевантаженими? Свою відповідь обґрунтуйте.
44. Що являє собою функція rand() модуля numpy.random системи
програмування Anaconda? Наведіть власні приклади використання цієї
функції.
45. Що являє собою функція randint() модуля numpy.random
системи програмування Anaconda? Наведіть власні приклади використання
цієї функції.
46. Що являє собою функція uniform() модуля numpy.random
системи програмування Anaconda? Наведіть власні приклади використання
цієї функції.
47. Що являє собою функція shuffle() модуля numpy.random
системи програмування Anaconda? Наведіть власні приклади використання
345
цієї функції.
48. Що являє собою функція permutation() модуля numpy.random
системи програмування Anaconda? Наведіть власні приклади використання
цієї функції.
49. Поясніть приклад 6.11.
50. Як у системі програмування Anaconda реалізовані алгебраїчні
операції між масивом та скаляром? Наведіть власні приклади виконання
таких операцій.
51. Поясніть приклади 6.12 та 6.13.
52. Як у системі програмування Anaconda реалізовані алгебраїчні
операції між двома масивами? Наведіть власні приклади виконання таких
операцій.
53. Чим алгебраїчні операції між двома масивами у системі програмування
Anaconda суттєво відрізняються від аналогічних операцій у системі науково-
технічних розрахунків MatLab? Наведіть власні приклади виконання таких
операцій в обох системах. Порівняйте наведені приклади з точки зору оцінки
ефективності засобів програмування першої та другої системи.
54. Поясніть приклад 6.14.
55. Як у системі програмування Anaconda реалізована операція
поелементного порівняння двох масивів? Наведіть власні приклади
виконання такої операції.
56. Чим операції поелементного порівняння двох масивів у системі
програмування Anaconda суттєво відрізняються від аналогічних операцій у
системі науково-технічних розрахунків MatLab? Наведіть власні приклади
виконання таких операцій в обох системах. Порівняйте наведені приклади з
точки зору оцінки ефективності засобів програмування першої та другої
системи.
57. Поясніть приклад 6.15.
58. Що являють собою логічні масиви у системі програмування
Anaconda? Наведіть власні приклади логічних масивів.

346
59. Поясніть визначення 6.1.
60. Що являє собою логічна індексація масивів у системі
програмування Anaconda? Наведіть власні приклади логічної індексації
масивів.
61. Поясніть визначення 6.2.
62. Поясніть приклади 6.16 та 6.17.
63. Що являє собою функція reshape() у системі програмування
Anaconda? Наведіть власні приклади використання цієї функції.
64. Як у системі програмування Anaconda реалізована функція
транспортування матриці? Наведіть власні приклади транспортування
матриці.
65. Поясніть приклади 6.18 та 6.19.
66. Що являють собою поелементні операції над масивами? Наведіть
власні приклади виконання поелементних операцій над масивами.
67. Поясніть співвідношення (6.1).
68. Поясніть приклад 6.20.
69. Що являє собою функція fromfunction() у системі
програмування Anaconda? Наведіть власні приклади використання цієї
функції.
70. Поясніть приклади 6.21, 6.22 та 6.23.
71. Що являє собою векторізація математичних функцій та як вона
реалізована в системі програмування Anaconda? Наведіть власні приклади
векторізації математичних функцій.
72. Поясніть визначення 6.3.
73. Поясніть приклад 6.24.
74. Що являє собою векторізація функцій користувача та як вона
реалізована в системі програмування Anaconda? Наведіть власні приклади
векторізації функції користувача.
75. Поясніть приклад 6.25.
76. Що являє собою векторізація анонімної лямбда-функції та як вона

347
реалізована в системі програмування Anaconda? Наведіть власні приклади
векторізації анонімної лямбда-функції.
75. Поясніть приклад 6.26.
76. Як у системі програмування Anaconda виконується опрацювання
масивів з використанням арифметико-логічних функцій? Наведіть власні
приклади опрацювання масивів з використанням арифметико-логічних
функцій.
77. Що являє собою логічна функція logical_and() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
78. Що являє собою логічна функція logical_or() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
79. Що являє собою логічна функція logical_not() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
80. Що являє собою логічна функція logical_xor() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
81. Поясніть приклад 6.27.
82. Які математичні функції системи програмування Anaconda
спеціально призначені для роботи з масивами? Наведіть власні приклади
використання цих функцій.
83. Що являє собою математична функція sum() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
84. Що являє собою математична функція cumsum() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
85. Що являє собою математична функція diff() та як вона
348
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
86. Що являє собою математична функція max() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
87. Що являє собою математична функція min() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
88. Що являє собою математична функція argmax() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
88. Що являє собою математична функція argmin() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
89. Як у системі програмування Anaconda для опрацювання масивів
використовується функція round(n)? Наведіть власні приклади
використання цієї функції.
90. Що являє собою математична функція mean() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
91. Що являє собою математична функція std() та як вона
використовується для опрацювання масивів? Наведіть власні приклади
використання цієї функції.
92. Поясніть приклад 6.28.
93. Які функції, призначені для виконання операцій лінійної алгебри,
реалізовані у системі програмування Anaconda? Наведіть власні приклади
використання цих функцій.
94. У яких модулях системи програмування Anaconda розташовані
функції, призначені для виконання операцій лінійної алгебри?
95. Що являє собою функція лінійної алгебри det()? Наведіть власні
349
приклади використання цієї функції.
96. Що являє собою функція лінійної алгебри norm()? Наведіть власні
приклади використання цієї функції.
97. Що являє собою функція лінійної алгебри inv()? Наведіть власні
приклади використання цієї функції.
98. Що являє собою функція лінійної алгебри matmul()? Наведіть
власні приклади використання цієї функції.
99. Що являє собою функція лінійної алгебри dot()? Наведіть власні
приклади використання цієї функції.
100. Що являє собою функція лінійної алгебри solve()? Наведіть
власні приклади використання цієї функції.
101. Поясніть приклади 6.29, 6.30 та 6.31.
102. Що являє собою бібліотека matplotlib системи програмування
Anaconda та як вона використовується для обробки результатів розрахунків
та оформлення наукової документації? Наведіть власні приклади такого
використання цієї функцій бібліотеки.
103. Як у системі програмування Anaconda створюється об’єкт класу
Figure? Наведіть власні приклади створення цього об’єкту.
104. Як у системі програмування Anaconda здійснюється відображення
рисунка? Наведіть власні приклади виконання цієї операції.
105. Що являє собою програма Spider та як використовується для роботи
з науковою графікою? Як ця програма пов’язана із програмним забезпеченням
системи Anaconda? Наведіть власні приклади виконання цієї програми.
106. Поясніть рис. 6.1.
107. Що являє собою команда plot() бібліотеки matplotlib?
Наведіть власні приклади використання цієї команди.
108. Поясніть приклади 6.32, 6.33 та 6.34.
109. Поясніть графічні залежності, наведені на рис. 6.2, а – в.
110. Які існують іконки панелі керування програми Spider, призначені для
налаштування властивостей графіків? Поясніть призначення цих іконок згідно
350
із рис. 6.3.
111. Який спосіб кодування кольорів використовується для графічних
об’єктів бібліотеки matplotlib системи програмування Anaconda?
Поясніть дані, наведені у таблиці 6.2. Наведіть власні приклади визначення
кольорів графічних об’єктів.
112. Який спосіб кодування типу лінії використовується для графічних
об’єктів бібліотеки matplotlib системи програмування Anaconda?
Поясніть дані, наведені у таблиці 6.3. Наведіть власні приклади визначення
типу лінії.
113. Який спосіб кодування типу маркера використовується для
графічних об’єктів бібліотеки matplotlib системи програмування
Anaconda? Поясніть дані, наведені у таблиці 6.4. Наведіть власні приклади
визначення типу маркера.
114. Який спосіб кодування кольору маркера використовується для
графічних об’єктів бібліотеки matplotlib системи програмування
Anaconda? Наведіть власні приклади визначення кольору маркера.
115. Поясніть приклад 6.35 та рис. 6.4.
116. Як з використанням засобів програмування системи Anaconda
можна розстити два графіка на одній координатній площині? Наведіть власні
приклади такого розміщення графіків.
117. Поясніть приклад 6.36 та рис. 6.5.
118. Як для оформлення графічних залежностей в системі
програмування Anaconda використовується функція text()? Наведіть
власні приклади використання цієї функції.
119. Як для оформлення графічних залежностей в системі
програмування Anaconda використовується функція gca()? Наведіть власні
приклади використання цієї функції.
120. Як в системі програмування Anaconda здійснюється кодування
математичних формул в форматі текстового редактора ТЕХ? Наведіть власні
приклади здійснення такого кодування математичних формул.
351
121. Поясніть приклади 6.37 та 6.38.
122. Як в системі програмування Anaconda для оформлення графічних
залежностей використовується функція annote()? Наведіть власні
приклади використання цієї функції.
123. Як в системі програмування Anaconda для оформлення графічних
залежностей використовується функції xlabel()та ylabel()? Наведіть
власні приклади використання цих функцій.
124. Як в системі програмування Anaconda для оформлення графічних
залежностей використовується функція grid()? Наведіть власні приклади
використання цієї функції.
125. Поясніть приклад 6.39 та рис. 6.6.
126. Обчислити у системі Anaconda наступні вирази та побудувати
графіки функцій для всіх значень константи n та діапазону змінної x. У тих
випадках, коли значенням функції на визначеному інтервалі є комплексне
число, побудувати окремо графіки дійсної частини, умовної частини та
модуля числа на одній площині рисунка, але на різних координатних осях.
Всі лінії на графіку рисувати різним стилем та зробити легенду, де визначити
значення параметра n для кожної кривої. Після побудови графіків дослідити
поведінку функцій, знайти їх максимуми та мінімуми, а також точки розриву.
x 2 − sin(nx )
а) х∈ [0,10]; n=1,2,3,4; f (x ) =
(nx + 1)⋅ cos(x )
.
3

nx 2 − 15
б) х∈ [-5,5]; n=1,3,5,7; f (x ) = .
tg nx 3 + 1 
 

arcsin  nx 2 − 20 x + 15 
в) х∈ [-5,5]; n=1,2,3,4; f (x ) =   .
 3   3 
ln nx + 1  + exp nx − 10 x + 25 
   

arccos nx 3 − 20 x 2 + 15 x − 5 
г) х∈ [-2,2]; n=1,3,5,7; f (x ) =   .
ln nx 3 + 2 x + 1  + exp nx 3 − 10 
   

352
arccos nx 3 − 5  + arcsin  nx 3 + 5 
д) х∈ [1,15]; n=1,2,3,4; f (x ) =    .
 nx 3 + 2 x + 1  + cos nx 3 − 10 
   
   

sh nx 3 − 10  + ch  nx 2 + 5 
е) х∈ [0,5]; n=1,2,3,4; f (x ) =    .
 nx 3 + 1  + ch  nx 3 − 10 
   
   

ch  nx 3 − 3x + 5  + sh nx 2 − 3x + 10 
є) х∈ [-2,2]; n=1,3,5,7; f (x ) =    .
 nx 3 + 1  + ch  nx 3 − 1 
   
   

sin  nx 2 − 2  + cos nx 2 − 2 
ж) х∈ [0,5]; n=1,2,3,4; f (x ) =    .
cos nx 2 + 1  + sin  nx 2 + 1 
   

arcsin nx 2 − 3  + arccos nx 2 − 3 
з) х∈ [0,10]; n=1,3,5,7; f (x ) =    .
arccos nx 2 + 1  + arcsin nx 2 + 1 
   

exp nx 2 + 3  − ln nx 2 + 3 
і) х∈ [0,1]; n=1,2,3,4; f (x ) =    .
ln nx 2 + 1  + exp nx 2 + 1 
   

cos nx 2 + 10 x + 3  − sin  nx 2 + 10 x + 3 
   
к) х∈ [0,1]; n=1,2,3,4; f ( x ) = .
 2   2
cos nx + 12 x + 5  + sin  nx + 12 x + 5  
   
127. Як в системі програмування Anaconda можна побудувати графік у
полярній системі координат? Наведіть власні приклади побудови такого
графіка.
128. Що являє собою команда polar() бібліотеки matplotlib?
Наведіть власні приклади використання цієї команди.
129. Поясніть приклад 6.40 та рис. 6.7.
130. Обчислити у системі Anaconda наступні вирази та побудувати
графіки функцій для всіх значень константи n та діапазону змінної φ ∈ [0, 2π].
353
а) n = 1, 2, 3, 4; f(φ) = 10ncos(nφ3 + 12φ2 – 1).
б) n = 1, 3, 5, 7; f(φ) = 15ncos(5nφ3 + 24φ2 – 10).
в) n = 2, 4, 6, 8; f(φ) = 43nsin(14nφ3 + 13φ – 15).
г) n = 3, 6, 9, 12; f(φ) = 3nsin(14nφ3 – 15) + 5ncos(11nφ2 – 14).
д) n = 4, 8, 12, 16; f(φ) = 23ncos(14nφ2 + 17) + 25nsin(21nφ3 – 10).
е) n = 2, 4, 6, 8; f(φ) = 26ncos(14nφ3 – 13nφ2 + 4nφ – 12).
є) n = 3, 6, 9, 12; f(φ) = 24nsin(25nφ3 – 13nφ2 + 4nφ – 12).
ж) n = 1, 3, 5, 7; f(φ) = 9nsin(14nφ3 – 11nφ2 – 15) + 5ncos(17nφ2 + 14).
і) n = 2, 4, 6, 8; f(φ) = 19ncos(34nφ3 – 21nφ2 – 11) + 15ncos(12nφ2 – 13).
к) n = 3, 6, 9, 12; f(φ) = 24nsin(25nφ3 – 13nφ2 + 4nφ – 12).
131. Як в системі програмування Anaconda можна побудувати
контурний графік? Наведіть власні приклади побудови контурного графіка.
132. Що являє собою команда meshgrid() бібліотеки numpy?
Наведіть власні приклади використання цієї команди.
133. Що являє собою команда contour() бібліотеки matplotlib?
Наведіть власні приклади використання цієї команди.
134. Що являє собою команда contourf() бібліотеки matplotlib?
Наведіть власні приклади використання цієї команди.
135. Поясніть приклади 6.41, 6.42 та рис. 6.8, 6.9.
136. З використанням програмних засобів системи Anaconda
побудувати контурні графіки з заповненням кольором та без заповнення для
наступних математичних функцій від двох змінних х та у у вказаному
їхньому діапазоні їхних значень.
x− y
cos
x + y 2 +3
2
а) х∈ [-2,2]; у∈ [-2,2]; f (x ) = e .
x+ y
sin
x 2 − y 2 +100
б) х∈ [-5,5]; у∈ [-2,2]; f (x ) = e .

x2 + y2 + 3 x 2 − y 2 + 100
в) х∈ [-5,5]; у∈ [-2,2]; f ( x ) = cos + cos .
x 2 − y 2 + 100 x2 + y2 + 3

354
 x2 + y 2 + 3 x 2 − y 2 + 100 
г) х∈ [-3,5]; у∈ [-1,2]; f ( x ) = sin + .
 x 2 − y 2 + 100 2 2
x + y +3  

 2 2 2 2 
 cos x + y + 5 + sin x − y +10 
 x 2 − y 2 +10 x 2 + y 2 + 5 
д) х∈ [0,5]; у∈ [-1,2]; f (x ) = e  .

 x2 + y2 + 3 x 2 − y 2 + 100 
sin  +
 2 2 
 x − y + 100 x2 + y2 + 3 
е) х∈ [-3,5]; у∈ [-1,2]; f ( x ) = .
2 2 2 2
x + y +3 x − y + 100
sin + cos +3
x 2 − y 2 + 100 x2 + y2 + 3

 x2 + y2 + 3 x 2 − y 2 + 100 
cos +
 2 2 
 x − y + 100 x2 + y2 + 3 
є) х∈ [-3,1]; у∈ [-1,2]; f ( x ) = .
2 2 2 2
x + y +3 x − y + 100
cos − sin +3
x 2 − y 2 + 100 x2 + y2 + 3

 x2 + y2 + 3 x 2 − y 2 + 100 
cos  + +5
 x 2 − y 2 + 100 x 2
+ y 2
+ 3 
ж) х∈ [-3,2]; у∈ [-1,3]; f ( x ) = ln   .
2 2 2 2
x + y +3 x − y + 100
cos − sin +3
2 2 2 2
x − y + 100 x + y +3

 x2 + y2 + 3 x 2 − y 2 + 20 
sin  +
 x 2 − y 2 + 20 x 2 + y 2 + 3 
з) х∈ [-3,3]; у∈ [-1,1]; f ( x ) = ln  .
2 2 2 2
x + y +3 x − y + 20
sin + cos +3
2 2 2 2
x − y + 20 x + y +3

137. Що являє собою команда imshow() бібліотеки matplotlib?


Наведіть власні приклади використання цієї команди.
138. Що являє собою команда flipud() бібліотеки numpy? Наведіть
власні приклади використання цієї команди.
139. Поясніть приклад 6.43.
140. Як з використанням засобів програмування системи Anaconda

355
можна суміщати два графіка, побудованих в різних системах координат, на
одному полотні? Наведіть власні приклади такого суміщення графіків.
141. Що являє собою команда add_axes() бібліотеки matplotlib
та як вона використовується для суміщення графіків? Наведіть власні
приклади такого використання цієї команди.
142. Поясніть приклад 6.44 та рис. 6.11.
143. Що являє собою команда subplot() бібліотеки matplotlib та
як вона використовується для суміщення графіків? Наведіть власні приклади
такого використання цієї команди.
144. Поясніть приклад 6.45 та рис. 6.12.
145. Які засоби для побудови тривимірної графіки існують в системі
програмування Anaconda та у яких бібліотеках вони розташовані? Наведіть
власні приклади використання цих програмних засобів.
146. Що являє собою бібліотека mpl_toolkits.mplot3d та як
функції цієї бібліотеки використовуються для побудови тривимірних
графіків? Наведіть власні приклади використання функцій цієї бібліотеки?
147. Поясніть приклад 6.46.
148. Що являє собою функція Axes3D() бібліотеки
mpl_toolkits.mplot3d та як вона використовується для побудови
тривимірних графіків? Наведіть власні приклади використання цієї функції.
149. Що являє собою функція plot(x, y, z) бібліотеки
mpl_toolkits.mplot3d та як вона використовується для побудови
тривимірних кривих ліній? Наведіть власні приклади використання цієї
функції.
150. Яка команда системи програмування Anaconda використовується
для побудови зафарбованих тривимірних поверхонь? Наведіть власні
приклади використання цієї функції.
151. Яка команда системи програмування Anaconda використовується
для побудови каркасних тривимірних поверхонь? Наведіть власні приклади
використання цієї функції.
356
152. Поясніть приклади 6.47 та 6.48 а також рис. 6.13 та 6.14.
153. Поясніть приклад 6.49 та рис. 6.15.
154. Які засоби для створення анімаційних ефектів існують в системі
програмування Anaconda та у яких бібліотеках вони розташовані? Наведіть
власні приклади використання цих програмних засобів.
155. Що являє собою функція FuncAnimation() та як вона
використовується для створення анімаційних ефектів? Наведіть власні
приклади використання цієї функції.
156. Що являє собою функція ArtistAnimation() та як вона
використовується для створення анімаційних ефектів? Наведіть власні
приклади використання цієї функції.
157. За яким найпростішим алгоритмом у системі програмування
Anaconda створюються анімаційні ролики та які параметри за такої умови
має функція FuncAnimation()? Наведіть власні приклади використання
цієї функції.
158. Поясніть приклади 6.50 та 6.51, а також рис. 6.16 та 6.17.
159. Поясніть приклад 6.52 та рис. 6.18.
160. Що являє собою функція pcolor() та як вона використовується
для побудови контурних графіків? Наведіть власні приклади такого
використання цієї функції.
161. Поясніть приклад 6.53 та рис. 6.19.
162. Як у системі програмування Anaconda реалізована інтеграція між
графічними об’єктами модулів matplotlib та tkinter. Наведіть власні
приклади організації такої взаємодії.
163. Що являє собою клас складеного полотна FigureCanvasTkAgg
та як він використовується для розташування об’єктів модуля matplotlib
у віконному інтерфейсі, сформованому на основі об’єктів модуля tkinter?
Наведіть власні приклади такого використання класу складеного полотна.
164. Що являє собою клас NavigationToolbar2TkAgg та як він
використовується для розташування об’єктів модуля matplotlib у
357
віконному інтерфейсі, сформованому на основі об’єктів модуля tkinter?
Наведіть власні приклади такого використання цього класу.
165. Опишіть узагальнений алгоритм, який застосовується для
розташування об’єктів модуля matplotlib у віконному інтерфейсі,
сформованому на основі об’єктів модуля tkinter, та наведіть власні
приклади такого використання цього алгоритму.
166. Поясніть приклад 6.54 та рис. 6.20.
167. Поясніть приклад 6.55, рис. 6.21 та 6.22, а також код програми,
наведений у додатку Ж.
168. Побудуйте графіки математичних функцій, наведених у завданнях
126, 130, 136 до цього розділу та у завданні 147 до розділу 5 через
розташування об’єктів модуля matplotlib у віконному інтерфейсі,
сформованому на основі об’єктів модуля tkinter.
169. Як у системі програмування Anaconda реалізовані функції
символьних обчислень та у якому модулі ці функції розташовані? Наведіть
власні приклади проведення символьних обчислень.
170. Що являє собою функція symbols() модуля sympy системи
програмування Anaconda? Наведіть власні приклади використання цієї
функції.
171. Що являє собою функція var() модуля sympy системи
програмування Anaconda? Наведіть власні приклади використання цієї
функції.
172. Проведіть порівняльний аналіз символьних процесорів таких
комп’ютерних систем, призначених для проведення науково-технічних
розрахунків, як MatLab, Maple та система програмування Anaconda. Свою
відповідь обґрунтуйте та наведіть доречні приклади проведення символьних
обчислень у цих трьох різних системах.
173. Поясніть приклади 6.56 та 6.57.
174. Що являє собою функція simplify() модуля sympy системи
програмування Anaconda та які вона має формати запису? Наведіть власні
358
приклади використання цієї функції.
175. Що являє собою функція subst() модуля sympy системи
програмування Anaconda та які вона має формати запису? Наведіть власні
приклади використання цієї функції.
176. Поясніть приклад 6.58.
177. Як метод symbols() модуля sympy системи програмування
Anaconda використовуєтсья для описання символьних змінних? Наведіть
власні приклади такого використання цього методу.
178. Як у системі програмування Anaconda можна визначити тип
символьної змінної ручним способом? Наведіть власні приклади такого
визначення типу символьної змінної.
179. Поясніть приклад 6.59.
180. Що являє собою команда del() модуля sympy системи
програмування Anaconda? Наведіть власні приклади використання цієї
команди.
181. Поясніть приклад 6.60.
182. Яких головних правил програмування, призначених для роботи з
символьними змінними, слід дотримуватись у системі програмування
Anaconda? Наведіть власні приклади використання цих правил.
183. Поясніть правила 6.3 – 6.8.
184. Поясніть приклад 6.61.
185. Що являє собою аргумент args та як він використовується для
проведення символьних обчислень? Наведіть власні приклади використання
цього аргументу.
186. Поясніть приклад 6.62.
187. Що являє собою системна змінна oo та як вона використовується
символьним процесором системи програмування Anaconda? Наведіть власні
приклади використання цієї системної змінної.
188. Поясніть приклад 6.63.
189. Яка системна змінна відповідає змінній oo у системі науково-
359
технічних розрахунків MatLab?
190. За якими правилами у системі програмування Anaconda
реалізовані функції алгебраїчних перетворень? Наведіть власні приклади
використання цих правил.
191. Поясніть правила 6.9 – 6.13.
192. У чому полягає перевага звернення до символьних виразів як до
об’єктів, незалежно від способу їхнього описання? Наведіть власні приклади
описання символьних виразів як об’єктів у системі програмування Anaconda.
193. Які загальні функції, призначені для здійснення алгебраїчних
перетворень, реалізовані у символьному процесорі системи програмування
Anaconda? Наведіть власні приклади здійснення алгебраїчних перетворень з
використанням цих функцій.
194. Що являє собою функція factor() та які аналітичні
перетворення алгебраїчних виразів вона виконує? Наведіть власні приклади
використання цієї функції.
195. Що являє собою функція expand() та які аналітичні
перетворення алгебраїчних виразів вона виконує? Наведіть власні приклади
використання цієї функції.
196. Що являє собою функція prod() та які аналітичні перетворення
алгебраїчних виразів вона виконує? Наведіть власні приклади використання
цієї функції.
197. Що являє собою функція collect() та які аналітичні
перетворення алгебраїчних виразів вона виконує? Наведіть власні приклади
використання цієї функції.
198. Що являє собою функція cancel() та які аналітичні
перетворення алгебраїчних виразів вона виконує? Наведіть власні приклади
використання цієї функції.
199. Що являє собою функція apart() та які аналітичні перетворення
алгебраїчних виразів вона виконує? Наведіть власні приклади використання
цієї функції.
360
200. Що являє собою функція simflify() та які аналітичні
перетворення алгебраїчних виразів вона виконує? Наведіть власні приклади
використання цієї функції.
201. Які загальні функції, призначені для здійснення тригонометричних
перетворень, реалізовані у символьному процесорі системи програмування
Anaconda? Наведіть власні приклади здійснення тригонометричних
перетворень з використанням цих функцій.
202. Що являє собою функція expand_trig() та які аналітичні
перетворення тригонометричних виразів вона виконує? Наведіть власні
приклади використання цієї функції.
203. Що являє собою функція trigsimp() та які аналітичні
перетворення тригонометричних виразів вона виконує? Наведіть власні
приклади використання цієї функції.
204. Поясніть приклад 6.64.
205. З використанням засобів символьного процесора системи
програмування Anaconda спростити наведені нижче вирази. Виділити окремо
чисельних та знаменник дробу, знайти область визначення функції та
побудувати її графік.

x 3 − 3 x 2 − 13 x + 15 x 3 + 6 x 2 + 5 x − 12 x 3 + 2 x 2 − 23x − 60
а) ; б) ; в) ;
x 3 + 6 x 2 + 5 x − 12 x 3 − 4 x 2 − 25 x + 28 x 3 + 14 x 2 + 61x + 84

x 3 + 4 x 2 − 17 x − 60 x 3 − 9 x 2 + 26 x − 24 x 3 + 3 x 2 − 18 x − 40
г) ; д) ; е) ;
x 3 + 14 x 2 + 63x + 90 x 3 − 3x 2 − 10 x + 24 x 3 + 11x 2 − 10 x − 200

x 3 − 19 x − 30 x 3 + 6 x 2 + 5 x − 12 x 3 + 2 x 2 − 23x − 60
є) ; ж) ; з) ;
x 3 + 4 x 2 − 27 x − 90 x 3 − 4 x 2 − 25 x + 28 x 3 + 14 x 2 + 61x + 84

x 3 + 13x 2 + 52 x + 60 x 3 − x 2 − 24 x − 36 x3 + 4 x 2 − 6
і) ; к) ; л) .
x 3 + 8 x 2 − 3x − 90 x 3 − 5 x 2 − 8 x + 12 x3 − x 2 − 4 x + 4
206. Як у символьномі процесорі системи програмування Anaconda
організована робота з комплексними числами? Наведіть власні приклади
аналітичних обчислень для математичних виразів з комплексними числами.

361
207. Які математичні функції реалізовані у символьномі процесорі
системи програмування Anaconda для роботи з комплексними числами?
Наведіть власні приклади використання таких функцій.
208. Що являє собою функція re(z) та як вона використовується для
аналітичних перетворень математичних виразів з комплексними числами?
Наведіть власні приклади такого використання цієї функції.
209. Що являє собою функція im(z) та як вона використовується для
аналітичних перетворень математичних виразів з комплексними числами?
Наведіть власні приклади такого використання цієї функції.
210. Що являє собою функція Abs(z) та як вона використовується для
аналітичних перетворень математичних виразів з комплексними числами?
Наведіть власні приклади такого використання цієї функції.
211. Що являє собою функція arg(z) та як вона використовується для
аналітичних перетворень математичних виразів з комплексними числами?
Наведіть власні приклади такого використання цієї функції.
212. Що являє собою функція conjugate(z) та як вона
використовується для аналітичних перетворень математичних виразів з
комплексними числами? Наведіть власні приклади такого використання цієї
функції.
213. Поясніть приклад 6.65.
214. З використанням засобів символьного процесора системи
програмування Anaconda спростити наведені нижче вирази з комплексними
числами. Знайти дійсну та уявну частини комплексного числа, його модуль,
аргумент та комплексно-спряжене число.
а) 5i(3exp(3i + 5) – 10sin(7i – 1)); б) 4i(12exp(7i + 11) – 14sin(8i – 1));
в) 3i(5ln(4i + 9) – 10exp(2i – 7)); г) 2i(17cos(2i + 15) – 17sin(4i – 3));
д) 7i(4sin(9i + 5) – 5ln(3i – 5)); е) 9i(13cos(6i + 15) – 7exp(4i – 7));
є) 8i(8sin(9i + 5) + 5ln(3i – 5)); ж) 6i(16cos(6i + 15) – 3exp(3i + 7));
з) 10i(15sin(2i + 5) – 5exp(5i + 6)); і) 12i(14exp(4i + 5) – 7ln(7i + 9));
к) 11i(12sin(12i + 15) + 5cos(3i + 10)); л) 13i(14cos(4i + 5) – 10ln(6i – 13)).

362
215. Які в системі програмування Anaconda існують засоби для
відображення результатів алгебраїчних перетворень? Наведіть власні
приклади використання цих засобів для відображення результатів
аналітичних розрахунків.
216. Що являє собою відображення результатів аналітичних
розрахунків через командний рядок інтерпретатора та в яких інших
комп’ютерних системах, призначених для проведення науково-технічних
розрахунків, реалізований такий спосіб роботи символьного процесора?
Назвіть головні переваги та недоліки такого способу організації роботи
символьного процесора.
217. Що являє собою відображення результатів аналітичних
розрахунків з використанням технології WYSIWYG та в яких інших
комп’ютерних системах, призначених для проведення науково-технічних
розрахунків, реалізований такий спосіб роботи символьного процесора?
Назвіть головні переваги та недоліки такого способу організації роботи
символьного процесора.
218. Що являє собою функція init_printing() бібліотеки sympy
та як вона використовується в системі програмування Anaconda для зміни
способу виведення результатів аналітичних розрахунків.
219. Поясніть приклад 6.66.
220. Які функції, призначені для аналітичного розв’язування
алгебраїчних рівнянь та їх систем, реалізовані в системі програмування
Anaconda? Наведіть власні приклади використання цих функцій.
221. Що являє собою функція Eq() та як вона може бути використана
для аналітичного розв’язування лінійних та нелінійних рівнянь? Наведіть
власні приклади такого використання цієї функції.
222. Поясніть приклад 6.67.
223. Які головні функції символьного процесора системи
програмування Anaconda використовуються для аналітичного розв’язування
алгебраїчних рівнянь та їх систем? Наведіть власні приклади використання

363
цих функцій.
224. Що являє собою функція solveset() символьного процесора
системи програмування Anaconda та як вона використовується для
аналітичного розв’язування алгебраїчних рівнянь? Наведіть власні приклади
такого використання цієї функції.
225. Що являє собою функція roots() символьного процесора
системи програмування Anaconda та як вона використовується для
аналітичного розв’язування алгебраїчних рівнянь? Наведіть власні приклади
такого використання цієї функції.
226. Що являє собою функція real_roots() символьного процесора
системи програмування Anaconda та як вона використовується для
аналітичного розв’язування алгебраїчних рівнянь? Наведіть власні приклади
такого використання цієї функції.
227. Що являє собою функція nroots() символьного процесора
системи програмування Anaconda та як вона використовується для
аналітичного розв’язування алгебраїчних рівнянь? Наведіть власні приклади
такого використання цієї функції.
228. Що являє собою функція solve() символьного процесора
системи програмування Anaconda та як вона використовується для
аналітичного розв’язування алгебраїчних рівнянь та їх систем? Наведіть
власні приклади такого використання цієї функції.
229. Що являє собою функція solve() символьного процесора
системи програмування Anaconda та як вона використовується для
аналітичного розв’язування систем лінійних алгебраїчних рівнянь? Наведіть
власні приклади такого використання цієї функції.
230. Поясніть приклад 6.68.
231. З використанням функцій символьного процесора системи
програмування Anaconda розв’язати наведені нижче кубічні рівняння та
пояснити отримані розв’язки.
а) x3 + 16x2 + 27x – 252; б) x3 + x2 – 14x – 24;
364
в) x3 + 13x2 + 27x – 252; г) x3 + 6x2 – 14x – 24;
д) x3 – 3x2 – 46x + 168; е) x3 + 6x2 – 51x – 280;
є) x3 + 5x2 – 51x – 280; ж) x3 – 3x2 – 46x + 16;
з) x3 – 20x2 + 51x + 360; і) x3 – 2x2 – 155x – 156;
к) x3 – 20x2 + 51x + 36; л) x3 – 2x2 – 15x – 156.
232. З використанням засобів програмування системи Anaconda знайти
корні нелінійних рівнянь у заданих діапазонах значень змінної х з точністю
до 10-6.

ex
а) = 3; x ∈ [0,6;0,8]; x ∈ [1,4;1,6];
x
e x − 0,25
б) = 0; x ∈ [0,2;0,3]; x ∈ [4,7;4,75];
cos( x ) − 1
cos( x ) − 2
в) = 0; x ∈ [0,1;1]; x ∈ [5;6];
cos( x ) + 3
sin ( x )
г) = 0; x ∈ [1,6;2,5]; x ∈ [5;6];
cos( x ) + 2
sin( x ) + cos( x )
д) = 0; x ∈ [1;3]; x ∈ [7;9];
cos( x ) − 2
sin ( x ) − cos( x )
е) = 0; x ∈ [0;2]; x ∈ [2;4];
cos( x ) + sin ( x )

ex − 2
є) = 0; x ∈ [− 1;−0,5]; x ∈ [0,6;0,8];
ln ( x ) − x

ex − x
ж) = −3; x ∈ [3;4];
ln( x ) − x 2

e x + x2
з) = 3; x ∈ [0,2;0,5];
cos( x ) − sin ( x )

e x − x2 − 1
і) = 2; x ∈ [2;3];
cos( x )sin ( x ) + 3
233. З використанням функцій символьного процесора системи
програмування Anaconda розв’язати наведені нижче системи лінійних

365
рівнянь.
5 x + 3 y − 8 z + 12t = 25 8 x + y − 5z + 13t = 14
2 x − 5 y + 17 z − 6t = 13 12 x − 10 y + 7 z − 6t = 10
 
а)  б) 
− 5 x + 12 y − 4 z + 13t = 11 3x + 8 y − 7 z + 13t = 25
25 x − 3 y − 8 z + 11t = 20  x − 7 y + z + t = 50

 x + y − 7 z + 13t = 5  x + 2 y − 5z + 3t = 4
x − 5 y + 7 z − t = 3 2 x − y + 7 z − 6t = 1
 
в)  г) 
4 x + 13 y − z + 17t = 1 3x + 8 y − 7 z + 3t = 5
5 x + 3 y − 8 z + t = 21 3x − y + z + t = 7

3x + 5 y − z + 2t = 5 6 x + 7 y − z + 3t = 4
x − y + 7z − t = 3 2 x − 11 y + z − 16t = 13
 
д)  е) 
5 x + 2 y − 3z + 13t = 15  x + y − z + 3t = 6
 x − 4 y − 9 z + t = 17  x − 7 y + 2 z + t = 5

x + 3y − 2z + t = 6 3x + 4 y − 5z + 3t = 4
 x − 5 y + 7 z − 2t = 7  x − 11 y + z − 16t = 13
 
є)  ж) 
 x + 2 y − z + 3t = 5 4 x + 3 y − z + 3t = 3
 x − y − 5z + 2t = 1 5 x − y + 2 z + t = 16

5 x + 13 y − 12 z + 3t = 15  x + 3 y − 8 z + 5t = 14
 2 x − 3 y + 9 z − 4t = 7  x − 4 y + 5z − 6t = 13
 
з)  і) 
3x + 2 y − 5z + 3t = 23 4 x + 3 y − 2 z + t = 3
 x − 6 y − 5z + 2t = 17 5 x − y + z + 3t = 6

234. Які головні функції символьного процесора системи


програмування Anaconda використовуються для аналітичних перетворень
математичних виразів із матрицями? Наведіть власні приклади використання
цих функцій.
235. Як з використанням засобів програмування системи Anaconda
можна створити матрицю для символьних перетворень? Наведіть власні
приклади створення такої матриці.
236. Чому функції аналітичних перетворень матричних виразів ц
системі програмування Anaconda зазвичай співпадають із відповідними
функціями для проведення чисельних розрахунків? Наведіть власні приклади
таких функцій.

366
237. Як з використанням засобів програмування системи Anaconda
можна отримати аналітичний вираз для власних чисел матриці? Наведіть
власні приклади отримання такого аналітичного виразу.
238. Як з використанням засобів програмування системи Anaconda
можна отримати аналітичний вираз для власних векторів матриці? Наведіть
власні приклади отримання такого аналітичного виразу.
239. Поясніть приклад 6.69.
240. Для наведених нижче матриць, елементи яких задані через
функцію від змінної x, з використанням символьного процесора системи
програмування Anaconda знайти аналітичні вирази для елементів зворотної
матриці, визначника, власних чисел та власних векторів матриці.
 x x2 x3   x 2x 3x 

а) 1,5 x 3x

5 x  ; б)
 2
( )
cos( x ) sin( x ) sin x  ;
 x x 23 x   x2 x exp( x )
   
 x −5 x2 + 3 x3 − 4 
 
в) sin ( x ) cos( x ) − sin( x ) arcsin ( x ) ;
 x x exp x 2 
 
 x−3 2x − 1 3x − 2 
 
г) cos2 ( x ) sin 2 ( x ) sin( x − 1) ;
 3 x 2 x −1 ln ( x ) 

 sin( x − 3) cos(2 x − 1) (3x − 2 ) 


 3 sin 2 ( x − 1) ;
д)  3 cos2 ( x ) 3 sin 2 ( x )

 
 x3 x −1 ln ( x ) 

 2x 3x 2 4 x3 
 
е) sin( x )cos( x ) cos( x ) − sin( x ) arcsin ( x 3) ;
 ln ( x ) x −1 exp x 2 
 
 x − 3 3 2x2 − 1 3x − 2 
 
є) 3 cos2 ( x ) 3 sin 2 ( x ) sin( x − 1) ;
3 2 
 x − 5 x −1 ln (5 x − 3) 

367
 2x
3
x2 x 3x 

ж)  ( )
3 cos x 2 ( )
3 sin x 2 ( ) 
sin x 2 − 1  .
3
 x 2 − 5x + 1 2x − 1 ( )

ln 5 x 2 − 3x + 2 

241. Які головні функції символьного процесора системи
програмування Anaconda використовуються для виконання аналітичних
перетворень математичного аналізу? Наведіть власні приклади виконання
таких операцій.
242. Що являє собою функція символьного процесора системи
Anaconda limit() та як вона використовується для виконання аналітичних
перетворень математичного аналізу? Наведіть власні приклади такого
використання цієї функції.
243. Що являє собою функція символьного процесора системи
Anaconda diff() та як вона використовується для виконання аналітичних
перетворень математичного аналізу? Наведіть власні приклади такого
використання цієї функції.
244. Що являє собою функція символьного процесора системи
Anaconda Function() та як вона використовується для виконання
аналітичних перетворень математичного аналізу? Наведіть власні приклади
такого використання цієї функції.
245. Що являє собою функція символьного процесора системи
Anaconda integrate() та як вона використовується для виконання
аналітичних перетворень математичного аналізу? Наведіть власні приклади
такого використання цієї функції.
246. Що являє собою функція символьного процесора системи
Anaconda summation() та як вона використовується для виконання
аналітичних перетворень математичного аналізу? Наведіть власні приклади
такого використання цієї функції.
247. Що являє собою функція символьного процесора системи

368
Anaconda series() та як вона використовується для виконання
аналітичних перетворень математичного аналізу? Наведіть власні приклади
такого використання цієї функції.
248. Поясніть приклади 6.70, 6.71 та 6.72.
249. Використовуючи функції символьного процесора системи
Anaconda, знайти похідні для наведених нижче функцій. З використанням
графічних засобів бібліотеки matplotlib побудувати графіки функції та її
похідної на одній координатній площині.
sin( x ) + cos( x )
а) ; б) arcsin ( x )arccos( x ) ; в) erf ( x )arcsin ( x ) ;
arcsin ( x ) + arccos( x )

sin( x )arccos( x ) sin( x )cos( x ) + cos( x )sin ( x )


г) ; д) ; е) erf ( x )sin ( x ) .
cos( x )arcsin ( x ) arcsin ( x ) + arccos( x )

250. Використовуючи функції символьного процесора системи


Anaconda, знайти аналітичні вирази для наведених нижче невизначених
інтеграли. Отриману функцію використати для обчислення визначеного
інтеграла на інтервалі [x1, x2].

а) ∫ x 3e − x dx , x1 = –2, x2 = 3; б) ∫ x 3 cos( x )dx , x1 = –5, x2 = 5;

в) ∫ x 4 cos( x )dx , x1= –2, x2= 3; г) ∫ exp( x ) cos( x )dx , x1= –1, x2 = 2;

д) ∫ x 3 sin ( x )dx , x1= 0, x2=2; е) ∫ x 2 exp( x )dx , x1 = 1, x2 = 2.


251. Що являє собою модуль системи програмування Anaconda scipy
та як він може бути використаний для розв’язування складних
обчислювальних інженерних та наукових завдань? Наведіть власні приклади
використання функцій цього модуля.
252. Як з використанням функцій модуля scipy системи
програмування Anaconda можна розв’язувати завдання чисельного
інтегрування складних математичних функцій. Наведіть власні приклади
такого використання функцій цього модуля.
253. Що являє собою функція quad() модуля scipy системи

369
програмування Anaconda та як вона використовується для розв’язування
завдань чисельного інтегрування математичних функцій? Наведіть власні
приклади такого використання цієї функції.
254. Що являє собою функція dblquad() модуля scipy системи
програмування Anaconda та як вона використовується для розв’язування
завдань чисельного інтегрування математичних функцій? Наведіть власні
приклади такого використання цієї функції.
255. Що являє собою функція tplquad() модуля scipy системи
програмування Anaconda та як вона використовується для розв’язування
завдань чисельного інтегрування математичних функцій? Наведіть власні
приклади такого використання цієї функції.
256. Що являє собою функція nquad() модуля scipy системи
програмування Anaconda та як вона використовується для розв’язування
завдань чисельного інтегрування математичних функцій? Наведіть власні
приклади такого використання цієї функції.
257. Що являє собою функція cumprapz() модуля scipy системи
програмування Anaconda та як вона використовується для розв’язування
завдань чисельного інтегрування математичних функцій? Наведіть власні
приклади такого використання цієї функції.
258. Поясніть приклади 6.73, 6.74 та 6.75.
259. Як з використанням засобів програмування системи Anaconda
обчислюються подвійні інтеграли? Поясніть формулу (6.6). Наведіть власні
приклади обчислення подвійних інтегралів.
260. Поясніть приклад 6.76.
261. Що являє собою інтеграл з невизначеною границею? Поясніть
формулу (6.7). Наведіть власні приклади обчислення інтегралів з
невизначеною границею.
262. Поясніть приклад 6.77 та рис. 6.23.
263. З використанням засобів програмування системи Anaconda
обчислити інтеграли, наведені у завданні 249, а – е, від нижньої границі x1 до

370
невизначеної верхньої границі x. З використанням графічних засобів
програмування системи Anaconda побудувати графік функції I(x), яка
відповідає обчисленому невизначеному інтегралу.
264. Як у загальній формі записується диференціальне рівняння
порядку n? Наведіть власні приклади диференціальних рівнянь, відомих Вам
з курсів математичного аналізу, основ фізики та фізичних основ електроніки.
265. Поясніть співвідношення (6.8).
266. Як у математиці у загальній формі записуються граничні умови
для диференціального рівняння порядку n? Наведіть власні приклади запису
граничних умов для диференціального рівняння.
267. Поясніть співвідношення (6.9).
268. Як формулюється задача Коші для диференціального рівняння
порядку n? Наведіть власні приклади формалізації диференціальних рівнянь
порядку n через розв’язування задачі Коші.
269. Поясніть співвідношення (6.10), (6.11).
270. Яка функція системи програмування Anaconda застосовується для
розв’язування диференціальних рівнянь та у якій бібліотеці вона
розташована? Наведіть власні приклади використання цієї функції.
271. Якій формат запису має функція odeint() та які параметри її

виклику? Наведіть власні приклади виклику функції odeint().

272. У якій формі формується розв’язок диференціального рівняння


порядку n через виклик функції odeint()?

273. Поясніть співвідношення (6.12) та (6.13).


274. Наведіть власні приклади використання функції odeint() для

чисельного розв’язування диференціальних рівнянь.


275. Які програмні засоби системи програмування Anaconda
використовуються для побудови графічних залежностей, пов’язаних із
371
розв’язком диференціального рівняння? Наведіть власні приклади побудови
таких графічних залежностей.
276. Чому для побудови графічних залежностей, пов’язаних із
розв’язком диференціального рівняння, необхідно транспортувати отриманий
числовий результат з вектора-стовпчика до вектора-рядка? Поясніть свою
відповідь на основі співвідношення (6.13).
277. Які засоби програмування системи Anaconda використовуються
для перетворення вектора-стовпчика до вектора-рядка? Наведіть власні
приклади використання таких програмних засобів.
278. Що являє собою функція flattern() системи програмування

Anaconda та як вона використовується для перетворення форми подання


векторів? Наведіть власні приклади такого використання цієї функції.
279. Що являє собою параметр rtol функції odeint() та як він

використовується для визначення точності розв’язування диференціального


рівняння? Наведіть власні приклади такого використання цього параметру.
280. Що являє собою параметр atol функції odeint() та як він

використовується для визначення точності розв’язування диференціального


рівняння? Наведіть власні приклади такого використання цього параметру.
281. Яке значення параметрів rtol та atol використовується в системі

програмування Anaconda за замовченням?


282. Як можна перевірити точність отриманого чисельного розв’язку
диференціального рівняння? Наведіть власні приклади виконання таких
перевірок.
283. Поясніть приклад 6.78 та рис. 6.24.
284. Поясніть приклад 6.79 та рис. 6.25.
285. Що являють собою фазові портрети та як вони використовуються

372
для аналізу отриманого розв’язку диференціального рівняння? Наведіть
власні приклади побудови та аналізу фазових портретів.
286. Поясніть приклад 6.80 та рис. 6.26.
287. Поясніть співвідношення (6.14) та (6.15).
288. Як записується диференціальне рівняння Ван-дер-Пола другого
порядку? Поясніть співвідношення (6.16) та (6.17).
289. Поясніть приклад 6.81 та рис. 6.27 та 6.28.
290. Виконати завдання 155 з розділу 5 з використанням засобів
програмування системи Anaconda.
291. Сформулюйте відповідну математичну модель Вашої наукової
дослідницької роботи у вигляді звичайного диференціального рівняння та
розв’яжіть це рівняння з використанням засобів програмування системи
Anaconda.
292. Що являє собою сервер у комп’ютерних мережах та які він
виконує функції? Наведіть власні приклади формування та використання
серверів.
293. Що являє собою клієнт у комп’ютерних мережах та які він
виконує функції? Наведіть власні приклади написання та використання
клієнтських програм.
294. У чому полягає головна сутність клієнт-серверних технологій
передавання інформації в комп’ютерних мережах? Наведіть власні приклади
використання клієнт-серверних технологій для розв’язування практичних
інженерних та наукових завдань.
295. Що являє собою мережна адреса комп’ютера та за якими
існуючими стандартами вона формується? Наведіть власні приклади
формування мережної адреси комп’ютера.
296. Які існують способи формування мережних адрес комп’ютерних
вузлів та як ці способи використовуються проектувальниками комп’ютерних

373
мереж? Наведіть власні приклади формування мережної адреси.
297. Що являє собою порт передавання інформації в комп’ютерних
мережах та як він формується? Наведіть власні приклади визначення портів
передавання інформації.
298. Чим відрізняється поняття апаратного порту електронної
апаратури від порту передавання інформації у теорії комп’ютерних мереж?
Поясніть свою відповідь та наведіть приклади відомих Вам портів першого
та другого типу.
299. Що являють собою сокети у теорії комп’ютерних мереж та як вони
формуються? Наведіть власні приклади формування сокетів.
300. Які моделі взаємодії клієнта та сервера Вам відомі? Наведіть
власні приклади використання різних моделей взаємодії для організації
роботи комп’ютерних мереж.
301. Що являє собою модель «запит – відповідь» та як вона
використовується для організації роботи комп’ютерних мереж? Наведіть
власні приклади використання цієї моделі.
302. Що являє собою модель «розгалуження на виході» та як вона
використовується для організації роботи комп’ютерних мереж? Наведіть
власні приклади використання цієї моделі.
303. Що являє собою модель «розгалуження на вході» та як вона
використовується для організації роботи комп’ютерних мереж? Наведіть
власні приклади використання цієї моделі.
304. Що являє собою модель «розсилання – підписка» та як вона
використовується для організації роботи комп’ютерних мереж? Наведіть
власні приклади використання цієї моделі.
305. Як за існуючим стандартом побудови комп’ютерних мереж
визначається мережна адреса локального комп’ютера? Наведіть приклад
визначення мережної адреси локального комп’ютера.
306. Що являє собою об’єкт класу socket у мові програмування
Python? Наведіть власні приклади створення екземплярів цього класу та

374
їхнього використання в мережному програмному забезпеченні.
307. Що являє собою метод bind() модуля socket інтерпретатора
мови програмування Python? Наведіть власні приклади використання цього
метода в мережному програмному забезпеченні.
308. Що являє собою метод listen() модуля socket інтерпретатора
мови програмування Python? Наведіть власні приклади використання цього
метода в мережному програмному забезпеченні.
309. Що являє собою метод connect() модуля socket
інтерпретатора мови програмування Python? Наведіть власні приклади
використання цього методу в мережному програмному забезпеченні.
310. Що являє собою метод accept() модуля socket інтерпретатора
мови програмування Python? Наведіть власні приклади використання цього
метода в мережному програмному забезпеченні.
311. Що являє собою метод send() модуля socket інтерпретатора
мови програмування Python? Наведіть власні приклади використання цього
метода в мережному програмному забезпеченні.
312. Що являє собою метод recv(n) модуля socket інтерпретатора
мови програмування Python? Наведіть власні приклади використання цього
метода в мережному програмному забезпеченні.
313. Що являє собою метод close() модуля socket інтерпретатора
мови програмування Python? Наведіть власні приклади використання цього
метода в мережному програмному забезпеченні.
314. Які системи кодування інформації використовуються для
формування повідомлень у сучасних комп’ютерних мережах. Наведіть власні
приклади формування мережних повідомлень.
315. Що являє собою метод encode() інтерпретатора мови
програмування Python? Наведіть власні приклади використання цього метода
в мережному програмному забезпеченні.
316. Як для створення мережного програмного забезпечення
використовуються функції модуля time інтерпретатора мови програмування
375
Python? Наведіть власні приклади використання цих функцій у мережному
програмному забезпеченні.
317. За яким загальним алгоритмом працює програма сервера у
мережному програмному забезпеченні?
318. За яким загальним алгоритмом працює програма клієнта у
мережному програмному забезпеченні?
319. Яке, серверне чи клієнтське програмне забезпечення, сьогодні
часто пишеться зі зручним графічним інтерфейсом користувача? Свою
відповідь обґрунтуйте та наведіть власні приклади такого програмного
забезпечення.
320. Як сучасні клієнт-серверні мережні технології використовуються
для створення розподілених баз даних та організації ефективного доступу до
них? Наведіть власні приклади такого використання клієнт-серверних
технологій.
321. Поясніть приклад 6.82 та рис. 6.29.
322. Поясніть приклад 6.83.
323. Поясніть приклад 6.84, а також рис. 6.30 та 6.31.
324. Як сучасні клієнт-серверні мережні технології використовуються
для організації проведення складних інженерних та наукових обчислень?
Наведіть власні приклади такого використання клієнт-серверних технологій.
325. Поясніть приклад 6.85, а також рис. 6.32 та 6.33.
326. Сформулюйте головні принципи, яких завжди слід дотримуватись
під час створення мережного програмного забезпечення. Наведіть власні
приклади використання цих підходів.
327. Сформулюйте відповідну математичну модель Вашої наукової
дослідницької роботи у вигляді системи алгебраїчних рівнянь та реалізуйте її
з використанням мережних клієнт-серверних технологій та засобів мови
програмування Python.
328. Які функції мови програмування Python використовуються для

376
програмування мікроконтролерів? Наведіть власні приклади використання
цих функцій.
329. У якому модулі розташовані функції мови програмування Python,
безпосередньо призначені для програмування мікроконтролерів? Наведіть
власні приклади використання функцій цього модуля.
330. Яка стандартна електронна апаратура завжди необхідна для
розв’язування завдання програмування мікроконтролерів? Наведіть власні
приклади формування запиту на закупівлю такої апаратури та з
використанням інформаційних ресурсів мережі Інтернет складіть
відповідний кошторис.
331. Як функції мови програмування Python, призначені для
програмування мікроконтролерів, пов’язані із теорією подійного
моделювання та із методами обробки подій?
332. Як функції мови програмування Python, призначені для
програмування мікроконтролерів, пов’язані із теорією скінченних автоматів?
333. Функції яких модулів інтерпретатора мови Python головним чином
використовуються для програмування мікроконтролерів?
334. Як для програмування мікроконтролерів використовуються
функції визначення системного часу?
335. Чому завдання програмування мікроконтролерів зазвичай
неможливо виконати лише з використанням засобів мови програмування
Python?
336. Які ще мови програмування обов’язково необхідно
використовувати для комплексного розв’язування завдань програмування
мікроконтролерів та в якій частині системи комп’ютер – мікроконтролер
розташовується програмне забезпечення, написане на цих мовах
програмування?
337. Як зазвичай розподіляються функції програмного забезпечення,
розташованого на мікроконтролері та на персональному комп’ютері? Свою
відповідь обґрунтуйте на наведіть власні приклади створення такого

377
розподіленого програмного забезпечення.
338. Як алгоритми програмування мікроконтролерів пов’язані із
теорією чисел та дискретною математикою?
339. Як алгоритми програмування мікроконтролерів пов’язані із
теорією подійного моделювання?
340. Як алгоритми програмування мікроконтролерів пов’язані із
теорією скінченних автоматів?
341. У якому модулі інтерпретатора мови програмування Python
розташовані функції, призначені для програмування мікроконтролерів?
Наведіть власні приклади використання цих функцій.
342. Що являє собою функція Serial() та як вона використовується
для програмування мікроконтролерів? Наведіть власні приклади
використання цієї функції.
343. Що являє собою функція readline() модуля serial та як вона
використовується для програмування мікроконтролерів? Наведіть власні
приклади використання цієї функції.
344. Що являє собою функція write() модуля serial та як вона
використовується для програмування мікроконтролерів? Наведіть власні
приклади використання цієї функції.
345. Чи можна назвати методи readline() та write()
перевантаженими? Свою відповідь обґрунтуйте.
346. Як функції модуля time інтерпретатора мови програмування
Python використовуються для програмування мікроконтролерів? Наведіть
власні приклади такого використання цих функцій.
347. Як для програмування мікроконтролерів використовуються цикли?
Наведіть власні приклади використання циклів для програмування
мікроконтролерів.
348. Поясніть приклад 6.86 та рис. 6.34.
349. Поясніть приклади 6.87 та 6.88.
350. Сформулюйте відповідну системну модель для Вашої наукової
дослідницької роботи, складіть алгоритм для цієї моделі та реалізуйте його з
використанням засобів мови програмування Python, призначених для
програмування мікроконтролерів.

378
Розділ 7 Практичні заняття
7.1 Заняття 1. Головні принципи об’єктно-орієнтованого
програмування

Індивідуальні завдання для виконання практичного заняття 1


1. Побудувати схему класифікації із успадкуванням класів для наступних
геометричних об’єктів: точка, пряма, відрізок, трикутник, прямокутний
трикутник, рівнобедрений трикутник, рівносторонній трикутник, чотирикутник,
паралелограм, ромб, прямокутник, квадрат, коло. Задаючи одногрупникам
питання та відповідаючи на них, описати властивості цих об’єктів. Для
виконання цього завдання використовувати приклади 1.1 та 1.2.
2. Побудувати схему класифікації із успадкуванням класів для
наступних об’єктів: натуральні числа, цілі числа, раціональні числа, дійсні
числа, комплексні числа. Задаючи одногрупникам питання та відповідаючи
на них, описати властивості цих об’єктів та математичні операції над ними.
Для виконання цього завдання використовувати приклади 1.1 та 1.2.
3. Побудувати схему класифікації із успадкуванням класів для наступних
математичних функцій: експоненціальна, логарифмічна, показникова, степенева,
тригонометричні, зворотні тригонометричні, гіперболічні, зворотні гіперболічні.
Задаючи одногрупникам питання та відповідаючи на них, описати властивості
цих об’єктів. Для виконання цього завдання використовувати приклади 1.1 та 1.2.
4. Побудувати схему класифікації із успадкуванням класів для компонентів
персонального комп’ютера. Задаючи одногрупникам питання та відповідаючи на
них, описати властивості цих об’єктів. Для виконання цього завдання
використовувати приклади 1.1 та 1.2.
5. Побудувати схему класифікації із успадкуванням класів для програмного
забезпечення різноманітного призначення. Задаючи одногрупникам питання та
відповідаючи на них, описати властивості цих об’єктів. Для виконання цього
завдання використовувати приклади 1.1 та 1.2.

379
6. Побудувати схему класифікації із успадкуванням класів для системи
команд мови програмування С. Задаючи одногрупникам питання та
відповідаючи на них, описати властивості цих об’єктів. Для виконання цього
завдання використовувати приклади 1.1 та 1.2.
7. Побудувати схему класифікації із успадкуванням класів для
компонентів операційної системи Windows. Задаючи одногрупникам питання
та відповідаючи на них, описати властивості цих об’єктів. Для виконання
цього завдання використовувати приклади 1.1 та 1.2.
За виконання завдань 1 – 7 студент отримує 7 балів.
8. Запропонувати, за власним бажанням, систему споріднених об’єктів
та побудувати для неї схему ієрархічної класифікації із успадкуванням
класів. Задаючи одногрупникам питання та відповідаючи на них, описати
властивості цих об’єктів. Для виконання цього завдання використовувати
приклади 1.1 та 1.2.
9. Організувати дискусію, під час якої спробувати сформулювати
правила, які є противними до правил філософії програмування мови Python,
наведених у підрозділі 1.5. Наприклад.
Красиве є кращим, ніж виродливе. → Виродливе також може
сприйматися як красиве (принцип сучасного абстрактного мистецтва).
Має існувати один – і бажано лише один – очевидний спосіб це
зробити. → Є такі задачі, які взагалі не можливо розв’язати. → Навіть у
класичній математиці існує багато задач, які можливо розв’язати різними,
альтернативними способами.
Практичність є важливішою за бездоганність. → Бездоганні речі
також можуть бути дуже практичними.
Під час проведення дискусії на ці теми підтверджуйте свої відповіді
доречними прикладами.
За виконання завдань 8, 9 студент отримує 3 бали.

380
Контрольні питання до практичного заняття 1
1. У чому полягає базова концепція об’єктно-орієнтованого програмування
та на яких теоретичних засадах вона ґрунтується?
2. Як базова концепція об’єктно-орієнтованого програмування пов’язана із
теорією регулярних мов та скінченних автоматів? Свою відповідь обґрунтуйте.
3. Що являє собою поняття об’єкту в теорії об’єктно-орієнтованого
програмування?
4. Що являє собою поняття події в теорії об’єктно-орієнтованого
програмування?
5. Що являє собою поняття поля в теорії об’єктно-орієнтованого
програмування?
6. Що являє собою поняття метода в теорії об’єктно-орієнтованого
програмування?
7. Що являє собою поняття класу в теорії об’єктно-орієнтованого
програмування?
8. Які операції із класами вважаються базовими в теорії об’єктно-
орієнтованого програмування?
9. Чому в теорії об’єктно-орієнтованого програмування вважається, що
клас має інтерфейсну природу?
10. Що являє собою абстрагування даних у теорії об’єктно-орієнтованого
програмування?
11. Що являє собою інкапсуляція в теорії об’єктно-орієнтованого
програмування?
12. Що являє собою успадкування в теорії об’єктно-орієнтованого
програмування?
13. Що являє собою батьківський клас у теорії об’єктно-орієнтованого
програмування?
14. Що являє собою дочірній клас у теорії об’єктно-орієнтованого
програмування?
15. Що являє собою поліморфізм у теорії об’єктно-орієнтованого
програмування?
16. Що являє собою поняття аспектів у теорії об’єктно-орієнтованого
програмування?
17. Як головні принципи об’єктно-орієнтованого програмування можна
пояснити через формулювання питань та відповіді на них?
381
18. Як теорія об’єктно-орієнтованого програмування пов’язана із
класифікацією електронних приладів?
19. Що являє собою ієрархія класів та спосіб формування запитів про
властивості об’єкту з точки зору теорії скінченних автоматів?
20. Чим відрізняється послідовна та паралельна ієрархія класів з точки
зору способу формування запиту?
21. У якому випадку, послідовної чи паралельної ієрархії, можна вважати,
що об’єкт належить двом незалежним класам?
22. У якому випадку, послідовної чи паралельної ієрархії, можна вважати,
що об’єкт належить двом залежним класам?
23. У чому полягає філософія мови програмування Python?
24. Які головні філософські принципи мови програмування Python Вам
відомі?

7.2 Заняття 2. Основи роботи з інтерпретатором мови Python


Індивідуальні завдання для виконання практичного заняття 2
1. Записати з використанням інтерпретатора мови програмування
Python функції, задані у таблиці 7.1, та обчислити їх значення за умови заданих
значень змінних.
Таблиця 7.1 – Завдання №1 для практичного заняття №2
Значення
№ варіанта Функція
змінних
х = 1,2,3,4,5,6,7,
x 2 − sin (nx )
f (x ) =
(nx + 1)⋅ cos(x)
. 8,9,10;
1. 3
N = 1,2,3,4

nx 2 − 15 х = –5, –4, –3, –2,


f (x ) = . –1, 0, 1, 2, 3, 4, 5;
2. tg nx 3 + 1 
  n=1,3,5,7
х = –5, –4, –3, –2,
sin  nx 2 − 20 x + 15 
  –1, 0, 1, 2, 3, 4, 5;
f (x ) = .
3.  3   3 
ln nx + 1  + exp nx − 10 x + 25  n=1,2,3,4
   

382
Таблиця 7.1 – Завдання №1 для практичного заняття №2 (продовження)

Значення
№ варіанта Функція
змінних

arccos nx 3 − 20 x 2 + 15 x − 5  х = –2, –1, 0, 1, 2;


f (x ) =   .
4. ln nx 3 + 2 x + 1  + exp nx 3 − 10  n=1,3,5,7
   

х = 1, 2, 3, 4, 5, 6, 7,

cos nx 3 − 5  + a sin  nx 3 + 5  8, 9, 10, 11, 12, 13,


   
f (x ) = .
5.  nx 3 + 2 x + 1  + cos nx 3 − 10  14, 15; n = 1,2,3,4;
   
   
a = 2,76

sh nx 3 − 10  + ch  nx 2 + 5  х = 0, 1, 2, 3, 4, 5;
6. f (x ) =    .
 nx 3 + 1  + ch  nx 3 − 10 
    n = 1,2,3,4
   

ch  nx 3 − 3x + 5  + sh nx 2 − 3x + 10 
f (x ) =    .
х = –2; n=1,3,5,7;
 nx 3 + 1  + ch  nx 3 − 1 
7.    
   

У яких випадках значення функції не може бути обчислене і чому?

За виконання першого завдання студент отримує 4 бали.

2. Записати з використанням інтерпретатора мови програмування

Python функції комплексної змінної, задані у таблиці 7.2, та обчислити їх

значення за умови заданих значень змінних. Обчислити також модуль

383
розрахованого комплексного числа та кут нахилу між його вектора у радіанах та

градусах.

Таблиця 7.2 – Завдання №2 для практичного заняття №2

№ варіанта Функція Значення змінної z

1. f(z) = w·exp(z)sin(z) w = 5 + 3j; z = 1 + 2j

w ⋅ z1
2. f ( z1, z2 ) = w = 15 + 4j; z1 = 3 + 6j; z2 = 7 + 10j
exp( z2 )

w ⋅ cos( z1 )
3. f ( z1, z2 ) = w = 5 + 8j; z1 = 7 + 2j; z2 = 13 + 15j
exp( z2 )

w ⋅ ln ( z2 )
4. f ( z1, z2 ) = w = 13 + 9j; z1 = 12 + 15j; z2 = 1 + 5j
exp( z2 ) + cos( z1 )

w ⋅ sin ( z2 )
5. f ( z1, z2 ) = w = 19 + 5j; z1 = 2 + 14j; z2 = 8 + 3j
ln( z2 ) + cos( z1 )

w ⋅ sin ( z2 )
6. f ( z1, z2 ) = w = 19 + 5j; z1 = 2 + 14j; z2 = 8 + 3j
ln( z2 ) + cos( z1 )

w ⋅ exp( z 2 )
7. f ( z1, z 2 ) = w = 19 + 5j; z1 = 2 + 14j; z2 = 8 + 3j
sin ( z 2 ) + cos( z1 )

За виконання другого завдання студент отримує 4 бали.


3. Записати математичні вирази, задані у таблицях 6.1 та 6.2, до
файлів, та провести обчислення значень функцій через виклик цих файлів.
Результати порівняти із тими, які були отримані у пунктах 1 та 2. Функції
написати таким чином, щоб у разі їх виклику на екран виводились не лише
значення обчислених змінних, але й їхні імена.
За виконання третього завдання студент отримує 2 бали.
Контрольні питання до практичного заняття 2
1. Що являють собою математичні функції у мові програмування
Python?
2. Як математичні функції у мові використовуються для формування
384
математичних виразів?
3. Які класи математичних функцій Вам відомі та як вони реалізовані в
мові програмування Python?
4. Що являє собою степенева функція та як вона реалізована в мові
програмування Python?
5. Чим відрізняється декларативний спосіб реалізації степеневої функції від
функціонального?
6. Що являє собою експоненціальна функція та як вона реалізована в
мові програмування Python?
7. Що являє собою логарифмічна функція та як вона реалізована в мові
програмування Python?
8. Що являють собою тригонометричні функції та як вони реалізовані в
мові програмування Python?
9. Що являють собою зворотні тригонометричні функції та як вони
реалізовані в програмування Python?
10. Що являють собою функції перетворення кутових величин та як
вони реалізовані в програмування Python?
11. Що являють собою гіперболічні функції та як вони реалізовані в
мові програмування Python?
12. Що являють собою зворотні гіперболічні функції та як вони
реалізовані в мові програмування Python?
13. Що являють собою функції комплексної змінної та як вони
реалізовані в мові програмування Python?
14. У чому полягає принцип модульного програмування мови Python?
15. Які модулі мови програмування Python, призначені для реалізації
математичних функцій, Вам відомі?
16. Як в мові програмування Python створюються власні модулі?
17. Що являють собою локальні змінні та як вони використовуються в мові
програмування Python?
18. Що являють собою глобальні змінні та як вони використовуються в
мові програмування Python?
19. Яким чином ім’я змінної в мові програмування Python може бути
використано для посилання на функцію?
20. Що являють собою вкладені функції та як вони формуються в мові
програмування Python?
385
21. Що являють собою зімкнені функції та як вони використовуються в
мові програмування Python?
22. Що являє собою простір імен у мові програмування Python та як він у
цій мові використовується?
23. Як простір імен мови програмування Python пов’язаний із концепцією
ООП?
24. Чому використання простору імен на завжди є ефективним стилем
програмування та іноді протерічить іншим, більш важливим філософським
принципам мови програмування Python?
25. Як у мові Python пов’язані між собою функціональний та модульний
стилі програмування?
26. Що являє собою операція імпортування модуля в мові
програмування Python?
27. Що являє собою операція імпортування функції в мові
програмування Python та як вона пов’язана з операцією імпортування модуля?
28. Як під час імпортування модулів та функцій використовуються імена
змінних та синоніми?
29. Як у мові програмування Python організується робота в через
командний рядок в інтерактивному режимі?
30. Як у мові програмування Python реалізується тестування програмного
забезпечення?

7.3 Заняття 3. Написання програми, призначеної для переведення


фізичних та інформаційних величин із однієї системи
вимірювання до іншої
Індивідуальні завдання для виконання практичного заняття 3
1. Написати власні функції, які здійснюють перетворення наступних
фізичних, інформаційних та економічних величин.
а) градусів за Цельсієм до градусів за Кельвіном, враховуючи те, що
T 0C = 273 +T 0K;
б) кіловатів до кінських сил (к.с.), враховуючи те, що 1 к.с. = 735,5 Вт;
в) км/год. до м/с, враховуючи те, що 1 год. = 3600 с, а 1 км = 1000 м;
г) дюймів до сантиметрів, враховуючи те, що 1 дюйм = 2,54 см;
д) мілів до кілометрів, враховуючи те, що 1 миля = 1,61 км;

386
е) фунтів до кілограмів 1 фунт = 0,4536 кг;
є) пудів до кілограмів 1 пуд = 16,38 кг;
ж) друкарських пунктів до міліметрів, враховуючи те, що
1 пункт = 0,376 мм;
з) ярдів до метрів, враховуючи те, що 1 ярд = 0,9144 м;
і) атомної одиниці маси (а.о.м.) до міліграмів, враховуючи те, що
1 а.о.м = 1,66·10−27 кг;
к) джоулів до мегаелектрон-вольтів, враховуючи те, що
1 еВ = 1,602·10−19 Дж;
л) періоду слідування імпульсів Tі до циклічної частоти їх слідування ωі,
2⋅π
враховуючи те, що ωi = ;
Ti
м) частоти електромагнітних коливань F до довжини хвилі у вакуумі λ ,
c
враховуючи те, що λ = , де c = 3·108 м/с – швидкість світла у вакуумі;
F
н) фокусної відстані оптичної лінзи F до оптичної сили лінзи у
1
діоптріях D, враховуючи те, що D = ;
F
о) байтів до кілобайтів, мегабайтів та гігабайтів, враховуючи те, що
1 кб = 1024 б, 1 Мб = 1024 кб, а 1 Гб = 1024 Мб;
п) бітів за секунду до мегабітів за секунду та гігабітів за секунду,
враховуючи те, що 1 Мб/c = 106 б/c, а 1 Гб/c = 109 б/c;
р) гривень до доларів та євро, вважаючи, що 1 $ = 28 грн., 1 євро = 31 грн;
с) кілометрів до світових літ, враховуючи те, що швидкість світла
становить 3·108 м/с, у році 365 діб, в одній добі 24 години, а у годині 3600
секунд;
т) десяткових чисел до двійкової та шістнадцяткової системи числення.
Всі функції написати таким чином, щоб вони могли здійснювати
перетворення як у прямому, так і у зворотному напрямку за модульним
принципом. Як шаблони для написання програм, призначених для

387
переведення величин із однієї системи вимірювання до іншої,
використовуйте приклади 2.46 – 2.48.
За виконання першого завдання студент отримує 6 балів.
2. Написати до створеної програми відповідний текст для функції
допомоги.
3. Провести тестування написаної програми.
4. Реалізувати написану програму з використанням засобів графічного
інтерфейсу користувача, які описані у розділі 5.
За виконання завдань 2 – 4 студент отримує 7 балів.

Контрольні питання до практичного заняття 3


1. Що являють собою конвертори фізичних величин та як вони
використовуються у сучасній інформаційній електронній апаратурі?
2. Чим суттєво відрізняються лінійні та нелінійні конвертори фізичних
величин?
3. Як здійснюється перетворення значення температури з градусів за
Цельсієм до градусів за Фаренгейтом?
4. Як класифікуються прилади для вимірювання тиску за
функціональним призначенням?
5. Як класифікуються прилади для вимірювання тиску за принципом дії
датчиків?
6. Як здійснюється перетворення значення тиску з Паскалей до
міліметрів ртутного стовпчика?
7. Які значення тиску зазвичай використовуються в сучасній
вимірювальній апаратурі?
8. Які значення тиску зазвичай використовуються для розв’язування
фізичних задач та технологічних завдань?
9. Як та у яких одиницях у сучасній акустиці вимірюється рівень
звукового сигналу та рівень шуму?

388
10. Чим відрізняється рівень шуму в відносних одиницях від його рівня
в децибелах?
11. Які головні особливості написання конверторів фізичних величин,
наведених у прикладах 2.46 – 2.48?
12. Які можливості мови Python програмування використані у прикладах
2.46 – 2.48?
13. Чому програми, наведені у прикладах 2.46 – 2.48, створені за
модульним принципом?
14. Які функції мови програмування Python використанні для
забезпечення можливості роботи програм, наведених у прикладах 2.46 – 2.48, в
інтерактивному режимі?
15. Що являє собою принцип програмування за шаблоном та як цей
спосіб програмування може бути використаний для створення конверторів
фізичних, інформаційних та економічних величин?
16. Чому засоби програмування мови Python можуть бути ефективно
використані для створення конверторів різних величин?

7.4 Заняття 4. Автоматичне визначення типу транзистора за його


маркуванням
7.4.1 Загальна постановка завдання визначення типу приладу за
його маркуванням та спосіб його розв’язування
Важливим завданням економіки виробництва, зокрема електронної
промисловості, є автоматизація визначення типа приладу за його
стандартним маркуванням. Для виконання цього завдання можуть бути
використані операції обробки рядків, які, для мови програмування Python, у
загальному вигляді були розглянуті у підрозділі 2.6. Алгоритм пошуку типу
приладу та його характеристик за заданими параметрами його маркування
можна у загальному вигляді сформулювати наступним чином.
1. Зчитування марки приладу.

389
2. Аналіз стандартів маркування.
3. Розбиття тексту, який характеризує марку приладу, на окремі
елементи, згідно із вимогами відповідних стандартів.
4. Аналіз елементів, отриманих в процесі розбиття.
5. Перевірка послідовностей символів, якій відповідає кожний з
елементів, на наявність відповідних послідовностей у стандарті, що
аналізується.
6. Якщо за пунктом 5 відповідність знайдена – формується відповідь,
яка характеризує, до якого класу, за відповідною категорією, згідно із
стандартом, належить даний прилад.
7. Якщо за пунктом 5 відповідність не знайдена – формується
повідомлення про помилку маркування.
8. Якщо помилок у маркуванні не знайдено – із сформованих
відповідей шляхом їх об’єднання формується повноцінне повідомлення про
властивості даного приладу за усіма категоріями, заданими у маркуванні.
Тобто, прилад розглядається як об’єкт, який за послідовностями
символів у маркуванні належить до відповідних класів.
Блок-схема алгоритму визначення типу приладу за його маркуванням
наведена на рис. 7.1.

7.4.2 Система маркування транзисторів


В класифікації марок транзисторів, яка сьогодні діє в Україні, розрізняють
стару та нову систему позначень [62]. За старою системою, яка діяла до 1964
року, до марки транзистора входить літера П та відповідний цифровий номер,
який характеризує діапазон роботи приладу за частотою та потужністю, а також
напівпровідниковий матеріал, із якого зроблений транзистор. Якщо транзистор
виготовлений в герметичному металевому корпусі, перед літерою П стоїть літера
М. Наприклад, П416Б, МП39Б. Цифрова система кодування класів транзисторів,
яка була прийнята згідно із цим стандартом, наведена у таблиці 7.3 [62].

390
Початок 6

Введення марки Формування черго-


1 приладу вого повідомлення
8 P(i) про клас при-
ладу

Аналіз
2 стандартів Об’єднання повідом-
маркування лення P(i) із поперед-
9 німи повідомленнями
та формування загаль-
Розбиття ного повідомлення П
3 введеного
тексту на
елементи 10
i = imax? 11
Ні
4 i=1 12
12 i = i + 1

Пошук елемента i
5 середь стандартів 5
маркування

6 10
Елемент
8
знайдений?

Ні Виведення оста-
точного сформо-
Виведення 11
ваного повідом-
повідомлення про лення П
7 помилку марки
приладу
Кінець

Кінець

Рис. 7.1 Узагальнений алгоритм автоматизованої класифікації приладу згідно


із існуючими стандартами маркування

391
Таблиця 7.3 – Цифрова система маркування транзисторів, розроблених до
1964 року

Цифрове позначення Матеріал Потужність Робоча частота


1 – 100 Германій Мала, P < 0,25 Вт Низька, F < 5 МГц
101 – 200 Кремній Мала, P < 0,25 Вт Низька, F < 5 МГц
201 – 300 Германій Велика, P > 0,25 Вт Низька, F < 5 МГц
301 – 400 Кремній Велика, P > 0,25 Вт Низька, F < 5 МГц
401 – 500 Германій Мала, P < 0,25 Вт Висока, F > 5 МГц
501 – 600 Кремній Мала, P < 0,25 Вт Висока, F > 5 МГц
601 – 700 Германій Велика, P > 0,25 Вт Висока, F > 5 МГц
701 – 800 Кремній Велика, P > 0,25 Вт Висока, F > 5 МГц

Наприклад, транзистор П416Б – це германієвий транзистор старої моделі,


малої потужності та високої частоти, без металевого корпусу. Останні дві цифри
маркування визначають номер розробки транзистора, а остання літра – її
різновид.
Згідно із новою системою маркування, введеною з 1964 року, перша
літера або цифра характеризує матеріал, із якого виготовлений транзистор.
Відповідність між напівпровідниковими матеріалами, літерами та цифрами,
показана у таблиці 7.4 [62].
Таблиця 7.4 – Система кодування матеріалу, із якого виготовлений
транзистор, згідно із стандартом 1964 р.

Цифра Літера Матеріал


1 Г Германій
2 К Кремній
3 А Арсенід галію
4 И Фосфат індію

392
Ця літера або цифра є першим блоком маркування. Другий блок – це літера,
яка характеризує тип транзистора за фізичним принципом його роботи, Т –
біполярний або П – польовий.
Третій блок маркування – це послідовність із трьох цифр. Друга і третя
цифри характеризують номер розробки, а перша – робочий діапазон транзистора
за частотою та за потужністю. Тобто, саме перша цифра є найважливішою для
визначення класу приладу. Цифрова система кодування класів транзисторів,
прийнята згідно із новим стандартом, наведена у таблиці 7.5 [62].

Таблиця 7.5 – Цифрова система маркування типів транзисторів,


розроблених після 1964 року, за частотою та за потужністю
Перша цифра Потужність Робоча частота
маркування
1 Мала, P < 0,3 Вт Низька, F < 3 МГц
2 Мала, P < 0,3 Вт Середня, 3 МГц < F < 30 МГц
3 Мала, P < 0,3 Вт Висока, 30 МГц < F < 300 МГц
4 Середня, 0,3 Вт < P < 1,5 Вт Низька, F < 3 МГц
5 Середня, 0,3 Вт < P < 1,5 Вт Середня, 3 МГц < F < 30 МГц
6 Середня, 0,3 Вт < P < 1,5 Вт Висока, 30 МГц < F < 300 МГц
7 Велика, P < 1,5 Вт Низька, F < 3 МГц
8 Велика, P > 1,5 Вт Середня, 3 МГц < F < 30 МГц
9 Велика, P > 1,5 Вт Висока, 30 МГц < F < 300 МГц

Четвертий елемент маркування – це літери від А до Я, які описують


групу, до якої належить транзистор, згідно із технологією його виготовлення.
Зазвичай для розробників електронної апаратури ця інформація є зайвою,
тобто, згідно із принципом абстрагування даних її можна ігнорувати.
Наприклад, КТ540Б – це кремнієвий транзистор нової моделі, середньої
потужності, середньої частоти, номер розробки – 40, технологія
виготовлення класу Б.

393
7.4.3 Індивідуальні завдання для виконання практичного заняття 4
1. Згідно із теоретичними відомостями, наведеними у підрозділі 7.4.2,
скласти класифікаційну діаграму транзисторів різних типів. Побудувати
діаграму таким чином, щоб за умови відомої марки транзистора можна було
визначити його фізичні властивості.
2. Згідно із блок-схемою алгоритму визначення типу приладу за його
маркуванням, наведеною на рис. 7.1, побудувати алгоритм визначення типу
транзистора. Для побудови такого алгоритму використати описання
стандартів маркування транзисторів, яке наведене у підрозділі 7.4.2.
3. Реалізувати цей алгоритм з використанням засобів програмування
мови Python, призначених для обробки рядкових даних, які були описані у
підрозділі 2.6.
4. Передбачити можливість введення марки транзистора у вікні командного
рядка в інтерактивному режимі роботи.
5. Перевірити коректність роботи написаної програми для транзисторів
марок МП9А, МП101А, МП111А, МП113, ГТ112А, 2ТМ103Д, КТ127А,
2Т201А, КТ201А, 2Т205, КТ206А, КТ302А, П307, П308, П309, ГТ404А,
КТ503Е, МП16, МП20, МП21(А,Б), МП25(А,Б), МП26(А,Б), МП35, МП36А,
МП37А, МП38, МП115, ГТ104, КТ104, КТ119А, КТ207В, КТ208М, КТ501А,
КТ339А, ГТ308А, КТ343В, КТ351А, КТ361А, КТ620Б, П414А, КТ812В,
КТ827А, ГТ701А, КТ814А, КТ604А, КТ927А.
6. Ввести неправильну марку транзистора та проаналізувати, як написана
програма обробляє некоректні ситуації.
7. Написати до створеної програми відповідний текст для функції
допомоги.
За виконання завдань 1 – 7 студент отримує 7 балів.
8. Провести тестування написаної програми.
9. Реалізувати написану програму з використанням засобів графічного
інтерфейсу користувача, які описані у розділі 5.
За виконання завдань 8, 9 студент отримує 3 бали.

394
Контрольні питання до практичного заняття 4
1. Як у мові програмування Python визначаються рядкові змінні?
2. Які операції над рядковими змінними можна виконувати у мові
програмування Python?
3. Як у мові програмування Python виконується операція об’єднання
рядків?
4. Як у мові програмування Python виконується операція виділення
окремих елементів із рядка?
5. Як у мові програмування Python виконується індексація елементів
рядкової змінної?
6. Яка функція мови програмування Python використовується для
визначення довжини рядка?
7. Як у мові програмування Python виконується операція розмноження
рядка?
8. Як у мові програмування Python здійснюється перетворення числової
змінної на рядкову?
9. Як у мові програмування Python здійснюється перетворення рядкової
змінної на числову?
10. Які спеціальні символи використовуються у мові Python для роботи
з рядками?
11. Який спеціальний символ мови програмування Python
використовується для переходу на новий рядок?
12. Який спеціальний символ мови програмування Python
використовується як знак табуляції?
13. Які функції мови програмування Python, призначені для роботи із
рядковими змінними, Вам відомі?
14. Як у мові програмування Python для роботи з рядковими змінними
використовується умовні оператори?
15. З яких блоків складається марка моделі для транзисторів старого
зразка?
16. Як у марці моделі транзисторів старого зразка позначається
напівпровідниковий матеріал, із якого виготовлений транзистор?
17. Як у марці моделі транзисторів старого зразка позначаються
транзистори, які герметизовані в металевому корпусі?
18. Як у марці моделі транзисторів старого зразка позначається
395
потужність транзистора?
19. Як у марці моделі транзисторів старого зразка позначається робоча
частота транзистора?
20. З яких блоків складається марка моделі для транзисторів нового
зразка?
21. Як у марці моделі транзисторів нового зразка позначається
напівпровідниковий матеріал, із якого виготовлений транзистор?
22. Як у марці моделі транзисторів нового зразка позначається
потужність транзистора?
23. Як у марці моделі транзисторів нового зразка позначається робоча
частота транзистора?

7.5 Заняття 5. Кусково-лінійна інтерполяція та лінійна апроксимація


таблично заданих функцій

7.5.1 Основи теорії лінійної інтерполяції


Лінійна інтерполяція часто використовується для обробки
експериментальних даних та отримання графічних залежностей, які дозволяють
оцінити результати експериментів. Зазвичай інтерполяція проводиться між
заданими значеннями аргументу x1, x2, …, xn, для яких визначені значення функції
f(x1), f(x2), ... , f(xn). Сутність методу лінійної інтерполяції є дуже простою. Точки з
декартовими координатами (x1, f(x1)), (x2, f(x2)), ..., (xn, f(xn)) з’єднуються між собою
прямими лініями. Результат кусково-лінійної інтерполяції таблично заданої функції
f(x) показаний на рис. 7.2.
f ( x)
f(x4)
2
f(x2)
f(x3) 1
f(x1)

x1 x2 x3 x4 x

Рис. 7.2 Результат кусково-лінійної інтерполяції (1) та лінійної апроксимації


(2) функції f(x), заданої дискретними відліками x1, x2, x3, x4

Слід відзначити, що лінійна інтерполяція сигналів широко


використовується в цифровій електроніці для оновлення дискретних сигналів
за заданими відліковими значеннями [60].

396
Згідно із рис. 7.2 значення функції f(x) для аргументу x ∈ [xi −1, xi ], для
будь-яких значень xi та xi–1 можна знайти із співвідношення [63, 64]:
f ( xi ) − f ( xi −1 )
f ( x ) = f ( xi −1 ) + ⋅ ( x − xi −1 ) . (7.1)
xi − xi −1
Розглянемо приклад пошуку значення функції f(x), заданої методом
кусково-лінійної інтерполяції. Будемо вважати, що дискретні відлікові
значення функції f(x) задані у таблиці 7.6. Знайдемо значення функції f(x) за
умови x = 0,68.
Таблиця 7.6 – Сукупність дискретних відлікових значень функції f(x)
x 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 1,0
f(x) 5,6 5,8 6,2 7,5 7,6 7,8 8,2 8,5 8,7 9,0
Згідно із співвідношенням (7.1) маємо:
f (0,7 ) − f (0,6) 8,2 − 7,8
f ( x ) = f (0,68) = f (0,6 ) + ⋅ (0,68 − 0,6 ) = 7,8 + ⋅ 0,08 = 8,12.
0,7 − 0,6 0,1
Узагальнений алгоритм обчислення значення функції f(x), заданої
методом лінійної інтерполяції, наведений на рис. 7.3.

Початок 4

Введення значень 5 i=2 7


1 x , ... x ; y , ... y
1 n 1 n

6
(x < xi)? 8
Введення
2 значення x
Ні
7 i=i+1 6
3
(x < x1) | (x > xn)? 5
6 Розрахунок значення
8 f(x) за формулою (7.1)
Ні
Повідомлення про
помилку: задане
4 значення x виходить Виведення зна-
9 чення функції f(x)
за межі області
визначення функції

Кінець Кінець

Рис. 7.3 Узагальнений алгоритм пошуку значення функції f(x), заданої


методом лінійної інтерполяції

397
7.5.2 Основи теорії лінійної апроксимації
Кусково-лінійна інтерполяція, розглянута у попередньому підрозділі,
дає досить високу точність оновлення функції f(x), але не враховує можливу
похибку експериментальних даних. Крім цього, у відлікових точках x1, x2, …,
xn функція інтерполяції не має похідної, що значно ускладнює її подальший аналіз.
Якщо залежність f(x) є близькою до лінійної, для подальшої ефективної
обробки експериментальних даних частіше використовують метод лінійної
апроксимації [63]. Головна ідея цього методу полягає у тому, що між
відліковими точками проводиться одна пряма лінія, але таким чином, що
сума відстаней від цієї лінії до кожної із відлікових точок має бути
мінімальною. Оскільки для статистичних оцінок відхилення важливішим є не
величина похибки, а квадрат цієї величини, частіше шукають мінімальне
значення не для суми відстаней, а для суми їхніх квадратів. В результаті між
відліковими точками проводиться пряма лінія, як показано на рис. 7.2.
Тобто, згідно із методом найменших квадратів, функцію оптимізації
для розв’язування завдання апроксимації слід шукати у вигляді [63]:
 n 
F (k , a0 ) = min ∑ ( yi − kxi − a0 )2  , (7.2)
k , a0  i =1 
де k та a0 – параметри лінійної функції апроксимації. Зрозуміло, що k – це
тангенс кута нахилу прямої лінії відносно осі абсцис, а a0 – її зміщення за
віссю ординат відносно нуля.
∂F (k , a0 ) ∂F (k , a0 )
Після взяття часткових похідних та та проведення
∂k ∂a0
відповідних аналітичних перетворень, можна отримати наступний вираз для
функції лінійної апроксимації [63]:
n
∑ i(x − m *
)⋅ (y − m *
) n
∑ ix
n
∑ yi
(x − m*x ), m*x = i =1 , m*y = i =1 .
x i y
y ( x ) = m*y + i =1
∑ (xi − m x )
n * 2 n n
i =1
(7.3)

398
де m*x – математичне сподівання величини x, а m*y – математичне сподівання

величини y. Тобто, згідно із співвідношеннями (7.2) та (7.3), для коефіцієнтів


функції апроксимації k та a0 та для лінійної функції апроксимації y ( x )
остаточно маємо:
n
( * *
∑ xi − mx ⋅ yi − m y)( )
k = i =1 , a0 = m y − k ⋅ mx , y ( x ) = k ⋅ x + a0 .
* *
(7.4)
n
( *2
∑ xi − mx )
i =1
Алгоритм формування лінійної функції апроксимації y ( x ) , заданої
співвідношеннями (7.3), (7.4), наведений на рис. 7.4. В цьому алгоритмі
введені наступні позначення:
n
(
S1 = ∑ xi − m*x ⋅ yi − m*y , )( ) n
(
S 2 = ∑ xi − m*x )2 . (7.5)
i =1 i =1

Початок 2

Введення значень Обчислення зна-


1 x , ... x ; y , ... y
1 n 1 n чень сум S1 та S2
3 за співвідноше-
ннями (7.5)
Обчислення зна-
* *
чень mx та m y Розрахунок значень k
2 4 та a за формулами (7.4)
0
за співвідноше-
ннями (7.3)
Кінець

Рис. 7.4 Алгоритм пошуку коефіцієнтів функції лінійної апроксимації

7.5.3 Індивідуальні завдання для виконання практичного заняття 5


1. Згідно із теоретичними відомостями, наведеними у підрозділі 7.5.1,
написати на мові програмування Python програмний модуль, який здійснює
інтерполяцію числових даних, заданих як масив. Кількість значень, за якими
проводиться інтерполяція, не повинна перевищувати 10.
2. За числовими даними, наведеними у таблиці 7.7, провести лінійну

399
інтерполяцію функції f(x) та знайти значення цієї функції для заданого
значення аргументу x. Програму писати згідно із блок-схемою алгоритму,
наведеною на рис. 7.4, з використанням арифметико-логічних виразів.
Таблиця 7.7 – Завдання для виконання практичного заняття 5

№ Значен-
Відлікові значення функції y(x)
варіанту ня x
xi 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9
1. 0,57
yi 0,23 0,32 0,39 0,49 0,61 0,7 0,81 0,89 1,1
xi 0,2 0,3 0,35 0,4 0,45 0,5 0,6 0,7 0,8
2. 0,48
yi 0,28 0,45 0,52 0,6 0,68 0,75 0,91 1,06 1,23
xi 1,0 1,5 2,0 2,5 3,0 4,0 5,5 6,0 7,0
3. 4,56
yi 1,2 2,3 3,4 4,3 5,5 7,6 8,8 10,1 11,3
xi 0,01 0,03 0,05 0,06 0,07 0,08 0,1 0,12 0,15
4. 0,038
yi 3,27 4,28 5,27 5,75 6,24 6,75 7,74 8,76 10,25
xi 2,0 2,5 3,0 3,5 4,0 5,0 6,0 6,5 7,0
5. 4,3
yi 7,25 8,23 9,24 10,25 11,25 13,27 15,3 16,25 17,35
xi 0,5 0,6 0,7 0,75 0,8 0,9 1,0 1,5 2,0
6. 0,86
yi 2,6 2,71 2,79 2,84 2,91 3,0 3,09 3,63 4,12
xi 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9
7. 0,44
yi 1,35 1,51 2,65 2,75 2,91 3,04 3,21 3,37 3,90
xi 1,0 1,5 2,0 3,0 3,5 4,0 5,5 6,0 7,0
8. 3,8
yi 0,3 0,41 0,49 0,71 0,80 0,89 1,01 1,12 1,35
xi 0,4 0,6 0,7 0,75 0,8 0,9 1,0 1,2 1,5
9. 0,83
yi 0,5 0,69 0,82 0,91 1,0 1,11 1,19 1,3 1,62
xi 2,0 2,5 3,0 3,5 4,0 5,0 6,0 7,0 8,0
10. 4,8
yi 0,3 0,51 0,69 0,92 1,09 1,50 1,92 2,31 2,69
xi 0,5 0,6 0,65 0,7 0,75 0,8 0,9 1,0 1,5
11. 0,77
yi 3,40 3,59 3,71 3,80 3,89 4,0 4,19 4,41 4,92
xi 0,4 0,5 0,6 0,7 0,75 0,8 0,9 1,0 1,2
12. 0,87
yi 5,72 5,81 5,89 5,98 6,04 6,11 6,19 6,28 6,51

400
3. Згідно із теоретичними відомостями, наведеними у підрозділі 7.5.1,
написати на мові програмування Python програмний модуль, який здійснює
лінійну апроксимацію числових даних. Програму писати згідно із блок-
схемою алгоритму, наведеною на рис. 7.4, з використанням оператору циклу
із заданою кількістю повторень.
4. За числовими даними, наведеними у таблиці 7.7, провести лінійну
апроксимацію функції f(x) та знайти значення цієї функції для заданого
значення аргументу x. Порівняти значення функції, отримані в результаті
інтерполяції та апроксимації.
5. Провести тестування написаних програмних модулів з
використанням функції testmod() модуля doctest.
6. Написати до створеної програми відповідний текст для функції
допомоги.
За виконання завдань 1 – 6 студент отримує 7 балів.
7. Реалізувати написану програму з використанням засобів графічного
інтерфейсу користувача, які описані у розділі 5.
8. Побудувати графічні залежності, на яких показати відлікові точки,
функцію лінійної інтерполяції та функцію лінійної апроксимації. Пояснити
отримані результати.
9. Перевірити отримані результати з використанням програмних засобів
системи Anaconda.
За виконання завдань 7 – 9 студент отримує 3 бали.

Контрольні питання до практичного заняття 5


1. Як у мові програмування Python формуються логічні вирази?
2. Які значення логічним виразам надає за замовченням інтерпретатор
мови програмування Python?
3. Як із логічних виразів мови програмування Python формуються
арифметико-логічні вирази?
4. Які форми умовного оператора мови програмування Python Вам
відомі та як вони працюють?
5. Як умовний оператори пов’язаний із арифметико-логічними виразами?

401
6. Який спосіб перетворення значень логічних виразів на числові
значення, реалізований у мові програмування Python, Вам відомий?
7. Які оператори циклу мови програмування Python Вам відомі та як
вони працюють?
8. Що являє собою кусково-лінійна інтерполяція функцій та як вона
здійснюється?
9. У чому полягає сутність лінійної інтерполяції та як вона пояснена на
рис. 7.2?
10. Як геометрична інтерпретація функції лінійної інтерполяції
пов’язана із її математичним описанням, заданим формулою (7.1)?
11. Як формула (7.1) пов’язана із алгоритмом розрахунку значення
функції лінійної інтерполяції, блок-схема якого наведена на рис. 7.3?
12. Чи може бути обчислене значення функції лінійної інтерполяції
через арифметико-логічний вираз?
13. Чим суттєво відрізняються ручний та автоматизований способи
розрахунку значення функції лінійної інтерполяції?
14. У чому полягають головні особливості реалізації функції кусково-
лінійної інтерполяції з використанням засобів програмування мови Python?
Які саме засоби цієї мови були використані Вами?
15. Як обчислюється похибка кусково-лінійної інтерполяції?
16. У чому полягають недоліки функції кусково-лінійної інтерполяції і
чому такий спосіб описання дискретних функцій не завжди є ефективним?
17. Як кусково-лінійна інтерполяція пов’язана із теорією дискретних
сигналів?
18. Як кусково-лінійна інтерполяція використовується для обробки
сигналів у сучасній цифровій електроніці?
20. Що являє собою функція лінійної апроксимації та чим вона суттєво
відрізняється від функції кусково-лінійної інтерполяції?
21. За якими критеріями найчастіше шукаються коефіцієнти функції
лінійної апроксимації?
22. Що являє собою метод найменших квадратів?
23. Як співвідношення (7.3) пов’язане із співвідношенням (7.2)?

402
24. Як співвідношення (7.4) та (7.5) пов’язані із співвідношенням (7.3)?
25. Як блок-схема алгоритму, наведена на рис. 7.4, пов’язана із
формулою (7.5)?
26. Які з операторів циклу мови програмування Python можуть бути
ефективно використані для реалізації алгоритму розрахунку коефіцієнтів
функції лінійної апроксимації, блок-схема якого наведена на рис. 7.4?
27. У чому полягають головні особливості реалізації функції лінійної
апроксимації з використанням засобів програмування мови Python? Які саме
засоби цієї мови були використані Вами?
28. Як обчислюється похибка лінійної апроксимації?

7.6 Заняття 6. Чисельне розв’язування нелінійних рівнянь


методом січних

7.6.1 Метод січних як спосіб розв’язування нелінійних рівнянь


Як відомо, метод січних – це ефективний метод розв’язування
нелінійних рівнянь виду f(x) = 0, яке є канонічною формою запису
узагальненого нелінійного рівняння [63]. Зрозуміло, що у разі, якщо рівняння
записано в будь-якій іншій формі f(x) = g(x), його завжди можна звести до
відповідного канонічного рівняння h(x) = f(x) – g(x) = 0.
Будемо вважати, корінь рівняння f(x) = 0 існує та лежить на відрізку [x1, x2].
Також вважатимемо, що функція f(x) на цьому відрізку є монотонною та не має
екстремумів. Графік функції f(x), яка відповідає описаним критеріям, показаний
на рис. 7.5.

f ( x)
f(x2)

1
2
x3 x4
f(x4) x1 x2 x
f(x3)
f(x1)

Рис. 7.5 Наочна ілюстрація ітераційних кроків методу січних


403
Тоді, як видно з рис. 7.5, можна провести пряму лінію між точками x1 та x2,
яка перетинає ось абсцис у точці x3. Можна легко обґрунтувати, що у будь-якому
випадку точка x3 належить відрізку [x1, x2]. Обчислюючи значення f(x3) бачимо,
що для випадку, який показаний на рис. 7.5, це значення, як і f(x1), є від’ємним, у
той час як значення f(x2) – це додатна величина. Тому тепер проведемо пряму
лінію між точками із декартовими координатами (x3, f(x3)) та (x2, f(x2)). Ця лінія
перетинає ось абсцис у точці x4. Це друга ітерація метода січних, і цілком
зрозуміло, що |x4 – x2| < |x3 – x2|. Продовжуючи відповідні геометричні побудови
та обчислення, можна знайти випадок, коли | f(xn)| < ε, де ε – наперед задана
точність розв’язування рівняння. У разі виконання цієї умови рівняння f(x) = 0
вважається розв’язаним.
Із рис. 7.5 зрозуміло, що перше наближення методу січних x3 можна
знайти за співвідношенням [63]:
f ( x1 ) ⋅ ( x2 − x1 )
x3 = x1 − . (7.6)
f ( x2 ) − f ( x1 )
У загальному випадку ітераційне співвідношення, яке відповідає
розглянутому вище методу січних, записується у вигляді [63]:
f ( xi −1 ) ⋅ ( xi − xi −1 )
xi +1 = xi −1 − . (7.7)
f ( xi ) − f ( xi −1 )
Слід відзначити, що частіше точність обчислень за методом січних
визначаться не неявно через зміну значення функції, а безпосередньо, через
зміну значення аргументу [63]. Тоді, за умови заданої точності обчислення
кореня нелінійного рівняння δ, корінь вважається знайденим у разі виконання
умови [63]:
xi − xi −1 < δ . (7.8)

7.6.2 Індивідуальні завдання для виконання практичного заняття 6


1. З використанням засобів програмування мови Python написати
функцію, яка реалізує метод січних, заданий співвідношенням (7.2). Функцію

404
написати таким чином, щоб математична функція f ( x ) , значення якої
обчислюються, передавалась до неї як один із аргументів.
2. З використанням написаної функції, в який реалізований алгоритм
метода січних, знайти корені заданого нелінійного рівняння у визначеному
діапазоні зміни аргументу x із заданою точністю:

ex
а) = 3; x ∈ [0,6;0,8], δ = 5 ⋅ 10− 4 ; x ∈ [1,4;1,6], δ = 2 ⋅ 10− 4 ;
x

e x − 0,25
б) = 0; x ∈ [0,2;0,3], δ = 7 ⋅ 10 −5 ; x ∈ [4,7;4,75], δ = 5 ⋅ 10 −5 ;
cos( x ) − 1
cos( x ) − 2
в) = 0; x ∈ [0,1;1], δ = 8 ⋅ 10− 4 ; x ∈ [5;6], δ = 9 ⋅ 10−5 ;
cos( x ) + 3
sin ( x )
г) = 0; x ∈ [1,6;2,5], δ = 3 ⋅ 10− 4 ; x ∈ [5;6], δ = 6 ⋅ 10− 4 ;
cos( x ) + 2
sin ( x ) + cos( x )
д) = 0; x ∈ [1;3], δ = 7 ⋅ 10−3 ; x ∈ [7;9], δ = 4 ⋅ 10−3;
cos( x ) − 2
sin ( x ) − cos( x )
е) = 0; x ∈ [0;2], δ = 2 ⋅ 10−3 ; x ∈ [2;4], δ = 3 ⋅ 10−3 ;
cos( x ) + sin ( x )

ex − 2
є) = 0; x ∈ [− 1;−0,5], δ = 7 ⋅ 10−5 ; x ∈ [0,6;0,8], δ = 5 ⋅ 10−5 ;
ln( x ) − x

ex − x
ж) = −3; x ∈ [3;4], δ = 4 ⋅ 10−3;
ln( x ) − x 2

e x + x2
з) = 3; x ∈ [0,2;0,5], δ = 4 ⋅ 10−3;
cos( x ) − sin ( x )

e x − x2 − 1
і) = 2; x ∈ [2;3], δ = 4 ⋅ 10−3.
cos( x )sin ( x ) + 3
Кількість знаків після десяткової коми для результату розрахунків,
який виводиться на екран, повинні відповідати визначеній точності.
3. Для заданої точності розрахунків провести тестування програми з
використанням функції testmod() модуля doctest. Після цього знизити
точність розрахунків, збільшуючи на порядок задане значення похибки, та

405
знову провести тестування програми. Пояснити отримані результати
тестування.
4. Написати до створеної програми відповідний текст для функції
допомоги.
За виконання завдань 1 – 4 студент отримує 7 балів.
5. Реалізувати написану програму з використанням засобів графічного
інтерфейсу користувача, які описані у розділі 5.
6. Побудувати графік математичної функції, для якої проводиться пошук
нульового значення, та дослідити властивості цієї функції у визначеному
числовому діапазоні.
7. Перевірити отримані результати з використанням програмних засобів
системи Anaconda.
За виконання завдань 5 – 7 студент отримує 3 бали.

Контрольні питання до практичного заняття 6


1. Якими способами у мові програмування Python можна передати одну
функцію до іншої функції як аргумент?
2. Як у мові програмування Python реалізується умовний оператор?
3. Як у мові програмування Python реалізується оператор циклу із
заданою кількістю повторень?
4. Як у мові програмування Python реалізуються оператори циклу із
виходом за заданою умовою?
5. Що являє собою метод січних та як він використовується для пошуку
коренів нелінійних рівнянь?
6. Як можна пояснити ітераційний процес, показаний на рис. 7.5?
7. Яким чином із геометричної інтерпретації метода січних, наведеної
на рис. 7.5, можна вивести співвідношення (7.7)?
8. Яким способом визначається точність розрахунків для метода
січних?
9. Чи залежить точність розрахунків метода січних від поведінки
функції f ( x ) , відносно якої розв’язується нелінійне рівняння?
10. За яких умов метод січних може розбігатися?
11. Який із способів реалізації оператору циклу слід обирати для
406
написання програми, призначеної для пошуку кореня нелінійного рівняння
методом січних?
12. Чи необхідно використовувати умовний оператор для реалізації
метода січних, і якщо потрібно – то за якої умови?
13. За якої умови програма, в який реалізований метод січних, може
давати негативний результат тестування і чому?
14. За якої умови програма, в який реалізований метод січних, завжди
дає позитивний результат тестування?

7.7 Заняття 7. Чисельне інтегрування функцій на заданому числовому


інтервалі методом трапецій

7.7.1 Чисельне інтегрування та метод трапецій


Відомо, що якщо похідну можна обчислити аналітично від будь-якої
комбінації елементарних функцій, аналітичні функції для невизначених
інтегралів від таких комбінацій часто не можуть бути знайдені. Тому в
сучасній обчислювальній математиці розроблені чисельні методи для
обчислення визначених інтегралів [6, 7, 63, 64].
Найпростішим із цих методів є метод прямокутників, який оснований
на розбиття площини, розташованою під графіком функції, на невеликі
елементарні прямокутники та на сумуванні їх площин [63]. Відповідний
процес розбиття на інтервалі інтегрування [a, b] із кроком інтегрування h
наочно показаний на рис. 7.6, а.
y y
f ( x)

f ( x)

0а h b x
0а b x
h

а) б)
Рис. 7.6 Наочна ілюстрація чисельного інтегрування функції f(x) на інтервалі
[a, b] із кроком інтегрування h з використанням метода прямокутників (а) та
метода трапецій (б)
407
Відомо, що для метода прямокутників приблизне значення визначеного
інтегралу від функції f(x) на інтервалі від a до b за умови рівного кроку
квантування h обчислюється через наступні співвідношення [63]:
b n b−a
∫ f ( x )dx ≈ ∑ f ( xi )h , h= , xi = a + i ⋅ h . (7.9)
a i =0 n

Похибка обчислень значення визначеного інтегралу з використанням


співвідношень (7.9) пропорційна максимальному значенню першої похідної
від функції f(x) та квадрату інтервалу інтегрування, тобто [63]:

 df ( x )  (b − a ) . 2
εпр =   ⋅ (7.10)
 dx max 2

Із рис. 7.6, а, видно, що значення похибки для метода прямокутників


може бути досить високим. Це пов’язано з тим, що визначення значень
функції f(x) використовується апроксимація нульового порядку, похибка якої
є досить високою.
Тому для зниження обчислювальної похибки чисельного інтегрування
переходять до лінійної апроксимації функції f(x), розглянутої у практичному
занятті 5. Такий спосіб інтегрування називається методом трапецій, він
наочно проілюстрований на рис. 7.6, б. Зрозуміло, що за умови використання
метода трапецій обчислювальна похибка є значно меншою, ніж для методу
прямокутників. Квадратурна формул для метода трапецій записується у
вигляді [63]:
b n −1 f ( x ) + f ( x ) b−a
∫ f ( x )dx ≈ ∑
i i +1 h, h= , xi = a + i ⋅ h . (7.11)
a i =0 2 n

Похибка методу трапецій пропорційна максимальному значенню


другої похідної від функції f(x) та квадрату кроку квантування h та величині
інтервалу інтегрування [63]:
 d 2 f (x ) 
 
 dx 2 
  max
ε тр = ⋅ (b − a ) ⋅ h 2 . (7.12)
12
408
7.7.2 Індивідуальні завдання для виконання практичного заняття 7
1. З використанням засобів програмування мови Python написати
функцію, яка реалізує метод трапецій для обчислювання значень визначеного
інтеграла, заданий співвідношенням (7.11). Функцію написати таким чином,
щоб математична функція f ( x ) , яка інтегрується, передавалась до неї як
один із аргументів. Іншими аргументами функції, яка реалізує метод
трапецій, мають бути мінімальне значення аргументу a, максимальне
значення аргументу b та кількість елементарних інтервалів n, на яких
проводиться обчислення за формулою (7.11). Також передбачити
використання функції обчислення середнього значення mean() для
розрахунку величини
f ( xi ) + f ( xi +1 )
ci = , (7.13)
2
яка стоїть під знаком суми у співвідношенні (7.11).
2. З використанням написаної функції, в який реалізований алгоритм
метода трапецій, знайти значення наступних визначених інтегралів для
заданої математичної функції у заданому діапазоні значень аргументу:
5π x3 cos( x ) 8 x 2 sin ( x )
а) ∫ dx , n = 4000; б) ∫ dx , n = 7000;
2π sin ( x ) + 5 4 ln ( x )

8π x sin ( x ) 8 x 4 exp( x )
в) ∫ dx , n = 3000; г) ∫ dx , n = 5000;
2π cos( x ) + 4 4 ln ( x )

4 ln ( x ) 
10 π sin ( x ) − cos( x ) 8 x  exp( x ) − x + 1 
д) ∫ dx , n = 6000; е) ∫   dx , n = 2000;
5π sin ( x ) + cos( x ) + 3 4 x 2 +2 x + 5

6 π x3 sin (2 x ) − 4 7 π sin 3 ( x ) − cos 4 ( x ) − 5


є) ∫ dx , n = 4500; ж) ∫ dx , n = 2500;
1,5π cos(3 x ) + 3 5π sin ( x ) + cos ( x ) + 3
2 5

 exp( x ) ln( x ) 
3 x5 (exp( x ) + ln ( x ))
x4 
7
− 
 x + 5 x2 + 1
з) ∫ dx , n = 8000; і) ∫ dx , n = 7000;
2 x3 + 2 x + 5 5 x 2 +2 x + 5

409
к) ∫
( )
3,5π sin 5 ( x ) − cos3 ( x ) − 10 ⋅ x 2 8 x3 exp( x − 1)
dx , n = 3500; л) ∫ dx , n = 5000.
1,5π sin ( x ) + cos ( x ) + 7
4 4
4 ln ( x + 5 )
3. Провести тестування програми з використанням функції
testmod() модуля doctest та пояснити отримані результати тестування.
4. Написати до створеної програми відповідний текст для функції
допомоги.
За виконання завдань 1 – 4 студент отримує 7 балів.
5. Реалізувати написану програму з використанням засобів графічного
інтерфейсу користувача, які описані у розділі 5.
6. З використанням засобів програмування системи Anaconda побудувати
графік підінтегральної функції у визначеному діапазоні значень змінної та
дослідити її властивості, а також обчислити інтеграл чисельно з використанням
функції quad() модуля scipy та порівняти отримані результати.
За виконання завдань 5, 6 студент отримує 3 бали.

Контрольні питання до практичного заняття 7

1. Які методи чисельного інтегрування функцій Вам відомі та чим вони


відрізняються?
2. Що являє собою метод прямокутників та які його головні переваги та
недоліки?
3. Як геометрична інтерпретація метода прямокутників, наведена на
рис. 7.6, а, пов’язана із формулами (7.9)?
4. Як обчислюється похибка інтегрування для метода прямокутників?
5. Чому у разі використання метода прямокутників похибка
інтегрування може бути досить високою?
6. Який метод апроксимації підінтегральної функції використовується в
методі прямокутників?
7. Що являє собою метод трапецій та які його головні переваги та
410
недоліки?
8. Як геометрична інтерпретація метода трапецій, наведена на рис. 7.6,
б, пов’язана із формулами (7.11)?
9. Як обчислюється похибка інтегрування для метода трапецій?
10. Чому у разі використання метода трапецій похибка інтегрування
завжди є меншою, ніж для метода прямокутників?
11. Який метод апроксимації підінтегральної функції використовується
в методі трапецій?
12. Чому для обчислення похибки метода прямокутників
використовується перша похідна підінтегральної функції, а для обчислення
похибки метода трапецій – друга похідна?
13. Яким чином для комп’ютерної реалізації метода трапецій може
бути використана функція обчислення середнього значення двох чисел?
14. Які засоби програмування мови Python можуть бути ефективно
використані для реалізації метода трапецій?
15. Чи можуть бути використані для реалізації метода трапецій засоби
функціонального програмування?
16. Чи можуть бути використані для реалізації метода трапецій засоби
модульного програмування?
17. Які модифікації умовного оператору мови програмування Python
Вам відомі?
18. Які модифікації оператору циклу мови програмування Python Вам
відомі?
19. Чи необхідно використовувати оператор циклу для реалізації
метода трапецій, і якщо потрібно – то яким чином?
20. Чи необхідно використовувати умовний оператор для реалізації
метода трапецій, і якщо потрібно – то за якої умови?
21. За якої умови програма, в який реалізований метод трапецій, може

411
давати негативний результат тестування і чому?
22. За якої умови програма, в який реалізований метод трапецій, завжди
дає позитивний результат тестування?
23. За якої умови програму, в який реалізований метод трапецій, можна
вважати надійною?
24. Як у програмі, в який реалізований метод трапецій, може бути
сформований простір імен?
25. Чи може бути використаний у програмі, в який реалізований метод
трапецій, апарат локальних та глобальних змінних мови програмування
Python?

7.8 Заняття 8. Розв’язування систем лінійних рівнянь методом


Крамера
7.8.1 Визначник матриці та спосіб розв’язування систем лінійних
рівнянь методом Крамера
Завданням цього заняття є написання універсальної програми,
призначеної для розв’язування систем із трьох нелінійних рівнянь із трьома
невідомими. Як відомо, для розв’язування цього завдання, для системи
рівнянь, записаної у загальному вигляді:
 a11 ⋅ x1 + a12 ⋅ x 2 + a13 ⋅ x3 = b1 ;

a 21 ⋅ x1 + a 22 ⋅ x 2 + a 23 ⋅ x3 = b2 ; (7.14)
 a 31 ⋅ x1 + a 32 ⋅ x 2 + a 33 ⋅ x3 = b3 ,

необхідно знайти визначник [6, 7, 42, 64]. Також відомо, що визначник


a11 a12 a13
матриці третього порядку A, A = a 21 a 22 a 23 , обчислюється за формулою
a 31 a 32 a 33

[6, 7, 42, 64]:


A = ∆ = a11 ⋅ a22 ⋅ a33 + a12 ⋅ a23 ⋅ a31 + a21 ⋅ a32 ⋅ a13 −

− a13 ⋅ a 22 ⋅ a 31 − a 21 ⋅ a12 ⋅ a 33 − a 32 ⋅ a 23 ⋅ a11 . (7.15)


Якщо у матриці A замінити перший стовпчик на вектор коефіцієнтів B, де

412
 b1 
B = b2  , (7.16)
b 
 3
отримуємо нову матрицю A1:
 b1 a12 a13 
A1 = b2 a22 a23  . (7.17)
b a32 a33 
 3
Аналогічно формуються матриці A2 та A3:
 a11 b1 a13   a11 a12 b1 
A 2 = a21 b2 a23  , A3 = a21 a22 b2  . (7.18)
a b3 a33  a a32 b3 
 31  31
Тоді корені системи рівнянь (7.1), x1, x2 та x3, згідно із відомим з
аналітичної геометрії методом Крамера, визначаються із співвідношень [6, 7, 42]:
A1 A2 A3
x1 = , x2 = , x3 = , (7.19)
A A A

де матриці A1, A2 та A3 визначаються співвідношеннями (7.17) та (7.18), а їх


визначники обчислюються через співвідношення, аналогічні співвідношенню
(7.15), з урахуванням заміни стовпчиків матриці.
Зрозуміло, що співвідношення (7.19) є коректними лише за умови
A ≠ 0 , а за умови A = 0 матриця вважається виродженою [6, 7, 42].

7.8.2 Приклади розв’язування систем лінійних рівнянь з


використанням метода Крамера
Розв’яжемо з використанням співвідношень (7.19) наступну систему
лінійних рівнянь:

 2 x1 − x2 − x3 = 7;

 x1 + x2 − 2 x3 = 2; (7.20)
 x1 − x2 − 3 x3 = −2.

Спочатку знайдемо визначних матриці A та впевнимося, що він не


дорівнює 0. Обчислення за формулою (7.2) дають наступний результат:

413
2 −1 −1
A = 1 1 − 2 = 2 ⋅ 1 ⋅ (− 3) + (− 1) ⋅ (− 1) ⋅ 1 + (− 1) ⋅ (− 2 ) ⋅ 1 −
1 −1 − 3

− (− 1) ⋅ 1 ⋅ 1 − (− 1) ⋅ 1 ⋅ (− 3) − (− 2 ) ⋅ (− 1) ⋅ 2 = −6 + 1 + 2 + 1 − 3 − 4 = −9 ≠ 0 .
Тобто, система є не виродженою і можна проводити обчислення далі.
7 −1 −1
A1 = 2 1 − 2 = 7 ⋅ 1 ⋅ (− 3) + (− 1) ⋅ (− 1) ⋅ 2 + (− 1) ⋅ (− 2 ) ⋅ (− 2 ) −
− 2 −1 − 3

− (− 1) ⋅ 1 ⋅ (− 2 ) − (− 1) ⋅ 2 ⋅ (− 3) − (− 2 ) ⋅ (− 1) ⋅ 7 = −21 + 2 − 4 − 2 − 6 − 14 = −45 .
2 7 −1
A 2 = 1 2 − 2 = 2 ⋅ 2 ⋅ (− 3) + (− 1) ⋅ (− 2 ) ⋅ 1 + 7 ⋅ (− 2) ⋅ 1 −
1 −2 −3

− (− 1) ⋅ 2 ⋅ 1 − 7 ⋅ 1 ⋅ (− 3) − (− 2 ) ⋅ (− 2 ) ⋅ 2 = −12 + 2 − 14 + 2 + 21 − 8 = −9 .
2 −1 7
A 3 = 1 1 2 = 2 ⋅ 1 ⋅ (− 2 ) + (− 1) ⋅ 2 ⋅ 1 + (− 1) ⋅ 7 ⋅ 1 −
1 −1 − 2

− 7 ⋅ 1 ⋅ 1 − (− 1) ⋅ 1 ⋅ (− 2 ) − 2 ⋅ (− 1) ⋅ 2 = −4 − 2 − 7 − 7 − 2 + 4 = −18 .
Тоді, згідно із співвідношеннями (7.19), остаточно маємо:
A1 − 45 A −9 A − 18
x1 = = = 5 ; x2 = 2 = = 1 ; x3 = 3 = = 2.
A −9 A −9 A −9
Впевнимось, що отримані значення x1, x2 та x3 дійсно задовольняють
системі рівнянь (7.20).
2 x1 − x2 − x3 = 2 ⋅ 5 − 1 − 2 = 7 ; x1 + x2 − 2 x3 = 5 + 1 − 2 ⋅ 2 = 2 ;
x1 − x2 − 3 x3 = 5 − 1 − 3 ⋅ 2 = −2 .
Оскільки за умови підстановки знайдених значень x1, x2 та x3 всі три
рівняння системи (7.20) виконуються, можна вважати, що знайдений
розв’язок є правильним.
Розглянемо інший приклад. Спробуємо розв’язати систему рівнянь:
 2 x1 − x2 − x3 = 7;

4 x1 − 2 x2 − 2 x3 = 2; (7.21)
 x1 − x2 − 3 x3 = −2.

У цьому випадку визначник матриці A становить:

414
2 −1 −1
A = 4 − 2 − 2 = 2 ⋅ (− 2 ) ⋅ (− 3) + (− 1) ⋅ (− 2 ) ⋅ 1 + (− 1) ⋅ (− 1) ⋅ 4 −
1 −1 − 3

− (− 1) ⋅ (− 2 ) ⋅ 1 − (− 1) ⋅ 4 ⋅ (− 3) − (− 2 ) ⋅ (− 1) ⋅ 2 = 12 + 2 + 4 − 2 − 12 − 4 = 0 .
Тобто, систему рівнянь (7.21) є виродженою і розв’язати її неможливо.
Це пояснюється тим, що перше та друге рівняння системи є лінійно-
залежними, оскільки друге рівняння є результатом множення на 2
коефіцієнтів першого рівняння. Відомо, для матриць із лінійно-залежними
рядками визначник завжди дорівнює 0 [42, 64].

7.8.3 Індивідуальні завдання для виконання практичного заняття 8


1. З використанням засобів програмування мови Python написати
програму для обчислення визначника матриці та реалізувати її як функцію в
окремому модулі.
2. Передбачити можливість введення елементів матриці, які є
коефіцієнтами системи рівнянь, а також коефіцієнтів вектора, який задає
праву частину системи рівнянь, з клавіатури в інтерактивному режимі.
3. Обчислити визначник матриці та перевірити, чи є вона виродженою.
У разі, якщо матриця є виродженою, виводити на екран повідомлення про
помилку та припиняти виконання програми.
4. За умови, що матриця є не виродженою, замінити послідовно
перший, другий та третій стовпчики матриці на вектор правої частини, та,
згідно із співвідношеннями (7.19) розв’язати задану систему рівнянь.
Результати обчислень вивести на екран із трьома знаками після десяткової
коми.
За виконання завдань 1 – 4 студент отримує 5 балів.
5. Перевірити коректність роботи написаної програми для наступних
систем лінійних рівнянь:
4 x1 − 5 x2 − 2 x3 = 2; 5 x1 − 7 x2 − 5 x3 = 3; 10 x1 − 2 x2 − 5 x3 = 13;
  
а)  5 x1 + x2 − 2 x3 = 4; б)  x1 + x2 − 5 x3 = 7; в)  12 x1 + x2 − 5 x3 = 17;
 6 x1 − x2 − 3 x3 = 2. 3 x1 − 2 x2 − 3 x3 = 2. 13x1 − 22 x2 − 3 x3 = 3.

415
 4 x1 − 5 x2 − 2 x3 = 2;  5 x1 − 7 x2 − 5 x3 = 3;  10 x1 − 2 x2 − 5 x3 = 13;
  
г) 8 x1 − 10 x2 − 4 x3 = 4; д)  3 x1 + 6 x2 − 5 x3 = 7; е) 12 x1 + 9 x2 − 15 x3 = 15;
 6 x − x − 3 x = 2. 10 x1 − 14 x2 − 15 x3 = 2.  4 x + 3 x − 5 x = 12.
 1 2 3  1 2 3
6. Провести автоматичне тестування роботи написаної програми з
використанням функції testmod() модуля doctest.
7. Написати до створеної програми відповідний текст для функції
допомоги.
За виконання завдань 5 – 7 студент отримує 2 бали.
8. Реалізувати написану програму з використанням засобів графічного
інтерфейсу користувача, які описані у розділі 5.
9. Перевірити отримані результати з використанням засобів програмування
системи Anaconda, описаних у підрозділах 6.1 та 6.3.
За виконання завдань 8 та 9 студент отримує 3 бали.
Контрольні питання до практичного заняття 8
1. Які способи розв’язування систем лінійних рівнянь Вам відомі?
2. Що являє собою визначник матриці та як він обчислюється?
3. Що являють собою мінори матриці та як вони обчислюються?
4. Що являють собою алгебраїчні доповнення матриці та як вони
обчислюються?
5. У чому полягає особливість обчислення визначників матриць
третього порядку?
6. Як з використанням визначників можна розв’язати систему лінійних
рівнянь?
7. У чому полягає сутність співвідношень (7.14) – (7.19)?
8. Як співвідношення (7.14) – (7.19) пов’язані із прикладом, наведеним
у підрозділі 7.8.2?
9. Який із методів розв’язування систем лінійних рівнянь, метод
Гаусса – Зейделя чи метод Крамера, є більш ефективним для розв’язування
систем лінійних рівнянь вручну, а який є більш придатним для комп’ютерної
реалізації?
10. За якої умови система лінійних рівнянь не може бути розв’язаною?
11. Чому метод Крамера не може бути ефективно використаний для
розв’язування систем лінійних рівнянь великого порядку?
12. Чим визначається точність проведення розрахунків за методом
Крамера?
13. Які засоби програмування мови Python можуть бути ефективно
використані для розв’язування систем лінійних рівнянь методом Крамера?
416
7.9 Заняття 9. Створення програмних засобів для подійного
моделювання фізичних процесів

7.9.1 Основи теорії подійного моделювання


Сучасні засоби комп’ютерного моделювання дозволяють аналізувати у
часі не лише окремі графіки функцій, але й рух частинок у часі та випадкові
процеси із змінними параметрами [6, 7, 60]. Такі моделі у теорії моделювання
називаються імітаційним моделюванням [6, 7, 60]. Головна сутність засобів
імітаційного моделювання полягає у тому, що за відомими функціями руху
частки або розподілу імовірності розраховуються параметри випадкового
процесу, після чого формується велика кількість реалізацій цього процесу.
Потім із отриманих реалізацій складається відеоролик, який спостерігач
може подивитися на екрані комп’ютера. Така імітаційна модель випадкового
процесу дійсно досить адекватно відображує реальний у часі процес, який
можна спостерігати в ході проведення фізичного експерименту. Єдина
проблема полягає в тому, що таку модель не можна відобразити на
паперовому листі наукової статті або підручника, її можна спостерігати лише
на комп’ютерному моніторі. Опублікованими у паперовому вигляді можуть
бути лише коди комп’ютерних програм та окремі реалізації детермінованих
або випадкових процесів, тому результати досліджень з імітаційного
моделювання сьогодні досить часто публікуються в Інтернеті. Іншим шляхом
розв’язування проблеми спостереження результатів імітаційного
моделювання є послідовне виведення графічних результатів для кожного
моменту часу. Для побудови детермінованих імітаційних моделей руху
фізичного об’єкту спочатку проводяться розрахунки траєкторії об’єкту, а
потім фіксується його положення в окремі моменти часу. Методика побудови
стохастичних імітаційних моделей теорії ймовірностей основана на
використанні разом із детермінованими математичними функціями
генератора випадкових чисел, який налаштовується за визначеним законом
розподілу. Потім, на основі проведених розрахунків, формуються кадри
двовимірного або тривимірного відеозображення, які можна спостерігати на
417
екрані. Існує також можливість змінювати параметри імітаційної моделі. Уза-
гальнене описання цієї методики та відповідних засобів програмування наве-
дено у навчальних посібниках [13, 14, 60].
Взагалі існує два способи побудови імітаційних моделей. Перший із них
полягає у зміні параметрів графічних об’єктів через певні моменти часу, і ця
зміна здійснюється автоматично. У цьому разі в інтерпретаторі мови
програмування Python для виконання затримки використовується метод
after(), а для переміщення об’єкту по полотну – метод move(). Якщо
змінюється не лише положення, але й форма об’єкту, цю операцію можна
виконати з використанням методу itemconfig(). Відповідні теоретичні
відомості були наведені у підрозділах 5.3.3 та 5.4.2. Саме такий підхід
використовується і в інших системах програмування для створення
анімаційного програмного забезпечення [6, 7].
Іншим підходом до створення імітаційних моделей є зміна зображення
як реакція на відповідну подію, наприклад, натиснення на кнопку графічного
інтерфейсу або на кнопку клавіатури. Цей підхід від першого відрізняється
тим, що затримки між виведенням зображень на екран робити не потрібно,
проте методи, в який реалізована обробка та зміна зображення, необхідно
прив’язувати до відповідних подій. Зрозуміло, що імітаційні моделі, зроблені
таким способом, є не настільки наочними, але оскільки результати
моделювання змінюються не динамічно, а послідовно, користувачу зазвичай
значно легше їх аналізувати. Саме такий підхід був реалізований у
прикладі 5.34.

7.9.2 Індивідуальні завдання для виконання практичного заняття 9


1. З використанням засобів програмування мови Python побудувати
траєкторію об’єкта, визначену математичними функціями, заданими
наведеними нижче співвідношеннями для варіантів а) – л). Положення
об’єкту фіксувати з моменту часу t0 до моменту tк через проміжки часу ∆t.
(4 бали)
а) x(t) = 5·cos(10·π·t), y(t) = 10·cos(15·π·t); t0 = 5 сек, tк = 20 сек, ∆t = 0,5 сек.
418
б) x(t) = 2·cos(12·π·t), y(t) = 3·t2 + 4·t + 10; t0 = 3 сек, tк = 15 сек, ∆t = 0,1 сек.
в) x(t) = 4·cos(7·π·t), y(t) = exp(0,3·t2); t0 = 2 сек, tк = 10 сек, ∆t = 0,2 сек.
г) x(t) = 10·sin(5·π·t), y(t) = ln(0,3·t2); t0 = 2 сек, tк = 12 сек, ∆t = 0,1 сек.
д) x(t) = 7·sin(10·π·t), y(t) = 10·cos(4·π·t); t0 = 1 сек, tк = 16 сек, ∆t = 0,4 сек.
е) x(t) = 8·cos(13·π·t), y(t) = 6·exp(0,5·t2); t0 = 3 сек, tк = 13 сек, ∆t = 0,5 сек.
є) x(t) = 15·cos(7·π·t), y(t) = 5·ln(0,8·t3); t0 = 5 сек, tк = 14 сек, ∆t = 0,3 сек.
ж) x(t) = 3·cos(15·π·t), y(t) = 6·t2 + 7·t + 12; t0 = 2 сек, tк = 10 сек, ∆t = 0,2 сек.
з) x(t) = 3·sin(4·π·t), y(t) = 12·cos(7·π·t); t0 = 4 сек, tк = 12 сек, ∆t = 0,4 сек.
і) x(t) = 3·cos(6·π·t), y(t) = 9·exp(0,15·t2); t0 = 2 сек, tк = 12 сек, ∆t = 0,5 сек.
к) x(t) = 5·sin(8·π·t), y(t) = 3·ln(0,7·t3); t0 = 3 сек, tк = 10 сек, ∆t = 0,2 сек.
л) x(t) = 5·sin(7·π·t), y(t) = 13·t2 + 5·t + 23; t0 = 1 сек, tк = 9 сек, ∆t = 0,4 сек.
2. З використанням засобів програмування мови Python побудувати
графіки випадкового процесу зміни параметрів амплітуди та частоти
електричного сигналу, вважаючи, що середнє значення амплітуди складає A0,
середнє значення частоти – f0, відносне відхилення амплітуди у відсотках –
∆A ∆f
η1 = ⋅ 100% , а відносне відхилення частоти у відсотках – η2 = ⋅100% .
A0 f0

Вважати розподіли величин відхилення ∆A та ∆f рівномірними та


розраховувати їх для кожного моменту часу з використанням генератора
випадкових чисел. Моменти часу брати від значення t0 до значення tк через
інтервал часу ∆t. На графіках виводити випадкові значення амплітуди та
частоти сигналу, розраховані для заданого моменту часу. Параметри
випадкового сигналу для різних варіантів індивідуальних завдань наведені у
пунктах а) – л). (6 балів)
а) A0 = 5 В, f0 = 5 кГц, η1 = 3%, η2 = 5%, t0 = 1 сек, tк = 5 сек, ∆t = 0,1 сек.
б) A0 = 7 В, f0 = 10 кГц, η1 = 2%, η2 = 7%, t0 = 0 сек, tк = 3 сек, ∆t = 0,2 сек.
в) A0 = 220 В, f0 = 50 Гц, η1 = 5%, η2 = 2%, t0 = 2 сек, tк = 7 сек, ∆t = 0,4 сек.
г) A0 = 0,3 В, f0 = 15 кГц, η1 = 6%, η2 = 4%, t0 = 3 сек, tк = 8 сек, ∆t = 0,5 сек.
д) A0 = 15 В, f0 = 1,5 кГц, η1 = 5%, η2 = 8%, t0 = 5 сек, tк = 15 сек, ∆t = 0,5 сек.
е) A0 = 10 В, f0 = 2,5 кГц, η1 = 4%, η2 = 3%, t0 = 2 сек, tк = 10 сек, ∆t = 0,4 сек.

419
є) A0 = 12 В, f0 = 25 кГц, η1 = 3%, η2 = 5%, t0 = 4 сек, tк = 7 сек, ∆t = 0,3 сек.
ж) A0 = 250 В, f0 = 50 Гц, η1 = 2%, η2 = 3%, t0 = 3 сек, tк = 10 сек, ∆t = 0,5 сек.
з) A0 = 18 В, f0 = 3,5 кГц, η1 = 4%, η2 = 6%, t0 = 2 сек, tк = 7 сек, ∆t = 0,2 сек.
і) A0 = 20 В, f0 = 30 кГц, η1 = 8%, η2 = 6%, t0 = 5 сек, tк = 12 сек, ∆t = 0,4 сек.
к) A0 = 0,2 В, f0 = 6 кГц, η1 = 3%, η2 = 2%, t0 = 2 сек, tк = 9 сек, ∆t = 0,1 сек.
л) A0 = 5 В, f0 = 7,5 кГц, η1 = 5%, η2 = 2%, t0 = 3 сек, tк = 12 сек, ∆t = 0,3 сек.
Виконати завдання 1 та 2 з використанням засобів анімації системи
програмування Anaconda.

Контрольні питання та завдання до практичного заняття 9


1. Що являє собою подійне моделювання та чим воно суттєво
відрізняється від інших засобів моделювання?
2. Для аналізу яких фізичних процесів використовуються засоби
подійного моделювання?
3. Як засоби подійного моделювання використовуються для аналізу
траєкторій рухомих об’єктів?
4. Які способи математичного описання траєкторій руху фізичних
об’єктів Вам відомі? Наведіть власні приклади таких описань.
5. Як засоби подійного моделювання використовуються для аналізу
стохастичних процесів?
6. Які способи математичного описання стохастичних процесів Вам
відомі?
7. Які засоби програмування мови Python можуть бути використанні
для імітаційного моделювання траєкторій рухомих об’єктів?
8. Які засоби програмування мови Python можуть бути використанні
для імітаційного моделювання випадкових процесів?
9. Які загальні підходи до створення імітаційних моделей Вам відомі?
10. Чим суттєво відрізняється відомі Вам два підходи до створення
програмних засобів імітаційного моделювання?

420
11. Які засоби імітаційного моделювання системи програмування
Anaconda Вам відомі? Наведіть власні приклади їхнього використання для
створення анімаційних ефектів.
12. Що являє собою функція FuncAnimation() системи
програмування Anaconda та як вона використовується для створення
анімаційних ефектів? Наведіть власні приклади такого використання цієї
функції.
13. Що являє собою функція ArtistAnimation() системи
програмування Anaconda та як вона використовується для створення
анімаційних ефектів? Наведіть власні приклади такого використання цієї
функції.
14. Як засоби комп’ютерної анімації можуть бути використані для
вивчення детермінованих та стохастичних фізичних ефектів? Наведіть власні
приклади такого використання засобів комп’ютерної анімації.
15. Сформулюйте математичну модель Вашої наукової дослідницької
роботи у вигляді імітаційної моделі та реалізуйте цю модель з використанням
засобів програмування системи Anaconda.

7.10 Заняття 10. Розв’язування диференціальних рівнянь з


використанням засобів програмування системи Anaconda

Індивідуальні завдання для виконання практичного заняття 10


1. З використанням засобів програмування системи Anaconda чисельно
розв’язати диференціальні рівняння першого порядку, задані наведеними нижче
співвідношеннями для варіантів а) – л). Для отриманого розв’язку
побудувати графічну залежність y(x). (4 бали)
dy dy dy
а) = e xy ; y (0) = 0; б) = e x − y ; y (0) = 0; в) = − ye x ; y (0) = 0;
dx dx dx
dy dy dy
г) = xye xy ; y (0) = 0; д) = xe y ; y (0) = 0; е) = − xye y ; y (0) = 0;
dx dx dx

421
2 xy
dy dy y dy
є) = xe 2 xy ; y (0) = 0; ж) = e x ; y (0) = 0; з) = −2 ye x + 2 ; y (0) = 0;
dx dx x 2 + 3 dx

dy  y  dy dy
і) = cos ; y (0) = 0; к) = xe y ; y (0) = 0; л) = −2 ye y − 3 x ; y (0) = 0.
dx 2 dx dx
 x + 1
2. З використанням засобів програмування системи Anaconda чисельно
розв’язати диференціальні рівняння другого порядку, задані наведеними нижче
співвідношеннями для варіантів а) – л). Для отриманого розв’язку з
використанням графічних засобів системи Anaconda побудувати графічну
залежність y(t) та фазовий портрет. (6 балів)

5 y ′ et + y
а) y ′′ − 5 y ′ + e yt , y (0 ) = 0, y ′(0 ) = 2; б) y ′′ − + , y (0 ) = 0, y ′(0 ) = 5;
y 2
t

2 y ′ e8t +3 y
в) y ′′ − 3ty ′ + e 5 yt
, y (0 ) = 0, y ′(0 ) = 8; г) y ′′ − + , y (0) = 0, y ′(0 ) = 3;
yt 5ty
2
д) y ′′ − 4t 3 y ′ + e 7 yt , y (0 ) = 0, y ′(0 ) = 1;
2
5 y′ e3 y t
′′
е) y − + , y (0 ) = 0, y ′(0 ) = 4;
2
y t 5t + 3 y

( )
є) y ′′ − 4 cos t 3 y ′ + 6 yt 2 , y (0 ) = 0, y ′(0 ) = 2;

3 y′ sin 2 y 2t ( )
, y (0 ) = 0, y ′(0 ) = 3;
ж) y ′′ −
( )+
cos 5 y 2t cos(5t + 3 y )

і) y ′′ −
7 y′
+
sin 3 y 2t ( )
, y (0 ) = 0, y ′(0 ) = 4;
8 y 2t cos(8t + 3 y )

( ) ( )
к) y ′′ − 4 cos 9t 3 y ′ + sin 2 y 3t 2 , y (0 ) = 0, y ′(0 ) = 7;

4 y′ sin 2 (3 y 2t )
л) y ′′ − + , y (0 ) = 0, y ′(0 ) = 4;
7 y 2t cos 3 (8t + 3 y )

422
Контрольні питання до практичного заняття 10

1. Як у загальній формі записується диференціальне рівняння порядку n?


2. Як у математиці у загальній формі записуються граничні умови для
диференціального рівняння порядку n?
3. Як формулюється задача Коші для диференціального рівняння
порядку n?
4. Яка функція системи програмування Anaconda застосовується для
розв’язування диференціальних рівнянь та у якій бібліотеці вона
розташована?
5. Якій формат запису має функція odeint() та які параметри її

виклику?
6. У якій формі формується розв’язок диференціального рівняння
порядку n через виклик функції odeint()?

7. Які програмні засоби системи програмування Anaconda


використовуються для побудови графічних залежностей, пов’язаних із
розв’язком диференціального рівняння?
8. Чому для побудови графічних залежностей, пов’язаних із розв’язком
диференціального рівняння, необхідно транспортувати отриманий числовий
результат з вектора-стовпця до вектора-рядка?
10. Які засоби програмування системи Anaconda використовуються для
перетворення вектора-стовпця до вектора-рядка?
11. Як можна перевірити точність отриманого чисельного розв’язку
диференціального рівняння?
12. Що являють собою фазові портрети та як вони використовуються
для аналізу отриманого розв’язку диференціального рівняння?

423
7.11 Заняття 11. Створення програмного забезпечення для
мережної обчислювальної системи

Індивідуальні завдання для виконання практичного заняття 11

1. З використанням засобів програмування мови Python створити


мережну обчислювальну систему, в основі роботи якої лежать клієнт-
серверні технології передавання інформації. На серверній частині проводити
обчислення значення вказаних функцій для заданих значень аргументу x та
параметрів функції a, b, c та d для варіантів а) – л). Значення параметрів
функції a, b, c та d, які вважаються незмінними, задавати на сервері з
використанням словника. Під час створення запиту передавати з клієнта на
сервер код функції та значення змінної x, які слід вводити у програмі клієнта.
Клієнтську частину програми написати з використанням засобів графічного
інтерфейсу користувача. Як шаблон для написання програм для сервера та
клієнта можна використовувати програми з прикладу 6.84, наведені у
додатку І. Якщо значення функції за будь-якої причини обчислити
неможливо, виводити в інтерфейсне вікно програми клієнта відповідне
повідомлення, наприклад, «Неправильне числове значення», «Помилка
ділення на 0» або «Неправильно заданий аргумент функції». (7 балів)

a sin ( x ) + b cos( x ) a cos( x ) + b sin ( x )


а) f1 ( x ) = , f 2 (x ) = ,
c + d sin 2 ( x ) c + d cos 2 ( x )
a = 1,35, b = –6,18, c = 25,31, d = 3,18, x ={–4,5, –2,5, –1,5, 0, 2,5}.

sin (ax ) + cos(bx ) cos(ax ) + sin (bx )


б) f1 ( x ) = , f 2 (x ) = ,
c 2 + sin (dx ) c 3 + d cos( x )
a = 5,25, b = –4,78, c = 36,31, d = 2,18, x ={–2,5, –1,5, –0,5, 0, 1,5}.

exp(ax ) + ln (bx ) exp(cx ) + ln(dx )


в) f1 ( x ) = , f 2 (x ) = ,
c + dx ax + dx
a = 4,65, b = –3,62, c = 67,26, d = 5,35, x ={–4,5, –3,5, –1,5, 0, 2,5}.

424
г) f1 ( x ) =
( )
exp a 2 x + ln(bx )2
, f 2 (x ) =
( )
exp c 2 x − ln (ax )2
,
3 2 3 2
c + dx d − bx
a = 7,35, b = –7,38, c = 43,56, d = 4,34, x ={–2,5, –1,5, –0,5, 0, 0,5}.

a 2 exp(bx ) + b ln(cx )2 ca exp(bx ) + bd ln (ax )2


д) f1 ( x ) = , f 2 (x ) = ,
3 2 3 2
a + dx b + cdx
a = –4,56, b = 2,34, c = –9,62, d = 84,4, x ={–5,5, –3,5, 0, 0,9, 1,5}.

е) f1 ( x ) =
( )
a exp b 2 x + b 3 ln(cx )4
,
4 2 3
a +d x

f 2 (x ) =
( )
c 2 a exp b 2 x + b 2 d 3 ln(ax )2
,
4 3 2
b + c dx
a = 5,73, b = –0,37, c = –3,68, d = 37,4, x ={–3,5, –1,5, 0, 2,8, 4,6}.

b sin (ax ) + a cos(bx ) c cos(bx ) + d sin (ax )


є) f1 ( x ) = , f 2 (x ) = ,
dc + sin (cx )
2
ac + d cos(ax )
3

a = –7,45, b = 5,78, c = –6,05, d = 4,73, x ={–5,5, –2,5, 0,5, 1,5 3,5}.

ж) f1 ( x ) =
( )
d sin bx 2 + c cos ax 2 ( ) , f 2 (x ) = c ( ) ( ),
cos bx 2 + d sin ax 2
d 3a 2 + sin (c 3 x 2 ) ac 3 + d cos(ax 2 )

a = –5,38, b = 4,62, c = 7,47, d = –2,53, x ={–0,3, 0, 0,3, 1,3 2,3}.

з) f1 ( x ) =
( ) ( ),
ad cos b 3 x 2 + b sin d 3 x 2
c 4b 2 + cos(a 3 x 2 )

cb sin (b 3 x 2 ) + d cos(ax 2 )
f 2 (x ) =
ab + d cos(c x )
,
3 3 2

a = –3,37, b = 3,42, c = –5,37, d = 9,35, x ={–3,2, –2,2, 0,2, 1,2 3,2}.

 
( )
ad sin  cos bx 2  + bc cos b sin dx 2 
 ,
( )
і) f1 ( x ) =
(
sin b 2 + cos ax 2 ( ))

425

( )  
( )
cb cos sin bx 2  + a sin  d cos ax 2 
,
f 2 (x ) =
(3
sin b + d cos cx ( ))
2

a = –4,73, b = 5,63, c = –1,69, d = 19,56, x ={–3,7, –2,7, 0,7, 1,7, 2,7}.


( ) 
( )
ab exp cos bx 2  + cd ln b sin dx 2 
,
к) f1 ( x ) =
2
(
b exp a + cos cx 2
( ))
cd exp sin (bx 2 ) + ab ln d cos(ax 2 )
f 2 (x ) =    ,
c exp(c + d cos(ax ))
3 2

a = –7,48, b = –2,59, c = –4,94, d = 9,33, x ={–5,4, –2,4, 0,4, 1,4, 2,4}.

ac cos exp

(dx 2 ) + bd sin c ln(bx 2 )
л) f1 ( x ) =
d cos(a + exp(cx ))
,
2 2

cd exp sin (bx 2 ) + ab ln d cos(ax 2 )


f 2 (x ) =    ,
c exp(c 3 + d cos(ax 2 ))

a = –4,78, b = 6,59, c = –5,74, d = 10,78, x ={–5,6, –2,6, 0,6, 1,6, 2,6}.


2. З використанням засобів програмування системи Anaconda дослідити
поведінку функцій f1 ( x ) та f 2 ( x ) та через отримані графічні залежності

знайти області визначення цих функцій. На основі отриманих результатів


щодо дослідження області визначення функції пояснити результати
розрахунків, отримані у пункті 1. (3 бали)

Контрольні питання до практичного заняття 11


1. Що являє собою сервер у комп’ютерних мережах та які він виконує
функції?
2. Що являє собою клієнт у комп’ютерних мережах та які він виконує
функції?

426
3. У чому полягає головна сутність клієнт-серверних технологій
передавання інформації в комп’ютерних мережах?
4. Що являє собою мережна адреса комп’ютера та за якими існуючими
стандартами вона формується?
5. Що являє собою порт передавання інформації в комп’ютерних
мережах та як він формується?
6. Чим відрізняється поняття апаратного порту електронної апаратури
від порту передавання інформації у теорії комп’ютерних мереж?
7. Що являють собою сокети у теорії комп’ютерних мереж та як вони
формуються?
8. Які існують моделі взаємодії клієнта та сервера? Наведіть приклади
використання цих моделей для вирішення прикладних завдань проектування
комп’ютерних мереж.
9. Що являє собою модель «запит – відповідь» та як вона
використовується для організації роботи комп’ютерних мереж?
10. Що являє собою модель «розгалуження на виході» та як вона
використовується для організації роботи комп’ютерних мереж?
11. Що являє собою модель «розгалуження на вході» та як вона
використовується для організації роботи комп’ютерних мереж?
12. Що являє собою модель «розсилання – підписка» та як вона
використовується для організації роботи комп’ютерних мереж?
13. Як за стандартом побудови комп’ютерних мереж визначається
мережна адреса локального комп’ютера?
14. Що являє собою об’єкт класу socket у мові програмування
Python?
15. Що являє собою метод bind() модуля socket інтерпретатора
мови програмування Python?

427
16. Що являє собою метод listen() модуля socket інтерпретатора
мови програмування Python?
17. Що являє собою метод connect() модуля socket інтерпретатора
мови програмування Python?
18. Що являє собою метод accept() модуля socket інтерпретатора
мови програмування Python?
19. Що являє собою метод send() модуля socket інтерпретатора
мови програмування Python?
20. Що являє собою метод recv(n) модуля socket інтерпретатора
мови програмування Python?
21. Що являє собою метод close() модуля socket інтерпретатора
мови програмування Python?
22. За яким загальним алгоритмом працює програма сервера у
мережному програмному забезпеченні?
23. За яким загальним алгоритмом працює програма клієнта у
мережному програмному забезпеченні?
24. Яке, серверне чи клієнтське програмне забезпечення, сьогодні часто
пишеться зі зручним графічним інтерфейсом користувача?

7.12 Заняття 12. Створення програмного забезпечення для


програмування мікроконтролерів

Індивідуальні завдання для виконання практичного заняття 12


1. З використанням засобів програмування мови Python створити
програму, у якій вмикати та вимикати світлодіод мікроконтролера Auderino із
заданими параметрами часу вмикання tвм , часу вимикання tвим та кількості

циклів n. Параметри tвм , tвим та n для варіантів 1 – 12 наведені у таблиці 7.8.

Завдання для цього практичного заняття виконувати за зразком


428
прикладу 6.87. Функція [x] у таблиці 7.8 означає найближче ціле число,
більше за x. Перед запуском написаної програми на мікроконтролері
обов’язково перевірте, що в усьому заданому діапазоні значень k = 1:n
дискретні значення функцій t вм (k ) та tвим (k ) є додатними натуральними

числами, більшими 0 та меншими за 100. Під час написання програми


коефіцієнти в формулах для визначення t вм (k ) та tвим (k ) зчитувати з бази

даних, сформованої з використанням словника. (7 балів)


Таблиця 7.8 – Завдання для виконання практичного заняття 12
Співвідношення Співвідношення
Початковий
№ Кількість для часу для часу
стан Коефіцієнти
варіанту циклів n вмикання вимикання
світлодіоду
t вм (k ) tвим (k )
a = 5, b = 4,
1. Ввімкнено 12 [(k2 + a)/b] ck + d
c = 3, d = 7
a = 6, b = 7, c
2. Вимкнено 16 a[(k2 + b)/c] – k2 d – [(k2 + e)/f] = 5, d = 45, e
= 7, f = 10
a = 5, b = 9,
3. Ввімкнено 18 a[(k2 + b)/c] – k2 [(k2 + d)/e] c = 4, d = 5,
e = 12
a = 8, b = 10,
4. Вимкнено 24 [(k2 + a) /b]+ c [k2/b] – k + d
c = 5, d = 3
a = 3, b = 9, c
a[(k2 + b)/c]– = 5, d = 2,
5. Ввімкнено 20 g – [(k2 + b)/h]
– d[k2/e] + f e = 3, f = 24,
g = 40, h = 12
a = 75, b = 60,
6. Вимкнено 32 [(a – bk)2/c5] [(d – k)2/e] c = 10, d = 40,
e = 30
a = 5, b = 10,
a(b – [(k2 + c)/d]) – e[(k2 + a)/d] –
7. Ввімкнено 25 c = 3, d = 4,
– [(d k2/c)] – a[k2/c]
e=7

429
Таблиця 7.8 (продовження)

Співвідношення Співвідношення
Початковий
№ Кількість для часу для часу
стан Коефіцієнти
варіанту циклів n вмикання вимикання
світлодіоду
t вм (k ) tвим (k )
a = 3, b = 11,
a[(k2 + a)/b] –
8. Вимкнено 15 [(k2 + a)/e] c = 2, d = 5,
– ck + d
e=6
a = 2, b = 7, c
9. Ввімкнено 14 ak + b [(ak + b)2/c]
= 25
[(k2 + a)/b] – 2
a = 7, b = 2, c
10. Вимкнено 10 [(k + a)/c]
– ck + b =3
a=100,b=17,
11. Ввімкнено 28 [(a – bk)2/c] + d [(a –bk)2/e] + f c=330,d=41,
e=380, f=35
a = 5, b = 12,
12. Вимкнено 17 [a(k2 + b)/c] – dk + e [(k2 + b)/c] – k + f c = 11, d = 7,
e = 22, f = 2

2. Проведіть дослідження функцій t вм (k ) та tвим (k ) , наведених у


таблиці 7.8, з використанням математичних методів теорії чисел та
дискретної математики (3 бали).

Контрольні питання до практичного заняття 12

1. Які функції мови програмування Python використовуються для


програмування мікроконтролерів?
2. У якому модулі розташовані функції мови програмування Python,
безпосередньо призначені для програмування мікроконтролерів?

430
3. Як функції мови програмування Python, призначені для
програмування мікроконтролерів, пов’язані із теорією подійного
моделювання та із методами обробки подій?
4. Як функції мови програмування Python, призначені для
програмування мікроконтролерів, пов’язані із теорією скінченних автоматів?
5. Функції яких модулів інтерпретатора мови Python головним чином
використовуються для програмування мікроконтролерів?
6. Як для програмування мікроконтролерів використовуються функції
визначення системного часу?
7. Чому завдання програмування мікроконтролерів зазвичай неможливо
виконати лише з використанням засобів мови програмування Python?
8. Які ще мови програмування обов’язково необхідно використовувати
для комплексного розв’язування завдань програмування мікроконтролерів та
в якій частині системи комп’ютер – мікроконтролер розташовується
програмне забезпечення, написане на цих мовах програмування?
9. Яке апаратне забезпечення та електронна апаратура є необхідними
для розв’язування завдань програмування мікроконтролерів?
10. Як алгоритми програмування мікроконтролерів пов’язані з теорією
чисел та дискретною математикою?
11. Як алгоритми програмування мікроконтролерів пов’язані з теорією
подійного моделювання?
12. Як алгоритми програмування мікроконтролерів пов’язані із теорією
скінченних автоматів?

431
8. Загальний перелік питань та завдань для самоконтролю знань

8.1 Загальні положення


Загальні положення щодо оцінювання знань студентів викладачем на
практичних заняттях з курсів «Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі» є стандартними. За повне та
безпомилкове виконання одного практичного заняття студент отримує 10
балів, розподіл балів за виконання окремих завдань наведений безпосередньо
в описанні практичних занять. За планом навчання студентів спеціальності
електронні прилади та пристрої факультету електроніки Національного
технічного університету України «Київський політехнічний інститут імені
Ігоря Сікорського» практичне заняття з першого по восьме відповідають
програмі курсу «Об’єктно-орієнтоване програмування», а з дев’ятого по
дванадцяте – програмі курсу «Обчислювальні системи та мережі». Крім
цього, в плані курсу «Обчислювальні системи та мережі» також, під час
виконання лабораторної роботи за темою «Вивчення основ роботи
гіпотетичного процесора» передбачене використання програми простого
калькулятора, яка розглянута у підрозділі 5.3.5.1, код якої наведений у
додатку Г. Це пов’язано з тим, що написана програма відображує всі головні
особливості роботи гіпотетичного процесора.
Базові оцінки рівня знань студентів з мови програмування Python також
є стандартними. Базовий рівень знань передбачає знання головних
особливостей цієї мови програмування та вміння пояснити всі наведені у
посібнику приклади закінчених кодів програм. Середній рівень знань
передбачає повне знання наведеного у посібнику матеріалу та вміння писати
свої функціональні програми за завданням, поставленим викладачем.
Високий рівень передбачає не лише повне знання матеріалу, але й вміння
розв’язувати нестандартні завдання інженерної та наукової діяльності. Для
підтвердження високого рівня знань студент повинен не лише написати
закінчену програму та показати її функціональність, але й виконати
додаткове завдання. Це може бути власна комп’ютерна програма з графічним
432
інтерфейсом користувача, написана за напрямком наукової або інженерної
дослідницької діяльності, виступ за темами курсу на семінарі або на
конференції, написання реферату за темами курсу тощо.
У зв’язку з цим студентам та тим, хто вивчає мову програмування
Python за цим посібником самостійно, надається можливість самим
перевірити загальний рівень своїх знань. Крім цього, для підтвердження
високого рівня знань надані можливі теми рефератів та індивідуальних
завдань підвищеної складності. Оскільки контрольні питання та завдання
наведені в кінці кожного розділу, у відповідних підрозділах цього розділу
надані лише посилання на них. Щодо практичних занять, наведених у
сьомому розділі, в них бали, які отримує студент за виконання кожного
завдання, визначені окремо, тому в підрозділах цього розділу надається лише
список занять, який відповідає кожному рівню знань. Також зрозуміло, що
якщо студент претендує на верхній рівень, наприклад на вищий, він повинен
виконати всі вимоги нижчих рівнів, зокрема базового та середнього.
Наприклад, якщо студент виконав індивідуальне завдання та написав
реферат, але не знає базових положень щодо програмування на мові Python,
він не може отримати задовільну оцінку.
Загалом оцінювання знань проводиться наступним чином. Достатніми
вважаються знання, наведені у розділах 1, 2, підрозділах 3.1 – 3.6, розділі 4,
підрозділах 5.1, 5.2 та підрозділах 6.1.1, 6.1.2 та 6.1.3. Для середнього рівня
знань необхідно також знати матеріал, наведений у підрозділах 3.7, 5.3, 5.4,
6.1.4, 6.1.5, 6.2 та 6.3.

8.2 Базовий рівень знань


1. Відповісти на контрольні питання та виконати контрольні завдання
1 – 66 до розділу 1.
2. Відповісти на контрольні питання та виконати контрольні завдання
1 – 48, 51 – 62, 64, 65, 81 – 123 до розділу 2.
3. Відповісти на контрольні питання та виконати контрольні завдання
1 – 62 до розділу 3.
433
4. Відповісти на контрольні питання та виконати контрольні завдання
1 – 14, 17 – 35, 41 – 93, 95 – 100 та 102 – 128 до розділу 4.
5. Відповісти на контрольні питання та виконати контрольні завдання
1 – 79 до розділу 5.
6. Відповісти на контрольні питання та виконати контрольні завдання
1 – 161 до розділу 6.
7. Виконати практичні заняття 1 – 4.

8.3 Середній рівень знань


1. Відповісти на контрольні питання та виконати контрольні завдання
49, 50, 63, 66 – 80, 124 – 159 до розділу 2.
2. Відповісти на контрольні питання та виконати контрольні завдання
63 – 73 до розділу 3.
3. Відповісти на контрольні питання та виконати контрольні завдання
15, 16, 36 – 40 до розділу 4.
4. Відповісти на контрольні питання та виконати контрольні завдання
80 – 146 до розділу 5.
6. Відповісти на контрольні питання та виконати контрольні завдання
162 – 167, 169 – 289, 292 – 325 та 328 – 349 до розділу 6.
7. Виконати практичні заняття 5 – 8.

8.4 Високий рівень знань


1. Виконати контрольні завдання 67, 68 до розділу 1.
2. Виконати контрольні завдання 160, 161 до розділу 2.
3. Виконати контрольні завдання 74 – 79 до розділу 3.
4. Виконати контрольні завдання 94, 101, 129 та 130 до розділу 4.
5. Відповісти на контрольні питання та виконати контрольні завдання
147 – 155 до розділу 5.
6. Відповісти на контрольні питання та виконати контрольні завдання
168, 290, 291, 326, 327 та 350 до розділу 6.

434
7. Виконати практичні заняття 9 – 12.
8. Здати реферат та виступити за темою реферату на семінарському
занятті. Реферат подається студентом на перевірку викладачеві та викладач
виставляє за нього попередню оцінку. Після обговорення з викладачем
результатів перевірки реферату студент виступає за обраною темою на
семінарському занятті. Максимальна оцінка за рейтинговою системою за
зданий реферат – 5 балів, за виступ на семінарському занятті студент
отримує 10 балів.

Можливі теми для рефератів та виступів на семінарських заняттях.


1. Засоби інтерполяції та апроксимації відлікових дискретних значень в
системі програмування Anaconda [24].
2. Засоби статистичної обробки математичних функцій та результатів
експерименту в системі програмування Anaconda та бібліотека Pandas [24].
3. Можливості використання карт жорсткості для аналізу аналітичних
та чисельних розв’язків звичайних диференціальних рівнянь [6, 7].
4. Можливості використання контурних графіків для відображення
розв’язків диференціальних рівнянь з частковими похідними [6, 7, 70].
5. Реалізація чисельних методів розв’язування диференціальних
рівнянь з частковими похідними з використанням програмних засобів
системи Anaconda [6, 7, 70].
6. Використання розширених можливостей символьного процесора
системи Anaconda для розв’язування складних прикладних інженерних та
наукових завдань [70].
7. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання роботи розподілених
систем зв’язку з використанням теорії черг [66].
8. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання роботи розподілених
комп’ютерних мереж з використанням теорії черг [66].

435
9. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для розв’язування прикладних завдань
обчислювальної математики [6, 7, 43, 44].
10. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для розв’язування прикладних завдань
дискретної математики та теорії чисел [42].
11. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для розв’язування прикладних завдань
теорії груп [42].
12. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для розв’язування прикладних завдань
системного аналізу [2].
13. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання електронних схем та
систем [6, 7].
14. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання сучасної цифрової
електронної апаратури [2].
15. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання сучасних вакуумних
електронних приладів [6, 7].
16. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання сучасних твердотільних
електронних приладів [6, 7].
17. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для апроксимації експериментальних
характеристик електронних приладів [6, 7].
18. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для моделювання сучасних технологічних
процесів виробництва електронної техніки [6, 7].

436
19. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для аналізу детермінованих електричних
сигналів [6, 7, 60].
20. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для аналізу стохастичних електричних
сигналів [6, 7, 60].
21. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для аналізу цифрових електричних
сигналів [6, 7, 60].
22. Можливості використання засобів програмування інтерпретаторів
мови Python та системи Anaconda для дослідження роботи складних систем з
використанням сучасних методів фрактального аналізу [66].
23. Розвинені засоби програмування сучасних мікроконтролерів з
використанням інтерпретатора мови Python [24, 75].
24. Python та сучасні математичні методи штучного інтелекту [24, 27 – 29].

437
Додаток А. Програма для формування рядка з відомостями про
студента для прикладу 5.19
# Функція формування повідомлення
def f_r ():
# Визначення провопису слова ‘рік’
# через аналіз значення віку студента.
if (int(spb.get()) == 21):
str3 = ' рік'
elif (22 <= int(spb.get()) <= 24):
str3 = ' роки'
else: str3 = ' років'
# Визначення навчання студента через
# аналіз обраного значення селекторної кнопки
# Radiobutton
if (var_rad.get()==1):
str6='відмінно'
elif(var_rad.get()==2):
str6='добре'
else:
str6='задовільно'
# Формування рядка повідомлення та виведення його у
# текстове вікно
str_n = str1+str.capitalize(et.get())\
+str2+str(spb.get())+str3+str4+str.\
upper(lstb1.get(lstb1.curselection()))+str5+\
str6
label2.config(text = str_n)
438
# Функція очищення текстового вікна
def clr_r ():
str_n = ''
label2.config(text = str_n)
# Головна програма. Створення елементів віконного
# інтерфейсу
from tkinter import *
# Створення головного вікна
window = Tk()
window.title('Формування звіту про успіш\
ність студента')
# Створення фрейму для елементів інтерфейсу,
# в яких здійснюєтсья введення інформації
# про студента
if_rep = Frame(window, borderwidth = 2, \
relief = SUNKEN, height = 200)
if_rep.pack()
lbl1=Label(window, text = 'Введення даних')
lbl1.place(x = 100, y = 5)
# Створення текстового вікна для введення прізвища
# студента
lbl_stud = Label(window, font='Arial 10', \
width = 12, text = 'Студент')
lbl_stud.place(x = 4, y = 30, width = 100, \
height = 20)
et = Entry(window, font='Arial 10', width = 15)
et.place(x = 4, y = 50)

439
# Створення списку-лічильника для введення віку
# студента
lbl_age = Label(window, font='Arial 10', \
width = 12, text = 'Вік')
lbl_age.place(x = 100, y = 30, width = 100, \
height = 20)
spb = Spinbox(window, from_ = 17, to = 28, \
width = 16, borderwidth = 4, font = 'Arial 10')
spb.place(x = 130, y = 50, width = 60, height = 30)
# Створення списку для введення групи, в якій
# навчається студент
lbl_grp = Label(window, font='Arial 10', \
width = 12, height = 50, text = 'Група')
lbl_grp.place(x = 180, y = 30, width = 100, \
height = 20)
lstb1 = Listbox(window, height = 3, width = 20,\
borderwidth = 3)
lstb1.place(x = 200, y = 50, width = 100, \
height = 50)
lst = ['ДЕ-71', 'ДЕ-72']
for elem in lst:
lstb1.insert(END, elem)
lstb1.selection_set(first = 0)
# Створення селекторної кнопки для обрання
# успішості навчання студента
lbl_std = Label(window, font='Arial 10', \
width = 12, text = 'Навчання')

440
lbl_std.place(x = 400, y = 30, width = 100, \
height = 20)
# Визначення змінної, яка описує обраний елемент
# селекторної кнопки
var_rad = IntVar()
# Описання та розташування елементів селекторної
# кнопки
rb1 = Radiobutton(window, \
text='Відмінно', variable=var_rad, value=1)
rb2 = Radiobutton(window, \
text='Добре', variable=var_rad, value=2)
rb3 = Radiobutton(window, \
text='Задовільно', variable=var_rad, value=3)
var_rad.set(1)
rb1.place(x = 320, y = 50)
rb2.place(x = 400, y = 50)
rb3.place(x = 480, y = 50)
# Описання рядкових змінних для формування
# інформаціійного повідомлення
str_n=StringVar()
str1 = 'Студент '
str2 = ', '
str4 = ', группа '
str5 = ', навчається '
# Створення та розташування фрейму для виведення
# інформаційного повідомлення
if_out = LabelFrame(window, text = 'Форму\

441
вання інформаційного повідомлення',\
borderwidth = 2, relief = SUNKEN, \
width = 200, height = 200)
if_out.place(x = 150, y = 100)
label2 = Label(if_out, text = str_n)
label2.pack()
# Створення кнопки для формування звіту
btn1 = Button(if_out, text = 'Формування звіту',\
command = f_r)
btn1.pack()
btn2 = Button(if_out, text = 'Очищення', \
command = clr_r)
btn2.pack()
window.mainloop

442
Додаток Б. Програма багатофункціонального годинника із
звуковим сигналом та секундоміром для прикладу 5.24
from tkinter import *
import time
import winsound
# Функція роботи годинника
def сlock():
# Визначення рядкової змінної для виведення у
# текстове вікно через читання з системного
# блоку комп’ютера поточного часу
label1['text'] = time.strftime('%H:%M:%S')
# Переписування значення поточного часу до
# текстового вікна класу Label
label1.after(200,сlock)
# Виклик функції роботи таймера у разі зміни
# обраного елементу селекторної кнопки класу
# Radiobutton
if (var_rad.get()==2):
label1.after_idle(timer)
# Виклик функції подання звукового сигналу за умови
# включення кнопки-перемикача та співпадання часу
# годинника із значеннями годин та хвилин,
# встановлених користувачем у відповідних вікнах
# списків – лічильників
if (int(chk.get())==1) and \
int(time.strftime('%H'))==int(spb1.get())) and \
(int(time.strftime('%M'))==int(spb2.get())):
check.after_idle(sound)
# Функція подання звукового сигналу
def sound():

443
# Цикл while для формуванн звукового сигналу із
# заданою кількістю повторень
while (i.get() < int(spb4.get())):
winsound.Beep(sci1.get(), 1000*int(sci2.get()))
winsound.Beep(10000, 1000*int(sci3.get()))
i.set(i.get()+1)
# Функція запуску секундоміра через надання змінній СТ
# значення 1
def runtime():
CT.set(1)
# Функція зупинки секундоміра через надання змінній СТ
# значення 0
def stoptime():
CT.set(0)
# Функція онулення секундоміра через надання змінним
# MIN, SEC та DSEC значення 0
def cleartime():
if (var_rad.get()==2):
MIN.set(0)
SEC.set(0)
DSEC.set(0)
# Функція відключення звукового сигналу через
# автоматичне відключення кнлпки-перемикача класу #
# Checkbutton та надання змінній i, яка задає кількість
# повторень звукового сигналу, значеня 1. Ця функція
# відповідає події натиснення на кнопку 'Вимкнути
# звуковий сигнал'
def sound_out():
i.set(0)
chk.set(0)
# Функція роботи секундоміра

444
def timer():
# Формування рядкової змінної для виведення у
# текстове вікно через об’єднання значень хвилин,
# секунд та десятих долей секунд до одного рядка
Str_Timer = str(MIN.get())+ \
':'+str(SEC.get())+'.'+str(DSEC.get());
# Переписування значення поточного часу на
# секундомірі до текстового вікна класу Label
label1['text'] = Str_Timer
if (CT.get()==1):
label1.after(100,timer)
# Зміна значення десятих долей секунд на 1
DSEC.set(DSEC.get()+1)
# Зміна значення секунд на 1 у разі, якщо значення
# десятих долей секунд складає 10.
# У цьому випадку значення десятих долей секунд
# змінюється на 0.
if(DSEC.get()==10):
DSEC.set(0)
SEC.set(SEC.get()+1)
# Зміна значення хвилин на 1 у разі, якщо значення
# секунд складає 60. У цьому випадку значення
# секунд змінюється на 0.
if(SEC.get()==60):
SEC.set(0)
MIN.set(MIN.get()+1)
# Автоматичне онулення секундоміра у разі,
# якщо значення хвилин складає 60.
if(MIN.get()==60):
MIN.set(0)
SEC.set(0)

445
DSEC.set(0)
# Виклик функції подання звукового сигналу за умови
# включення кнопки-перемикача та співпадання часу
# секундоміра із значеннями хвилин та секунд,
# встановлених користувачем у відповідних вікнах
# списків – лічильників
if (int(chk.get())==1) and\
(MIN.get()==int(spb2.get())) and \
(SEC.get()==int(spb3.get())):
check.after_idle(sound)
# Виклик функції роботи годинника у разі зміни
# обраного елементу селекторної кнопки класу
# Radiobutton
if (var_rad.get()==1):
label1.after_idle(сlock)
# Головна программа із описанням та розташуванням
# об’єктів інтерфейсного вікна
# =================================================
# Описання головного вікна
window = Tk()
window.title('Багатофункціональний годинник')
# Описання та розташування текстового вікна для
# виведення значення часу
label1 = Label (window, font='sans 14')
label1.place(x = 4, y = 10)
# Визначення змінної і, яка відповідає кількості
# повторень звукового сигналу. Початкове значення цієї
# змінної дорівнює 0.
i=IntVar()
i.set(0)
# Визначення змінної var_rad, яка відповідає

446
# обраному елементу селекторної кнопки класу
# Radiobutton
var_rad = IntVar()
# Описання та розташування елементів селекторної кнопки
# класу Radiobutton
rb1 = Radiobutton(window, text='Годинник', \
variable=var_rad, value=1)
rb2 = Radiobutton(window, text='Секундомір', \
variable=var_rad, value=2)
var_rad.set(1)
rb1.place(x = 100, y = 15)
rb2.place(x = 170, y = 15)
# Визначення змінної CT, яка відповідає функції
# включення та виключення секундоміра. Якщо CT = 1,
# секундомір вважається включеним, а якщо CT = 0 –
# виключеним. За замовченням CT = 1.
CT = IntVar()
CT.set(1)
# Визначення змінних DSEC, SEC та MIN, які відповідають
# часу, що відображується на секундомірі. Початові
# значення цих змінних дорівнюють нулю.
MIN=IntVar()
SEC=IntVar()
DSEC=IntVar()
MIN.set(0)
SEC.set(0)
DSEC.set(0)
# Описання та розташування кнопки 'Старт'
btn1 = Button(window, text = 'Старт', command = \
runtime)
btn1.place(x = 4, y = 40)

447
# Описання та розташування кнопки 'Стоп'
btn2 = Button(window, text = 'Стоп', command = \
stoptime)
btn2.place(x = 60, y = 40)
# Описання та розташування кнопки 'Онулення'
btn3 = Button(window, text = 'Онулення', command = \
cleartime)
btn3.place(x = 110, y = 40)
# Описання та розташування кнопки 'Вихід'
btn4 = Button(window, text = 'Вихід', command = \
window.destroy)
btn4.place(x = 190, y = 40)
# Описання та розташування текстових вікон для
# виведення тексту 'Встановлення часу подання звукового
# сигналу та його параметрів'
label21 = Label (window, font='Arial 10', text = \
'Встановлення часу подання ')
label22 = Label (window, font='Arial 10', text = \
'звукового сигналу та його параметрів')
label21.place(x = 4, y = 70)
label22.place(x = 4, y = 90)
# Описання та розташування текстових вікон для
# виведення відповідних підписів під списками-
# лічильниками. Год: – години, Хв: – хвилини,
# Сек: – секунди.
label3 = Label (window, font='Arial 10', text = 'Год:')
label3.place(x = 4, y = 110)
label4 = Label (window, font='Arial 10', text = 'Хв:')
label4.place(x = 64, y = 110)
label5 = Label (window, font='Arial 10', text = 'Сек:')
label5.place(x = 124, y = 110)

448
# Описання та розташування списків-лічильників для
# введення значень годин, хвилин та секунд
spb1 = Spinbox(window, from_ = 0, to = 23, width = 16,
borderwidth = 4, font = 'Arial 10')
spb1.place(x = 4, y = 130, width = 60, height = 30)
spb2 = Spinbox(window, from_ = 0, to = 59, width = 16, \
borderwidth = 4, font = 'Arial 10')
spb2.place(x = 64, y = 130, width = 60, height = 30)
spb3 = Spinbox(window, from_ = 0, to = 59, width = 16, \
borderwidth = 4, font = 'Arial 10')
spb3.place(x = 124, y = 130, width = 60, height = 30)
# Описання та розташування текстового вікна для
# виведення підпису 'Встановлення частоти сигналу, Гц:'
label6 = Label (window, font='Arial 10', text = \
'Встановлення частоти сигналу, Гц:')
label6.place(x = 4, y = 160)
# Описання та розташування лінійки з повзунцем
# для визначення частоти звукового сигналу
sci1 = Scale(window, orient = HORIZONTAL, length = 300, \
from_ = 50, to = 5000, tickinterval = 900, \
resolution = 1, relief = SUNKEN)
sci1.set(1000)
sci1.place(x = 4, y = 180)
# Описання та розташування текстового вікна для
# виведення підпису 'Встановлення тривалості сигналу,
# сек:'
label7 = Label (window, font='Arial 10', \
text = 'Встановлення тривалості сигналу, сек:')
label7.place(x = 4, y = 240)
# Описання та розташування лінійки з повзунцем
# для визначення тривалості звукового сигналу
sci2 = Scale(window, orient = HORIZONTAL, length = 300, \
from_ = 0.9, to = 10, tickinterval = 0.9, \

449
resolution = 0.1, relief = SUNKEN)
sci2.set(1)
sci2.place(x = 4, y = 260)
# Описання та розташування текстового вікна для
# виведення підпису 'Встановлення тривалості паузи,
# сек:'
label8 = Label (window, font='Arial 10', \
text = 'Встановлення тривалості паузи, сек:')
label8.place(x = 4, y = 320)
# Описання та розташування лінійки з повзунцем
# для визначення тривалості паузи
sci3 = Scale(window, orient = HORIZONTAL, length = 300, \
from_ = 0.9, to = 10, tickinterval = 0.9, \
resolution = 0.1, relief = SUNKEN)
sci3.set(1)
sci3.place(x = 4, y = 340)
# Описання та розташування текстового вікна для
# виведення підпису 'Встановлення кількості повторень:'
label9 = Label (window, font='Arial 10', \
text = 'Встановлення кількості повторень:')
label9.place(x = 4, y = 400)
# Описання та розташування списку-лічильника для
# визначення кількості повторень звукового сигналу
spb4 = Spinbox(window, from_ = 1, to = 20, width = 16, \
borderwidth = 4, font = 'Arial 10')
spb4.place(x = 230, y = 400, width = 60, height = 30)
# Описання та розташування кнопки-перемикача для
# ввімкнення звукового сигналу
chk = IntVar()
check = Checkbutton(window, \
text = 'Подати звуковий сигнал', variable = chk)
chk.set(0)
check.place(x = 4, y = 450)
# Описання та розташування кнопки вимкнення
450
# звукового сигналу
btn5 = Button(window, text = 'Вимкнути зву\
ковий сигнал', command = sound_out)
btn5.place(x = 170, y = 450)
if (CT.get()==1):
# Запуск функції роботи годинника
if (var_rad.get()==1):
label1.after_idle(сlock)
# Запуск функції роботи секундоміра
elif (var_rad.get()==2):
label1.after_idle(timer)
window.mainloop

451
Додаток В. Програма текстового редактора для прикладу 5.25
# Імпорт функцій, які відображують елементи
# інтерфейсу та виконують операції з файлами
from tkinter import *
from tkinter.filedialog import askopenfile, \
asksaveasfile
from tkinter.messagebox import showinfo
# Функція для виведення інформації про програму
def about():
msg = '''Навчальна програма для студентів
другого курсу кафедри електронних приладів
та пристроїв. Текстовий редактор. Написав
Мельник Ігор Віталійович, професор кафедри
електронних приладів та пристроїв факультету
електроніки Національного технічного
університету України КПІ імені Ігоря
Сікорського'''
showinfo('Про програму', msg)
# Функція для створення нового файлу
def newfile():
text.delete(0.0, END)
# Функція для відкриття файлу
def openfile():
# Запит на відкриття файлу
fopen = askopenfile(mode = 'r', \
defaultextension = '.txt', filetypes = \
(('Текстові файли', '*.txt'), ('Всі файли', \
'*.*')))
# Перевірка, чи відбулася подія відкриття файлу
if fopen == None: return

452
# Виклик функції читання файлу
str = fopen.read()
# Очищення текстового вікна
text.delete(0.0, END)
# Запис рядка, який відповідає прочитаному
# файлу, до текстового вікна
text.insert(END, str)
# Функція для записування файлу
def savefile():
# Запит на записування файлу
fsave = asksaveasfile(mode = 'w', \
defaultextension = '.txt', filetypes = \
(('Текстові файли', '*.txt'), ('Всі файли',\
'*.*')))
# Перевірка, чи відбулася подія записування
# файлу
if fsave == None: return
# Формування рядка для запису
str = text.get(0.0, END)
# Запис файлу
fsave.write(str)
# Закриття записаного файлу
fsave.close()
# Створення головного інтерфейсного вікна
window = Tk()
window.title('Текстовий редактор')
# Створення об’єкта класу Text для відображення
# та редагування тексту
text = Text(window, wrap = WORD, height = 3,\
width = 40)
text.pack(side = 'left', fill = 'both', \
expand = 'yes')
# Створення лінійки прокручення scrollbar та
# її прив’язування до текстового вікна
scrollbar = Scrollbar(window, command = text.yview)

453
text.configure(yscrollcommand = scrollbar.set)
scrollbar.pack(side = 'right', fill = Y)
# Формування та відображення рядка меню
menubar = Menu(window)
window.config(menu = menubar)
# Формування спливаючого меню «Файл»
filemenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = 'Файл', \
underline = 0, menu = filemenu)
# Формування списку команд спливаючого меню «Файл»
filemenu.add_command(label = 'Новий', \
underline = 0, accelerator = 'Ctrl + n', \
command = newfile)
filemenu.add_command(label = 'Відкрити', \
underline = 0, accelerator = 'Ctrl + o', \
command = openfile)
filemenu.add_command(label = 'Закрити', \
underline = 0, command = newfile)
filemenu.add_command(label = 'Зберегти', \
underline = 0, accelerator = 'Ctrl + s', \
command = savefile)
filemenu.add_command(label = 'Вихід', \
underline = 1, accelerator = 'Ctrl + q', \
command = window.destroy)
# Формування спливаючого меню «Допомога»
helpmenu = Menu(menubar, tearoff = 0)
helpmenu.add_command(label = 'Про програму', \
accelerator = 'Ctrl + h', command = about)
menubar.add_cascade(label = 'Допомога', \
menu = helpmenu)
# Створення в кінці програми головного циклу
# для інтерфейсного вікна
window.mainloop()

454
Додаток Г. Програма простого калькулятора з реалізацією
головних математичних функцій та з десятьми комірками пам’яті
для прикладу 5.26
from tkinter import *
from math import *
# Перевірка першого та другого текстових вікон на
# числові значення
def is_digit():
try:
W1.set(float(et1.get()))
W2.set(float(et2.get()))
return TRUE
except ValueError:
pass
return False
def is_digit1():
try:
W1.set(float(et1.get()))
return True
except ValueError:
pass
return False
# Перевірка першого та другого текстових вікон на
# числові значення
def is_int():
try:
W1.set(int(et1.get()))
W2.set(int(et2.get()))
return True
except ValueError:

455
pass
return False
# Функція для очищення вікон операндів та вікна
# результату обчислень
def clear():
et1.delete(0,END)
et2.delete(0,END)
et1.insert(0,'0')
et2.insert(0,'0')
label7.config(text = '0')
label4.config(text='F2:')
label2.config(text='F1:')
# Функція додавання
def plus():
ChkDig=is_digit()
if ChkDig==TRUE:
RES=float(et1.get())+float(et2.get())
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='+')
label2.config(text='')
# Функція віднімання
def minus():
ChkDig=is_digit()
if ChkDig==TRUE:
RES=float(et1.get())-float(et2.get())
RES_TXT=str(RES)
else:

456
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='-')
label2.config(text='')
# Функція множення
def multiply():
ChkDig=is_digit()
if (ChkDig==TRUE) and (abs(W1.get())<1e30) \
and (abs(W2.get())<1e30):
RES=float(et1.get())*float(et2.get())
RES_TXT=str(RES)
elif ((abs(W1.get())>=1e30) and \
(abs(W2.get())>=1e30)):
RES_TXT='Занадто велике значення'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='*')
label2.config(text='')
# Функція ділення
def devision():
ChkDig=is_digit()
if (ChkDig==TRUE) and (abs(W1.get())<1e40) \
and (not(abs(W2.get())==0)):
RES=float(et1.get())/float(et2.get())
RES_TXT=str(RES)
elif (abs(W1.get()))>=1e40:
RES_TXT='Занадто велике значення'
elif abs(W2.get())==0:
RES_TXT='Невизначена операція'

457
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='/')
label2.config(text='')
# Функція обчислення відсотку
def percent():
ChkDig=is_digit()
if (ChkDig==TRUE) and (abs(W2.get())<1e40) \
and (not(abs(W1.get())==0)):
RES=float(et2.get())/float(et1.get())*100
RES_TXT=str(RES)
elif (abs(W2.get()))>=1e40:
RES_TXT='Занадто велике значення'
elif abs(W1.get())==0:
RES_TXT='Невизначена операція'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='%')
label2.config(text='')
# Функція взяття остачі
def module():
ChkDig=is_int()
if (ChkDig==TRUE) and (abs(W1.get())<1e40) \
and (not(abs(W2.get())==0)):
RES=int(et1.get())%int(et2.get())
RES_TXT=str(RES)
elif (abs(W1.get()))>=1e40:
RES_TXT='Занадто велике значення'

458
elif abs(W2.get())==0:
RES_TXT='Невизначена операція'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='mod')
label2.config(text='')
# Функція факторіалу
def fakt():
ChkDig=is_int()
if (ChkDig==TRUE) and (0<W1.get()<100):
if (W1.get()<50):
RES=factorial(int(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT=str(float(factorial(int
(et1.get()))))
elif W1.get()>=100:
RES_TXT='Занадто велике значення'
elif W1.get()<0:
RES_TXT='Невірний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='n!')
# Функція обчислення зворотної величини
def invertor():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (W1.get()!=0):

459
RES=1/float(et1.get())
RES_TXT=str(RES)
elif W2.get()==0:
RES_TXT='Невизначена операція'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='1/x')
# Функція +B2
def incr():
ChkDig=is_digit()
if (ChkDig==TRUE) and (W2.get()!=0):
RES=float(et1.get())+float(et2.get())
RES_TXT=str(RES)
et1.delete(0,END)
et1.insert(0,RES_TXT)
label4.config(text='')
label2.config(text='B1=B1+B2')
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='B1=B1+B2')
# Функція -B2
def decr():
ChkDig=is_digit()
if (ChkDig==TRUE) and (W2.get()!=0):
RES=float(et1.get())-float(et2.get())
RES_TXT=str(RES)

460
et1.delete(0,END)
et1.insert(0,RES_TXT)
label4.config(text='')
label2.config(text='B1=B1-B2')
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='B1=B1-B2')
# Функція округлення до найбільшого цілого
def fn_ceil():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=ceil(float(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='ceil')
# Функція округлення до найменшого цілого
def fn_floor():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=floor(float(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')

461
label2.config(text='floor')
# Функція округлення до найменшого цілого
def fn_round():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=round(float(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='round')
# Функція модуля
def fn_abs():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=abs(float(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='round')
# Експоненціальна функція
def fn_exp():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (W1.get()<100):
RES=exp(float(et1.get()))
RES_TXT=str(RES)
elif (W1.get()>=100):

462
RES_TXT='Занадто велике значення'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='exp')
# Степенева функція
def fn_pow():
ChkDig=is_digit()
if (ChkDig==TRUE) and (W1.get()<100) \
and (W2.get()<100):
RES=(float(et1.get()))**(float(et2.get()))
RES_TXT=str(RES)
elif (W1.get()>=100) or (W2.get()>=100):
RES_TXT='Занадто велике значення'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='^')
label2.config(text='')
# Функція квадратного кореня
def fn_sqrt():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (W1.get()>=0):
RES=sqrt((float(et1.get())))
RES_TXT=str(RES)
elif (W1.get()<0) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'

463
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='sqrt')
# Функція натурального логарифму
def fn_ln():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (W1.get()>0):
RES=log((float(et1.get())))
RES_TXT=str(RES)
elif (W1.get()<=0) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='ln')
# Функція десяткового логарифму
def fn_log10():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (W1.get()>0):
RES=log((float(et1.get())),10)
RES_TXT=str(RES)
elif (W1.get()<=0) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='log10')
# Функція двійкового логарифму

464
def fn_log2():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (W1.get()>0):
RES=log((float(et1.get())),2)
RES_TXT=str(RES)
elif (W1.get()<=0) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='log2')
# Функція логарифму за довільною основою,
# заданою у вікні В2
def fn_logB2():
ChkDig=is_digit()
if (ChkDig==TRUE) and (W1.get()>0) and \
(W2.get()>0):
RES=log((float(et1.get())),(float(et2.get())))
RES_TXT=str(RES)
elif (W1.get()<=0) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='log[B2]')
# Функція 2^x
def fn_pow2():
ChkDig=is_digit()

465
if (ChkDig==TRUE) and (W1.get()<100) and \
(W2.get()<100):
RES=2**(float(et1.get()))
RES_TXT=str(RES)
elif (W1.get()>=100) or (W2.get()>=100):
RES_TXT='Занадто велике значення'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='2^x')
# Функція 10^x
def fn_pow10():
ChkDig=is_digit()
if (ChkDig==TRUE) and (W1.get()<100) and \
(W2.get()<100):
RES=10**(float(et1.get()))
RES_TXT=str(RES)
elif (W1.get()>=100) or (W2.get()>=100):
RES_TXT='Занадто велике значення'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='10^x')
# Введення до вікна В1 значення числа пі
def disp_pi():
et1.delete(0,END)
str_pi=str(pi);
et1.insert(0,str_pi)

466
# Функція синуса
def fn_sin():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=sin(float(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='sin')
# Функція косинуса
def fn_cos():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=cos(float(et1.get()))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='cos')
# Функція тангенса
def fn_tg():
ChkDig=is_digit1()
znm=cos(float(et1.get()))
if (ChkDig==TRUE) and (znm!=0):
RES=sin(float(et1.get()))/znm
RES_TXT=str(RES)
elif (znm==0):

467
RES_TXT='Невизначена операція'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='tg')
# Функція котангенса
def fn_ctg():
ChkDig=is_digit1()
znm=sin(float(et1.get()))
if (ChkDig==TRUE) and (znm!=0):
RES=cos(float(et1.get()))/znm
RES_TXT=str(RES)
elif (znm==0):
RES_TXT='Невизначена операція'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='ctg')
# Функція арксинуса
def fn_asin():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (abs(W1.get())<=1):
RES=asin((float(et1.get())))
RES_TXT=str(RES)
elif (abs(W1.get())>1) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'

468
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='arcsin')
# Функція арккосинуса
def fn_acos():
ChkDig=is_digit1()
if (ChkDig==TRUE) and (abs(W1.get())<=1):
RES=acos((float(et1.get())))
RES_TXT=str(RES)
elif (abs(W1.get())>1) :
RES_TXT='Неправильний аргумент'
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='arccos')
# Функція арктангенса
def fn_atan():
ChkDig=is_digit1()
if (ChkDig==TRUE):
RES=atan((float(et1.get())))
RES_TXT=str(RES)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='arctg')
# Функції для копіювання даних між вікнами пам'яті
# Посередня адресація
def trans_mem():

469
ChkDig=is_int()
if (ChkDig==TRUE):
n1=int(et1.get())
n2=int(et2.get())
else:
RES_TXT='Перевірте числові значення'
label4.config(text='')
str_out = 'B'+str(n1)+ '=>' +'B'+str(n2)
label2.config(text=str_out)
label7.config(text=RES_TXT)
if (3<=n1<=13) and (1<=n2<=13) and (n1!=n2):
if (n2==3):
func='et'+str(n1)+'.get()'
RES_TXT=memconf1(lambda: eval(func))
str_out = 'B'+str(n1)+ '=>' +'B'+str(n2)
label2.config(text=str_out)
elif (n1==3):
RES_TXT=label7.cget('text')
srt_del = 'et'+str(n2)+'.delete(0,END)'
memconf2(lambda: eval(srt_del))
str_ins = 'et'+str(n2)+'.insert(0,RES_TXT)'
eval(str_ins)
str_out = 'B3=>B'+str(n2)
label2.config(text= str_out)
else:
str1= 'et'+str(n1)+'.get()'
RES_TXT=memconf3(lambda: eval(str1))
str2 = 'et'+str(n2)+'.delete(0,END)'
str3 = 'et'+str(n2)+'.insert(0,RES_TXT)'
eval(str2)

470
eval(str3)
str_out = 'B'+str(n1)+ '=>' +'B'+str(n2)
label2.config(text=str_out)
else:
RES_TXT='Перевірте числові значення'
label7.config(text=RES_TXT)
label4.config(text='')
label2.config(text='MEM:')
# Копіювання результату обчислень з вікна
# В3 до вікна В1 для продовження проведення
# обчислень
def trans_mem_31():
RES_TXT=label7.cget('text')
et1.delete(0,END)
et1.insert(0,RES_TXT)
label2.config(text='B3=>B1')
# Пряма адресація
def trans_mem_direct():
n1=int(spb1.get())
n2=int(spb2.get())
if (n1!=n2):
if (n2==3):
func='et'+str(n1)+'.get()'
RES_TXT=memconf1(lambda: eval(func))
str_out = 'B'+str(n1)+ '=>' +'B'+str(n2)
label2.config(text=str_out)
elif (n1==3):
RES_TXT=label7.cget('text')
srt_del = 'et'+str(n2)+'.delete(0,END)'
memconf2(lambda: eval(srt_del))

471
str_ins = 'et'+str(n2)+'.insert(0,RES_TXT)'
eval(str_ins)
str_out = 'B3=>B'+str(n2)
label2.config(text= str_out)
else:
str1= 'et'+str(n1)+'.get()'
RES_TXT=memconf3(lambda: eval(str1))
str2 = 'et'+str(n2)+'.delete(0,END)'
str3 = 'et'+str(n2)+'.insert(0,RES_TXT)'
eval(str2)
eval(str3)
str_out = 'B'+str(n1)+ '=>' +'B'+str(n2)
label2.config(text=str_out)
else:
RES_TXT='Перевірте числові значен \
ня лічильників'
label7.config(text=RES_TXT)
label4.config(text='')
str_out = 'B'+str(n1)+ '=>' +'B'+str(n2)
label2.config(text=str_out)
# Функція для проведення арифметичних операцій
# між вікнами пам'яті. Результат обчислень записується
# до вікна В3
def mem_operations():
n1=int(spb1.get())
n2=int(spb2.get())
if (n1==3) and (n2==3):
R1=label7.cget('text')
R2=R1
elif (n2==3):

472
func='et'+str(n1)+'.get()'
R1=eval(func)
R2=label7.cget('text')
elif (n1==3):
func='et'+str(n2)+'.get()'
R2=eval(func)
R1=label7.cget('text')
else:
func1='et'+str(n1)+'.get()'
func2='et'+str(n2)+'.get()'
R1=eval(func1)
R2=eval(func2)
try:
V1=float(R1)
V2=float(R2)
ChkDig=True
except:
ChkDig=False
if (ChkDig==True):
num_op=var_rad.get()
if (num_op == 1):
str_op = '+'
RES = V1 + V2
RES_TXT = str(RES)
elif (num_op == 2):
str_op = '-'
RES = V1 - V2
RES_TXT = str(RES)
elif (num_op == 3):
str_op = '*'

473
RES = V1 * V2
if abs(RES) < 1e50:
RES_TXT = str(RES)
else:
RES_TXT = 'Занадто велике значення'
elif (num_op == 4):
str_op = '/'
if abs(V1) > 1e50 or abs(V2) < 1e-50:
RES_TXT = 'Занадто велике значення'
elif (V2 == 0):
RES_TXT = 'Невизначена операція'
else:
RES = V1 / V2
RES_TXT = str(RES)
else:
str_op = '^'
RES = V1 ** V2
if abs(RES) < 1e50:
RES_TXT = str(RES)
else:
RES_TXT = 'Занадто велике значення'
else:
RES_TXT = 'Перевіртe числові дані'
if (var_rad.get() == 1):
str_op = '+'
elif (var_rad.get() == 2):
str_op = '-'
elif (var_rad.get() == 3):
str_op = '*'
elif (var_rad.get() == 4):

474
str_op = '/'
elif (var_rad.get() == 5):
str_op = '^'
label7.config(text = RES_TXT)
str_out = 'B'+str(n1)+ str_op +'B'+str(n2)
label2.config(text=str_out)
# Функція очищення комірок пам’яті
def mem_clear():
et4.delete(0,END)
et4.insert(0,'0')
et5.delete(0,END)
et5.insert(0,'0')
et6.delete(0,END)
et6.insert(0,'0')
et7.delete(0,END)
et7.insert(0,'0')
et8.delete(0,END)
et8.insert(0,'0')
et9.delete(0,END)
et9.insert(0,'0')
et10.delete(0,END)
et10.insert(0,'0')
et11.delete(0,END)
et11.insert(0,'0')
et12.delete(0,END)
et12.insert(0,'0')
et13.delete(0,END)
et13.insert(0,'0')
# Анонімні лямбда-функції для роботи з
# текстовими вікнами

475
def memconf1(lf):
label7.config(text = lf())
def memconf2(lf):
lf()
# Описання головного вікна
window = Tk()
window.title('Простий калькулятор')
# Текстове вікно для описання блоку проведення
обчислень
label1 = Label (window,font='Arial 14', text = \
'Блок проведення обчислень:')
label1.place(x = 200, y = 10)
# Ініціалізація текстових змінних для виведення
# виконаної функції
RES_TXT=''
W1=DoubleVar()
W2=DoubleVar()
W3=DoubleVar()
# Текстове вікно для описання введеної функції
# у разі одного операнда
label2 = Label (window,font='Arial 12', text = 'F1')
label2.place(x = 4, y = 60)
# Описання та розташування текстового вікна для
# введення першого операнда
label3 = Label (window,font='Arial 12', \
text = 'Вікно 1')
label3.place(x = 100, y = 35)
et1 = Entry(window, font='Arial 12', width = 15)
et1.insert(0,'0')
et1.place(x = 90, y = 60)

476
ETS1=et1.get()
# Текстове вікно для описання введеної функції
# у разі двох операндів
label4 = Label (window,font='Arial 12', text = 'F2')
label4.place(x = 230, y = 60)
# Описання та розташування текстового вікна для
# введення другого операнда
label5 = Label (window,font='Arial 12', \
text = 'Вікно 2')
label5.place(x = 320, y = 35)
et2 = Entry(window, font='Arial 12', width = 15)
et2.insert(0,'0')
et2.place(x = 280, y = 60)
ETS2=et2.get()
# Описання та розташування текстового вікна для
# виведення результату обчислень
label6 = Label (window,font='Arial 12', \
text = 'Вікно 3')
label6.place(x = 480, y = 35)
label7 = Label(window, font='Arial 12', width = 60,
text = '0', background = 'black', foreground = 'white')
label7.place(x = 450, y = 60)
label8 = Label (window,font='Arial 12', text = '=')
label8.place(x = 410, y = 60)
# Розташування в обчислювальному блоці кнопки
# "Очистити"
btn1 = Button(window, text = 'Очистити', command =
clear)
btn1.place(x = 550, y = 20)
# Текстове вікно для описання блоку

477
# арифметичних операцій
label9 = Label (window,font='Arial 14', \
text = 'Блок арифметичних операцій:')
label9.place(x = 50, y = 90)
# Описання та розташування кнопок для блоку
# арифметичних операцій
btn2 = Button(window, text = '+', width = 3, \
command = plus)
btn2.place(x = 20, y = 120)
btn3 = Button(window, text = '-', width = 3, \
command = minus)
btn3.place(x = 55, y = 120)
btn4 = Button(window, text = '*', width = 3, \
command = multiply)
btn4.place(x = 90, y = 120)
btn5 = Button(window, text = '/', width = 3, \
command = devision)
btn5.place(x = 125, y = 120)
btn5 = Button(window, text = '%', width = 3, \
command = percent)
btn5.place(x = 160, y = 120)
btn6 = Button(window, text = 'mod', width = 3, \
command = module)
btn6.place(x = 195, y = 120)
btn7 = Button(window, text = 'n!', width = 3, \
command = fakt)
btn7.place(x = 230, y = 120)
btn8 = Button(window, text = '1/x', width = 3, \
command = invertor)
btn8.place(x = 265, y = 120)

478
btn33 = Button(window, text = '+B2', width = 3, \
command = incr)
btn33.place(x = 300, y = 120)
btn34 = Button(window, text = '-B2', width = 3, \
command = decr)
btn34.place(x = 335, y = 120)
# Текстове вікно для описання блоку операцій
# округлення та функції модуля
label10 = Label (window,font='Arial 14', text = 'Блок
операцій округлення:')
label10.place(x = 400, y = 90)
# Описання та розташування кнопок для блоку
# операцій округлення
btn8 = Button(window, text = 'ceil', width = 5, \
command = fn_ceil)
btn8.place(x = 420, y = 120)
btn9 = Button(window, text = 'floor', width = 5, \
command = fn_floor)
btn9.place(x = 470, y = 120)
btn10 = Button(window, text = 'round', width = 5, \
command = fn_round)
btn10.place(x = 520, y = 120)
btn10 = Button(window, text = '|x|', width = 5, \
command = fn_abs)
btn10.place(x = 570, y = 120)
# Текстове вікно для описання блоку степеневих,
# логарифмічної та експоненціальної функції
label10 = Label (window,font='Arial 14', \
text = 'Блок степеневих, логарифмічної та експонен\
ціальної функції:')

479
label10.place(x = 20, y = 150)
# Описання та розташування кнопок для блоку степеневих,
логарифмічних та показникових функцій
btn12 = Button(window, text = 'exp', width = 5, \
command = fn_exp)
btn12.place(x = 70, y = 180)
btn13 = Button(window, text = '^', width = 5, \
command = fn_pow)
btn13.place(x = 120, y = 180)
btn14 = Button(window, text = 'sqrt', width = 5, \
command = fn_sqrt)
btn14.place(x = 170, y = 180)
btn15 = Button(window, text = 'ln', width = 5, \
command = fn_ln)
btn15.place(x = 220, y = 180)
btn16 = Button(window, text = 'log10', width = 5, \
command = fn_log10)
btn16.place(x = 270, y = 180)
btn17 = Button(window, text = 'log2', width = 5, \
command = fn_log2)
btn17.place(x = 320, y = 180)
btn32 = Button(window, text = 'log[B2]', width = 5, \
command = fn_logB2)
btn32.place(x = 370, y = 180)
btn18 = Button(window, text = '2^x', width = 5, \
command = fn_pow2)
btn18.place(x = 420, y = 180)
btn19 = Button(window, text = '10^x', width = 5, \
command = fn_pow10)
btn19.place(x = 470, y = 180)

480
# Текстове вікно для описання блоку
# тригонометричних функцій
label11 = Label (window,font='Arial 14', \
text = 'Блок тригонометричних функцій:')
label11.place(x = 20, y = 225)
# Описання та розташування кнопок для блоку
# тригонометричних функцій
btn19 = Button(window, text = 'pi', width = 5, \
command = disp_pi)
btn19.place(x = 50, y = 260)
btn20 = Button(window, text = 'sin', width = 5, \
command = fn_sin)
btn20.place(x = 100, y = 260)
btn20 = Button(window, text = 'cos', width = 5, \
command = fn_cos)
btn20.place(x = 150, y = 260)
btn21 = Button(window, text = 'tg', width = 5, \
command = fn_tg)
btn21.place(x = 200, y = 260)
btn22 = Button(window, text = 'ctg', width = 5, \
command = fn_ctg)
btn22.place(x = 250, y = 260)
# Текстове вікно для описання блоку зворотних
# тригонометричних функцій
label11 = Label (window,font='Arial 14', \
text = 'Блок зворотних')
label11.place(x = 350, y = 210)
label12 = Label (window,font='Arial 14', \
text = 'тригонометричних функцій:')
label12.place(x = 350, y = 235)

481
# Описання та розташування кнопок для блоку зворотних
тригонометричних функцій
btn23 = Button(window, text = 'arcsin', width = 5, \
command = fn_asin)
btn23.place(x = 400, y = 270)
btn24 = Button(window, text = 'arccos', width = 5, \
command = fn_acos)
btn24.place(x = 450, y = 270)
btn25 = Button(window, text = 'arctg', width = 5, \
command = fn_atan)
btn25.place(x = 500, y = 270)
# Текстове вікно для описання блоку пам'ятi
label12 = Label (window,font='Arial 14', \
text = "Пам'ять:")
label12.place(x = 750, y = 90)
# Описання та розташування текстового вікон
# регістрів пам'яті калькулятора
label13 = Label (window,font='Arial 12', \
text = 'Вікно 4')
label13.place(x = 680, y = 120)
et4 = Entry(window, font='Arial 12', width = 15)
et4.insert(0,'0')
et4.place(x = 650, y = 150)
label14 = Label (window,font='Arial 12', \
text = 'Вікно 5')
label14.place(x = 830, y = 120)
et5 = Entry(window, font='Arial 12', width = 15)
et5.insert(0,'0')
et5.place(x = 800, y = 150)
label15 = Label (window,font='Arial 12', \

482
text = 'Вікно 6')
label15.place(x = 680, y = 180)
et6 = Entry(window, font='Arial 12', width = 15)
et6.insert(0,'0')
et6.place(x = 650, y = 210)
label16 = Label (window,font='Arial 12', \
text = 'Вікно 7')
label16.place(x = 830, y = 180)
et7 = Entry(window, font='Arial 12', width = 15)
et7.insert(0,'0')
et7.place(x = 800, y = 210)
label17 = Label (window,font='Arial 12', \
text = 'Вікно 8')
label17.place(x = 680, y = 240)
et8 = Entry(window, font='Arial 12', width = 15)
et8.insert(0,'0')
et8.place(x = 650, y = 270)
label18 = Label (window,font='Arial 12', \
text = 'Вікно 9')
label18.place(x = 830, y = 240)
et9 = Entry(window, font='Arial 12', width = 15)
et9.insert(0,'0')
et9.place(x = 800, y = 270)
label19 = Label (window,font='Arial 12', \
text = 'Вікно 10')
label19.place(x = 680, y = 300)
et10 = Entry(window, font='Arial 12', width = 15)
et10.insert(0,'0')
et10.place(x = 650, y = 330)
label20 = Label (window,font='Arial 12', \

483
text = 'Вікно 11')
label20.place(x = 830, y = 300)
et11 = Entry(window, font='Arial 12', width = 15)
et11.insert(0,'0')
et11.place(x = 800, y = 330)
label21 = Label (window,font='Arial 12', \
text = 'Вікно 12')
label21.place(x = 680, y = 360)
et12 = Entry(window, font='Arial 12', width = 15)
et12.insert(0,'0')
et12.place(x = 650, y = 390)
label22 = Label (window,font='Arial 12', \
text = 'Вікно 13')
label22.place(x = 800, y = 360)
et13 = Entry(window, font='Arial 12', width = 15)
et13.insert(0,'0')
et13.place(x = 800, y = 390)
# Текстове вікно для описання блоку роботи з пам'яттю
label23 = Label (window,font='Arial 14', \
text = "Блок роботи з пам'яттю:")
label23.place(x = 100, y = 290)
btn26 = Button(window, text = 'M(B1)=>M(B2)', width =
15, command = trans_mem)
btn26.place(x = 50, y = 350)
btn27 = Button(window, text = 'Продовжити', width = 15,
command = trans_mem_31)
btn27.place(x = 50, y = 320)
label24 = Label(window, font='Arial 12', \
text = 'Звідки:')
label24.place(x = 170, y = 360)

484
spb1 = Spinbox(window, from_ = 1, to = 13, \
width = 16, borderwidth = 4, font = 'Arial 10')
spb1.place(x = 240, y = 360, width = 60, height = 30)
label25 = Label (window, font='Arial 12', \
text = 'Куди:')
label25.place(x = 170, y = 390)
spb2 = Spinbox(window, from_ = 1, to = 13, \
width = 16, borderwidth = 4, font = 'Arial 10')
spb2.place(x = 240, y = 390, width = 60, height = 30)
btn28 = Button(window, text = 'Копіювати', \
width = 20, command = trans_mem_direct)
btn28.place(x = 170, y = 320)
var_rad = IntVar()
rb1 = Radiobutton(window, text='+', \
variable = var_rad, value=1)
rb2 = Radiobutton(window, text='-', \
variable = var_rad, value=2)
rb3 = Radiobutton(window, text='*', \
variable = var_rad, value=3)
rb4 = Radiobutton(window, text='/', \
variable = var_rad, value=4)
rb5 = Radiobutton(window, text='^', \
variable = var_rad, value=5)
var_rad.set(1)
rb1.place(x = 320, y = 350)
rb2.place(x = 360, y = 350)
rb3.place(x = 400, y = 350)
rb4.place(x = 440, y = 350)
rb5.place(x = 480, y = 350)
btn29 = Button(window, text = 'Виконати', \

485
width = 30, command = mem_operations)
btn29.place(x = 320, y = 320)
btn30 = Button(window, text = 'Очистити', \
width = 30, command = mem_clear)
btn30.place(x = 320, y = 380)
btn31 = Button(window, text = 'Вихід', \
width = 30, command = window.destroy)
btn31.place(x = 680, y = 420)
window.mainloop

486
Додаток Д. Конвертор фізичних величин із віконним інтерфейсом
для прикладу 5.28
def arb():
if var_rad.get()==1:
label2.config(text = 'Цельсій:')
label3.config(text = 'Фаренгейт:')
elif var_rad.get()==2:
label2.config(text = 'Паскаль:')
label3.config(text = 'Тор:')
else:
label2.config(text = 'Рази:')
label3.config(text = 'Децибели:')
def trans_direct():
from math import log10
if var_rad.get()==1:
TC=et1.get()
try:
TF=1.8*float(TC)+32
TFR=round(TF,3)
STF=str(TFR)
except:
STF='Помилка'
et2.delete(0,END)
et2.insert(0,STF)
elif var_rad.get()==2:
Pa=et1.get()
try:
MM=133.32*float(Pa)
MM_S=round(MM,3)
STF=str(MM_S)

487
except:
STF='Помилка'
et2.delete(0,END)
et2.insert(0,STF)
else:
KU=et1.get()
try:
KUD=10*log10(float(KU))
KUD_S=round(KUD,3)
STF=str(KUD_S)
except:
STF='Помилка'
et2.delete(0,END)
et2.insert(0,STF)
def trans_inverse():
from math import pow
if var_rad.get()==1:
TF=et2.get()
try:
TC=5*(float(TF)-32)/9
TCR=round(TC,3)
STF=str(TCR)
except:
STF='Помилка'
et1.delete(0,END)
et1.insert(0,STF)
elif var_rad.get()==2:
MM=et2.get()
try:
Pa=7.5e-3*float(MM)

488
PaR=round(Pa,3)
STF=str(PaR)
except:
STF='Помилка'
et1.delete(0,END)
et1.insert(0,STF)
else:
KUD=et2.get()
try:
KU=pow(10,float(KUD)/10)
KU_S=round(KU,3)
STF=str(KU_S)
except:
STF='Помилка'
et1.delete(0,END)
et1.insert(0,STF)
def clear_et():
et1.delete(0,END)
et1.insert(0,'0')
et2.delete(0,END)
et2.insert(0,'0')
from tkinter import *
# Описання головного вікна
window = Tk()
window.title('Конвертор')
label1 = Label (window,font='Arial 12', \
text = 'Яку величину перетворювати: ')
label1.place(x = 10, y = 10)
var_rad = IntVar()
rb1 = Radiobutton(window, text='Температура', \

489
variable=var_rad, value=1, command=arb)
rb2 = Radiobutton(window, text='Тиск', \
variable=var_rad, value=2, command=arb)
rb3 = Radiobutton(window, text='Підсилення',\
variable=var_rad, value=3, command=arb)
var_rad.set(1)
rb1.place(x = 10, y = 35)
rb2.place(x = 110, y = 35)
rb3.place(x = 160, y = 35)
label2 = Label (window,font='Arial 12', \
text = 'Цельсій:')
label2.place(x = 10, y = 50)
label3 = Label (window,font='Arial 12', \
text = 'Фаренгейт:')
label3.place(x = 150, y = 50)
et1 = Entry(window, font='Arial 10', width = 10)
et1.insert(0,'0')
et1.place(x = 10, y = 75)
et2 = Entry(window, font='Arial 10', width = 10)
et2.insert(0,'0')
et2.place(x = 150, y = 75)
btn1 = Button(window, text = '=>', width = 5, \
command = trans_direct)
btn1.place(x = 100, y = 60)
btn2 = Button(window, text = '<=', width = 5, \
command = trans_inverse)
btn2.place(x = 100, y = 90)
btn3 = Button(window, text = 'Очистити', \
width = 15, command = clear_et)
btn3.place(x = 10, y = 120)

490
btn3 = Button(window, text = 'Вихід', \
width = 15, command = window.destroy)
btn3.place(x = 120, y = 120)
window.mainloop

491
Додаток E. Програма для визначення матеріалу за його
електрофізичними параметрами для прикладу 5.29
def def_mat():
PAR=et1.get()
try:
VAL=float(PAR)
if var_rad.get()==2:
VAL_AN=1/VAL
else:
VAL_AN=VAL
if (var_rad.get()==1) or (var_rad.get()==2):
if 5.4e-8 <= VAL_AN <= 5.6e-8:
STR_OUT = 'Вольфрам'
STF = STR+STR_OUT
elif 9.9e-8 <= VAL_AN <= 1.15e-7:
STR_OUT = 'Чисте залізо'
STF = STR+STR_OUT
elif 1.3e-7 <= VAL_AN <= 1.5e-7:
STR_OUT = 'Сталь'
STF = STR+STR_OUT
elif 1.18e-7 <= VAL_AN <= 1.25e-7:
STR_OUT = 'Олово'
STF = STR+STR_OUT
elif 4.8e-7 <= VAL_AN <= 5.2e-7:
STR_OUT = 'Константан'
STF = STR+STR_OUT
elif 9.9e-7 <= VAL_AN <= 1.1e-6:
STR_OUT = 'Чавун'
STF = STR+STR_OUT
elif 1.58e-8 <= VAL_AN <= 1.62e-8:

492
STR_OUT = 'Срібло'
STF = STR+STR_OUT
elif 1.7e-8 <= VAL_AN <= 1.75e-8:
STR_OUT = 'Мідь'
STF = STR+STR_OUT
elif 2.6e-8 <= VAL_AN <= 2.8e-8:
STR_OUT = 'Алюміній'
STF = STR+STR_OUT
elif 4.9e-8 <= VAL_AN <= 5.2e-8:
STR_OUT = 'Цинк'
STF = STR+STR_OUT
elif 1.9e-7 <= VAL_AN <= 2.1e-7:
STR_OUT = 'Свинець'
STF = STR+STR_OUT
elif 7.9e-6 <= VAL_AN <= 8.1e-6:
STR_OUT = 'Графіт'
STF = STR+STR_OUT
else:
STF = 'Введене неправильне значення '
else:
if 2.2 <= VAL_AN <= 2.8:
STR_OUT = 'Ізоляційне масло'
STF = STR+STR_OUT
elif 3.5 <= VAL_AN <= 4.9:
STR_OUT = 'Дерево'
STF = STR+STR_OUT
elif 5.0 <= VAL_AN <= 5.9:
STR_OUT = 'Фарфор'
STF = STR+STR_OUT
elif 6.0 <= VAL_AN <= 10.0:

493
STR_OUT = 'Слюда'
STF = STR+STR_OUT
elif 11 <= VAL_AN <= 15:
STR_OUT = 'Скло'
STF = STR+STR_OUT
elif 25.1 <= VAL_AN <= 25.5:
STR_OUT = 'Етиловий спирт'
STF = STR+STR_OUT
elif 30 <= VAL_AN <= 31:
STR_OUT = 'Дистильована вода'
STF = STR+STR_OUT
else:
STF = 'Введене неправильне значення '
except:
STF='Помилка'
label2.config(text = STF)
def clear_et():
et1.delete(0,END)
et1.insert(0,'0')
label2.config(text = 'Матеріал: ')
from tkinter import *
window = Tk()
window.title('Визначення матеріалу')
label1 = Label (window,font='Arial 12', \
text = 'За яким параметром визначати:')
label1.place(x = 10, y = 10)
var_rad = IntVar()
rb1 = Radiobutton(window, text='Питомий опір', \
variable=var_rad, value=1)
rb2 = Radiobutton(window, \

494
text='Питома електропровідність', \
variable=var_rad, value=2)
rb3 = Radiobutton(window, \
text='Діелектрична проникність', variable=var_rad, \
value=3)
var_rad.set(1)
rb1.place(x = 10, y = 35)
rb2.place(x = 10, y = 55)
rb3.place(x = 10, y = 75)
et1 = Entry(window, font='Arial 10', width = 30)
et1.insert(0,'0')
et1.place(x = 10, y = 100)
STR='Матеріал: '
label2 = Label (window,font='Arial 12', text = STR)
label2.place(x = 10, y = 125)
btn1 = Button(window, text = 'Визначити', \
width = 10, command = def_mat)
btn1.place(x = 10, y = 150)
btn2 = Button(window, text = 'Очистити', \
width = 10, command = clear_et)
btn2.place(x = 90, y = 150)
btn3 = Button(window, text = 'Вихід', \
width = 10, command = window.destroy)
btn3.place(x = 170, y = 150)
window.mainloop

495
Додаток Є. Програма для побудови графіків математичних
функцій в інтерфейсному вікні для прикладу 5.36
from tkinter import *
from tkinter.ttk import *
import math
def sc(x):
return math.log(math.sin(x)**2- \
math.cos(x)+1.5)*math.sin(x)
def g(x):
return math.log((math.sin(x)-1)/(x- \
math.pi/2)+1.5)-0.05
def f(x):
return x*math.exp(-x**2)
def makecanvas(txt, bgclr):
cnvs = Canvas(nb, background = bgclr)
nb.add(cnvs, text = txt, padding = 3)
return cnvs
def drawFunc(canvas, fun, a, b, kx, ky, \
exclude = None):
points = []
num = 500
for n in range(num):
x = a + ((b - a)/num)*n
if exclude != None:
if x in exclude: continue
y = fun(x)
pp = (xo + kx*x, yo - ky*y)
points.append(pp)
canvas.create_line(points, fill = 'black', /
smooth = 0, width = 3)
x_Axe = [(xo + a*kx,yo), (xo + b*kx,yo)]
canvas.create_line(x_Axe, fill = 'black', \

496
width = 2)
my = max([abs(e[1] - yo) for e in points])
y_Axe = [(xo, yo - my*1.05), (xo, yo + \
my*1.05)]
canvas.create_line(y_Axe, fill = 'black', \
width = 2)
maxy = min([e[1] - yo for e in points])
gor_Mark = [(xo - 5, yo + maxy), (xo + 5, \
yo + maxy)]
canvas.create_line(gor_Mark, fill = 'black', \
width = 1)
canvas.create_text(xo + 28, yo + maxy, \
text = '{0:.3f}'.format(-maxy/ky))
canvas.create_line([(xo + kx, yo - 5), \
(xo + kx, yo + 5)], fill = 'black', width = 1)
canvas.create_text(xo + kx +5, yo + 10, \
text = '1.0')
window = Tk()
window.title('Побудова графіків функцій')
nb = Notebook(width = 480, height = 360)
nb.pack(expand = 1, fill = 'both')
cnvs1 = makecanvas('log(sin(x)**2- \
cos(x)+1.5)*sin(x)', '#f7ffff')
cnvs2 = makecanvas('log((sin(x)-1)/(x- \
pi/2)+1.5)-0.05', '#fff7ff')
cnvs3 = makecanvas('x*epx(-x**2)', '#fffff7')
xo, yo = 20, 180
drawFunc(cnvs1, sc, 0, 12, 35, 150)
xo, yo = 240, 180
drawFunc(cnvs2, g, -20, 20, 11, 230, [math.pi/2])
drawFunc(cnvs3, f, -3, 3, 80, 350)
window.mainloop

497
Додаток Ж. Програма для побудови графіків математичних
функцій засобами бібліотеки matplotlib в інтерфейсному вікні
модуля tkinter для прикладу 6.55
from tkinter import *
from numpy import *
from matplotlib.figure import figure
from matplotlib.backends.backend_tkagg \
import FigureCanvasTkAgg
from tkinter.messagebox import showerror
import warnings
def evaluate(event):
try:
mystr = entry.get()
exec(‘f = lambda x:’ + mystr, gloabls())
a = float(strA.get())
b = float(strB.get())
X = linspace(a, b, 300)
Y = [f(x) for x in X]
ax.clear()
ax.plot(X, Y, linewidth = 2)
ax.grid(color = ‘b’, alpha = 0.5, \
linestyle = ‘dashed’, linewidth = 0.5)
canvasAgg.draw()
return
except:
showerror(‘Неправильний математичний ви\
раз або числові значення’)
def evaluate2(event):
window.after(100, evaluate, event)
window = Tk()

498
window.wm_title(‘Побудова графіка функції’)
warnings.filterwarnings(‘error’)
frameUp = (window, relief = SUNKEN, height = 64)
frameUp.pack(side = TOP, fill = X)
Label1(frameUp, text = ‘Математичний вираз:’).\
place(x = 20, y = 4, width = 100, height = 25)
Label2(frameUp, text = ‘Початок інтервалу:’).\
place(x = 250, y = 4, width = 140, height = 25)
Label3(frameUp, text = ‘Кінець інтервалу:’).\
place(x = 370, y = 4, width = 140, height = 25)
entry = Entry(frameUp, relief = RIDGE, \
borderwidth = 4)
entry.bind(‘<Return>’, evalute)
entry.place(x = 6, y = 30, width = 250, height = 25)
strA = StringVar()
strA.set(0)
entryA = Entry(frameUp, relief = RIDGE, \
borderwidth = 4, textvariable = strA)
entryA.place(x = 280, y = 30, width = 80, height = 25)
entryA.bind(‘<Return>’, evalute)
strB = StringVar()
strB.set(1)
entryB = Entry(frameUp, relief = RIDGE, \
borderwidth = 4, textvariable = strB)
entryB.place(x = 400, y = 30, width = 80, height = 25)
entryB.bind(‘<Return>’, evalute)
fig = Figure(figsize = (5, 4), dpi = 100, \
facecolor = ‘white’)
ax = fig.add_subplot(1 1 1)
canvasAgg = FigureCanvasTkAgg(fig, master = window)

499
canvasAgg.show()
canvas = canvasAgg.get_tk_widget()
canvas.pack(fill = BOTH, expsnd = 1)
btn = Button(window, text = ‘Графік’)
btn.bind(‘<Button-1>’, evalute2)
btn.pack(ipady =2, pady =4, padx = 10)
window.bind(‘<Control-z>’, \
lambda event: window.destroy())
window.mainloop()

500
Додаток З. Програма клієнта для виведення інформації про
успішність студента у діалогове інтерфейсне вікно, написана з
використанням мережних технологій для прикладу 6.84

# Функція для формування запиту та надсилання його


# до програми сервера
def req_serv():
# Визначення прізвища студента для формування запиту серез
# аналіз обраного пункта списку
OutName = ''
OutName_UA = ''
inp = lstb1.get(lstb1.curselection())
if (inp == 'Абраменко'):
OutName = 'Abramenko'
OutName_UA = 'Абраменко'
elif (inp == 'Ігнатенко'):
OutName = 'Ignatenko'
OutName_UA = 'Ігнатенко'
elif (inp == 'Костюченко'):
OutName = 'Kostiuchenko'
OutName_UA = 'Костюченко'
elif (inp == 'Потапенко'):
OutName = 'Potapenko'
OutName_UA = 'Потапенко'
elif (inp == 'Хоменко'):
OutName = 'Homenko'
OutName_UA = 'Хоменко'
elif (inp == 'Шинкаренко'):
OutName = 'Shinkarenko'
OutName_UA = 'Шинкаренко'
# Формування сокета та здійснення з’єднання

501
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.connect((HOST, PORT))
# Визначення дати та часу формування запиту
OutDate = dt.strftime('%d:%m:%Y')
OutTime = dt.strftime('%H:%M:%S')
# Формування рядка для надсвилання запиту
SendString = OutDate + ' o ' + OutTime + '|'+ OutName
# Визначення способу кодування та надсилання запиту
s.send(SendString.encode('utf-8'))
# Прийняття відповіді на запит
Resp=s.recv(1024)
# Визначення дати та часу прийняття відповіді на запит
RecDate = dt.strftime('%d:%m:%Y')
RecTime = dt.strftime('%H:%M:%S')
RecDT = RecDate + ' о ' + RecTime
# Аналіз відповіді на запит та формування повідомлення
# для виведення у текстове вікно
Resp_Str = str(Resp)
Resp_Out = Resp_Str[2:len(Resp_Str)-1]
Resp_Num = int(Resp_Out)
if(Resp_Num == 3):
Resp_Prn = 'задовільно'
elif(Resp_Num == 4):
Resp_Prn = 'добре'
elif(Resp_Num == 5):
Resp_Prn = 'відмінно'
if(Resp_Num == 0):
PrintStr = RecDT + ': Студент ' + OutName_UA + \
' у списку не знайдений.'
else:

502
PrintStr = RecDT + ': Студент ' + OutName_UA + \
' навчається ' + Resp_Prn
# Виведення повідомлення у текстове вікно та закриття
# з’єднання з сервером
label2.config(text = PrintStr)
s.close()
# Функція закриття діалогового вікна
def clr_r ():
str_n = ''
label2.config(text = str_n)
# Головна програма
# Відкриття модулів socket, time та tkinter
import socket as soc
import time as dt
from tkinter import *
# Визначення мережної адреси та порта для з’єднання з
# сервером
HOST = '127.0.0.1'
PORT = 5000
# Формування головного вікна
window = Tk()
window.title('Інформація про студентів')
# Формування випливаючого списку для обрання прізвища
# студента
lbl_stud = Label(window, font='Arial 10', width = 30,
height = 50, text = 'Прізвище студента')
lbl_stud.place(x = 10, y = 30, width = 150, height = 20)
lstb1 = Listbox(window, height = 3, width = 20, \
borderwidth = 3)
lstb1.place(x = 10, y = 50, width = 100, height = 100)

503
lst = ['Абраменко', 'Ігнатенко', 'Костюченко', \
'Потапенко', 'Хоменко', 'Шинкаренко']
lstb1.selection_set(first = 0)
for elem in lst:
lstb1.insert(END, elem)
lstb1.selection_set(first = 0)
str_n=StringVar()
# Визначення рядкових змінних OutName та OutName_UA
OutName = StringVar()
OutName_UA = StringVar()
# Створення та розташування фрейму для виведення
# інформаційного повідомлення
if_out = LabelFrame(window, text = 'Формування \
інформаційного повідомлення', borderwidth = 2, \
relief = SUNKEN, width = 200, height = 200)
if_out.place(x = 10, y = 150)
label2 = Label(if_out, text = str_n)
label2.pack()
# Створення кнопки для формування запиту
btn1 = Button(if_out, text = 'Формування запиту', \
command = req_serv)
btn1.pack()
# Створення кнопки для очищення текстового вікна
btn2 = Button(if_out, text = 'Очищення', command = clr_r)
btn2.pack()
# Створення кнопки для завершення роботи з програмою
btn3 = Button(window, text = 'Вихід', \
command = window.destroy)
btn3.place(x = 150, y = 100, width = 70, height = 20)
window.mainloop

504
Додаток І. Програми клієнта та сервера для проведення
розрахунків значень математичних функцій з використанням
клієнт-серверних технологій для прикладу 6.85
Програма клієнта
def req_serv():
Send_Digit1 = ''
Send_Digit2 = ''
inp = lstb1.get(lstb1.curselection())
if (inp == 'f(x)=exp(-cos(x)/sqrt(sin(x)))'):
Send_Digit1 = '1'
elif (inp == 'f(x)=log((sin(x))/(x+1))'):
Send_Digit1 = '2'
elif (inp == 'f(x)=exp(sqrt(asin(x))/(x-1))'):
Send_Digit1 = '3'
Send_Digit2 = et1.get()
Send_Str = '|' + Send_Digit1 + '#' + Send_Digit2
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.connect((HOST, PORT))
OutDate = dt.strftime('%d:%m:%Y')
OutTime = dt.strftime('%H:%M:%S')
SendString = OutDate + ' o ' + OutTime + Send_Str
s.send(SendString.encode('utf-8'))
Resp=s.recv(1024)
RecDate = dt.strftime('%d:%m:%Y')
RecTime = dt.strftime('%H:%M:%S')
RecDT = RecDate + ' о ' + RecTime
Resp_Str = str(Resp)
Resp_Out = Resp_Str[2:len(Resp_Str)-1]
if (Resp_Out == 'Inf'):
Resp_Out_Str = 'Помилка ділення на нуль.'
elif (Resp_Out == 'NaN'):

505
Resp_Out_Str = 'Направильний аргумент функції.'
elif (Resp_Out == 'Error'):
Resp_Out_Str = 'Направильне числове значення.'
else:
Resp_Out_Str = Resp_Out
PrintStr2 = 'Прийнято: ' + RecDT
label2.config(text = PrintStr2)
label3.config(text = Resp_Out_Str)
s.close()
def clr_r ():
Out_Text = ''
label2.config(text = Out_Text)
label3.config(text = Out_Text)
import socket as soc
import time as dt
from tkinter import *
HOST = '127.0.0.1'
PORT = 5000
window = Tk()
window.title('Мережний калькулятор')
i = 1
lbl_stud = Label(window, font='Arial 12', width = 30,
height = 50, text = 'Функція:')
lbl_stud.place(x = 10, y = 30, width = 150, height = 20)
lstb1 = Listbox(window, height = 3, width = 20, \
borderwidth = 3)
lstb1.place(x = 10, y = 55, width = 160, height = 60)
lst = ['f(x)=exp(-cos(x)/sqrt(sin(x)))',
'f(x)=log((sin(x))/(x+1))', 'f(x)=exp\
(sqrt(asin(x))/(x-1))']

506
lstb1.selection_set(first = 0)
for elem in lst:
lstb1.insert(END, elem)
lstb1.selection_set(first = 0)
label1 = Label (window,font='Arial 12', \
text = 'Числове значення:')
label1.place(x = 180, y = 30)
et1 = Entry(window, font='Arial 10', width = 20)
et1.insert(0,'0')
et1.place(x = 180, y = 55)
Out_Text = StringVar()
Send_Digit1 = StringVar()
Send_Digit2 = StringVar()
Send_Str = StringVar()
# Створення та розташування фрейму для виведення
# результатів обчислення
if_out = LabelFrame(window, font='Arial 12', text =
'Результати обчислення:', borderwidth = 2, \
relief = SUNKEN, width = 200, height = 200)
if_out.place(x = 10, y = 150)
label2 = Label(if_out, text = Out_Text, font='Arial 12')
label2.pack()
label3 = Label(if_out, text = Out_Text, font='Arial 12')
label3.pack()
# Створення кнопки для надсилання запиту
btn1 = Button(if_out, text = 'Обчислити', \
command = req_serv)
btn1.pack()
btn2 = Button(if_out, text = 'Очищення', command = clr_r)
btn2.pack()

507
btn3 = Button(if_out, text = 'Вихід', command =
window.destroy)
btn3.pack()
window.mainloop

Програма сервера
import socket as soc
import time as dt
import math as m
HOST = '127.0.0.1'
PORT = 5000
print('Сервер обчислення значень математичних функцій.')
print('Режим очікування запиту від клієнта.')
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
RecvDate = dt.strftime('%d:%m:%Y')
RecvTime = dt.strftime('%H:%M:%S')
RecvDT = RecvDate + ' о ' + RecvTime
OutMark = '0'
i = 1
print(RecvDT, ': отриманий запит від клієнта з ад\
ресою ', HOST)
while 1:
while (i > 0):
data = conn.recv(1024)
print(data)
if not data:
break

508
else:
Rec_Str = str(data)
n1 = str.find(Rec_Str, '|')
Req_Cont = Rec_Str[(n1 + 1):len(Rec_Str)-1]
Num_Fun = int(Req_Cont[0])
Dig = Req_Cont[2:len(Req_Cont)]
try:
Dig_Num = float(Dig)
if(Num_Fun == 1):
if ((m.sin(Dig_Num)) == 0):
Calc_Result='Inf'
elif ((m.sin(Dig_Num)) < 0):
Calc_Result='NaN'
else:
Calc_Result=str(m.exp\
(-m.cos(Dig_Num)/m.sqrt(m.sin\
(Dig_Num))))
if(Num_Fun == 2):
if ((Dig_Num + 1) == 0):
Calc_Result='Inf'
elif ((m.sin(Dig_Num)/(Dig_\
Num + 1)) <= 0):
Calc_Result='NaN'
else:
Calc_Result=str(m.log((m.sin(\
Dig_Num)/(Dig_Num + 1))))
if(Num_Fun == 2):
if ((Dig_Num - 1) == 0):
Calc_Result='Inf'
elif (1 < Dig_Num < -1):

509
Calc_Result='NaN'
elif (m.asin(Dig_Num) < 0):
Calc_Result='NaN'
else:
Calc_Result=str(m.exp\
((m.sqrt(m.asin(Dig_Num))/(Dig_\
Num - 1))))
except:
Calc_Result='Error'
conn.send(Calc_Result.encode('utf-8'))
SendDate = dt.strftime('%d:%m:%Y')
SendTime = dt.strftime('%H:%M:%S')
SendDT = SendDate + ' о ' + SendTime
print(SendDT, ': Клієнту з адресою ', HOST, \
' відправлено відповідь на запит. ', \
Calc_Result)
conn.close()
print('Сервер обчислення значень матема\
тичних функцій.')
print('Режим очікування запиту від клієнта.')
s = soc.socket(soc.AF_INET, soc.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print(RecvDT, ': отриманий запит від клієн\
та з хїадресою ', HOST)

510
Література
1. Мельник І.В. Методичні вказівки для виконання лабораторних робіт
з курсу «Електронні пристрої обчислювальної техніки». – К.: ІВЦ
«Політехніка», 2003. – 88 с.
2. Денбновецький С.В., Мельник І.В., Писаренко Л.Д. Кодування
сигналів в електронних системах. Частина 2. Математичні основи теорії
кодування: комплексний електронний навчальний посібник з дисциплін
«Імовірнісні основи обробки даних», «Обчислювальні системи та мережі»,
«Електронні системи» та «Теорія інформації» для студентів спеціальності
171 «Електроніка» спеціалізації електронні прилади та пристрої. Том 3.
Теорія систем штучного інтелекту. – Київ, Кафедра, 2018. – 353 с.
3. Керниган Б., Ритчи Д. Язык программирования С. – СПб.: «Невский
диалект», 2003. – 352 с.
4. Неммет Э., Снайдер Г., Сиббас С., Хейн Т.Р. UNIX. Руководство
системного администратора. - Киев, BHV, 1994.
5. Вунтесмері Ю.В. Цифрові технології в мікроелектроніці. Методичні
вказівки для виконання лабораторних робіт для студентів спеціалізації
фізична та біомедична електроніка. Електронне видання. – К.: НТУУ «КПІ»,
2012.
6. Мельник І.В. Система науково-технічних розрахунків MatLab та її
використання для розв’язання задач із електроніки: навчальний посібник у
2-х томах. Т. 1. Основи роботи та функції системи. – К.: Університет
«Україна», 2009. – 507 с.
7. Мельник І.В. Система науково-технічних розрахунків MatLab та її
використання для розв’язання задач із електроніки: навчальний посібник у 2-
х томах. Т. 2. Основи програмування та розв’язання прикладних задач. – К.:
Університет «Україна», 2009. – 327 с.
8. Буч Г. Объектно-ориентированное проектирование. – Киев,

511
«Диалектика», 1992. – 519 с.
9. Буч Г. Объектно-ориентированное проектирование с примерами
применения. – М.: Конкорд, 1992. – 519 с.
10. Буч Г. Объектно-ориентированный анализ и проектирование с
примерами приложений на С++. М.: Бином, СПб.: Невский диалект, 1998. –
560 с.
11. https://ru.wikipedia.org/wiki/Объектно-ориентированное_программирование
12. Лунтовський А.О. Технології розподілених програмних додатків.
Монографія. К.: Державний університет інформаційно-комунікаційних
технологій, 2010. – 452 с.
13. Лунтовський А.О., Климаш М.М., Семенко А.І. Розподілені сервіси
телекомунікаційних мереж та повсякденний комп’ютінг і Cloud-технології.
Монографія. – Львів: Національний університет «Львівська політехніка»,
2012. – 368 с.
14. Лунтовський А.О., Климаш М.М. Інформаційна безпека
розподілених систем. Монографія. – Львів: Національний університет
«Львівська політехніка», 2014. – 444 с.
15. Страуструп Б. Язык программирования С++ – М.: Бином, 2002. –
355 c.
16. Телло Э. Объектно-ориентированное программирование в среде
Windows. – М.: 1993. – 347 с.
17. Стивенс У.Р., Раго С.А. UNIX, профессиональное
программирование. – СПб, Символ-Плюс, 1040 с.
18. Фаулер М., Скотт К. UML. Основы. – СПб.: Символ, 2006, 184 с.
19. Леоненков А.В. Объектно-ориентированный анализ и
проектирование с использованием UML и IBM Rational Rose. – М.: Интернет-
Университет Информационных Технологий, БИНОМ, Лаборатория знаний,
2006. – 319 с.
20. Мельник І.В. Інформаційні комп’ютерні мережі: навчальний
посібник для дистанційного навчання. – К.: Університет «Україна», 2006. –

512
250 с.
21. Мельник І.В., Лунтовський А.О. Проектування та дослідження
комп’ютерних мереж: навчальний посібник. – К.: Університет «Україна»,
2010. – 361 с.
22. Мельник И.В., Гамидов Г.И. Основы построения компьютерных
сетей. Учебное пособие. – Баку, Издательство «Элм», 2013. – 480 с.
23. Баклан І.В. Системне програмування. Практичне програмування на
мові Java. Посібник для студентів 3-го курсу фізико-технічного факультету. –
Київ, НТУУ “КПІ”, 1998. – 247 с.
24. Фёдоров Д.Ю. Основы программирования на языке Python. Учебное
пособие. – СПб.: Юрайт, 2018. – 168 с.
25. Любанович Б. Простой Python. Современный стиль программирования. –
СПб.: Питер, 2016. – 480 с.
26. Вандер Плас Дж. Python для сложных задач: наука о данных и
машинное обучение. – СПб.: Питер, 2016. – 576 с.
27. Лутц М. Программирование на Python. Т.2 – СПб.: Символ-Плюс,
2011. – 992 с.
28. Доусон М. Программируем на Python. – СПб.: Питер, 2014. — 416 с.
29. Мюллер А., Ван Россум Г. Введение в машинное обучение с помощью
Python. – М.: Издательский дом «Вильямс», 2017. – 480 с.
30. https://uk.wikipedia.org/wiki/Гвідо_ван_Россум
31. http://www.python.org
32. http://conda.pydata.org/miniconda.html
33. http://www.python.org/downloads
34. http://www.python.org/downloads/windows
35. https://www.anaconda.com/download/
36. http://repo.continuum.io/anaconda/pkg-docs.html
37. http://bit.ly/jm-pip-vlenv
38. http://bit.ly/hhgp-pip

513
39. Керниган Б.В., Пайк Р. UNIX – универсальная среда
программирования. – М.: Финансы и статистика, 1992. – 304 с.
40. Готье Р. Руководство по операционной системе UNIX. – М.:
Финансы и статистика, 1985. – 232 с.
41. https://uk.wikipedia.org/wiki/GNU
42. Денбновецький С.В., Мельник І.В., Писаренко Л.Д. Кодування
сигналів в електронних системах. Частина 2. Математичні основи теорії
кодування: комплексний електронний навчальний посібник з дисциплін
«Імовірнісні основи обробки даних», «Обчислювальні системи та мережі»,
«Електронні системи» та «Теорія інформації» для студентів спеціальності
171 «Електроніка» спеціалізації електронні прилади та пристрої. Том 1.
Теорія чисел, теорія множин, теорія груп, теорія поліномів, матриці, вектори
та векторні простори. – Київ, Кафедра, 2018. – 353 с.
43. https://docs.python.org/3/library/math.html
44. https://ru.wikiversity.org/wiki/Программирование_и_научные_
вычисления_на_языке_Python/§2/Приложение
45. Бронштейн И.Н., Семендяев К.А. Справочник по математике. Для
инженеров и учащихся втузов. – М.: «Наука», Главная редакция физико-
математической литературы, 1986. – 723 с.
46. http://pythonicway.com/
47. https://uk.wikipedia.org/wiki/Шкала_Фаренгейта
48. https://ru.aliexpress.com/popular/fahrenheit-celsius-thermometer.html
49. https://uk.wikipedia.org/wiki/Генеральна_конференція_мір_і_ваг
50. Кухлинг Х. Справочник по физике. – М.: Мир, 1980. – 520 с.
51. Изучение методов и средств измерения давления. Методические
указания к выполнению лабораторной работы №503 по курсу «Элементы и
устройства систем управления» для студентов направления 550200
«Автоматизация и управление» и специальности 220201 «Управления и
информатика в технических системах». – Издательство томского
политехнического университета, Томск, 2010.

514
http://portal.tpu.ru:7777/SHARED/k/KURGANOV/academics
/Tab/Измерение%20давления.pdf
52. https://prom.ua/p630098365-vakuummetr-tochnyh-izmerenij.html
53. http://www.millab.ru/equipments/3368_vacuumetr_vacuu-view/
54. https://uk.wikipedia.org/wiki/Барометр
55. http://inforico.ua/klimaticheskaya-tehnika-c1168/pogodnye-stancii-c1 41
6/elektronnye-meteostancii-termometr-gigrometr-barometr-cifrovoy-domashniy-i1
347986299171961.html
56. https://uk.wikipedia.org/wiki/Тонометр
57. https://ru.wikipedia.org/wiki/Сфигмоманометр#Автоматический_и_
полуавтоматический
58. https://ru.wikipedia.org/wiki/Измеритель_уровня_звука
59. https://prom.ua/Izmeriteli-shuma.html
60. Денбновецький С.В., Мельник І.В., Писаренко Л.Д. Кодування
сигналів в електронних системах. Частина 1. Параметри сигналів та каналів
зв’язку та методи їхнього оцінювання. – К.: Кафедра, 2016. – 524 с.
61. Деньгуб В.М., Смирнов В.Г. Единицы величин. Словарь-
справочник. — М.: Издательство стандартов, 1990. — С. 45—46. — 240 с.
62. Полупроводниковые приборы: Транзисторы. Справочник /
В.Л. Арнов, А.В. Баюков, А.А. Зайцев и др. Под общ. ред. Н.Н. Горюнова. –
М.: Энергоатомиздат, 1983. – 904 с.
63. Самарский А.А., Гулин А.В. Численные методы. Численные
методы: Учебн. пособие для вузов. – М.: Наука, 1989. – 432 с.
64. Сигорский В.П. Математический аппарат инженера. – К.: Техника,
1975. – 768 с.
65. http://pythonz.net/
66. Денбновецький С.В., Мельник І.В., Писаренко Л.Д. Кодування
сигналів в електронних системах. Частина 2. Математичні основи теорії
кодування: комплексний електронний навчальний посібник з дисциплін
«Імовірнісні основи обробки даних», «Обчислювальні системи та мережі»,

515
«Електронні системи» та «Теорія інформації» для студентів спеціальності
171 «Електроніка» спеціалізації електронні прилади та пристрої. Том 2.
Основи теорії імовірностей, математичної статистики, теорії систем масового
обслуговування та статистичної радіотехніки. – Київ, Кафедра, 2018. – 353 с.
67. https://unicode-table.com/ru/
68. https://ru.wikipedia.org/wiki/Кириллица_в_Юникоде
69. https://ideafix.name/wp-content/uploads/2012/08/Python-12.pdf
70. Доля П.Г. Введение в Научный Python. Часть 2. Дополнительные
темы. – Харьков, Харьковский национальный университет им. В.Н. Каразина,
2015. – 68 с. – http://geometry.karazin.ua/resources/documents/
20161225173818_3231ade03.pdf
71. https://www.rupython.com/python-468-3803.html
72. https://uk.wikipedia.org/wiki/Дуглас_Енгельбарт
73. https://uk.wikipedia.org/wiki/Айвен_Сазерленд
74. https://uk.wikipedia.org/wiki/Sketchpad
75. https://arduinoplus.ru/upravlenie-arduino-obolochka-python/

516

You might also like