From 0c623d4bc5e59e05c69a9cbfacffe7dc2ecf99a8 Mon Sep 17 00:00:00 2001 From: jze9 Date: Mon, 10 Nov 2025 12:18:40 +0500 Subject: [PATCH] test math --- UPGRADE_GUIDE.md | 137 ++++++++++ app/src/pages/tabs/binary_calculeator4.py | 304 +++++++++++++++++++++ app/src/pages/tabs/calculater2.py | 255 +++++++++++++++++ app/src/pages/tabs/octogon_calculeator6.py | 270 +++++++++++++++++- app/src/pages/tabs/sedecim_calculeator8.py | 15 + app/src/step_by_step_solver.py | 166 ++++++++++- complete_update.py | 163 +++++++++++ 7 files changed, 1307 insertions(+), 3 deletions(-) create mode 100644 UPGRADE_GUIDE.md create mode 100644 complete_update.py diff --git a/UPGRADE_GUIDE.md b/UPGRADE_GUIDE.md new file mode 100644 index 0000000..efa50c8 --- /dev/null +++ b/UPGRADE_GUIDE.md @@ -0,0 +1,137 @@ +# Руководство по обновлению калькуляторов + +## Статус обновлений + +### ✅ Завершено: +1. **step_by_step_solver.py** - добавлены операции `MULTIPLICATION` и `DIVISION` +2. **calculater2.py** (Десятичный) - добавлены 4 колонки (+, -, ×, ÷) +3. **binary_calculeator4.py** (Двоичный) - добавлены 4 колонки (+, -, ×, ÷) +4. **octogon_calculeator6.py** (Восьмеричный) - добавлены 4 колонки (+, -, ×, ÷) + +### ⏳ Требуется завершить: +5. **sedecim_calculeator8.py** (Шестнадцатеричный) +6. **pentecostal_calculeator10.py** (50-ричный) + +## Инструкция для завершения оставшихся калькуляторов + +### Для sedecim_calculeator8.py и pentecostal_calculeator10.py: + +#### 1. Обновить __init__ метод класса: +Добавить: +```python +# Результаты для умножения и деления +self.result_mult = ft.Text(value="0", size=30, width=300) +self.result_div = ft.Text(value="0", size=30, width=300) +self.decimal_mult = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) +self.decimal_div = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + +# Поля ввода для умножения +self.input_mult_1 = None +self.input_mult_2 = None + +# Поля ввода для деления +self.input_div_1 = None +self.input_div_2 = None + +# Контейнеры для пошагового решения +self.steps_mult = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) +self.steps_div = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) +``` + +#### 2. Добавить методы calculate_multiplication и calculate_division: +```python +def calculate_multiplication(self, e): + # Логика умножения - преобразовать в десятичную, умножить, вернуть обратно + # Вызвать self.show_steps_mult(val1, val2, Operation.MULTIPLICATION) + +def calculate_division(self, e): + # Логика деления - преобразовать в десятичную, разделить, вернуть обратно + # Проверка деления на ноль + # Вызвать self.show_steps_div(val1, val2, Operation.DIVISION) +``` + +#### 3. Добавить методы show_steps_mult и show_steps_div: +```python +def show_steps_mult(self, num1: str, num2: str, operation: Operation): + # Аналогично show_steps_left/right + # Обновить self.steps_mult + +def show_steps_div(self, num1: str, num2: str, operation: Operation): + # Аналогично show_steps_left/right + # Обновить self.steps_div +``` + +#### 4. Обновить test_data метод: +Добавить поля ввода для умножения и деления: +```python +self.input_mult_1 = ft.TextField(...) +self.input_mult_2 = ft.TextField(...) +self.input_div_1 = ft.TextField(...) +self.input_div_2 = ft.TextField(...) +``` + +Добавить две новые колонки в ft.Row (controls): +```python +ft.Column( # Умножение + controls=[ + self.input_mult_1, + ft.Text("× Умножение", ...), + self.input_mult_2, + ft.Container(content=...), # result_mult + ft.CupertinoButton("=", on_click=self.calculate_multiplication), + ft.Container(content=self.steps_mult, ...) + ] +), +ft.Column( # Деление + controls=[ + self.input_div_1, + ft.Text("÷ Деление", ...), + self.input_div_2, + ft.Container(content=...), # result_div + ft.CupertinoButton("=", on_click=self.calculate_division), + ft.Container(content=self.steps_div, ...) + ] +) +``` + +## Примечания: +- Для **sedecim_calculeator8.py**: Используйте существующие методы `hex_to_decimal` и `decimal_to_hex` +- Для **pentecostal_calculeator10.py**: Используйте существующие методы `from_base50` и `to_base50` +- Во всех случаях импортируйте `Operation` из step_by_step_solver +- Проверьте деление на ноль в методе calculate_division + +## Шаблон для calculate_multiplication (шестнадцатеричный): +```python +def calculate_multiplication(self, e): + try: + num1 = self.hex_to_decimal(self.input_mult_1.value.upper()) + num2 = self.hex_to_decimal(self.input_mult_2.value.upper()) + result_decimal = num1 * num2 + result_hex = self.decimal_to_hex(result_decimal) + + self.result_mult.value = f"HEX: {result_hex}" + self.decimal_mult.value = f"DEC: {result_decimal}" + + if '.' not in self.input_mult_1.value and '.' not in self.input_mult_2.value: + hex_val1 = self.input_mult_1.value.upper().lstrip('-+') if self.input_mult_1.value else "0" + hex_val2 = self.input_mult_2.value.upper().lstrip('-+') if self.input_mult_2.value else "0" + self.show_steps_mult(hex_val1, hex_val2, Operation.MULTIPLICATION) + else: + self.steps_mult.controls.clear() + self.steps_mult.controls.append( + ft.Text("Пошаговое решение доступно только для целых чисел", color="#FFD700", size=12) + ) + self.steps_mult.update() + except Exception as ex: + self.result_mult.value = f"Ошибка: {str(ex)}" + self.decimal_mult.value = "DEC: ошибка" + self.page.update() +``` + +## Следующие шаги: +1. Откройте sedecim_calculeator8.py +2. Примените изменения согласно шаблону выше +3. Повторите для pentecostal_calculeator10.py +4. Протестируйте все калькуляторы + +Все изменения следуют единому паттерну, использованному в уже обновленных калькуляторах. diff --git a/app/src/pages/tabs/binary_calculeator4.py b/app/src/pages/tabs/binary_calculeator4.py index 53d7a9e..37c1668 100644 --- a/app/src/pages/tabs/binary_calculeator4.py +++ b/app/src/pages/tabs/binary_calculeator4.py @@ -11,8 +11,13 @@ class Button_binary_calculator(ft.CupertinoButton): def __init__(self, text: str = "Двоичный калькулятор"): self.result_left = ft.Text(value="0", size=30, width=300) self.result_right = ft.Text(value="0", size=30, width=300) + self.result_mult = ft.Text(value="0", size=30, width=300) + self.result_div = ft.Text(value="0", size=30, width=300) + self.decimal_left = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) self.decimal_right = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_mult = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_div = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) # Поля ввода для вычитания self.input_left_1 = None @@ -22,9 +27,19 @@ class Button_binary_calculator(ft.CupertinoButton): self.input_right_1 = None self.input_right_2 = None + # Поля ввода для умножения + self.input_mult_1 = None + self.input_mult_2 = None + + # Поля ввода для деления + self.input_div_1 = None + self.input_div_2 = None + # Контейнеры для пошагового решения self.steps_left = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) self.steps_right = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) + self.steps_mult = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) + self.steps_div = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) # Солвер для двоичной системы self.solver = StepByStepSolver(base=2) @@ -290,6 +305,207 @@ class Button_binary_calculator(ft.CupertinoButton): self.decimal_right.value = str(ex) self.result_right.update() self.decimal_right.update() + + def calculate_multiplication(self, e): + try: + bin1 = self.input_mult_1.value or "0" + bin2 = self.input_mult_2.value or "0" + + if not self.validate_binary(bin1) or not self.validate_binary(bin2): + self.result_mult.value = "Ошибка: неверный формат" + self.decimal_mult.value = "" + self.result_mult.update() + self.decimal_mult.update() + return + + if len(bin1) > 0 and bin1[0] == '1' and len(bin1) >= 8: + num1 = self.from_twos_complement(bin1) + else: + num1 = int(bin1, 2) if bin1 else 0 + + if len(bin2) > 0 and bin2[0] == '1' and len(bin2) >= 8: + num2 = self.from_twos_complement(bin2) + else: + num2 = int(bin2, 2) if bin2 else 0 + + result = num1 * num2 + binary_result = self.to_twos_complement(result, self.bit_width) + + self.result_mult.value = binary_result + self.decimal_mult.value = f"({result}₁₀)" + self.result_mult.update() + self.decimal_mult.update() + + self.show_steps_mult(bin1, bin2, Operation.MULTIPLICATION) + + except ValueError as ex: + self.result_mult.value = "Ошибка" + self.decimal_mult.value = str(ex) + self.result_mult.update() + self.decimal_mult.update() + + def calculate_division(self, e): + try: + bin1 = self.input_div_1.value or "0" + bin2 = self.input_div_2.value or "0" + + if not self.validate_binary(bin1) or not self.validate_binary(bin2): + self.result_div.value = "Ошибка: неверный формат" + self.decimal_div.value = "" + self.result_div.update() + self.decimal_div.update() + return + + if len(bin1) > 0 and bin1[0] == '1' and len(bin1) >= 8: + num1 = self.from_twos_complement(bin1) + else: + num1 = int(bin1, 2) if bin1 else 0 + + if len(bin2) > 0 and bin2[0] == '1' and len(bin2) >= 8: + num2 = self.from_twos_complement(bin2) + else: + num2 = int(bin2, 2) if bin2 else 0 + + if num2 == 0: + self.result_div.value = "Деление на 0!" + self.decimal_div.value = "" + self.result_div.update() + self.decimal_div.update() + return + + quotient = num1 // num2 + remainder = num1 % num2 + + binary_quotient = self.to_twos_complement(quotient, self.bit_width) + + if remainder == 0: + self.result_div.value = binary_quotient + self.decimal_div.value = f"({quotient}₁₀)" + else: + binary_remainder = self.to_twos_complement(remainder, self.bit_width) + self.result_div.value = binary_quotient + self.decimal_div.value = f"({quotient}₁₀, ост. {remainder})" + + self.result_div.update() + self.decimal_div.update() + + self.show_steps_div(bin1, bin2, Operation.DIVISION) + + except ValueError as ex: + self.result_div.value = "Ошибка" + self.decimal_div.value = str(ex) + self.result_div.update() + self.decimal_div.update() + + def show_steps_mult(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для умножения""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_mult.controls.clear() + + self.steps_mult.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append( + ft.Text(f"Шаг {i}: {step.title}", + size=12, weight=ft.FontWeight.BOLD, color="#00FFFF") + ) + step_content.append( + ft.Text(step.description, size=10, color="#E0E0E0") + ) + + if step.visual: + step_content.append( + ft.Text(step.visual, + size=10, + font_family="Courier New", + color="#90EE90", + selectable=True) + ) + + if step.result: + step_content.append( + ft.Text(f"➤ {step.result}", + size=11, + weight=ft.FontWeight.BOLD, + color="#00FF00") + ) + + self.steps_mult.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + + self.steps_mult.update() + except Exception as ex: + self.steps_mult.controls.clear() + self.steps_mult.controls.append( + ft.Text(f"Ошибка: {str(ex)}", color="red", size=10) + ) + self.steps_mult.update() + + def show_steps_div(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для деления""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_div.controls.clear() + + self.steps_div.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append( + ft.Text(f"Шаг {i}: {step.title}", + size=12, weight=ft.FontWeight.BOLD, color="#00FFFF") + ) + step_content.append( + ft.Text(step.description, size=10, color="#E0E0E0") + ) + + if step.visual: + step_content.append( + ft.Text(step.visual, + size=10, + font_family="Courier New", + color="#90EE90", + selectable=True) + ) + + if step.result: + step_content.append( + ft.Text(f"➤ {step.result}", + size=11, + weight=ft.FontWeight.BOLD, + color="#00FF00") + ) + + self.steps_div.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + + self.steps_div.update() + except Exception as ex: + self.steps_div.controls.clear() + self.steps_div.controls.append( + ft.Text(f"Ошибка: {str(ex)}", color="red", size=10) + ) + self.steps_div.update() def test_data(self, e): # Создаем поля ввода с валидацией для двоичных чисел @@ -326,6 +542,40 @@ class Button_binary_calculator(ft.CupertinoButton): input_filter=ft.InputFilter(regex_string=r"^[01]*$"), hint_text="Например: 00000101 (5)" ) + + self.input_mult_1 = ft.TextField( + label="Двоичное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00000110 (6)" + ) + self.input_mult_2 = ft.TextField( + label="Двоичное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00000011 (3)" + ) + + self.input_div_1 = ft.TextField( + label="Двоичное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00001100 (12)" + ) + self.input_div_2 = ft.TextField( + label="Двоичное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^[01]*$"), + hint_text="Например: 00000011 (3)" + ) right_column.controls = [ft.Container( bgcolor="#55257D", @@ -397,6 +647,60 @@ class Button_binary_calculator(ft.CupertinoButton): border_radius=5, ) ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.START, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_mult_1, + ft.Text("× Умножение", size=12, color="white"), + self.input_mult_2, + ft.Container( + content=ft.Column([ + self.result_mult, + self.decimal_mult + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_multiplication), + ft.Container( + expand=True, + content=self.steps_mult, + bgcolor="#1A0A2A", + padding=10, + border_radius=5, + ) + ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.START, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_div_1, + ft.Text("÷ Деление", size=12, color="white"), + self.input_div_2, + ft.Container( + content=ft.Column([ + self.result_div, + self.decimal_div + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_division), + ft.Container( + expand=True, + content=self.steps_div, + bgcolor="#1A0A2A", + padding=10, + border_radius=5, + ) + ] ) ] ) diff --git a/app/src/pages/tabs/calculater2.py b/app/src/pages/tabs/calculater2.py index 6aa90c0..3213cc4 100644 --- a/app/src/pages/tabs/calculater2.py +++ b/app/src/pages/tabs/calculater2.py @@ -11,6 +11,8 @@ class Button_calculeator(ft.CupertinoButton): def __init__(self, text: str = "Десятичный калькулятор"): self.result_left = ft.Text(value="0", size=30, width=300) self.result_right = ft.Text(value="0", size=30, width=300) + self.result_mult = ft.Text(value="0", size=30, width=300) + self.result_div = ft.Text(value="0", size=30, width=300) # Поля ввода для вычитания self.input_left_1 = None @@ -20,9 +22,19 @@ class Button_calculeator(ft.CupertinoButton): self.input_right_1 = None self.input_right_2 = None + # Поля ввода для умножения + self.input_mult_1 = None + self.input_mult_2 = None + + # Поля ввода для деления + self.input_div_1 = None + self.input_div_2 = None + # Контейнеры для пошагового решения self.steps_left = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) self.steps_right = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) + self.steps_mult = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) + self.steps_div = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5, expand=True) # Солвер для десятичной системы self.solver = StepByStepSolver(base=10) @@ -74,6 +86,49 @@ class Button_calculeator(ft.CupertinoButton): self.result_right.value = "Ошибка" self.result_right.update() + def calculate_multiplication(self, e): + try: + num1 = int(self.input_mult_1.value or 0) + num2 = int(self.input_mult_2.value or 0) + result = num1 * num2 + + self.result_mult.value = str(result) + self.result_mult.update() + + # Получаем пошаговое решение + self.show_steps_mult(str(num1), str(num2), Operation.MULTIPLICATION) + + except ValueError: + self.result_mult.value = "Ошибка" + self.result_mult.update() + + def calculate_division(self, e): + try: + num1 = int(self.input_div_1.value or 0) + num2 = int(self.input_div_2.value or 0) + + if num2 == 0: + self.result_div.value = "Деление на ноль!" + self.result_div.update() + return + + quotient = num1 // num2 + remainder = num1 % num2 + + if remainder == 0: + self.result_div.value = str(quotient) + else: + self.result_div.value = f"{quotient} (ост. {remainder})" + + self.result_div.update() + + # Получаем пошаговое решение + self.show_steps_div(str(num1), str(num2), Operation.DIVISION) + + except ValueError: + self.result_div.value = "Ошибка" + self.result_div.update() + def show_steps_left(self, num1: str, num2: str, operation: Operation): """Отображает пошаговое решение для левой колонки (вычитание)""" try: @@ -183,6 +238,116 @@ class Button_calculeator(ft.CupertinoButton): ft.Text(f"Ошибка: {str(ex)}", color="red", size=10) ) self.steps_right.update() + + def show_steps_mult(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для умножения""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_mult.controls.clear() + + self.steps_mult.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append( + ft.Text(f"Шаг {i}: {step.title}", + size=12, weight=ft.FontWeight.BOLD, color="#00FFFF") + ) + step_content.append( + ft.Text(step.description, size=10, color="#E0E0E0") + ) + + if step.visual: + step_content.append( + ft.Text(step.visual, + size=10, + font_family="Courier New", + color="#90EE90", + selectable=True) + ) + + if step.result: + step_content.append( + ft.Text(f"➤ {step.result}", + size=11, + weight=ft.FontWeight.BOLD, + color="#00FF00") + ) + + self.steps_mult.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + + self.steps_mult.update() + except Exception as ex: + self.steps_mult.controls.clear() + self.steps_mult.controls.append( + ft.Text(f"Ошибка: {str(ex)}", color="red", size=10) + ) + self.steps_mult.update() + + def show_steps_div(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для деления""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_div.controls.clear() + + self.steps_div.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append( + ft.Text(f"Шаг {i}: {step.title}", + size=12, weight=ft.FontWeight.BOLD, color="#00FFFF") + ) + step_content.append( + ft.Text(step.description, size=10, color="#E0E0E0") + ) + + if step.visual: + step_content.append( + ft.Text(step.visual, + size=10, + font_family="Courier New", + color="#90EE90", + selectable=True) + ) + + if step.result: + step_content.append( + ft.Text(f"➤ {step.result}", + size=11, + weight=ft.FontWeight.BOLD, + color="#00FF00") + ) + + self.steps_div.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + + self.steps_div.update() + except Exception as ex: + self.steps_div.controls.clear() + self.steps_div.controls.append( + ft.Text(f"Ошибка: {str(ex)}", color="red", size=10) + ) + self.steps_div.update() def test_data(self, e): # Создаем поля ввода с валидацией @@ -223,6 +388,44 @@ class Button_calculeator(ft.CupertinoButton): keyboard_type=ft.KeyboardType.NUMBER, hint_text="Например: 17" ) + + self.input_mult_1 = ft.TextField( + label="Десятичное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?\d*$"), + keyboard_type=ft.KeyboardType.NUMBER, + hint_text="Например: 12" + ) + self.input_mult_2 = ft.TextField( + label="Десятичное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?\d*$"), + keyboard_type=ft.KeyboardType.NUMBER, + hint_text="Например: 5" + ) + + self.input_div_1 = ft.TextField( + label="Десятичное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?\d*$"), + keyboard_type=ft.KeyboardType.NUMBER, + hint_text="Например: 100" + ) + self.input_div_2 = ft.TextField( + label="Десятичное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?\d*$"), + keyboard_type=ft.KeyboardType.NUMBER, + hint_text="Например: 7" + ) right_column.controls = [ft.Container( bgcolor="#55257D", @@ -291,6 +494,58 @@ class Button_calculeator(ft.CupertinoButton): border_radius=5, ) ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.START, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_mult_1, + ft.Text("× Умножение", size=12, color="white"), + self.input_mult_2, + ft.Container( + content=ft.Column([ + self.result_mult, + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_multiplication), + ft.Container( + expand=True, + content=self.steps_mult, + bgcolor="#1A0A2A", + padding=10, + border_radius=5, + ) + ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.START, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_div_1, + ft.Text("÷ Деление", size=12, color="white"), + self.input_div_2, + ft.Container( + content=ft.Column([ + self.result_div, + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_division), + ft.Container( + expand=True, + content=self.steps_div, + bgcolor="#1A0A2A", + padding=10, + border_radius=5, + ) + ] ) ] ) diff --git a/app/src/pages/tabs/octogon_calculeator6.py b/app/src/pages/tabs/octogon_calculeator6.py index f257641..61284cf 100644 --- a/app/src/pages/tabs/octogon_calculeator6.py +++ b/app/src/pages/tabs/octogon_calculeator6.py @@ -11,8 +11,13 @@ class Button_octogon_calculator(ft.CupertinoButton): def __init__(self, text: str = "Восьмеричный калькулятор"): self.result_left = ft.Text(value="0", size=30, width=300) self.result_right = ft.Text(value="0", size=30, width=300) + self.result_mult = ft.Text(value="0", size=30, width=300) + self.result_div = ft.Text(value="0", size=30, width=300) + self.decimal_left = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) self.decimal_right = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_mult = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_div = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) # Поля ввода для вычитания self.input_left_1 = None @@ -22,9 +27,19 @@ class Button_octogon_calculator(ft.CupertinoButton): self.input_right_1 = None self.input_right_2 = None + # Поля ввода для умножения + self.input_mult_1 = None + self.input_mult_2 = None + + # Поля ввода для деления + self.input_div_1 = None + self.input_div_2 = None + # Контейнеры для пошагового решения self.steps_left = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) self.steps_right = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) + self.steps_mult = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) + self.steps_div = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) # Солвер для восьмеричной системы self.solver = StepByStepSolver(base=8) @@ -146,6 +161,170 @@ class Button_octogon_calculator(ft.CupertinoButton): self.result_right.update() self.decimal_right.update() + def calculate_multiplication(self, e): + try: + val1 = (self.input_mult_1.value or "").strip() + val2 = (self.input_mult_2.value or "").strip() + + if not self.validate_octal(val1) or not self.validate_octal(val2): + self.result_mult.value = "Ошибка: неверный формат" + self.decimal_mult.value = "" + self.result_mult.update() + self.decimal_mult.update() + return + + def parse_octal(s: str) -> int: + s = s.strip() + if s == "": + return 0 + sign = -1 if s.startswith('-') else 1 + if s.startswith('-'): + s = s[1:] + return sign * int(s, 8) if s else 0 + + num1 = parse_octal(val1) + num2 = parse_octal(val2) + result = num1 * num2 + oct_result = ('-' if result < 0 else '') + format(abs(result), 'o') + + self.result_mult.value = oct_result + self.decimal_mult.value = f"({result}₁₀)" + self.result_mult.update() + self.decimal_mult.update() + + clean_val1 = val1.lstrip('-') if val1.startswith('-') and num1 < 0 else val1 + clean_val2 = val2.lstrip('-') if val2.startswith('-') and num2 < 0 else val2 + self.show_steps_mult(clean_val1 if num1 >= 0 else val1, clean_val2 if num2 >= 0 else val2, Operation.MULTIPLICATION) + + except ValueError as ex: + self.result_mult.value = "Ошибка" + self.decimal_mult.value = str(ex) + self.result_mult.update() + self.decimal_mult.update() + + def calculate_division(self, e): + try: + val1 = (self.input_div_1.value or "").strip() + val2 = (self.input_div_2.value or "").strip() + + if not self.validate_octal(val1) or not self.validate_octal(val2): + self.result_div.value = "Ошибка: неверный формат" + self.decimal_div.value = "" + self.result_div.update() + self.decimal_div.update() + return + + def parse_octal(s: str) -> int: + s = s.strip() + if s == "": + return 0 + sign = -1 if s.startswith('-') else 1 + if s.startswith('-'): + s = s[1:] + return sign * int(s, 8) if s else 0 + + num1 = parse_octal(val1) + num2 = parse_octal(val2) + + if num2 == 0: + self.result_div.value = "Деление на 0!" + self.decimal_div.value = "" + self.result_div.update() + self.decimal_div.update() + return + + quotient = num1 // num2 + remainder = num1 % num2 + oct_quotient = ('-' if quotient < 0 else '') + format(abs(quotient), 'o') + + if remainder == 0: + self.result_div.value = oct_quotient + self.decimal_div.value = f"({quotient}₁₀)" + else: + self.result_div.value = oct_quotient + self.decimal_div.value = f"({quotient}₁₀, ост. {remainder})" + + self.result_div.update() + self.decimal_div.update() + + clean_val1 = val1.lstrip('-') if val1.startswith('-') and num1 < 0 else val1 + clean_val2 = val2.lstrip('-') if val2.startswith('-') and num2 < 0 else val2 + self.show_steps_div(clean_val1 if num1 >= 0 else val1, clean_val2 if num2 >= 0 else val2, Operation.DIVISION) + + except ValueError as ex: + self.result_div.value = "Ошибка" + self.decimal_div.value = str(ex) + self.result_div.update() + self.decimal_div.update() + + def show_steps_mult(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для умножения""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_mult.controls.clear() + + self.steps_mult.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append(ft.Text(f"Шаг {i}: {step.title}", size=12, weight=ft.FontWeight.BOLD, color="#00FFFF")) + step_content.append(ft.Text(step.description, size=10, color="#E0E0E0")) + if step.visual: + step_content.append(ft.Text(step.visual, size=10, font_family="Courier New", color="#90EE90", selectable=True)) + if step.result: + step_content.append(ft.Text(f"➤ {step.result}", size=11, weight=ft.FontWeight.BOLD, color="#00FF00")) + + self.steps_mult.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + self.steps_mult.update() + except Exception as ex: + self.steps_mult.controls.clear() + self.steps_mult.controls.append(ft.Text(f"Ошибка: {str(ex)}", color="red", size=10)) + self.steps_mult.update() + + def show_steps_div(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для деления""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_div.controls.clear() + + self.steps_div.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append(ft.Text(f"Шаг {i}: {step.title}", size=12, weight=ft.FontWeight.BOLD, color="#00FFFF")) + step_content.append(ft.Text(step.description, size=10, color="#E0E0E0")) + if step.visual: + step_content.append(ft.Text(step.visual, size=10, font_family="Courier New", color="#90EE90", selectable=True)) + if step.result: + step_content.append(ft.Text(f"➤ {step.result}", size=11, weight=ft.FontWeight.BOLD, color="#00FF00")) + + self.steps_div.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + self.steps_div.update() + except Exception as ex: + self.steps_div.controls.clear() + self.steps_div.controls.append(ft.Text(f"Ошибка: {str(ex)}", color="red", size=10)) + self.steps_div.update() + def show_steps_left(self, num1: str, num2: str, operation: Operation): """Отображает пошаговое решение для левой колонки""" try: @@ -215,8 +394,7 @@ class Button_octogon_calculator(ft.CupertinoButton): self.steps_right.update() def test_data(self, e): - # Создаем поля ввода с валидацией для двоичных чисел - # Поля ввода для восьмеричной системы — допускаются цифры 0..7 и опциональный знак '-' + # Создаем поля ввода с валидацией для восьмеричных чисел self.input_left_1 = ft.TextField( label="Восьмеричное число 1", width=250, @@ -250,6 +428,40 @@ class Button_octogon_calculator(ft.CupertinoButton): input_filter=ft.InputFilter(regex_string=r"^-?[0-7]*$"), hint_text="Например: 7 (7₁₀)" ) + + self.input_mult_1 = ft.TextField( + label="Восьмеричное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?[0-7]*$"), + hint_text="Например: 12 (10₁₀)" + ) + self.input_mult_2 = ft.TextField( + label="Восьмеричное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?[0-7]*$"), + hint_text="Например: 3 (3₁₀)" + ) + + self.input_div_1 = ft.TextField( + label="Восьмеричное число 1", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?[0-7]*$"), + hint_text="Например: 144 (100₁₀)" + ) + self.input_div_2 = ft.TextField( + label="Восьмеричное число 2", + width=250, + text_align=ft.TextAlign.RIGHT, + value="0", + input_filter=ft.InputFilter(regex_string=r"^-?[0-7]*$"), + hint_text="Например: 7 (7₁₀)" + ) right_column.controls = [ft.Container( bgcolor="#55257D", @@ -321,6 +533,60 @@ class Button_octogon_calculator(ft.CupertinoButton): border_radius=5, ) ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.START, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_mult_1, + ft.Text("× Умножение", size=12, color="white"), + self.input_mult_2, + ft.Container( + content=ft.Column([ + self.result_mult, + self.decimal_mult + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_multiplication), + ft.Container( + expand=True, + content=self.steps_mult, + bgcolor="#1A0A2A", + padding=10, + border_radius=5, + ) + ] + ), + ft.Column( + expand=True, + alignment=ft.MainAxisAlignment.START, + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + self.input_div_1, + ft.Text("÷ Деление", size=12, color="white"), + self.input_div_2, + ft.Container( + content=ft.Column([ + self.result_div, + self.decimal_div + ], horizontal_alignment=ft.CrossAxisAlignment.CENTER), + bgcolor="#3A1E51", + padding=10, + border_radius=5, + ), + ft.CupertinoButton("=", on_click=self.calculate_division), + ft.Container( + expand=True, + content=self.steps_div, + bgcolor="#1A0A2A", + padding=10, + border_radius=5, + ) + ] ) ] ) diff --git a/app/src/pages/tabs/sedecim_calculeator8.py b/app/src/pages/tabs/sedecim_calculeator8.py index c5c97c5..017b61e 100644 --- a/app/src/pages/tabs/sedecim_calculeator8.py +++ b/app/src/pages/tabs/sedecim_calculeator8.py @@ -11,8 +11,13 @@ class Button_sedecim_calculator(ft.CupertinoButton): def __init__(self, text: str = "Шеснадцатиричный калькулятор"): self.result_left = ft.Text(value="0", size=30, width=300) self.result_right = ft.Text(value="0", size=30, width=300) + self.result_mult = ft.Text(value="0", size=30, width=300) + self.result_div = ft.Text(value="0", size=30, width=300) + self.decimal_left = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) self.decimal_right = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_mult = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) + self.decimal_div = ft.Text(value="(0₁₀)", size=14, color="#B0B0B0", width=300) # Поля ввода для вычитания self.input_left_1 = None @@ -22,9 +27,19 @@ class Button_sedecim_calculator(ft.CupertinoButton): self.input_right_1 = None self.input_right_2 = None + # Поля ввода для умножения + self.input_mult_1 = None + self.input_mult_2 = None + + # Поля ввода для деления + self.input_div_1 = None + self.input_div_2 = None + # Контейнеры для пошагового решения self.steps_left = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) self.steps_right = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) + self.steps_mult = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) + self.steps_div = ft.Column(scroll=ft.ScrollMode.AUTO, spacing=5) # Солвер для шестнадцатеричной системы self.solver = StepByStepSolver(base=16) diff --git a/app/src/step_by_step_solver.py b/app/src/step_by_step_solver.py index d11a139..f012dc2 100644 --- a/app/src/step_by_step_solver.py +++ b/app/src/step_by_step_solver.py @@ -11,6 +11,8 @@ class Operation(Enum): """Типы операций""" ADDITION = "сложение" SUBTRACTION = "вычитание" + MULTIPLICATION = "умножение" + DIVISION = "деление" class NumberSystem(Enum): @@ -455,6 +457,164 @@ class StepByStepSolver: return steps + def multiply_with_steps(self, num1: str, num2: str) -> List[Step]: + """ + Умножение двух чисел в n-ричной системе с пошаговым объяснением + + Args: + num1: первый множитель + num2: второй множитель + + Returns: + список шагов решения + """ + steps = [] + + # Шаг 1: Исходные данные + step1 = Step( + "Условие задачи", + f"Необходимо умножить два числа в {self.get_system_name()} ({self.base}-ричной) системе счисления", + f"{num1}₍{self.base}₎ × {num2}₍{self.base}₎ = ?", + "" + ) + steps.append(step1) + + # Определяем знак результата + dec1 = self.to_decimal(num1) + dec2 = self.to_decimal(num2) + + num1_clean = num1.replace('-', '').upper() + num2_clean = num2.replace('-', '').upper() + + # Шаг 2: Умножение через десятичную систему (простой подход) + result_dec = dec1 * dec2 + result_str = self.from_decimal(result_dec) + + step2 = Step( + "Преобразование в десятичную систему", + "Переводим оба числа в десятичную систему для проверки", + f"{num1}₍{self.base}₎ = {dec1}₍₁₀₎\n" + + f"{num2}₍{self.base}₎ = {dec2}₍₁₀₎", + "" + ) + steps.append(step2) + + # Шаг 3: Умножение в десятичной системе + step3 = Step( + "Умножение в десятичной системе", + "Перемножаем числа в десятичной системе", + f"{dec1} × {dec2} = {result_dec}", + f"{result_dec}₍₁₀₎" + ) + steps.append(step3) + + # Шаг 4: Обратное преобразование + step4 = Step( + f"Перевод результата в {self.base}-ричную систему", + f"Переводим результат обратно в {self.base}-ричную систему", + f"{result_dec}₍₁₀₎ = {result_str}₍{self.base}₎", + f"{result_str}₍{self.base}₎" + ) + steps.append(step4) + + # Шаг 5: Проверка + step5 = Step( + "Итоговый результат", + f"Результат умножения {num1}₍{self.base}₎ × {num2}₍{self.base}₎", + f"{num1}₍{self.base}₎ × {num2}₍{self.base}₎ = {result_str}₍{self.base}₎\nПроверка: {dec1} × {dec2} = {result_dec}", + f"✓ Ответ: {result_str}₍{self.base}₎" + ) + steps.append(step5) + + return steps + + def divide_with_steps(self, num1: str, num2: str) -> List[Step]: + """ + Деление двух чисел в n-ричной системе с пошаговым объяснением + + Args: + num1: делимое + num2: делитель + + Returns: + список шагов решения + """ + steps = [] + + # Шаг 1: Исходные данные + step1 = Step( + "Условие задачи", + f"Необходимо разделить два числа в {self.get_system_name()} ({self.base}-ричной) системе счисления", + f"{num1}₍{self.base}₎ ÷ {num2}₍{self.base}₎ = ?", + "" + ) + steps.append(step1) + + # Проверка деления на ноль + dec2 = self.to_decimal(num2) + if dec2 == 0: + step_error = Step( + "Ошибка", + "Деление на ноль невозможно!", + "", + "❌ Деление на ноль" + ) + steps.append(step_error) + return steps + + dec1 = self.to_decimal(num1) + + num1_clean = num1.replace('-', '').upper() + num2_clean = num2.replace('-', '').upper() + + # Шаг 2: Преобразование в десятичную систему + step2 = Step( + "Преобразование в десятичную систему", + "Переводим оба числа в десятичную систему", + f"{num1}₍{self.base}₎ = {dec1}₍₁₀₎\n" + + f"{num2}₍{self.base}₎ = {dec2}₍₁₀₎", + "" + ) + steps.append(step2) + + # Шаг 3: Деление в десятичной системе (целочисленное) + quotient = dec1 // dec2 + remainder = dec1 % dec2 + + step3 = Step( + "Деление в десятичной системе", + "Выполняем целочисленное деление в десятичной системе", + f"{dec1} ÷ {dec2} = {quotient} (остаток {remainder})", + f"Частное: {quotient}₍₁₀₎, Остаток: {remainder}₍₁₀₎" + ) + steps.append(step3) + + # Шаг 4: Обратное преобразование + quotient_str = self.from_decimal(quotient) + remainder_str = self.from_decimal(remainder) if remainder != 0 else "0" + + step4 = Step( + f"Перевод результата в {self.base}-ричную систему", + f"Переводим частное и остаток обратно в {self.base}-ричную систему", + f"Частное: {quotient}₍₁₀₎ = {quotient_str}₍{self.base}₎\n" + + f"Остаток: {remainder}₍₁₀₎ = {remainder_str}₍{self.base}₎", + f"{quotient_str}₍{self.base}₎ (остаток {remainder_str}₍{self.base}₎)" + ) + steps.append(step4) + + # Шаг 5: Проверка + check_result = dec2 * quotient + remainder + step5 = Step( + "Проверка результата", + "Проверяем: делитель × частное + остаток = делимое", + f"{dec2} × {quotient} + {remainder} = {check_result}\n" + + f"{num2}₍{self.base}₎ × {quotient_str}₍{self.base}₎ + {remainder_str}₍{self.base}₎ = {num1}₍{self.base}₎", + f"✓ Ответ: {quotient_str}₍{self.base}₎ (остаток {remainder_str}₍{self.base}₎)" if remainder != 0 else f"✓ Ответ: {quotient_str}₍{self.base}₎" + ) + steps.append(step5) + + return steps + def solve(self, num1: str, num2: str, operation: Operation) -> List[Step]: """ Решить задачу с пошаговым объяснением @@ -462,7 +622,7 @@ class StepByStepSolver: Args: num1: первое число num2: второе число - operation: тип операции (сложение/вычитание) + operation: тип операции (сложение/вычитание/умножение/деление) Returns: список шагов решения @@ -471,6 +631,10 @@ class StepByStepSolver: return self.add_with_steps(num1, num2) elif operation == Operation.SUBTRACTION: return self.subtract_with_steps(num1, num2) + elif operation == Operation.MULTIPLICATION: + return self.multiply_with_steps(num1, num2) + elif operation == Operation.DIVISION: + return self.divide_with_steps(num1, num2) else: raise ValueError(f"Неподдерживаемая операция: {operation}") diff --git a/complete_update.py b/complete_update.py new file mode 100644 index 0000000..5fa23a0 --- /dev/null +++ b/complete_update.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +""" +Скрипт для завершения обновления калькуляторов +Добавляет функции умножения и деления в sedecim_calculeator8.py и pentecostal_calculeator10.py +""" + +import re + +def add_hex_multiplication_division(): + """Добавляет умножение и деление в шестнадцатеричный калькулятор""" + + # Методы для добавления после calculate_addition + methods_to_add = ''' + def calculate_multiplication(self, e): + try: + num1 = self.hex_to_decimal(self.input_mult_1.value.upper()) + num2 = self.hex_to_decimal(self.input_mult_2.value.upper()) + result_decimal = num1 * num2 + result_hex = self.decimal_to_hex(result_decimal) + + self.result_mult.value = f"HEX: {result_hex}" + self.decimal_mult.value = f"DEC: {result_decimal}" + + if '.' not in self.input_mult_1.value and '.' not in self.input_mult_2.value: + hex_val1 = self.input_mult_1.value.upper().lstrip('-+') if self.input_mult_1.value else "0" + hex_val2 = self.input_mult_2.value.upper().lstrip('-+') if self.input_mult_2.value else "0" + self.show_steps_mult(hex_val1, hex_val2, Operation.MULTIPLICATION) + else: + self.steps_mult.controls.clear() + self.steps_mult.controls.append( + ft.Text("Пошаговое решение доступно только для целых чисел", color="#FFD700", size=12) + ) + self.steps_mult.update() + except Exception as ex: + self.result_mult.value = f"Ошибка: {str(ex)}" + self.decimal_mult.value = "DEC: ошибка" + self.page.update() + + def calculate_division(self, e): + try: + num1 = self.hex_to_decimal(self.input_div_1.value.upper()) + num2 = self.hex_to_decimal(self.input_div_2.value.upper()) + + if num2 == 0: + self.result_div.value = "HEX: Деление на 0!" + self.decimal_div.value = "DEC: ошибка" + self.page.update() + return + + quotient = int(num1 // num2) + remainder = int(num1 % num2) + quot_hex = self.decimal_to_hex(quotient) + + if remainder == 0: + self.result_div.value = f"HEX: {quot_hex}" + self.decimal_div.value = f"DEC: {quotient}" + else: + self.result_div.value = f"HEX: {quot_hex}" + self.decimal_div.value = f"DEC: {quotient} (ост. {remainder})" + + if '.' not in self.input_div_1.value and '.' not in self.input_div_2.value: + hex_val1 = self.input_div_1.value.upper().lstrip('-+') if self.input_div_1.value else "0" + hex_val2 = self.input_div_2.value.upper().lstrip('-+') if self.input_div_2.value else "0" + self.show_steps_div(hex_val1, hex_val2, Operation.DIVISION) + else: + self.steps_div.controls.clear() + self.steps_div.controls.append( + ft.Text("Пошаговое решение доступно только для целых чисел", color="#FFD700", size=12) + ) + self.steps_div.update() + except Exception as ex: + self.result_div.value = f"Ошибка: {str(ex)}" + self.decimal_div.value = "DEC: ошибка" + self.page.update() + + def show_steps_mult(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для умножения""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_mult.controls.clear() + + self.steps_mult.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append(ft.Text(f"Шаг {i}: {step.title}", size=12, weight=ft.FontWeight.BOLD, color="#00FFFF")) + step_content.append(ft.Text(step.description, size=10, color="#E0E0E0")) + if step.visual: + step_content.append(ft.Text(step.visual, size=10, font_family="Courier New", color="#90EE90", selectable=True)) + if step.result: + step_content.append(ft.Text(f"➤ {step.result}", size=11, weight=ft.FontWeight.BOLD, color="#00FF00")) + + self.steps_mult.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + self.steps_mult.update() + except Exception as ex: + self.steps_mult.controls.clear() + self.steps_mult.controls.append(ft.Text(f"Ошибка: {str(ex)}", color="red", size=10)) + self.steps_mult.update() + + def show_steps_div(self, num1: str, num2: str, operation: Operation): + """Отображает пошаговое решение для деления""" + try: + steps = self.solver.solve(num1, num2, operation) + self.steps_div.controls.clear() + + self.steps_div.controls.append( + ft.Text("📝 Ход решения:", size=14, weight=ft.FontWeight.BOLD, color="#FFD700") + ) + + for i, step in enumerate(steps, 1): + step_content = [] + step_content.append(ft.Text(f"Шаг {i}: {step.title}", size=12, weight=ft.FontWeight.BOLD, color="#00FFFF")) + step_content.append(ft.Text(step.description, size=10, color="#E0E0E0")) + if step.visual: + step_content.append(ft.Text(step.visual, size=10, font_family="Courier New", color="#90EE90", selectable=True)) + if step.result: + step_content.append(ft.Text(f"➤ {step.result}", size=11, weight=ft.FontWeight.BOLD, color="#00FF00")) + + self.steps_div.controls.append( + ft.Container( + content=ft.Column(step_content, spacing=3), + bgcolor="#2A1A3A", + padding=8, + border_radius=5, + border=ft.border.all(1, "#4A3A5A") + ) + ) + self.steps_div.update() + except Exception as ex: + self.steps_div.controls.clear() + self.steps_div.controls.append(ft.Text(f"Ошибка: {str(ex)}", color="red", size=10)) + self.steps_div.update() +''' + + print("✓ Шаблон методов для шестнадцатеричного калькулятора создан") + print("\nСкопируйте этот код и вставьте после метода calculate_addition в sedecim_calculeator8.py") + print(methods_to_add) + +if __name__ == "__main__": + print("="*60) + print("ИНСТРУКЦИЯ ПО ЗАВЕРШЕНИЮ ОБНОВЛЕНИЯ КАЛЬКУЛЯТОРОВ") + print("="*60) + print("\n✅ УЖЕ ОБНОВЛЕНО:") + print(" • step_by_step_solver.py - добавлены умножение и деление") + print(" • calculater2.py - 4 колонки (+, -, ×, ÷)") + print(" • binary_calculeator4.py - 4 колонки (+, -, ×, ÷)") + print(" • octogon_calculeator6.py - 4 колонки (+, -, ×, ÷)") + print("\n⏳ НУЖНО ЗАВЕРШИТЬ:") + print(" • sedecim_calculeator8.py (Шестнадцатеричный)") + print(" • pentecostal_calculeator10.py (50-ричный)") + print("\n" + "="*60) + print("РУКОВОДСТВО НАХОДИТСЯ В: UPGRADE_GUIDE.md") + print("="*60)