Professional Documents
Culture Documents
Konspekt
Konspekt
Мельник
Київ
Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»
2019
Рекомендовано до друку
Методичною радою Національного технічного університету України „Київський
політехнічний інститут імені Ігоря Сікорського”, протокол № ___ від ___ грудня
2019 р.
Рецензенти:
В.Т. Лазурік, доктор технічних наук, професор, декан факультету
математики та інформатики Харківського національного
університету ім. В.Н. Каразіна
С.С. Забара, доктор технічних наук, професор, завідуючий ка-
федрою інформаційних технологій та програмування Інституту
комп’ютерних технологій Відкритого міжнародного університету
розвитку людини „Україна”, лауреат Державної премії СРСР,
лауреат Державної премії України
Мельник І.В.
Основи програмування на мові Python. Комплексний навчальний
посібник з курсів «Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі» для студентів-бакалаврів
напряму підготовки 171 «Електронні пристрої та системи». Том 1.
Базові принципи побудови мови програмування Python та головні
синтаксичні конструкції – 372 с.
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
Відомості про автора
Мельник Ігор Віталійович
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.
23
програмування історики обчислювальної техніки називають мовами другого
покоління. Різні варіанти мови асемблер є популярними і сьогодні. Їх
використовують для написання драйверів периферійних пристроїв та для
програмування мікроконтролерів з метою керування швидкодіючими
об’єктами. Наприклад, досить популярною сьогодні є мова програмування
асемблер для мікропроцесорів сімейства Intel 80x86 [1]. Недоліком мов
програмування другого покоління є їх орієнтація на професіональних
програмістів та відсутність єдиного стандарту для всіх типів обчислювальних
систем.
Ситуація ретельно змінилась у 1955 році, коли видатний математик та
програміст Джон Бекус запропонував фірмі IBM створити нову, ефективну
мову програмування для проведення науково-технічних та економічних
розрахунків. В результаті робіт Д. Бекуса була створена мова програмування
FORTRAN, яку вважають першою високорівневою мовою програмування,
або мовою програмування третього покоління. Практичні результати,
отримані Д. Бекусом під час створення мови FORTRAN, були обґрунтовані з
точки зору теорії регулярних мов [2] та удосконалені Петером Науром. До
мов програмування третього покоління відносять також мови PL1, Algol,
Cobol, Pascal, Ada, C. Доречи, до кінця дев’яностих років минулого століття
мова програмування FORTRAN досить ефективно використовувалась для
проведення складних математичних розрахунків.
24
Окремо слід відзначити мову програмування С, на основі якої
американськими програмістами К. Томпсоном та Д. Рітчі на початку
сімдесятих років минулого століття була створена операційна система UNIX
[3 – 5]. Саме С на довгі роки стала основною мовою системного
програмування, яка згодом у значній мірі замінила асемблер. Це було
пов’язано з тим, що на мову С був розроблений єдиний міжнародний
стандарт і вона стала апаратно-незалежною.
25
У 1961 році К.Ю. Айверсон розробляє мову програмування APL, у якій
було вперше запропоновано та використано безпосередня адресація не окремих
даних, а їх структур, зокрема векторів та матриць. Також в APL вперше була
реалізована можливість виконання алгебраїчних операцій над структурованими
даними. Зараз така концепція називається матричним програмуванням. Сьогодні
засоби матричного програмування у найбільш повній формі реалізовані у системі
науково-технічних розрахунків MatLab [6, 7] та у мові програмування Python.
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]. Фундаментальні роботи цих авторів, які були
опубліковані у вісімдесятих-дев’яностих роках ХХ століття, мали вкрай важливе
значення для розвитку та поширення загальної концепції ООП і для її
практичного використання в задачах моделювання та проектування
різноманітних технічних систем.
29
Сьогодні кількість мов програмування, які реалізують парадигму ООП, є
найбільшою порівняно із іншими парадигмами, зокрема із мовами,
орієнтованими на структурне, логічне, функціональне та матричне
програмування. Зрозуміло, що насамперед це пов’язано із тим, що концепція
ООП тісно пов’язана із моделями сучасної теорії скінченних автоматів, яка є
загальнотеоретичним підґрунтям всіх концепцій програмування [2]. Сьогодні
найбільш популярними серед мов ООП стали мова С++, система програмування
Delphi, а також мови C#, Java та Python.
Четверте покоління мов програмування пов’язане із створенням мов,
призначених для реалізації величезних проектів та проблемно-орієнтованих
мов програмування, призначених для описання конкретних понять вузької
галузі. Прикладами таких мов є SQL, HTML, XML, Prolog [12 – 14].
Щоправда ряд мов, які відносять до четвертого покоління, не є мовами
програмування у повному значенні цього слова. Наприклад, SQL є мовою
формування запитів до баз даних, а HTML – мовою розмітки гіпертексту та
формування гіперпосилань. Тому ці мови не є повноцінними мовами
програмування, скоріше вони виступають своєрідними спеціалізованими
доповненнями до мов програмування. Теж саме стосується XML. Основною
відмінною рисою мов програмування четвертого покоління є наближення до
людської мови. З точки зору теорії регулярних мов такі мови називають
декларативними [2, 8, 9, 12 – 14].
31
Батьківський клас
Об’єкти, Живі
екземпляри істоти
класів
Пінгвін
Птахи Тварини Класи –
спадкоємці
Страус
Заяць Летуча
миша
Їдять
Дихають Літають траву
Рис. 1.1 Класифікація об’єктів, які належать до класу живих істот, та їхні ознаки
Приклад 1.2
– А тріод?
транзисторами.
32
– Ні, існують також транзистори із низьким значенням струму.
кристалу.
а напівпровідникові – тиристорами.
Класи
Вакуумні Напівпровідникові Два Три Чотири
прилади прилади
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 Ієрархія класів з точки зору теорії скінченних автоматів та
узагальнений алгоритм формування запитів про властивості об’єкта
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 відповіді
Кінець
Кінець
43
Розглянемо блок-схему обробки конкретних запитів. Для ієрархії об’єктів,
показаної на рис. 1.1, проаналізуємо запит «Чи вміє кішка літати?», а для ієрархії
Початок
Чи вміє кішка
1 літати?
Кішка – це птах?
2
Ні, тварина.
3
Більшість тварин
не літає. Кішка є
4 виключенням?
5 Ні.
Відповідь: кішка
не літає.
6
Кінець
Рис. 1.6 Блок-схема алгоритму пошуку відповіді на питання «Чи вміє кішка
44
Початок
Транзистор –
це вакуумний
1 прилад?
Ні, напівпро-
2 відниковий.
Кінець
45
Обчислення у комп’ютерних мережах насамперед пов’язані із використанням
клієнт-серверних технологій. Надамо відповідні визначення [20 – 22].
Визначення 1.14 Клієнтом у теорії комп’ютерних мереж називається
46
розвитку наукових та технологічних розробок починають переважати
тенденції об’єднання високих технологій у програмуванні навколо крупних
корпорацій. Результатом такого розвитку стала розробка мови С# на
платформі .NET [12 – 14].
Із розвитком Інтернет та клієнт-серверних технологій програмування,
разом із мовою Java, розробляється та починає бурхливо розвиватися нова мова
програмування Python [24 – 29]. За основу для розробки цієї мови була взята
модель ООП мови Smalltalk, яка була розроблена однією із перших та завдяки
своїй простоті стала досить популярною серед широкого кола програмістів [8, 9].
Python з’явився на початку дев’яностих років минулого століття майже
одночасно із мовою програмування Java, а його розробником був відомий
голландський математик та програміст Гвідо ван Россум.
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
Пристрасть до
наукових
Машинне
навчання
досліджень Знання методів
або до статистичної
написання обробки даних
комп’ютерних
програм
Наука
про дані
Традиційні
Небезпечна дослідження
зона
49
простою для розуміння. Зараз базові конструкції цієї мови вивчаються навіть
у школах та коледжах.
Крім цього, сьогодні мова Python ефективно використовується для
програмування програмованих мікроелектронних пристроїв та систем.
Зокрема, транслятори мови Python мають мікрокомп’ютери Raspberry та
Auderino. Через послідовний порт передавання даних USB відлагоджені
програми, написані мовою Python, передаються на мікрокомп’ютери та
використовуються для керування складною електронною апаратурою [27].
Також важливим фактором щодо привабливості використання мови
програмування Python у системі освіти та у наукових закладах є те, що
транслятори Python є безкоштовними та вільно поширюються через мережу
Internet. Python належить не до комерційного програмного забезпечення, а до
безкоштовного проекту вільних програм, який називається GNU [5]. Саме у
зв’язку з цим мова програмування Python є апаратно-незалежною та
кросплатформною системою. Зокрема, існують версії Python для
програмування під операційними системами Windows, UNIX, Linux та
MacOS [26]. Засновником та головним ідеологом концепції вільного
програмного забезпечення GNU вважається видатний американський
програміст Річард Столмен.
Річард Столмен
(нар. 1953)
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 може не працювати. Так що, у
будь-якому разі, рішення за вами, обирайте самі між традиційними та новітніми
технологіями програмування.
54
відповідні лінгвістичні конструкції з використанням методів та засобів теорії
ООП, але й сформулювали головні філософські принципи, яких бажано
дотримуватись, працюючи із цією системою. Будь-який інтерпретатор мови
Python завжди має файл під назвою this, який містить в собі головні принципи,
за якими формується філософія програмування цієї мови. Вони прості, лаконічні,
трішки жартівливі, проте їх легко зрозуміти. Сформулюємо їх наприкінці цього
підрозділу та будемо намагатися дотримуватися їх під час написання програм на
Python. Щоб прочитати ці принципи англійською мовою, достатньо в
інтерпретаторі набрати просту команду: import this. Команда import
пов’язана із завантаженням бібліотек та модульним програмуванням [6, 7].
Основи роботи з інтерпретатором мови Python розглядатимуться у підрозділах
2.1 та 2.2, а основи роботи із бібліотечними файлами та модулями – у підрозділі
2.5.4. У таблиці 1.1 наведені ці шістнадцять головних філософських принципів
мови програмування Python, англійською мовою, в оригіналі, та в українському
перекладі [24, 25].
55
Таблиця 1.1 – Головні філософські принципи мови програмування Python,
записані авторами у файлі this.py (продовження)
56
Контрольні питання та завдання до розділу 1
58
програмування? Поясніть визначення 1.13.
26. Що являють собою мови програмування четвертого покоління? Які
мови програмування четвертого покоління Вам відомі?
27. Як головні принципи об’єктно-орієнтованого програмування можна
пояснити через формулювання питань та відповіді на них? Наведіть власні
приклади таких діалогів.
28. Поясніть приклад 1.1 та діаграму, яка наведена на рис. 1.1.
29. Як теорія об’єктно-орієнтованого програмування пов’язана із
класифікацією електронних приладів? Поясніть приклад 1.2 та діаграму, яка
наведена на рис. 1.2.
30. Наведіть приклади класифікації електронних приладів за іншими
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. Окрема увага приділяється операціям над рядками та
функціям, призначеним для роботи з ними. Як приклад написання
програмного модуля розглянуті конвертори фізичних та інформаційних
величин.
63
Рис. 2.1. Інтернет-сторінка для з інформацією про останні версії Python [33]
(екранна копія)
66
Рис. 2.5 Інтернет-сторінка для завантаження системи Miniconda [32] (екранна
копія)
67
встановлення цієї системи та для роботи з нею. Документація до пакету
Anaconda міститься на сайті [36].
Для тих програмістів, які не бажають встановлювати Anaconda,
альтернативним рішенням є використання разом із Python пакетів
розширення pip та virtualenv [25, 37, 38]. Прочитати досконале описання
можливостей цих пакетів та знайти відповідні інсталяції можна на сайтах [37,
38]. Вікна Інтернет-сторінок [37, 38] показані на рис. 2.6 та 2.7.
68
Рис. 2.7 Інтернет-сторінка [38], яку можна використовувати для встановлення
пакету розширення pip (екранна копія)
69
Рис. 2.8 Запуск інтерпретаторів Python із командним рядком та із оболонкою
редагування файлів через командне меню ОС Windows (екранна копія)
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 – –
83
2.4 Математична бібліотека Python та математичні функції
2.4.1 Бібліотека математичних функцій мови Python та доступ до неї
Як було вже відмічено, за останні роки Python, разом із системою
науково-технічних розрахунків MatLab, а також C, Java та іншими мовами
програмування, стає однією із самих популярних систем в академічному
середовищі. Крім системи Anacoda, створеної на базі IPython, можливості
якої у підрозділі 6.3 розглядатимуться окремо, у базовій версії Python також
розроблена потужна стандартна бібліотека математичних функцій math.
Прочитати описання цих функцій в Інтернет можна на сторінці [43].
Для підключення цих бібліотек до інтерпретатора достатньо ввести
команду import math, а потім посилатися на ці функції із зазначенням
імені бібліотеки перед іменем функції, при цьому імена бібліотеки та функції
розділяються точкою. Таке звернення до бібліотек у мові Python є
стандартним.
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
>>>
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.
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)
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 Гіперболічні та зворотні гіперболічні функції
x2-y2=1
S=arcsinh(x0)
x0 x
96
Враховуючи те, що функція x = sh ( y ) визначається співвідношенням
(2.5), для зворотної до неї функції y = Arsh( x ) можна записати наступне
співвідношення [6, 7, 45]:
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 Графіки гіперболічних (а) та зворотних гіперболічних (б) функцій
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
>>>
100
множення, ділення та піднесення до степені [6, 7, 45].
2. Функції обчислення дійсної частини комплексного числа z Re(z) та його
уявної частини Im(z) [6, 7, 45].
3. Функції обчислення модуля комплексного числа [6, 7, 45]:
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
5
104
мати більший об’єм стеку [5 – 7]. Тому програміст, під час написання
програми, може обирати, яку модель пам’яті, стекову чи прямого доступу
4
2
f(... (f ( f ( f (x) ) ) ) )
1
3
n разів
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.
108
пишеться текст програми, командні рядки та системні повідомлення про
помилки програмування.
3. Можливість більш ефективного аналізу програмного коду та його
відлагодження через отримання повідомлень про помилки у багатовіконному
режимі.
Хоча оболонка IDLE, призначена для роботи із мовою програмування
Python версії 3.4 під операційною системою Windows, є інтерпретатором, а не
компілятором, вона також має простий та зручний графічний інтерфейс. Цей
інтерфейс не перенасичений великою кількістю іконок та графічних
зображень, але має зручну та розвинену систему меню із ієрархією
командних вікон. Екранна копія головного вікна командного інтерпретатора
із верхнім рядком меню та великим робочим вікном для введення команд та
перегляду результатів їх виконання показана на рис. 2.13.
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, та кількість символів тексту, яка відповідає табуляції. Використання
символу табуляції під час написання програм не є обов’язковим, але значно
спрощує роботу із текстом програми.
111
вікном налаштування параметрів текстового вікна під вікном із кнопками на
вкладенці Highlighting показаний вигляд командного вікна з текстами різних
стилів. У разі зміни кольору відповідного тексту відразу змінюється вигляд
цього шаблона командного вікна.
112
– Python Definition – визначення мови Python, наприклад, визначення
типів даних або модулів.
– Python Comments – коментарі.
– Python Strings – рядкові змінні.
– Selected Text – виділений текст.
– Found Text – знайдений текст.
– Cursor – колір та фон для риски, яка показує положення курсору.
– Error Text – текст повідомлень про помилки.
Після обрання типу тексту, атрибути виведення якого необхідно
поміняти, змінюється надпис на кнопці із типом тексту. Тоді можна
натиснути на верхню кнопку «Choose Colours for:», що призводить до
виведення на екран стандартного вікна системи Windows із палітрою
кольорів, яке наведене на рис. 2.16. Для фіксації проведених змін необхідно
натиснути кнопки Apply та Ok у нижній частині вікна налаштування
властивостей.
113
Рис. 2.17 Вікно налаштування гарячих клавіш (екранна копія)
114
– No Prompt – не повідомляти користувача про збереження файлу.
Вікно інтерфейсу, яке відповідає вкладенці General, показане на рис. 2.18.
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.36
Ім’я об’єктної змінної Ім’я об’єктної Функція
змінної
def sqrt (x): id1 Функція користувача
sqrt (x)
math.sqrt (9) id3 Функція math.sqrt
Рис. 2.19 Опція меню Run оболонки редагування файлу IDLE (екранна копія)
137
доступні для інтерпретатора, взяти в лапки та перелічені через коми.
Наприклад, доступною є папка ‘C:\\Python34\\Lib\\’, туди і
збережемо створений файл під ім’ям module_1.py.
Існує інша можливість подивитися шляхи до папок, які читаються
інтерпретатором Python. Після запуску оболонки IDLE необхідно зайти до
опції командного меню File → Path Browser. У цьому разі всі шляхи до
доступних папок відображуються в інформаційному вікні, аналогічному
наведеному на рис. 2.20.
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 свідчить про те, що ця мова орієнтована саме на
створення професійних програмних комплексів.
146
Слід відзначити, що існують аналогові та цифрові термометри, на яких
значення температури позначені за двома шкалами – за Цельсієм та за Фаренгейтом.
Фотографії таких вимірювальних приладів показані на рис. 2.21 [47, 48].
а) б)
Рис. 2.21 Аналоговий (а) та цифровий (б) термометри, які показують
значення температури за шкалами Цельсія та Фаренгейта [47, 48]
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Н
міру тиску системну одиницю Паскаль, 1 Па = [50]. У разі, якщо тиск
2
1м
виражений в Паскалях, значно легше проводити складні фізичні та інженерні
розрахунки, оскільки відпадає потреба постійно переводити значення тиску з
однієї системи вимірювань до іншої. Такі розрахунки часто є вкрай необхідними
для розробки технології виробництва напівпровідникових приладів.
Взаємозв’язок між цими двома одиницями вимірювання тиску виражається
простим математичним співвідношенням:
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]
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]
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. Там же будуть розглянуті приклади створення віконних інтерфейсів для
розглянутих нами у цьому підрозділі конверторів фізичних величин.
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 існують
функції перетворення типів даних, які розглядатимуться у наступному підрозділі.
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].
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()
169
>>> print(str_out_2)
Студент Потапенко навчається Добре.
>>>
170
4. print() – інший метод для запису інформації до файлу.
який відкривається [24 – 29]. Цей параметр складається із двох літер, перша з
яких описує можливі операції із відкритим файлом, а друга – його тип.
Можливими операціями над файлом можуть бути наступні [24 – 29].
1. r – лише читання файлу.
не існує.
4. a – запис до файлу із дописуванням інформації у разі, якщо файл із
2. b – двійковий файл.
підряд, без символів розділення, у той час для функції print() може бути
попередньому підрозділі.
В цілому робота з файлами у мові програмування Python організується
наступним чином. Файл із заданим іменем відкривається з використання
функції open(), а атрибути для подальшої роботи з файлом задаються як
параметри виклику цієї функції через змінну mode. Після цього, в інших
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 існує велика кількість функцій,
об’єктами [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.
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: «Якщо
реалізацію складно пояснити, така ідея є поганою»; «Якщо реалізацію
легко пояснити, така ідея, можливо, є гарною».
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.
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. Розглянуті
також можливості використання циклів для роботи зі списками. Окремо
розглядаються два типа циклів – із заданою кількістю повторень та із
заданою умовою. Розглянуті приклади розв’язування задач дискретної
математики, обчислювальної математики та прикладної фізики з
використанням циклічних структур. Як приклади оригінальних засобів
програмування, яких не існує в інших мовах, розглянуті анонімні лямбда-
функції та функції генератора числових послідовностей.
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’>
>>>
На основі базових операцій порівняння формуються логічні вирази, які
розглядатимуться у наступному підрозділі.
200
називається будь-який вираз, який формується на основі логічних функцій та
операцій порівняння.
Таке визначення є вірним з точки зору дискретної математики, проте у
теорії предикатів та у сучасній теорії програмування логічні вирази зазвичай
розуміють значно ширше. Тому надамо інше визначення.
Визначення 3.3 Логічним виразом у широкому значенні цього слова
називається будь-яке висловлення, відносно якого можна однозначно сказати,
є воно істинним чи хибним.
Розглянемо взаємозв’язок між визначеннями 3.2 та 3.3 як властивість
логічних виразів.
Властивість 3.1 Логічний вираз у вузькому значенні слова завжди є
також логічним виразом у широкому значенні слова. Противне твердження є
неправильним.
Наприклад, логічний вираз 4<5 є логічним виразом у вузькому значенні
слова, тому він є логічним виразом також у широкому значенні слова.
Навпаки, вираз «Потапенко – студент» є логічним виразом у широкому
значенні слова, але його не можна вважати логічним виразом у вузькому
значенні слова, оскільки він не сформований із операцій порівняння.
Зрозуміло, що логічні вирази у вузькому значенні слова легко
аналізувати і завжди можна сказати, є вони істинними чи хибними. Цього не
можна сказати про логічні вирази у широкому значенні слова. Висловлення
«Потапенко – студент» легко перевірити, якщо прочитати списки студентів
факультету, а ось висловлення «Він студент» перевірити неможливо без
додаткової інформації щодо людини, про яку йде мова. Те ж саме можна
сказати про інші вирази, у яких не йдеться про конкретний об’єкт. Наприклад,
не можна вважати логічними виразами наступні висловлення: «Десь літає
птах» (невідомо де), «У неї карі очі» (невідомо у кого), «Це блакитні квіти»
(невідомо, що за квіти). Якщо надати додаткову інформацію, ці висловлення
можуть стати логічними виразами. Наприклад: «В саду над яблунею літає
птах», «У Наталки карі очі», «Незабудки – блакитні квіти».
Логічні вирази можна об’єднувати з використанням логічних операцій
201
алгебри Буля: and, or, xor та not. Якщо об’єднуються два логічних вирази,
значення яких відомо, можна легко знайти значення остаточного виразу. Для
цього використовуються відомі правила алгебри Буля, які у загальному
вигляді, для різних значень числових аргументів логічних функцій, зведені у
таблиці 3.1 [42].
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.
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
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, синтаксис якого більш досконало буде розглянутий у
наступному підрозділі.
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('Введене невірне значення \
електропровідності або електричного\
опору. Перевірте вхідні дані')
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
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, буде розглянутий інший спосіб введення та виведення інформації, з
використанням засобів віконного інтерфейсу.
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
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
>>>
однакові структури, у разі зміни однієї з них автоматично буде змінена інша.
Про це просте правило завжди слід пам’ятати під час роботи зі структурами.
приклад.
Приклад 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
>>>
підрозділі 3.2.
об’єкта-оригінала.
елементів об’єкта-оригінала.
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
>>>
236
Таблиця 3.5 – Функції обробки списків мови програмування Python
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.
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.
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.
Розглянемо у наступному підрозділі різні способи формування списків
з використанням оператора циклу.
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: «Має існувати один – і
бажано лише один – очевидний спосіб щось зробити, хоча спочатку він
для Вас може бути не очевидним, якщо Ви не голландець».
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.
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
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
Визначечння 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
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]. У наступному підрозділі
розглянемо можливості використання вкладених циклів для розв’язування
завдань квантової електроніки та оптоелектроніки.
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 = 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 відразу перераховується з метрів до нанометрів, що у
значній мірі спрощує аналіз розрахунків. Крім цього, у разі невірного
279
числові параметри, які необхідно знати для перерахунку значень відповідних
фізичних величин, наведені у практичному занятті 3 підрозділу 7.3.
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.
285
похідної, значно спрощується [63]. Взагалі метод Стеффенсона є методом
другого порядку збіжності, хоча він і не потребує використання похідної.
Замість взяття похідної у співвідношенні (3.10) використане обчислення
значення функції f ( xn + f ( xn )) .
Недоліком розглянутого модульного принципу побудови
обчислювального процесу є велика кількість модулів, що у значній мірі
утруднює аналіз програмного коду. Іншим, більш ефективним засобом
створення власних функцій користувача у мові програмування Python є
анонімні лямбда-функції, спосіб побудови та використання яких
розглядатиметься у підрозділі 3.7.8.
Для закріплення матеріалу, наведеного у цьому підрозділі, необхідно
виконати практичне заняття 6, наведене у розділі 7.
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
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
чи меншим
Рис. 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
>>>
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.
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 у значній мірі спрощує програмний код.
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
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'
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 реалізовані
механізми інкапсуляції та захисту приватних властивостей класів. Базові
поняття цих концепцій об’єктно-орієнтованого програмування були надані у
першому розділі посібника.
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.
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, проте
використання класів та об’єктів для розв’язування цього практичного
завдання прикладної електроніки має певні особливості.
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
Початок
7 ii = 0
Створення класу Metals з 12
2 полями metal, min_res та
max_res
8 Met = List_Metals(n)
Створення структури 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
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]. З
іншого боку, у всіх сучасних мовах програмування існують відповідні
програмні засоби, призначені для створення об’єктів та для роботи з ними.
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’
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.
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 з використанням діаграм Вейля
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’ Дифіренціальна
Різниця
різниця
359
Множини М1 та М2 для прикладу, який розглядається, наочно показані
на рис. 4.5 з використанням діаграми Вейля.
‘D’
‘B’‘A’ M2
M1
‘F’
360
Елемент ‘F’ належить до множини М2
Слід відзначити, що хоча множини та математичні операції над ними
не відіграють особливо важливої ролі у мові програмування Python,
розглянутий у цьому підрозділі теоретичний матеріал є необхідним для
кращого розуміння багатьох загальних положень дискретної математики,
зокрема теорії множин [42]. На практиці множини часто використовуються
для роботи зі списками та зі словниками. Поняття про словники та способи
роботи з ними будуть розглянуті у підрозділі 4.4.
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 розглядаються як одна з альтернатив використання
об’єктів.
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].
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__()
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.
373
інтерпретатора його елементи відображаються у вигляді такої структурованої
сукупності даних:
{Ключ_1: Значення_1, Ключ_2: Значення_2, ... \
Ключ_n: Значення_n}
Правило 4.40 Ключі у словниках, на відміну від значень, не можуть
бути зміненими.
На рис. 4.7 показана узагальнена структура словника у вигляді діаграми
Вейля із встановленими відношеннями між двома множинами [42].
Ключ 1 Значеня 1
Ключ 2 Значеня 2
Ключ n Значеня n
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].
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
Мельник І.В.
Київ
Національний технічний університет України
«Київський політехнічний інститут імені Ігоря Сікорського»
2019
Рекомендовано до друку
Методичною радою Національного технічного університету України „ Київський
політехнічний інститут імені Ігоря Сікорського”, протокол № ____ від
___ грудня 2019 р.
Рецензенти:
В.Т. Лазурік, доктор технічних наук, професор, декан факультету
математики та інформатики Харківського національного універ-
ситету ім. В.Н. Каразіна
С.С. Забара, доктор технічних наук, професор, завідуючий ка-
федрою інформаційних технологій та програмування Інституту
комп’ютерних технологій Відкритого міжнародного університету
розвитку людини „Україна”, лауреат Державної премії СРСР, ла-
уреат Державної премії України
Мельник І.В.
Основи програмування на мові Python. Комплексний навчальний
посібник з курсів «Об’єктно-орієнтоване програмування» та
«Обчислювальні системи та мережі» для студентів-бакалаврів
напряму підготовки 171 «Електронні пристрої та системи». Том 2.
Розвинені засоби мови програмування Python, призначені для
розв’язування складних інженерних та наукових завдань. – 515 с.
2
Розділ 5 Створення програм із віконними графічними
інтерфейсами
У цьому розділі розглядаються засоби мови програмування Python для
створення елементів графічного інтерфейсу користувача та їх
розташування на головному інтерфейсному вікні. Розглянута узагальнена
класифікація елементів інтерфейсу, а також способи їх створення та
визначення їхніх властивостей з використанням засобів програмування мови
Python. Як приклади програм із графічним інтерфейсом користувача
розглянуті прості лічильники кількості натиснень на кнопку, простий
калькулятор, калькулятор для проведення наукових розрахунків, конвертори
фізичних величин та програма для визначення типу матеріалу за його
електрофізичними властивостями. Розглянуті також способи розміщення в
інтерфейсному вікні графічних об’єктів.
4
тому відлагодження алгоритмів можна проводити і з використанням
консольного режиму роботи.
Блок-схема узагальненого алгоритму роботи консольної програми
наведена на рис. 5.1, а, а алгоритму роботи програми з віконним
інтерфейсом – на рис. 5.1, б [24].
Початок Початок 3
Відкриття вікна 4
Введення 1 графічного Є запит на
1 вхідних даних Ні
інтерфейсу 3 завершення 5
роботи?
Запуск циклу
2
2 Обробка даних обробки подій 5
Кінець
3
Виведення Є подія для Ні 4
3 результатів 2
обробки?
5 Обробка даних
Кінець 4
а) б)
Рис. 5.1 Узагальнені блок-схеми алгоритмів роботи програм із консольним
(а) та віконним (б) інтерфейсами
Корневе вікно
7
Для спрощення розуміння та вивчення, а також для спрощення
написання програмного коду, у теорії програмування об’єкти графічного
інтерфейсу поділені на відповідні класи, які будуть розглянуті у наступному
підрозділі.
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.
10
1. Бути розташованими на головному вікні, що необхідно відобразити в
комп’ютерній програмі через механізм наслідування.
2. У разі зміни тексту через його введення з клавіатури відповідні зміни
мають бути відображені у текстовому вікні через механізм обробки подій.
Розглянемо найпростіший приклад створення текстового вікна, у якому
зміна виведеного тексту не передбачається. Для створення вікна виведення
тексту будемо використовувати універсальний об’єкт Label, призначений
для виведення текстової та графічної інформації [24].
Приклад 5.2
# Підключення модуля, де розташовані об’єкти
# для роботи з віконним інтерфейсом
import tkinter
# Виклик функції створення головного вікна
window = tkinter.Tk()
# Виклик функції створення універсального
# елемента інтерфейсу для виведення тексової
# інформації
label=tkinter.Label(window, text = ‘Це тек\
ст для виведення у вікно’)
# Відображуємо створений об’єкт на головному
# вікні з використанням функції pack()
label.pack()
# Виклик функції циклічної обробки подій для
# головного вікна
window.mainloop()
Результат роботи цих командних рядків показаний на рис. 5.5.
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.
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 елементів інтерфейсу із
посиланням на фрейм
Кінець
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.
17
Початок
Створення посилання на
рядкову змінну з
1 викорисанням оператора
data = StringVar()
Кінець
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.
20
5.2.5 Розташування кнопок як елементів віконного інтерфейсу та
способи аналізу події натиснення на кнопку
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.
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.
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
після відображення другої (а) та третьої (б) кнопки
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.
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.
30
Слід відзначити, що більшість методів та властивостей, розглянутих у
цьому підрозділі для кнопок як елементів інтерфейсу, можуть бути
використані і для інших його елементів. Це пов’язано із властивістю
поліморфізму для об’єктів визначеного класу, яка була розглянута у
підрозділі 1.2 та описана визначенням 1.13. Дійсно, для елементів інтерфейсу
зазвичай важливими є лише зовнішні властивості, як-то розміри, колір,
положення тощо, а їх внутрішня структура описується окремо та для
загального завдання побудови віконного інтерфейсу вона часто не має
суттєвого значення [16].
Відповідні способи створення інших елементів віконного інтерфейсу
будуть розглянуті у підрозділі 5.2.6. У наступному підрозділі розглянемо
більш досконало методи аналізу події натиснення на кнопку, які тісно
пов’язані із теорією скінченних автоматів.
Подія натиснення на
кнопку Стан
Завершення роботи
вікна
32
Алгоритм обробки події натиснення на кнопку аналогічний
узагальненому алгоритму роботи віконного інтерфейсу, блок-схема якого
наведена на рис 5.1. Блок-схема алгоритму обробки події натиснення на
кнопку наведена на рис. 5.19.
Початок 5 6 3
Аналіз поточного 2
стану вікна з вико- 1
3 ристанням методу
get() 6
Є запит на Ні
завершення 1
4 роботи?
Кінець
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,
після натиснення кнопок «Друк» (а) та «Очистити» (б)
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().
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’.
Надалі ці способи описання подій будуть використовуватися для
написання відповідних програмних кодів, призначених для формування
віконного інтерфейсу.
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, у
разі встановленого (а) та не встановленого (б) прапорця
42
зміна здійснюється через аналіз значення змінної, яка описує властивість
об’єкту.
Блок-схема описаного узагальненого алгоритму створення та аналізу
властивостей об’єкту із вибором варіантів наведена на рис. 5.23.
3
Початок
Визначення мето-
4 да для аналізу ста-
Створення об’єкту
ну об’єкту
інтерфейсу для
1 здійснення
функції вибору
Читання значення
змінної, яка описує
5 поточний стан
Розташування
об’єкту
2 створеного
об’єкту
Кінець
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
Початок
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 повідомлення про те, який
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.
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
Початок Початок
Розташування Розташування
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():
label2.config(text = str_n)
window = Tk()
window.title('Тестування лінійки-повзунця')
ifscale.place(x = 0, y = 0)
sci.set(50)
59
sci.place(x = 150, y = 20)
str_n=StringVar()
command = fnscale)
window.mainloop
а)
б)
60
5.2.6.7 Формування інформаційного рядка про успішність студента
повідомлення.
він навчається, ДЕ-71 або ДЕ-72, через інше спливаюче меню списку – його
61
3. У функції f_r передбачений контроль написання слова «рік» у
оператора for.
фреймі if_out.
розташування pack().
на рис. 5.30, а – в.
62
а)
б)
в)
Рис. 5.30 Результат роботи програмного коду, наведеного у прикладі 5.19, у
разі формування звіту для різних студентів (а, б) та за умови натиснення
кнопки «Очищення» (в)
63
У прикладі 5.19 розглянута проста, але закінчена програма із різними
елементами віконного інтерфейсу, якими як текстове вікно, вікно
редагування тексту, список спливаючого меню та селекторна кнопка. Аналіз
значень, введених в цих елементах, будь то ручним способом або
автоматично, дозволяє формувати відповідну звітну документацію. Такий
спосіб обробки інформації є дуже простим та зручним, тому він часто
використовується для роботи з сучасними базами даних [12, 23].
Приклади створення інших елементів віконного інтерфейсу можна
знайти у підручниках та навчальних посібниках [24, 25, 70] та на сторінках
Інтернет [65]. У підрозділі 5.3.4 будуть розглянуті об’єкти віконного меню
для роботи з файлами на прикладі створення текстового редактора, а у
підрозділі 5.4 – особливості роботи з графічними об’єктами у віконному
інтерфейсі.
Приклади закінчених програм, написаних з використанням розглянутих
у цьому підрозділі елементів віконного інтерфейсу, розглядатимуться у
підрозділі 5.3.
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
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
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
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
програми?
Кінець
74
для секундоміра, а потім, у разі, якщо поточний час співпадає із заданим,
подається звуковий сигнал. Недолік такого способу обробки цих двох
одночасних подій полягає у тому, що виконуються вони послідовно. З точки
зору організації логіки роботи програми це означає, що під час подання
звукового сигналу рядок відображення часу у текстовому вікні тимчасово не
змінюється. Така послідовна обробка одночасних подій притаманна
більшості сучасних комп’ютерних систем, винятком є лише найсучасніші
системи паралельних обчислень [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.38 Спливаюче меню команди Файл (а) та вікно системи допомоги (б)
для програми, наведеної у прикладі 5.25
87
а)
б)
Рис. 5.39 Вікна відкриття (а) та збереження (б) файлу для програми,
наведеної у прикладі 5.25
88
5.3.5 Програми для простого та інженерного калькулятора
89
повідомлення виводиться у разі x > 10100 .
90
6. Операції з пам’яттю.
Операція збільшення та зменшення числа, занесеного до першого
вікна, на величину, задану у другому вікні, віднесемо для блоку
арифметичних операцій. Ці операції є вкрай важливими для проведення
ітераційних розрахунків
Залишається визначити операції з пам’яттю.
У теорії програмування існує два типи таких операцій: операції із
прямою та із посередньою адресацією. У разі прямої адресації адреси
комірок пам’яті вказуються в окремих регістрах. У моделі калькулятора,
який розробляється, цю операцію зручно робити з використанням списків-
лічильників.
Посередню адресацію для вікон калькулятора будемо проводити
наступним чином. У разі натиснення на кнопку М(В1) => М(В2) число, яке
знаходиться у вікні з номером, що вказаний у першому вікні, переноситься
до вікна з номером, який вказаний у другому вікні. Нумерацію вікон будемо
проводити наступним чином.
Вікно В1 – перший операнд, або крайнє ліве вікно у блоці проведення
обчислень.
Вікно В2 – другий операнд, середнє вікно у блоці проведення
обчислень.
Вікно В3 – результат обчислень.
Вікна 4 – 13 – додаткові вікна пам’яті, розташовані праворуч від блоку
проведення обчислень та функціональних кнопок калькулятора.
Наведемо приклад роботи із пам’яттю калькулятора. Припустимо, що,
для проведення подальших обчислень, необхідно перенести отриманий
результат до першого вікна. Тоді до першого вікна необхідно занести цифру
3, до другого – цифру 1, та натиснути кнопку М(В1) => М(В2). У теорії
програмування такий спосіб роботи з пам’яттю називається неявною
адресацією [1].
Кнопку М(В1) => М(В2) розташуємо у нижній частині вікна у блоці під
назвою «Блок операцій з пам’яттю».
Узагальнена схема запропонованого та описаного вище віконного
91
інтерфейсу калькулятора наведена на рис. 5.40.
Код програми для калькулятора з описаними вище функціональними
можливостями, написаний з використанням засобів мови програмування
Python, наведений у додатку Г.
Програма, яка наведена у додатку Г, містить велику кількість рядків та,
напевно, є найскладнішою для аналізу із програм, наведений у цьому посібнику.
Тому розглянемо її та проаналізуємо особливості її написання більш досконало.
Вікно 5
Блок арифметичних операцій
Вікно 6
Вікно 8
Блок степеневих, логарифмічної та
експоненціальної функції Вікно 9
Вікно 10
Блок тригонометричних функцій
Вікно 11
Вікно 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
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π), б – обчислення значення
112
Вельми цікавим є результат, показаний на рис. 5.44, е. Дійсно, якщо у
вікні текстового редактора вказане ім’я математичної функції без її
аргументу, обчислення не проводяться, а у вікно результату виводиться
інформація про цю функцію. Відповідні теоретичні відомості про
особливості роботи інтерпретатора мови Python у разі виникнення цієї
виключної ситуації були розглянуті у підрозділі 2.3. У будь-якому разі
зрозуміло, що оператор обробки виключних ситуацій try: except у коді
програми, наведеному у прикладі 5.27, працює правильно.
Порівнюючи модель простого калькулятора, розглянуту у підрозділі
5.3.5.1, та інженерного калькулятора, розглянуту у цьому підрозділі, можна
сказати, що вагомою перевагою простого калькулятора є наочність
проведення математичних операцій та операцій із пам’яттю та простота
проведення обчислень через натиснення відповідних кнопок. На відміну від
цього, розглянута модель інженерного калькулятора є простішою з точки
зору невеликої кількості функціональних кнопок, але для того, щоб
ефективно працювати з калькулятором такого типу, необхідно досконало
знати правила запису математичних виразів у мові програмування Python, які
були розглянуті у підрозділі 2.4. З іншого боку, код програми, призначеної
для реалізації моделі інженерного калькулятора та наведений у прикладі 5.27,
є значно коротшим та простішим.
114
Інтерфейсне вікно
Селекторна кнопка для обрання
фізичної величини, яка перетворюється
в) г)
д)
Рис. 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. Тому аналогічну структуру має програма, призначена для
визначення типу матеріалу за його електрофізичними властивостями, яка
буде розглянута у наступному підрозділі.
118
електропровідність або діелектрична проникність.
2. Вікно текстового редактора, в яке вводиться значення цієї
електрофізичної величини. Для зручності роботи з графічний віконним
інтерфейсом розташуємо це вікно безпосередньо під селекторною кнопкою.
3. Текстове вікно, у якому виводиться результат роботи програми. Це
може бути або визначений матеріал, або повідомлення про помилку введення
даних.
4. Під вікнами текстових редакторів розташуємо кнопки «Визначити»,
«Очистити» та «Вихід».
Загальна структура інтерфейсного вікна з описаними вище елементами
наведена на рис. 5.47. Код програми, призначеної для визначення типу
речовини за її електрофізичними параметрами, написаний мовою
програмування Python, наведений у додатку Е. Результати роботи цієї
програми у разі обрання різних електрофізичних параметрів, натиснення
кнопки «Очищення», а також у випадку введення помилкових даних,
представлені на рис. 5.48.
Інтерфейсне вікно
119
а) б)
в) г)
д) е)
121
значення не відповідає жодному матеріалу, змінній STF присвоюється
значення рядка «Введене неправильне значення».
В іншому код програми, наведений у додатку Е, є досить простим для
розуміння та не потребує зайвих додаткових пояснень.
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
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
130
Узагальнена класифікація графічних команд модуля tkinter та
відповідні параметри цих команд наведені у таблиці 5.1.
131
Таблиця 5.1 (продовження)
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
133
– для конвертора значення тиску – фотографію, наведену на
рис. 2.23, а, відповідному файлу надати ім’я press.gif;
на полотні нову.
Розглянемо послідовно командні рядки, які реалізують завдання,
поставлені в пунктах 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)
135
Результат роботи наведених вище командних рядків для конвертору
фізичних величин у разі внесення відповідних змін до коду програми,
наведеної у додатку Д, показаний на рис. 5.51.
а) б) в)
Рис. 5.51 Конвертор фізичних величин, програмний код якого наведений у
додатку Д, у разі розташування в нижній частині вікна відповідних
фотографій: а – конвертор значення температури, б – конвертор значення
тиску, в – конвертор значення підсилення
формат [70]:
Canvas.move(fig, deltaX, deltaY)
136
Команда Canvas.itemconfig() має формат:
Canvas.itemconfig(fig, [options])
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
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, призначені для видалення,
переміщення графічних об’єктів та зміни їхніх властивостей
142
вкладенки. Вкладки, разом із кнопками та текстовими вікнами, також є
одним із стандартних елементів віконних інтерфейсів, які дозволяють робити
вікна прикладних програм більш інформативними за рахунок підвищення
степені систематизації інформації, яка в них розташовується [16]. З точки
зору спрощення аналізу графічних залежностей велику кількість графіків
варто розташовувати на різних вкладенках [70].
Вікну із вкладенками в інтерпретаторі мови програмування Python
відповідає об’єкт Notebook, який розташований в модулі tkinter.ttk.
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.
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(), який
146
9. Через аналіз сукупності заданих дискретних точок D визначається
D xdif
kx = . (5.1)
Dx
D dif
y
ky = . (5.2)
Dy
( ) ( )
через точки з координатами 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 ,
148
7
Початок
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
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). Імена цих
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 за умови відомих
154
універсальним. Пошук масиву виключних точок, для яких неможливо
обчислити значення заданої функції f(x) згідно із областю її визначення, є
окремим завданням обчислювальної математики.
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
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 ) .
Uвх R
Uвих
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 + 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].
У наступному підрозділі розглянемо поняття масиву, способи описання
масивів та функції для роботи з ними. Із наведеного вище описання
зрозуміло, що це поняття взагалі є базовим для реалізації концепції
матричного програмування.
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 та будуть розглянуті у
наступному підрозділі. Окремо будуть розглянуті математичні функції,
призначені для реалізації елементарних матричних макрооперацій та
операцій лінійної алгебри.
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]
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. Значення елементів масиву обчислюються через їхні номери з
203
бібліотеки дозволяє використовувати ці функції для виконання матричних
макрооперацій над елементами масивів.
Розглянемо інші можливості використання функції векторізації
vectorize() [26, 70].
2. Векторізація функцій користувача.
Функція vectorize()може мати своїм аргументом не лише
математичні функції, але й визначені у програмі імена функцій користувача.
Розглянемо відповідний приклад, побудований на основі прикладу 6.24.
Приклад 6.25 З використанням матричної макрооперації обчислити
π π π
значення функції y(x) = sin2(x) + x для значень x = 0, x = , x= , x= ,
6 4 2
3π
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].
213
проводяться швидше. Однією з таких функцій є функція solve_banded(),
призначена для роботи із матрицями з переважно діагональними
елементами [26, 70]. Особливості роботи з такими функціями описані у
навчальних посібниках [26, 70].
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
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]
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.
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
Тип маркера:
українською П’яти- Шести-
Квадрат Коло Ромб / Хрест Зірка Плюс
мовою / кутник / кутник /
/ 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 пункти
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]
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.7 Графіки функцій y(t) = t (а), y(t) = 1 (б) та y(t) = 2cos(t) (в), побудовані
в полярних координатах з використанням функції polar(), розташованої в
бібліотеці matplotlib.pyplot системи програмування Anaconda [70]
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]
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.
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()
більш чітко відображує плавну зміну значень функції 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
240
Формат цієї команди має наступний вигляд.
plt.subplot_adjust(hspace = a, wspace = b)
а) б)
Рис. 6.12 Розбиття області розташування графіків на підобласті за
замовченням (а) та із визначенням параметрів ширини та довжини
підобластей для вирівнювання полів (б)
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.
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]
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]
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].
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]
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]
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()
258
Рис. 6.20 Результат роботи програмного коду, наведеного у прикладі 6.54 [70]
259
необхідно виводити її графік на заданому числовому інтервалі.
Почнемо розв’язування цього завдання з побудови проекту віконного
інтерфейсу. У верхній частині інтерфейсного вікна розташуємо три
текстових вікна для введення інформації, під ними – область виведення
графіка, а у нижній частині вікна – кнопку з надписом «Графік».
Узагальнений вигляд такого віконного інтерфейсу показаний на рис. 6.21.
Кнопка «Графік»
260
використані засоби програмування, розглянуті у підрозділі 5.2. Виведення
графіка в інтерфейсне вікно здійснюється з використанням розглянутого у
цьому підрозділі алгоритму, який дозволяє встановлювати взаємозв’язок між
об’єктами модулів matplotlib та tkinter. Код програми з віконним
261
6.1.4 Символьні обчислення в системі програмування Anaconda
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.
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].
278
Таблиця 6.6 – Головні функції системи програмування Anaconda,
призначені для аналітичного розв’язування алгебраїчних рівнянь та їх систем
Функція Призначення
Аналітичне розв’язування рівняння відносно заданої
solveset()
змінної. Результат розрахунків повертається як множина
Функція повертає значення коренів рівняння у символьній
формі у вигляді словника у форматі {корінь:
roots()
кратність}. У разі встановлення опції dict = False
словник автоматично перетворюється на список
Функція повертає значення коренів заданого рівняння, які
real_roots()
лежать в області дійсних чисел
Функція повертає значення коренів заданого
nroots() поліноміального рівняння із заданою кількістю значущих
цифр
Головна функція символьного процесору системи
solve() Anaconda для розв’язування алгебраїчних рівнянь та їх
систем
linsolve() Функція для розв’язування систем лінійних рівнянь
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 Аналітичні функції матричної алгебри
Функція Призначення
Matrix() Створення із списку матриці для символьних перетворень
det() Формування аналітичного виразу для визначника матриці
M.T Функція транспортування матриці
Формування аналітичного виразу для матриці, зворотної
inv()
до заданої
eigenvals() Обчислення власних чисел матриці [42]
eigenvects() Обчислення власних векторів матриці [42]
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].
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].
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
Функція Призначення
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 )
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]
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 – це обчислені значення
299
значень змінної i, для побудови таких залежностей необхідно транспортувати
вектор yi з вектора-стовпця до вектора-рядка. Крім цього, часто дослідників
цікавлять залежності y j ( yi ) за умови j > i, які у науковій літературі з
300
Результат роботи програмного коду, наведеного у прикладі 6.78,
показаний на рис. 6.24 [70].
Рис. 6.24 Результат роботи програмного коду, наведеного у прикладі 6.78 [70]
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]
d2y
dt 2
(
− ε 1 − y2 )dydt + ω2 y = 0, (6.16)
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
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]. Спочатку
необхідно запустити додаток сервера, а після цього, запущений пізніше
додаток клієнта, встановлює з ним зв’язок.
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.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, екранна
копія
332
Python, розглянуті в цьому посібнику. Наприклад, у додатках для роботи з
базами даних ефективно використовуються списки та словники, а у
програмному забезпеченні, призначеному для розв’язування складних
інженерних та наукових завдань матепматичного моделювання в
розподілених обчислювальних мережах, важливим є використання функцій
математичного блоку, розглянутих у підрозділі 2.4.
У будь-якому разі, під час створення мережного програмного
забезпечення головним принципом є простота та лаконічність повідомлень,
які передаються. У разі необхідності передавання через мережу великої
кількості інформації, наприклад графічної інформації або відеороликів,
зазвичай використовуються ефективні цифрові методи її стиснення [12 – 14].
Для закріплення теоретичного матеріалу, наведеного у цьому
підрозділі, необхідно виконати практичне заняття 11.
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].
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
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
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 )
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 )
в) ∫ x 4 cos( x )dx , x1= –2, x2= 3; г) ∫ exp( x ) cos( x )dx , x1= –1, x2 = 2;
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() та які параметри її
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. Головні принципи об’єктно-орієнтованого
програмування
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 Вам
відомі?
382
Таблиця 7.1 – Завдання №1 для практичного заняття №2 (продовження)
Значення
№ варіанта Функція
змінних
х = 1, 2, 3, 4, 5, 6, 7,
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.
383
розрахованого комплексного числа та кут нахилу між його вектора у радіанах та
градусах.
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 )
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 балів.
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 можуть бути ефективно
використані для створення конверторів різних величин?
389
2. Аналіз стандартів маркування.
3. Розбиття тексту, який характеризує марку приладу, на окремі
елементи, згідно із вимогами відповідних стандартів.
4. Аналіз елементів, отриманих в процесі розбиття.
5. Перевірка послідовностей символів, якій відповідає кожний з
елементів, на наявність відповідних послідовностей у стандарті, що
аналізується.
6. Якщо за пунктом 5 відповідність знайдена – формується відповідь,
яка характеризує, до якого класу, за відповідною категорією, згідно із
стандартом, належить даний прилад.
7. Якщо за пунктом 5 відповідність не знайдена – формується
повідомлення про помилку маркування.
8. Якщо помилок у маркуванні не знайдено – із сформованих
відповідей шляхом їх об’єднання формується повноцінне повідомлення про
властивості даного приладу за усіма категоріями, заданими у маркуванні.
Тобто, прилад розглядається як об’єкт, який за послідовностями
символів у маркуванні належить до відповідних класів.
Блок-схема алгоритму визначення типу приладу за його маркуванням
наведена на рис. 7.1.
390
Початок 6
Аналіз
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 помилку марки
приладу
Кінець
Кінець
391
Таблиця 7.3 – Цифрова система маркування транзисторів, розроблених до
1964 року
392
Ця літера або цифра є першим блоком маркування. Другий блок – це літера,
яка характеризує тип транзистора за фізичним принципом його роботи, Т –
біполярний або П – польовий.
Третій блок маркування – це послідовність із трьох цифр. Друга і третя
цифри характеризують номер розробки, а перша – робочий діапазон транзистора
за частотою та за потужністю. Тобто, саме перша цифра є найважливішою для
визначення класу приладу. Цифрова система кодування класів транзисторів,
прийнята згідно із новим стандартом, наведена у таблиці 7.5 [62].
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. Як у марці моделі транзисторів нового зразка позначається робоча
частота транзистора?
x1 x2 x3 x4 x
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
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)
за межі області
визначення функції
Кінець Кінець
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 – математичне сподівання
Початок 2
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 бали.
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. Як обчислюється похибка лінійної апроксимації?
f ( x)
f(x2)
1
2
x3 x4
f(x4) x1 x2 x
f(x3)
f(x1)
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 бали.
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
df ( x ) (b − a ) . 2
εпр = ⋅ (7.10)
dx max 2
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
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 бали.
411
давати негативний результат тестування і чому?
22. За якої умови програма, в який реалізований метод трапецій, завжди
дає позитивний результат тестування?
23. За якої умови програму, в який реалізований метод трапецій, можна
вважати надійною?
24. Як у програмі, в який реалізований метод трапецій, може бути
сформований простір імен?
25. Чи може бути використаний у програмі, в який реалізований метод
трапецій, апарат локальних та глобальних змінних мови програмування
Python?
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
2 x1 − x2 − x3 = 7;
x1 + x2 − 2 x3 = 2; (7.20)
x1 − x2 − 3 x3 = −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.
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].
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. Створення програмних засобів для подійного
моделювання фізичних процесів
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.
420
11. Які засоби імітаційного моделювання системи програмування
Anaconda Вам відомі? Наведіть власні приклади їхнього використання для
створення анімаційних ефектів.
12. Що являє собою функція FuncAnimation() системи
програмування Anaconda та як вона використовується для створення
анімаційних ефектів? Наведіть власні приклади такого використання цієї
функції.
13. Що являє собою функція ArtistAnimation() системи
програмування Anaconda та як вона використовується для створення
анімаційних ефектів? Наведіть власні приклади такого використання цієї
функції.
14. Як засоби комп’ютерної анімації можуть бути використані для
вивчення детермінованих та стохастичних фізичних ефектів? Наведіть власні
приклади такого використання засобів комп’ютерної анімації.
15. Сформулюйте математичну модель Вашої наукової дослідницької
роботи у вигляді імітаційної моделі та реалізуйте цю модель з використанням
засобів програмування системи Anaconda.
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
виклику?
6. У якій формі формується розв’язок диференціального рівняння
порядку n через виклик функції odeint()?
423
7.11 Заняття 11. Створення програмного забезпечення для
мережної обчислювальної системи
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}.
е) 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}.
ж) 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 )
з) 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
( )
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
( )
( )
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
ac cos exp
(dx 2 ) + bd sin c ln(bx 2 )
л) f1 ( x ) =
d cos(a + exp(cx ))
,
2 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. Яке, серверне чи клієнтське програмне забезпечення, сьогодні часто
пишеться зі зручним графічним інтерфейсом користувача?
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
430
3. Як функції мови програмування Python, призначені для
програмування мікроконтролерів, пов’язані із теорією подійного
моделювання та із методами обробки подій?
4. Як функції мови програмування Python, призначені для
програмування мікроконтролерів, пов’язані із теорією скінченних автоматів?
5. Функції яких модулів інтерпретатора мови Python головним чином
використовуються для програмування мікроконтролерів?
6. Як для програмування мікроконтролерів використовуються функції
визначення системного часу?
7. Чому завдання програмування мікроконтролерів зазвичай неможливо
виконати лише з використанням засобів мови програмування Python?
8. Які ще мови програмування обов’язково необхідно використовувати
для комплексного розв’язування завдань програмування мікроконтролерів та
в якій частині системи комп’ютер – мікроконтролер розташовується
програмне забезпечення, написане на цих мовах програмування?
9. Яке апаратне забезпечення та електронна апаратура є необхідними
для розв’язування завдань програмування мікроконтролерів?
10. Як алгоритми програмування мікроконтролерів пов’язані з теорією
чисел та дискретною математикою?
11. Як алгоритми програмування мікроконтролерів пов’язані з теорією
подійного моделювання?
12. Як алгоритми програмування мікроконтролерів пов’язані із теорією
скінченних автоматів?
431
8. Загальний перелік питань та завдань для самоконтролю знань
434
7. Виконати практичні заняття 9 – 12.
8. Здати реферат та виступити за темою реферату на семінарському
занятті. Реферат подається студентом на перевірку викладачеві та викладач
виставляє за нього попередню оцінку. Після обговорення з викладачем
результатів перевірки реферату студент виступає за обраною темою на
семінарському занятті. Максимальна оцінка за рейтинговою системою за
зданий реферат – 5 балів, за виступ на семінарському занятті студент
отримує 10 балів.
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
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