Вы находитесь на странице: 1из 41

Факультет Информационных технологий

Кафедра Кафедра информационных систем

Направление подготовки/Специальность Прикладная информатика

КУРСОВАЯ РАБОТА

по дисциплине Высокоуровневые методы программирования

Студента Бутова Сергей Михайловича


(фамилия, имя, отчество)

на тему: Разработка программного продукта для решения прикладных задач


(тема работы)

Руководитель работы к.т.н., Блощук Андрей Алексеевич


(ученая степень, звание, инициалы и фамилия)

г.Москва 2021 г.
2

Оглавление

Введение 3

1. Анализ заданий курсовой работы 3

1.1 Исходные данные к заданиям курсовой работы 4


2. Разработка программного продукта для решения прикладных задач 7

2.1 Работа с наборами данных 7

2.1.1 Исходный код 9

2.2. Разработка экспертной системы 10

2.2.1. Исходный код 14

2.3. Разработка аналитической системы 17

2.3.1. Исходный код 23

2.4. Разработка логико-аналитической системы 31

2.4.1 Исходный код 36


Выводы 38

Список литературы 39
3

Введение
1. Анализ заданий курсовой работы
Чтобы выполнить данные задания, студент использует среду разработки –
Jetbrains PyCharm Community Edition. Чтобы разрабатывать интерфейс - PySide
6
Таким образом задания подобраны для того, чтобы студент мог приобрести
практические навыки для разработки программных продуктов и решения
прикладных задач.
Приблизительный срок написания кода и решения составил около 9 дней и
время для определения какие методы применять в том или ином случае.
4

1.1 Исходные данные к заданиям

курсовой работы
Первое задание – текстовый файл, заранее написанный преподавателем;
Слова должны быть отсортированы по убыванию их количества появления в
тексте, а при одинаковой частоте появления — в лексикографическом
порядке; Вывод должен осуществляться в текстовый файл result_1.txt
Второе задание – первый клиент банка; Количество команд, которые может
ввести пользователь за один раз – не более 20; ID с фамилией владельца
счёта; Команды вводятся пользователем только большими буквами. Сама
команда, имя клиента, суммы (числа) разделяются пробелами; Вывод должен
осуществляться в текстовый файл result_2.txt.
Третье задание - исходными данными является необходимый нам
функционал калькулятора
Стандартный функционал
1. Арифметические действия + - * /.
2. Возможность ввода отрицательного числа
3. Возведение в степень.
4. Извлечение квадратного корня.
5. Работа с памятью, состоящей из одной ячейки.
6. Должна быть кнопка сброса и кнопка «=» (равно).
Расширенный функционал
1. Наличие кнопки/меню перехода в расширенный режим
2. Возможность работы с несколькими ячейками памяти. Количество
ячеек памяти выбирается согласно методическим указаниям.
3. Отображение последовательности математических операций и цифр
в n-строчном «дисплее», с возможностью «прокрутки». Количество
строк «дисплея» калькулятора выбирается согласно методическим
5

указаниям.
4. Реализация «инженерных» функций расширенного режима.
Конкретный перечень функций выбирается согласно методическим
указаниям.
Программа должна быть сохранена под именем exercise_3.py

Четвертое задание - имеет следующие исходные данные:


Существует 8 шпинделей, пронумерованных от 8 до 1 слева направо. На
каждом шпинделе надеты диски, в количестве, равном соответствующей
цифре из ID студента. Все диски имеют разные диаметры. Диаметр диска
равен M * 10 + N, где М – номер шпинделя, на котором надет диск, а N – это
номер диска на шпинделе, считая сверху вниз. Диски на шпинделе имеют
случайный цвет.
Программа должна быть сохранена под именем exercise_4.py
6

1.3 Выбор и обоснование необходимых


библиотек и среды разработки
Интегрированной средой разработки была выбрана программа – PyCharm,
потому что она используется в учебном процессе.
Графический фреймворк использован Qt 6, и его официальная привязка к
Python – PySide 6, которая является аналогом PyQt.
7

2. Разработка программного продукта


для решения прикладных задач
2.1 Работа с наборами данных
Входные данные – текстовый файл resourse_1.txt в котором написано 5-6
абзацев слов.
Выходные данные – список слов, отсортированных по частоте встречаемости
и алфавиту
Для начала откроем файл с входными данными. Указываем кодировку utf-8
вместо windows-1251 используемой по умолчанию
with open('resource_1.txt', 'r', encoding='utf8') as f:
file = f.read()

Помешаем каждое слово в отдельный элемент списка

word_list = file.split()

Используем цикл для каждого уникального слова, помещая его в пустой


список вместе с количеством появления их в тексте

word_count = []
for i in list(dict.fromkeys(word_list)):
word_count.append((word_list.count(i), i))

Благодаря лямбда функции, возвращаем отрицательное число появления


слов в тексте, для правильной сортировки по алфавиту

word_count = sorted(word_count, key=lambda x: (-x[0],


x[1]))
8

Выводим список на экран c помощью f-строк

with open('result_1.txt', 'w', encoding='utf8') as f:


for i in word_count:
out = f'{i[1]} {i[0]}'
print(out)
f.write(out + '\n')

Без лямбда функции: Правильный вариант:


damme 4 damme 4
van 3 is 3
name 3 name 3
is 3 van 3
my 2 bond 2
hi 2 claude 2
claude 2 hi 2
bond 2 my 2
your 1 james 1
what 1 jean 1
jean 1 what 1
james 1 your 1

Задание по работе с данными выполнено.


9

2.1.1 Исходный код


exercise_1.py

with open('resource_1.txt', 'r', encoding='utf8') as f:


file = f.read()

word_list = file.split()
# Список для выходных данных
word_count = []
for i in list(dict.fromkeys(word_list)):
word_count.append((word_list.count(i), i))

# Сортировка с ключём на лямбда-функцию


word_count = sorted(word_count, key=lambda x: (-x[0], x[1]))
# word_count.sort(reverse=True) Неверный вариант сортировки

# Вывод списка в удобном формате


with open('result_1.txt', 'w', encoding='utf8') as f:
for i in word_count:
out = f'{i[1]} {i[0]}'
print(out)
f.write(out + '\n')
10

2.2. Разработка экспертной системы


Начнем с внедрения системы управления счетами клиентов,
поддерживающую следующие операции:
1. (DEPOSIT name sum) Пополнение счета клиента.
2. (WITHDRAW name sum) Снятие денег со счета.
3. (BALANCE name) Запрос остатка средств на счете.
4. (TRANSFER name1 name2 sum) Перевод денег между счетами
клиентов.
5. (INCOME p) Начисление процентов всем клиентам.
В скрипте будет два текстовых поля, поле слева для ввода команд и поле
справа для вывода результата. Текстовые команды выполняются только после
нажатия кнопки Calculate и присутствует кнопка Clear для очистки полей.

Для начала нам нужно импортировать нужные библиотеки. Я выбрал


графический фреймворк PySide 6, потому что он является аналогом PyQt, но
сделан официальными разработчиками Qt
import sys

from PySide6 import QtUiTools, QtCore


from PySide6.QtWidgets import QMainWindow, QApplication

Используем клиента со моей фамилией, как указано в методических


указаниях
clients = {
'Butov': 46584
}
Моя программа будет использовать принципы объектно-ориентированное
программирования, поэтому обязательно необходимо создать класс
основного графического окна унаследованного от QMainWindow
class MainWindow(QMainWindow):
11

Функция загрузки интерфейса из ui файл


def load_ui_widget(self, ui_filename, parent=None):
loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_filename)
ui_file.open(QtCore.QFile.ReadOnly)
ui = loader.load(ui_file, parent)
ui_file.close()
return ui

Вводим конструктор класса, в котором будет показан интерфейс и подключает


действие к кнопкам

def __init__(self):
super(MainWindow, self).__init__()
self.ui = self.load_ui_widget("exercise_2.ui")

self.ui.pushButton_calculate.clicked.connect(self.calcul
ate)

self.ui.pushButton_clear.clicked.connect(self.clear)

self.ui.show()
sys.exit(app.exec_())

Используем обязательные функции из описания к заданию которые


выполняют определенные математические вычисления

def check_client(self, name):


if name not in clients:
clients[name] = 0

def deposit(self, name, money):


money = int(money)
self.check_client(name)
clients[name] += money

def withdraw(self, name, money):


money = int(money)
self.deposit(name, -1 * money)

def balance(self, name):


if self.check_client(name):
12

self.print_text(clients[name])
else:
self.print_text("NO CLIENT")

def transfer(self, name1, name2, money):


money = int(money)
self.withdraw(name1, money)
self.deposit(name2, money)

def income(self, percent):


p = int(percent)
for i in clients:
if clients[i] > 0:
clients[i] += int(clients[i] * p / 100)

def print_text(self, text):


text = str(text)
print(text)
self.ui.textEdit_output.append(text)

def clear(self):
self.ui.textEdit_input.clear()
self.ui.textEdit_output.clear()

Я воспользовался функцией eval которая исполняет функции, введенные из


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

def calculate(self):
commands =
self.ui.textEdit_input.toPlainText().splitlines()
for i in commands:
if i:
command = i.split(' ', 1)[0].lower()
args = i.split(' ', 1)[1].replace(' ',
'","')
eval(f'self.{command}("{args}")', {"self":
self})
13
14

Для того, чтобы программа не запускалась при импортировании в модуле,


используем конструкцию сравнения - это правила хорошего тона. Делаем
приложение и свежее окно из написанного выше класса.
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())

Скриншот 1, Примеры всех команд

Необходимое задание систем управления счетов выполнено.


15

2.2.1. Исходный код


exercise_2.py

import sys

# Импорт библиотеки PySide6, официальной привязки Qt для Python, аналог PyQt


from PySide6 import QtUiTools, QtCore
from PySide6.QtWidgets import QMainWindow, QApplication

# Данные задания
clients = {
'Antonyan': 70154003
}

class MainWindow(QMainWindow):
# Функция загрузки интерфейса из ui файла
def load_ui_widget(self, ui_filename, parent=None):
loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_filename)
ui_file.open(QtCore.QFile.ReadOnly)
ui = loader.load(ui_file, parent)
ui_file.close()
return ui

def __init__(self):
super(MainWindow, self).__init__()
self.ui = self.load_ui_widget("exercise_2.ui")

# Подключение действий к кнопкам


self.ui.pushButton_calculate.clicked.connect(self.calculate)
self.ui.pushButton_clear.clicked.connect(self.clear)

self.ui.show()
sys.exit(app.exec_())

def deposit(self, name, money):


money = int(money)
if name not in clients:
clients[name] = 0
clients[name] += money

def withdraw(self, name, money):


money = int(money)
self.deposit(name, -1 * money)

def balance(self, name=None):


if name == None:
text = ""
for i in clients:
text += f'{i} {clients[i]}\n'
self.print_text(text[:-2])
elif name in clients:
self.print_text(clients[name])
else:
self.print_text("NO CLIENT")

def transfer(self, name1, name2, money):


money = int(money)
self.withdraw(name1, money)
self.deposit(name2, money)
16

def income(self, percent):


p = int(percent)
for i in clients:
if clients[i] > 0:
clients[i] += int(clients[i] * p / 100)

def print_text(self, text):


text = str(text)
print(text)
self.ui.textEdit_output.append(text)

def clear(self):
self.ui.textEdit_input.clear()
self.ui.textEdit_output.clear()

def calculate(self):
commands = self.ui.textEdit_input.toPlainText().splitlines()
for i in commands:
if i:
# Преобразованеи строк в нижний регистр и замена пробелов
скобками
split = i.split(' ', 1)
command = split[0].lower()
if len(split) > 1:
args = split[1].replace(' ', '","')
eval(f'self.{command}("{args}")', {"self": self})
else:
eval(f'self.{command}()', {"self": self})

if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
17

exercise_2.ui

<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"><class>MainWindow</class><widget


class="QMainWindow" name="MainWindow"><property
name="geometry"><rect><x>0</x><y>0</y><width>576</width><height>335</height></rect></property><pro
perty name="windowTitle"><string>Банковская система</string></property><widget class="QWidget"
name="centralwidget"><layout class="QHBoxLayout" name="horizontalLayout_3"><item><layout
class="QVBoxLayout" name="verticalLayoutLeft"><item><widget class="QLabel"
name="label_left"><property name="text"><string>Ввод
команд</string></property></widget></item><item><widget class="QTextEdit"
name="textEdit_input"/></item><item><widget class="QPushButton"
name="pushButton_calculate"><property
name="text"><string>Calculate</string></property></widget></item></layout></item><item><layout
class="QVBoxLayout" name="verticalLayoutRight"><item><widget class="QLabel"
name="label_right"><property
name="text"><string>Вывод</string></property></widget></item><item><widget class="QTextEdit"
name="textEdit_output"/></item><item><widget class="QPushButton" name="pushButton_clear"><property
name="text"><string>Clear</string></property></widget></item></layout></item></layout></widget></w
idget><resources/><connections/></ui>
18

2.3. Разработка аналитической системы


Необходимо написать калькулятор со стандартными и расширенными
функциями.
Стандартный функционал:
1. Арифметические действия + - * /.
2. Работа с памятью, состоящей из одной ячейки.
3. Возможность ввода отрицательного числа
4. Должна быть кнопка сброса и кнопка «=» (равно).
5. Возведение в степень.
6. Извлечение квадратного корня.
Расширенный функционал:
1. Наличие кнопки/меню перехода в расширенный режим
2. Возможность работы с несколькими ячейками памяти. Количество
ячеек памяти выбирается согласно методическим указаниям.
3. Отображение последовательности математических операций и
цифр в n-строчном «дисплее», с возможностью «прокрутки». Количество
строк «дисплея» калькулятора выбирается согласно методическим указаниям.
4. Реализация «инженерных» функций расширенного режима.
Конкретный перечень функций выбирается согласно методическим
указаниям.

Импортируем необходимые библиотеки


import math
import sys

from PySide6 import QtUiTools, QtCore


from PySide6.QtWidgets import QMainWindow, QApplication
19

Создаём класс, который будет хранить историю операций и значение


калькулятора по умолчанию
class DataStorage:
history = []
history_str = ""
current = ""
result = ""

Содержит функции используемые в обоих режимах работы - основной класс в


обычном и продвинутом режимах
class SetupWindow(QMainWindow):
def load_ui_widget(self, ui_filename, parent=None):
def init_buttons(self):
def update_history_str(self):
def clear_results(self):
def equals(self):
def evaluate(self):
def write_number(self, symbol):
def sum(self):
def sqrt(self):
def sin(self):
def tan(self):
def exp(self):
def fact(self):
def frac(self):
def sign(self):

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


которые отличаются от расширенного режима
class MainWindow(SetupWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = self.load_ui_widget("exercise_3.ui")
self.init_buttons()

def back(self):
DataStorage.current = DataStorage.current[:-1]

self.ui.textEdit_Result.setText(DataStorage.current)

def write(self, action, result="Nothing"):


20

DataStorage.history.append(DataStorage.current)
DataStorage.history.append(action)
if result != "Nothing":
DataStorage.history.append(result)
self.ui.textEdit_Result.setText(str(result))
else:
self.ui.textEdit_Result.setText(action)
self.update_history_str()
DataStorage.current = ""

def write_current(self):

self.ui.textEdit_Result.setText(DataStorage.current)

Расширенный режим, содержащий дополнительные


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

class AdvWindow(SetupWindow):
def __init__(self):
super(AdvWindow, self).__init__()
self.ui =
self.load_ui_widget("exercise_3_adv.ui")
self.init_buttons()
self.ui.pushButton_Pi.clicked.connect(lambda:
self.write_number(3.1415))
self.ui.pushButton_Sin.clicked.connect(self.sin)
self.ui.pushButton_Tan.clicked.connect(self.tan)

self.ui.pushButton_Nexp.clicked.connect(self.exp)

self.ui.pushButton_Fact.clicked.connect(self.fact)

self.ui.pushButton_Frac.clicked.connect(self.frac)

# Создание списка с 4 кнопками памяти


self.memory = [None] * 4

for i in range(1, 4):

eval(f"self.ui.pushButton_MS_{i}.clicked.connect(lambda:
self.memory_save({i}))", {"self": self})

eval(f"self.ui.pushButton_MR_{i}.clicked.connect(lambda:
21

self.memory_read({i}))", {"self": self})

eval(f"self.ui.pushButton_MC_{i}.clicked.connect(lambda:
self.memory_clear({i}))", {"self": self})

eval(f"self.ui.pushButton_MP_{i}.clicked.connect(lambda:
self.memory_plus({i}))", {"self": self})

eval(f"self.ui.pushButton_MM_{i}.clicked.connect(lambda:
self.memory_minus({i}))", {"self": self})

def write_current(self):

self.ui.textEdit_Result.setText(DataStorage.history_str
+ DataStorage.current)

def back(self):
DataStorage.current = DataStorage.current[:-1]
self.write_current()

def memory_save(self, i):


if self.evaluate():
self.memory[i] = DataStorage.result

def memory_read(self, i):


self.write_number(self.memory[i])

def memory_clear(self, i):


self.memory[i] = ""

def memory_plus(self, i):


self.memory[i] += int(DataStorage.current)

def memory_minus(self, i):


self.memory[i] -= int(DataStorage.current)

def write(self, action, result="False"):


DataStorage.history.append(DataStorage.current)
DataStorage.history.append(action)
if result != "False":
DataStorage.history.append(result)
self.update_history_str()
DataStorage.current = ""

self.ui.textEdit_Result.setText(DataStorage.history_str)

Класс, который реализует запуск окна и переключение между режимами,


22

управляет показом окна

class Controller:
def __init__(self):
self.window = MainWindow()
self.window_adv = AdvWindow()

def start_app(self):

self.window.ui.pushButton_Extend.clicked.connect(self.sh
ow_adv)
self.window.ui.show()

def show_main(self):
self.window_adv.ui.close()

self.window.ui.pushButton_Extend.clicked.connect(self.sh
ow_adv)

self.window.ui.textEdit_Result.setText(DataStorage.curre
nt)
self.window.ui.show()

def show_adv(self):
self.window.ui.close()

self.window_adv.ui.pushButton_Extend.clicked.connect(sel
f.show_main)

self.window_adv.ui.textEdit_Result.setText(DataStorage.h
istory_str + DataStorage.current)
self.window_adv.ui.show()
23

Скриншот 2, Обычный режим

Скриншот 3, Расширенный режим


24

2.3.1. Исходный код


exercise_3.py

import math
import sys

from PySide6 import QtUiTools, QtCore


from PySide6.QtWidgets import QMainWindow, QApplication

class DataStorage:
history = []
history_str = ""
current = ""
result = ""

class SetupWindow(QMainWindow):
# Функция загрузки интерфейса из ui файла
def load_ui_widget(self, ui_filename, parent=None):
loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_filename)
ui_file.open(QtCore.QFile.ReadOnly)
ui = loader.load(ui_file, parent)
ui_file.close()
return ui

# Функия по подключению действий к кнопкам


def init_buttons(self):
# Создание списка с 4 кнопками памяти
self.memory = [None] * 4
self.ui.pushButton_MS_1.clicked.connect(lambda: self.memory_save(1))
self.ui.pushButton_MR_1.clicked.connect(lambda: self.memory_read(1))
self.ui.pushButton_MC_1.clicked.connect(lambda: self.memory_clear(1))
self.ui.pushButton_MP_1.clicked.connect(lambda: self.memory_plus(1))
self.ui.pushButton_MM_1.clicked.connect(lambda: self.memory_minus(1))

self.ui.pushButton_Zero.clicked.connect(lambda: self.write_number(0))
self.ui.pushButton_One.clicked.connect(lambda: self.write_number(1))
self.ui.pushButton_Two.clicked.connect(lambda: self.write_number(2))
self.ui.pushButton_Three.clicked.connect(lambda: self.write_number(3))
self.ui.pushButton_Four.clicked.connect(lambda: self.write_number(4))
self.ui.pushButton_Five.clicked.connect(lambda: self.write_number(5))
self.ui.pushButton_Six.clicked.connect(lambda: self.write_number(6))
self.ui.pushButton_Seven.clicked.connect(lambda: self.write_number(7))
self.ui.pushButton_Eight.clicked.connect(lambda: self.write_number(8))
self.ui.pushButton_Nine.clicked.connect(lambda: self.write_number(9))

self.ui.pushButton_Plus.clicked.connect(lambda: self.write_number("+"))
self.ui.pushButton_Minus.clicked.connect(lambda: self.write_number("-"))
self.ui.pushButton_Divide.clicked.connect(lambda: self.write_number("/"))
self.ui.pushButton_Multiply.clicked.connect(lambda: self.write_number("*"))
self.ui.pushButton_Dot.clicked.connect(lambda: self.write_number("."))
self.ui.pushButton_Exp.clicked.connect(lambda: self.write_number("**"))

self.ui.pushButton_Back.clicked.connect(self.back)
self.ui.pushButton_Clear.clicked.connect(self.clear_results)
self.ui.pushButton_Sum.clicked.connect(self.sum)
self.ui.pushButton_Equals.clicked.connect(self.equals)
self.ui.pushButton_Sqrt.clicked.connect(self.sqrt)
self.ui.pushButton_Sign.clicked.connect(self.sign)

def update_history_str(self):
if len(DataStorage.history) > 2:
for i in range(len(DataStorage.history) - 2):
DataStorage.history.pop(0)
log = ""
for i in DataStorage.history:
log += str(i) + "\n"
DataStorage.history_str = log

def clear_results(self):
self.write("C")

def equals(self):
if self.evaluate():
self.write("=", DataStorage.result)

def evaluate(self):
if DataStorage.current != "":
try:
DataStorage.result = eval(DataStorage.current)
return True
except:
self.write("Неверное действие")
return False

# self.write(result)

def write_number(self, symbol):


symbol = str(symbol)
DataStorage.current += symbol
self.write_current()

def sum(self):
if self.evaluate():
r = 0
n = DataStorage.result
25
while n:
r, n = r + n % 10, n // 10
self.write("<>", r)

def sqrt(self):
if self.evaluate():
self.write("√", math.sqrt(DataStorage.result))

def sin(self):
if self.evaluate():
self.write("Sin", math.sin(DataStorage.result))

def tan(self):
if self.evaluate():
self.write("Tan", math.tan(DataStorage.result))

def exp(self):
if self.evaluate():
self.write("Exp", math.exp(DataStorage.result))

def fact(self):
if self.evaluate():
self.write("n!", math.factorial(DataStorage.result))

def frac(self):
if self.evaluate():
f = float(DataStorage.result) - int(DataStorage.result)
self.write("Frac", f)

def sign(self):
try:
number = DataStorage.current
if "." in number:
DataStorage.current = str(float(number) * -1)
else:
DataStorage.current = str(int(number) * -1)
self.write_number("")
except:
pass

def memory_save(self, i):


if self.evaluate():
self.memory[i] = DataStorage.result

def memory_read(self, i):


if self.memory[i] != None:
self.write_number(self.memory[i])

def memory_clear(self, i):


self.memory[i] = ""

def memory_plus(self, i):


self.memory[i] += int(DataStorage.current)

def memory_minus(self, i):


self.memory[i] -= int(DataStorage.current)

class MainWindow(SetupWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = self.load_ui_widget("exercise_3.ui")
self.init_buttons()

def back(self):
DataStorage.current = DataStorage.current[:-1]
self.ui.textEdit_Result.setText(DataStorage.current)

def write(self, action, result="Nothing"):


DataStorage.history.append(DataStorage.current)
DataStorage.history.append(action)
if result != "Nothing":
DataStorage.history.append(result)
self.ui.textEdit_Result.setText(str(result))
else:
self.ui.textEdit_Result.setText(action)
self.update_history_str()
DataStorage.current = ""

def write_current(self):
self.ui.textEdit_Result.setText(DataStorage.current)

class AdvWindow(SetupWindow):
def __init__(self):
super(AdvWindow, self).__init__()
self.ui = self.load_ui_widget("exercise_3_adv.ui")
self.init_buttons()
self.ui.pushButton_Pi.clicked.connect(lambda: self.write_number(3.1415))
self.ui.pushButton_Sin.clicked.connect(self.sin)
self.ui.pushButton_Tan.clicked.connect(self.tan)
self.ui.pushButton_Nexp.clicked.connect(self.exp)
self.ui.pushButton_Fact.clicked.connect(self.fact)
self.ui.pushButton_Frac.clicked.connect(self.frac)

for i in range(2, 4):


eval(f"self.ui.pushButton_MS_{i}.clicked.connect(lambda: self.memory_save({i}))", {"self": self})
eval(f"self.ui.pushButton_MR_{i}.clicked.connect(lambda: self.memory_read({i}))", {"self": self})
eval(f"self.ui.pushButton_MC_{i}.clicked.connect(lambda: self.memory_clear({i}))", {"self": self})
eval(f"self.ui.pushButton_MP_{i}.clicked.connect(lambda: self.memory_plus({i}))", {"self": self})
eval(f"self.ui.pushButton_MM_{i}.clicked.connect(lambda: self.memory_minus({i}))", {"self": self})

def write_current(self):
self.ui.textEdit_Result.setText(DataStorage.history_str + DataStorage.current)

def back(self):
DataStorage.current = DataStorage.current[:-1]
self.write_current()

def write(self, action, result="False"):


DataStorage.history.append(DataStorage.current)
26
DataStorage.history.append(action)
if result != "False":
DataStorage.history.append(result)
self.update_history_str()
DataStorage.current = ""
self.ui.textEdit_Result.setText(DataStorage.history_str)

class Controller:
def __init__(self):
self.window = MainWindow()
self.window_adv = AdvWindow()

def start_app(self):
self.window.ui.pushButton_Extend.clicked.connect(self.show_adv)
self.window.ui.show()
# self.window_adv.ui.pushButton_Extend.clicked.connect(self.show_main)
# self.window_adv.ui.show()

def show_main(self):
self.window_adv.ui.close()
self.window.ui.pushButton_Extend.clicked.connect(self.show_adv)
self.window.ui.textEdit_Result.setText(DataStorage.current)
self.window.ui.show()

def show_adv(self):
self.window.ui.close()
self.window_adv.ui.pushButton_Extend.clicked.connect(self.show_main)
self.window_adv.ui.textEdit_Result.setText(DataStorage.history_str + DataStorage.current)
self.window_adv.ui.show()

if __name__ == "__main__":
app = QApplication(sys.argv)
controller = Controller()
controller.start_app()
sys.exit(app.exec_())

exercise_3.ui

<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"><class>MainWindow</class><widget class="QMainWindow"


name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>417</width><height>364</height></rect></property><property
name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property
name="windowTitle"><string>Калькулятор - обычный режим</string></property><widget class="QWidget" name="centralwidget"><property
name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string
notr="true">QPushButton[style=&quot;gray_small&quot;]{
color: rgb(255, 255, 255);
background-color: #9e9e9e;
font: 15px serif;
}
QPushButton[style=&quot;gray&quot;]{
color: rgb(255, 255, 255);
background-color: #9e9e9e;
}
QPushButton[style=&quot;red&quot;]{
color: rgb(255, 255, 255);
background-color: #f44336;
}
QPushButton[style=&quot;blue&quot;]{
color: rgb(255, 255, 255);
background-color: #3f51b5;
}

</string></property><layout class="QGridLayout" name="gridLayout"><item row="2" column="1"><widget class="QPushButton" name="pushButton_MR_1"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>MR</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="3"

column="4"><widget class="QPushButton" name="pushButton_Exp"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>x^ʸ</string></property><property name="style" stdset="0"><string>gray</string></property></widget></item><item row="4" column="3"><widget

class="QPushButton" name="pushButton_Multiply"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>*</string></property></widget></item><item row="4" column="2"><widget

class="QPushButton" name="pushButton_Six"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>6</string></property></widget></item><item row="1" column="1"><widget

class="QPushButton" name="pushButton_Sum"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe
27
UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>&lt;&gt;</string></property><property name="style" stdset="0"><string>red</string></property></widget></item><item row="6" column="0"

colspan="2"><widget class="QPushButton" name="pushButton_Zero"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>0</string></property></widget></item><item row="2" column="3"><widget

class="QPushButton" name="pushButton_MP_1"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M+</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="3" column="2"><widget class="QPushButton" name="pushButton_Nine"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property name="text"><string>9</string></property></widget></item><item

row="4" column="0"><widget class="QPushButton" name="pushButton_Four"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>4</string></property></widget></item><item row="2" column="4"><widget

class="QPushButton" name="pushButton_MM_1"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M-</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="4" column="1"><widget class="QPushButton" name="pushButton_Five"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property name="text"><string>5</string></property></widget></item><item

row="5" column="0"><widget class="QPushButton" name="pushButton_One"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>1</string></property></widget></item><item row="5" column="4"><widget

class="QPushButton" name="pushButton_Sign"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property name="text"><string>+/-

</string></property><property name="style" stdset="0"><string>gray</string></property></widget></item><item row="6" column="2"><widget class="QPushButton"

name="pushButton_Dot"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>.</string></property></widget></item><item row="0" column="0"

colspan="5"><widget class="QTextEdit" name="textEdit_Result"><property name="sizePolicy"><sizepolicy hsizetype="Expanding"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="minimumSize"><size><width>0</width><height>46</height></size></property><property

name="maximumSize"><size><width>16777215</width><height>46</height></size></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="inputMethodHints"><set>Qt::ImhNone</set></property><property

name="verticalScrollBarPolicy"><enum>Qt::ScrollBarAlwaysOff</enum></property><property

name="horizontalScrollBarPolicy"><enum>Qt::ScrollBarAlwaysOff</enum></property><property

name="sizeAdjustPolicy"><enum>QAbstractScrollArea::AdjustToContents</enum></property></widget></item><item row="4" column="4"><widget class="QPushButton"

name="pushButton_Sqrt"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>√</string></property><property name="style"

stdset="0"><string>gray</string></property></widget></item><item row="5" column="3"><widget class="QPushButton" name="pushButton_Minus"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property name="text"><string>-</string></property></widget></item><item

row="3" column="0"><widget class="QPushButton" name="pushButton_Seven"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>7</string></property></widget></item><item row="1" column="4"><widget

class="QPushButton" name="pushButton_Clear"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>C</string></property><property name="style" stdset="0"><string>red</string></property></widget></item><item row="6" column="4"><widget

class="QPushButton" name="pushButton_Equals"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>=</string></property><property name="style" stdset="0"><string>blue</string></property></widget></item><item row="3" column="3"><widget

class="QPushButton" name="pushButton_Divide"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>/</string></property></widget></item><item row="1" column="0"><widget

class="QPushButton" name="pushButton_Extend"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>≡</string></property><property name="style" stdset="0"><string>red</string></property></widget></item><item row="5" column="2"><widget


28
class="QPushButton" name="pushButton_Three"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>3</string></property></widget></item><item row="5" column="1"><widget

class="QPushButton" name="pushButton_Two"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>2</string></property></widget></item><item row="3" column="1"><widget

class="QPushButton" name="pushButton_Eight"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>8</string></property></widget></item><item row="6" column="3"><widget

class="QPushButton" name="pushButton_Plus"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>+</string></property></widget></item><item row="1" column="3"><widget

class="QPushButton" name="pushButton_Back"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><pointsize>20</pointsize></font></property><property name="text"><string> ⌫</string></property><property name="style"

stdset="0"><string>red</string></property></widget></item><item row="2" column="0"><widget class="QPushButton" name="pushButton_MS_1"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>MS</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="2"

column="2"><widget class="QPushButton" name="pushButton_MC_1"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>MC</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item></layout></widget></widget><resources/><connections/></ui>

exercise_3_adv.ui

<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"><class>MainWindow</class><widget class="QMainWindow"


name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>824</width><height>460</height></rect></property><property
name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property
name="windowTitle"><string>Калькулятор - расширенный режим</string></property><widget class="QWidget"
name="centralwidget"><property name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property
name="styleSheet"><string notr="true">QPushButton[style=&quot;gray_small&quot;]{
color: rgb(255, 255, 255);
background-color: #9e9e9e;
font: 15px serif;
}
QPushButton[style=&quot;gray&quot;]{
color: rgb(255, 255, 255);
background-color: #9e9e9e;
}
QPushButton[style=&quot;red&quot;]{
color: rgb(255, 255, 255);
background-color: #f44336;
}
QPushButton[style=&quot;blue&quot;]{
color: rgb(255, 255, 255);
background-color: #3f51b5;
}

</string></property><layout class="QGridLayout" name="gridLayout_3"><item row="0" column="0" colspan="5"><widget class="QTextEdit"


name="textEdit_Result"><property name="sizePolicy"><sizepolicy hsizetype="Expanding"
vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property
name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property
name="inputMethodHints"><set>Qt::ImhMultiLine</set></property><property
name="verticalScrollBarPolicy"><enum>Qt::ScrollBarAlwaysOff</enum></property><property
name="horizontalScrollBarPolicy"><enum>Qt::ScrollBarAlwaysOff</enum></property><property
name="sizeAdjustPolicy"><enum>QAbstractScrollArea::AdjustIgnored</enum></property><property name="html"><string>&lt;!DOCTYPE HTML
PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot;
/&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:20pt; font-weight:400; font-
style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-

size:30pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string></property><property

name="acceptRichText"><bool>false</bool></property></widget></item><item row="1" column="0"><widget class="QPushButton" name="pushButton_Extend"><property


29
name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>≡</string></property><property name="style" stdset="0"><string>red</string></property></widget></item><item row="1" column="1"><widget

class="QPushButton" name="pushButton_Sum"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>&lt;&gt;</string></property><property name="style" stdset="0"><string>red</string></property></widget></item><item row="1" column="4"><widget

class="QPushButton" name="pushButton_Clear"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>C</string></property><property name="style" stdset="0"><string>red</string></property></widget></item><item row="2" column="0"><widget

class="QPushButton" name="pushButton_Seven"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>7</string></property></widget></item><item row="2" column="1"><widget

class="QPushButton" name="pushButton_Eight"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>8</string></property></widget></item><item row="2" column="2"><widget

class="QPushButton" name="pushButton_Nine"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>9</string></property></widget></item><item row="2" column="3"><widget

class="QPushButton" name="pushButton_Divide"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>/</string></property></widget></item><item row="2" column="4"><widget

class="QPushButton" name="pushButton_Exp"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>x^ʸ</string></property><property name="style" stdset="0"><string>gray</string></property></widget></item><item row="3" column="0"><widget

class="QPushButton" name="pushButton_Four"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>4</string></property></widget></item><item row="3" column="1"><widget

class="QPushButton" name="pushButton_Five"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>5</string></property></widget></item><item row="3" column="2"><widget

class="QPushButton" name="pushButton_Six"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>6</string></property></widget></item><item row="3" column="3"><widget

class="QPushButton" name="pushButton_Multiply"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>*</string></property></widget></item><item row="3" column="4"><widget

class="QPushButton" name="pushButton_Sqrt"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>√</string></property><property name="style"

stdset="0"><string>gray</string></property></widget></item><item row="4" column="0"><widget class="QPushButton" name="pushButton_One"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>Segoe UI</family><pointsize>20</pointsize></font></property><property name="text"><string>1</string></property></widget></item><item

row="4" column="1"><widget class="QPushButton" name="pushButton_Two"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>2</string></property></widget></item><item row="4" column="2"><widget

class="QPushButton" name="pushButton_Three"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>3</string></property></widget></item><item row="4" column="3"><widget

class="QPushButton" name="pushButton_Minus"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>-</string></property></widget></item><item row="4" column="4"><widget

class="QPushButton" name="pushButton_Sign"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property name="text"><string>+/-

</string></property><property name="style" stdset="0"><string>gray</string></property></widget></item><item row="5" column="0"><widget class="QPushButton"

name="pushButton_Zero"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>0</string></property></widget></item><item row="5" column="2"><widget

class="QPushButton" name="pushButton_Dot"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"


30
vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>.</string></property></widget></item><item row="5" column="3"><widget

class="QPushButton" name="pushButton_Plus"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="text"><string>+</string></property></widget></item><item row="5" column="4"><widget

class="QPushButton" name="pushButton_Equals"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>Segoe

UI</family><pointsize>20</pointsize></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>=</string></property><property name="style" stdset="0"><string>blue</string></property></widget></item><item row="0" column="5"><layout

class="QGridLayout" name="gridLayout_2"><item row="0" column="0"><widget class="QPushButton" name="pushButton_Pi"><property name="sizePolicy"><sizepolicy

hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="text"><string>π</string></property></widget></item><item row="0" column="1"><widget class="QPushButton" name="pushButton_Sin"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="text"><string>Sin</string></property></widget></item><item row="0" column="2"><widget class="QPushButton" name="pushButton_Tan"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="text"><string>Tan</string></property></widget></item><item row="1" column="0"><widget class="QPushButton" name="pushButton_Nexp"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="text"><string>Exp</string></property></widget></item><item row="1" column="1"><widget class="QPushButton" name="pushButton_Fact"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="text"><string>n!</string></property></widget></item><item row="1" column="2"><widget class="QPushButton" name="pushButton_Frac"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="text"><string>Frac</string></property></widget></item></layout></item><item row="1" column="5" rowspan="5"><layout class="QGridLayout"

name="gridLayout"><item row="2" column="1"><widget class="QPushButton" name="pushButton_MS_3"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>MS</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="0" column="1"><widget class="QPushButton" name="pushButton_MS_1"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>MS</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="1"

column="4"><widget class="QPushButton" name="pushButton_MP_2"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M+</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="1" column="1"><widget class="QPushButton" name="pushButton_MS_2"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>MS</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="2"

column="7"><widget class="QPushButton" name="pushButton_MM_3"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M-</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="1" column="7"><widget class="QPushButton" name="pushButton_MM_2"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M-

</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="2" column="4"><widget class="QPushButton"

name="pushButton_MP_3"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M+</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="0" column="4"><widget class="QPushButton" name="pushButton_MP_1"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>M+</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="0"

column="7"><widget class="QPushButton" name="pushButton_MM_1"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>M-</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="0" column="2"><widget class="QPushButton" name="pushButton_MR_1"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>MR</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="1"

column="2"><widget class="QPushButton" name="pushButton_MR_2"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="text"><string>MR</string></property><property name="style"

stdset="0"><string>gray_small</string></property></widget></item><item row="2" column="2"><widget class="QPushButton" name="pushButton_MR_3"><property

name="sizePolicy"><sizepolicy hsizetype="Minimum" vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property


31
name="font"><font><family>serif</family><pointsize>-1</pointsize><italic>false</italic><bold>false</bold></font></property><property

name="text"><string>MR</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="0"

column="3"><widget class="QPushButton" name="pushButton_MC_1"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>MC</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="1"

column="3"><widget class="QPushButton" name="pushButton_MC_2"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>MC</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item><item row="2"

column="3"><widget class="QPushButton" name="pushButton_MC_3"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="font"><font><family>serif</family><pointsize>-

1</pointsize><italic>false</italic><bold>false</bold></font></property><property name="styleSheet"><string notr="true"/></property><property

name="text"><string>MC</string></property><property name="style" stdset="0"><string>gray_small</string></property></widget></item></layout></item><item row="1"

column="3"><widget class="QPushButton" name="pushButton_Back"><property name="sizePolicy"><sizepolicy hsizetype="Minimum"

vsizetype="Minimum"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property

name="font"><font><pointsize>20</pointsize></font></property><property name="text"><string> ⌫</string></property><property name="style"

stdset="0"><string>red</string></property></widget></item></layout></widget></widget><resources/><connections/></ui>
32

2.4. Разработка логико-аналитической

системы
Условие задания: имеется 8 шпинделей, с номерами 8 до 1 слева направо. На
каждом шпинделе надеты диски, в количестве, равном соответствующей
цифре из ID студента
Нужно переместить все диски на самый правый стержень.

Картинка 4, условие задачи


Из-за на размеров дисков меняются от числа ножки, можно минимизировать
эту задачу до рекурсивного решения. Постепенно перекладывая с самого
левого шпинделя, на стоящий справа от него, и повторяя это до тех пор, пока
все диски не будут находится на крайне правом месте.
Функция, позволяющая перекладывать диски с i шпинделя на k, имея n
дисков, была разработана рекурсивная
def hanoi(n, i, k):
if n == 1:
print(f"Move disk {n} from pin {i} to {k}")
else:
tmp = 6 - i - k
hanoi(n - 1, i, tmp)
33

print(f"Move disk {n} from pin {i} to {k}")


hanoi(n - 1, tmp, k)
34

Картинки 5-12, Показ алгоритма


35

Используем этот алгоритм для каждого кольца, в конце-концов все кольца


будут лежать от большего к меньшему, на самом правом стержне.
36

Графическая оболочка показана ниже:

Картинка 13

Все кольца хранились отдельно как объект класса, в котором хранится его
цвет, положение, длина

class Disk:
def __init__(self, x, y, length, color):
self.x = x
self.y = y
self.length = length
self.color = color

После, каждое по отдельности кольцо передавалась в функцию,которая


отрисовывала в соответствии со своими координатами. То же самое
происходило ч умножением на коэффициент, для того чтобы окно можно
было масштабировать на весь экран

def drawRing(self, qp, disk):


x = disk.x
y = disk.y
ring_length = disk.length
color = disk.color
size = self.size()

qp.setBrush(color)
qp.drawRect((150 * x - ring_length / 2) *
self.size().width() / WEIGHT,
37

(450 + y * 15) * size.height() / HEIGHT,


ring_length * size.width() / WEIGHT,
10 * size.height() / HEIGHT)

qp.drawText((150 * x - 5) * size.width() / WEIGHT,


(450 + y * 15 + 9) * size.height() / HEIGHT,
str(ring_length))

Не совсем понятно стало, как закончить данную работу, поэтому я оставил это.
38

2.4.1 Исходный код


import random
import sys
from PySide6 import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *

WEIGHT = 1350
HEIGHT = 700

def hanoi(n, i, k):


if n == 1:
print(f"Move disk {n} from pin {i} to {k}")
else:
tmp = 6 - i - k
hanoi(n - 1, i, tmp)
print(f"Move disk {n} from pin {i} to {k}")
hanoi(n - 1, tmp, k)

# n - Количество дисков или номер диска


# i - Источник
# k - Назначение

class Disk:
def __init__(self, x, y, length, color):
self.x = x
self.y = y
self.length = length
self.color = color

class count_iterator:
n = 1

def __iter__(self):
return self

def __next__(self):
y = self.n
if y > 7:
self.n = 1
else:
self.n += 1
return y

class Example(QWidget):
def __init__(self):
super().__init__()
self.colors = {1: Qt.red, 2: Qt.cyan, 3: Qt.yellow, 4: Qt.green, 5: Qt.blue, 6: Qt.gray,
7: Qt.black,
8: Qt.white}
self.counter = count_iterator()
self.Disks = []

self.initUI()

def initUI(self):
self.setGeometry(300, 100, WEIGHT, HEIGHT)
self.setWindowTitle('Ханойские башни')

self.show()

def generate_full_disks(self):
self.Disks = []
for x in range(8, 0, -1):
# for y in range(1, 10):
for y in range(1, random.randint(0, 9)):
ring_length = x * 10 + y
self.Disks.append(Disk(x, y, ring_length, self.colors[next(self.counter)]))

def paintEvent(self, e):


qp = QPainter()
qp.begin(self)
self.drawSticks(qp)
# random.shuffle(Disks)
39
#self.drawRings(qp)
self.generate_full_disks()
for d in self.Disks:
self.drawRing(qp, d)
#print(f'x: {d.x}, y: {d.y}, length: {d.length}, color: {d.color}')
qp.end()

def drawSticks(self, qp):


for i in range(1, 9):
size = self.size()
qp.drawRect(150 * i * size.width() / WEIGHT, 70 * size.height() / HEIGHT, 4, 500 *
size.height() / HEIGHT)

def drawRings(self, qp):


for x in range(1, 9):
for y in range(1, 9):
size = self.size()
# qp.drawRect(125 * i * size.width() / WEIGHT, 550, 80, 10)
qp.setBrush(self.colors[next(self.counter)])
ring_length = 91 - x * 11 + y
qp.drawRect((150 * x - ring_length / 2) * size.width() / WEIGHT,
(450 + y * 15) * size.height() / HEIGHT, ring_length * size.width() / WEIGHT,
10 * size.height() / HEIGHT)
qp.drawText((150 * x - 5) * size.width() / WEIGHT, (450 + y * 15 + 10) * size.height() / HEIGHT,
str(ring_length))

def drawRing(self, qp, disk):


x = disk.x
y = disk.y
ring_length = disk.length
color = disk.color
size = self.size()

qp.setBrush(color)
qp.drawRect((150 * x - ring_length / 2) * self.size().width() / WEIGHT,
(450 + y * 15) * size.height() / HEIGHT, ring_length * size.width() / WEIGHT,
10 * size.height() / HEIGHT)

qp.drawText((150 * x - 5) * size.width() / WEIGHT, (450 + y * 15 + 9) * size.height() /


HEIGHT,
str(ring_length))

# qp.drawRect((150 * x - ring_length / 2) * self.size().width() / WEIGHT,


# 400 - 200 + y * 50, ring_length * size.width() / WEIGHT,
# 10 * size.height() / HEIGHT)

# qp.drawText((150 * x - 5) * size.width() / WEIGHT, (500- y * 50 + 10) * size.height() /


HEIGHT,
# str(ring_length))

if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
40

Выводы
Таким образом после выполнения курсовой работы я укрепил свои
навыки в программировании, полученные во время обучения в
институте.Практика с ООП, Qt и PyCharm позволила мне убедиться в
моих силах, которые оказались весьма незаурядными. В данной
курсовой работе я использовал опыт и знания, данные мне во время
обучения, которые регулярно повторяются в Python.
41

Список литературы
1. f-строки в Python 3 - применение и производительность

(shultais.education)
2. How to Import a PyQt5 .ui File in a Python GUI - Nitratine
3. utf 8 - python 3.0 open() default encoding
4. Рисование в PyQt5 | Python 3 для начинающих и чайников
(pythonworld.ru)
5. QUiLoader Class | Qt UI Tools 5.15.4
6. python - Loading QtDesigner's .ui files in PySide
7. Correct way to address Pyside Qt widgets from a .ui file via Python
8. python - How to convert list to string
9. if __name__ == "__main__" — Документация Python для сетевых
инженеров 3.0
10. Python and PyQt: Building a GUI Desktop Calculator – Real
Python
11. python - Print a list in reverse order with range
12. Ханойская башня на пальцах
13. Lambda в Python: синтаксис, аргументы и много примеров
14. How do I concatenate two lists in Python?
15.re — Regular expression operations — Python 3.9.5

documentation

Вам также может понравиться