dev: рабочие изменения
163
app/.gitignore
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
*.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# Flet
|
||||
storage/
|
||||
81
app/README.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# App app
|
||||
|
||||
## Run the app
|
||||
|
||||
### uv
|
||||
|
||||
Run as a desktop app:
|
||||
|
||||
```
|
||||
uv run flet run
|
||||
```
|
||||
|
||||
Run as a web app:
|
||||
|
||||
```
|
||||
uv run flet run --web
|
||||
```
|
||||
|
||||
### Poetry
|
||||
|
||||
Install dependencies from `pyproject.toml`:
|
||||
|
||||
```
|
||||
poetry install
|
||||
```
|
||||
|
||||
Run as a desktop app:
|
||||
|
||||
```
|
||||
poetry run flet run
|
||||
```
|
||||
|
||||
Run as a web app:
|
||||
|
||||
```
|
||||
poetry run flet run --web
|
||||
```
|
||||
|
||||
For more details on running the app, refer to the [Getting Started Guide](https://flet.dev/docs/getting-started/).
|
||||
|
||||
## Build the app
|
||||
|
||||
### Android
|
||||
|
||||
```
|
||||
flet build apk -v
|
||||
```
|
||||
|
||||
For more details on building and signing `.apk` or `.aab`, refer to the [Android Packaging Guide](https://flet.dev/docs/publish/android/).
|
||||
|
||||
### iOS
|
||||
|
||||
```
|
||||
flet build ipa -v
|
||||
```
|
||||
|
||||
For more details on building and signing `.ipa`, refer to the [iOS Packaging Guide](https://flet.dev/docs/publish/ios/).
|
||||
|
||||
### macOS
|
||||
|
||||
```
|
||||
flet build macos -v
|
||||
```
|
||||
|
||||
For more details on building macOS package, refer to the [macOS Packaging Guide](https://flet.dev/docs/publish/macos/).
|
||||
|
||||
### Linux
|
||||
|
||||
```
|
||||
flet build linux -v
|
||||
```
|
||||
|
||||
For more details on building Linux package, refer to the [Linux Packaging Guide](https://flet.dev/docs/publish/linux/).
|
||||
|
||||
### Windows
|
||||
|
||||
```
|
||||
flet build windows -v
|
||||
```
|
||||
|
||||
For more details on building Windows package, refer to the [Windows Packaging Guide](https://flet.dev/docs/publish/windows/).
|
||||
41
app/pyproject.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
[project]
|
||||
name = "app"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.9"
|
||||
authors = [
|
||||
{ name = "Flet developer", email = "you@example.com" }
|
||||
]
|
||||
dependencies = [
|
||||
"flet==0.28.3"
|
||||
]
|
||||
|
||||
[tool.flet]
|
||||
# org name in reverse domain name notation, e.g. "com.mycompany".
|
||||
# Combined with project.name to build bundle ID for iOS and Android apps
|
||||
org = "com.mycompany"
|
||||
|
||||
# project display name that is used as an app title on Android and iOS home screens,
|
||||
# shown in window titles and about app dialogs on desktop.
|
||||
product = "app"
|
||||
|
||||
# company name to display in about app dialogs
|
||||
company = "Flet"
|
||||
|
||||
# copyright text to display in about app dialogs
|
||||
copyright = "Copyright (C) 2025 by Flet"
|
||||
|
||||
[tool.flet.app]
|
||||
path = "src"
|
||||
|
||||
[tool.uv]
|
||||
dev-dependencies = [
|
||||
"flet[all]==0.28.3",
|
||||
]
|
||||
|
||||
[tool.poetry]
|
||||
package-mode = false
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
flet = {extras = ["all"], version = "0.28.3"}
|
||||
BIN
app/src/assets/icon.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
app/src/assets/splash_android.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
app/src/assets/Система счисления 1.jpg
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
app/src/assets/Система счисления 2.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
app/src/assets/Система счисления 3.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/assets/Система счисления 4.jpg
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
app/src/assets/Система счисления 5.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
app/src/assets/Система счисления 6.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
10
app/src/designer.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import flet as ft
|
||||
from flet.core.types import OptionalControlEventCallable
|
||||
|
||||
right_column = ft.Column(
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
expand=True,
|
||||
|
||||
)
|
||||
|
||||
alphabet="αβγδεζηθικλμνξοπρστυφχψω"
|
||||
16
app/src/main.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import flet as ft
|
||||
from views import ViewsHendler
|
||||
import designer as ds
|
||||
|
||||
def main(page: ft.Page):
|
||||
page.title = "Calculater CHELGU"
|
||||
def PageLoading(route={}):
|
||||
print(page.route)
|
||||
page.views.clear()
|
||||
page.views.append(ViewsHendler(page=page)[page.route])
|
||||
page.update()
|
||||
|
||||
page.on_route_change = PageLoading
|
||||
page.go("/")
|
||||
|
||||
ft.app(target=main, assets_dir="assets")
|
||||
40
app/src/pages/main_page.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import flet as ft
|
||||
import designer as ds
|
||||
from pages.tabs import start1,calculater2, binary_data3, binary_calculeator4, octogon_data5, octogon_calculeator6, sedecim_data7
|
||||
|
||||
class Main_page(ft.View):
|
||||
def __init__(self, page):
|
||||
self.page = page
|
||||
super().__init__(
|
||||
route="/",
|
||||
controls=[
|
||||
ft.Row(
|
||||
expand=True,
|
||||
controls=[
|
||||
ft.Column(
|
||||
horizontal_alignment=ft.CrossAxisAlignment.START,
|
||||
width=300,
|
||||
alignment=ft.MainAxisAlignment.START,
|
||||
controls=[
|
||||
start1.Button_text_data(),
|
||||
calculater2.Button_calculeator(),
|
||||
binary_data3.Button_binary_data(),
|
||||
binary_calculeator4.Button_binary_calculator(),
|
||||
octogon_data5.Button_text_data(),
|
||||
octogon_calculeator6.Button_octogon_calculator(),
|
||||
sedecim_data7.Button_sedecim_data(),
|
||||
ft.Container(
|
||||
bgcolor="#280A3F",
|
||||
expand=True,
|
||||
)
|
||||
]
|
||||
),
|
||||
ds.right_column
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
237
app/src/pages/tabs/binary_calculeator4.py
Normal file
@@ -0,0 +1,237 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
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.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.input_left_1 = None
|
||||
self.input_left_2 = None
|
||||
|
||||
# Поля ввода для сложения
|
||||
self.input_right_1 = None
|
||||
self.input_right_2 = None
|
||||
|
||||
# Количество бит для представления (по умолчанию 8)
|
||||
self.bit_width = 16
|
||||
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def to_twos_complement(self, num, bit_width):
|
||||
"""Преобразует число в дополнительный код"""
|
||||
if num >= 0:
|
||||
return format(num, f'0{bit_width}b')
|
||||
else:
|
||||
# Для отрицательных чисел используем дополнительный код
|
||||
return format((1 << bit_width) + num, f'0{bit_width}b')
|
||||
|
||||
def from_twos_complement(self, binary_str):
|
||||
"""Преобразует из дополнительного кода в десятичное число"""
|
||||
bit_width = len(binary_str)
|
||||
value = int(binary_str, 2)
|
||||
|
||||
# Проверяем знаковый бит (старший бит)
|
||||
if binary_str[0] == '1':
|
||||
# Отрицательное число
|
||||
value = value - (1 << bit_width)
|
||||
|
||||
return value
|
||||
|
||||
def validate_binary(self, value):
|
||||
"""Проверяет, является ли строка корректным двоичным числом"""
|
||||
if not value:
|
||||
return True
|
||||
# Только 0 и 1
|
||||
return all(c in "01" for c in value)
|
||||
|
||||
def calculate_subtraction(self, e):
|
||||
try:
|
||||
bin1 = self.input_left_1.value or "0"
|
||||
bin2 = self.input_left_2.value or "0"
|
||||
|
||||
# Проверка корректности двоичных чисел
|
||||
if not self.validate_binary(bin1) or not self.validate_binary(bin2):
|
||||
self.result_left.value = "Ошибка: неверный формат"
|
||||
self.decimal_left.value = ""
|
||||
self.result_left.update()
|
||||
self.decimal_left.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_left.value = binary_result
|
||||
self.decimal_left.value = f"({result}₁₀)"
|
||||
self.result_left.update()
|
||||
self.decimal_left.update()
|
||||
except ValueError as ex:
|
||||
self.result_left.value = "Ошибка"
|
||||
self.decimal_left.value = str(ex)
|
||||
self.result_left.update()
|
||||
self.decimal_left.update()
|
||||
|
||||
def calculate_addition(self, e):
|
||||
try:
|
||||
bin1 = self.input_right_1.value or "0"
|
||||
bin2 = self.input_right_2.value or "0"
|
||||
|
||||
# Проверка корректности двоичных чисел
|
||||
if not self.validate_binary(bin1) or not self.validate_binary(bin2):
|
||||
self.result_right.value = "Ошибка: неверный формат"
|
||||
self.decimal_right.value = ""
|
||||
self.result_right.update()
|
||||
self.decimal_right.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_right.value = binary_result
|
||||
self.decimal_right.value = f"({result}₁₀)"
|
||||
self.result_right.update()
|
||||
self.decimal_right.update()
|
||||
except ValueError as ex:
|
||||
self.result_right.value = "Ошибка"
|
||||
self.decimal_right.value = str(ex)
|
||||
self.result_right.update()
|
||||
self.decimal_right.update()
|
||||
|
||||
def test_data(self, e):
|
||||
# Создаем поля ввода с валидацией для двоичных чисел
|
||||
self.input_left_1 = ft.TextField(
|
||||
label="Двоичное число 1",
|
||||
width=250,
|
||||
text_align=ft.TextAlign.RIGHT,
|
||||
value="0",
|
||||
input_filter=ft.InputFilter(regex_string=r"^[01]*$"), # только 0 и 1
|
||||
hint_text="Например: 00001010 (10) или 11110110 (-10)"
|
||||
)
|
||||
self.input_left_2 = ft.TextField(
|
||||
label="Двоичное число 2",
|
||||
width=250,
|
||||
text_align=ft.TextAlign.RIGHT,
|
||||
value="0",
|
||||
input_filter=ft.InputFilter(regex_string=r"^[01]*$"),
|
||||
hint_text="Например: 00000101 (5)"
|
||||
)
|
||||
|
||||
self.input_right_1 = ft.TextField(
|
||||
label="Двоичное число 1",
|
||||
width=250,
|
||||
text_align=ft.TextAlign.RIGHT,
|
||||
value="0",
|
||||
input_filter=ft.InputFilter(regex_string=r"^[01]*$"),
|
||||
hint_text="Например: 00001010 (10)"
|
||||
)
|
||||
self.input_right_2 = ft.TextField(
|
||||
label="Двоичное число 2",
|
||||
width=250,
|
||||
text_align=ft.TextAlign.RIGHT,
|
||||
value="0",
|
||||
input_filter=ft.InputFilter(regex_string=r"^[01]*$"),
|
||||
hint_text="Например: 00000101 (5)"
|
||||
)
|
||||
|
||||
right_column.controls = [ft.Container(
|
||||
bgcolor="#55257D",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
controls=[
|
||||
ft.Text("Двоичный калькулятор (дополнительный код)", size=20, color="white", weight=ft.FontWeight.BOLD),
|
||||
ft.Text("Отрицательные числа в дополнительном коде (старший бит = 1)", size=11, color="#B0B0B0", italic=True),
|
||||
ft.Text(f"Разрядность: {self.bit_width} бит. Диапазон: {-(1 << (self.bit_width-1))} .. {(1 << (self.bit_width-1))-1}", size=11, color="#B0B0B0"),
|
||||
ft.Row(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
vertical_alignment=ft.CrossAxisAlignment.START,
|
||||
controls=[
|
||||
ft.Column(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
self.input_left_1,
|
||||
ft.Text("——— Вычитание", size=12, color="white"),
|
||||
self.input_left_2,
|
||||
ft.Container(
|
||||
content=ft.Column([
|
||||
self.result_left,
|
||||
self.decimal_left
|
||||
], horizontal_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
bgcolor="#3A1E51",
|
||||
padding=10,
|
||||
border_radius=5,
|
||||
),
|
||||
ft.CupertinoButton("=", on_click=self.calculate_subtraction)
|
||||
]
|
||||
),
|
||||
ft.Column(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
self.input_right_1,
|
||||
ft.Text("—|— Сложение", size=12, color="white"),
|
||||
self.input_right_2,
|
||||
ft.Container(
|
||||
content=ft.Column([
|
||||
self.result_right,
|
||||
self.decimal_right
|
||||
], horizontal_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
bgcolor="#3A1E51",
|
||||
padding=10,
|
||||
border_radius=5,
|
||||
),
|
||||
ft.CupertinoButton("=", on_click=self.calculate_addition)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
],
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
120
app/src/pages/tabs/binary_data3.py
Normal file
@@ -0,0 +1,120 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
class Button_binary_data(ft.CupertinoButton):
|
||||
def __init__(self, text: str = "Двоичная система счисления"):
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def test_data(e, self):
|
||||
md1="""
|
||||
Двоичная система счисления — это система, в которой используются только две цифры: 0 и 1.
|
||||
Двои́чная систе́ма счисле́ния — позиционная система счисления с основанием 2. Благодаря непосредственной реализации в цифровых электронных схемах на логических вентилях, двоичная система используется практически во всех современных компьютерах и прочих вычислительных электронных устройствах.
|
||||
|
||||
Компьютеры хранят отрицательные числа иначе, чем положительные, из-за особенностей двоичной системы и конструкции процессоров. Вот основные способы:
|
||||
|
||||
1. Прямой код (очень редко используется)
|
||||
|
||||
Старший бит (самый левый) делает число отрицательным:
|
||||
Например, для 8 бит:
|
||||
00010101 — это +21
|
||||
10010101 — это -21
|
||||
Недостатки: две разные записи нуля (положительный и отрицательный), сложнее реализовать арифметику.
|
||||
|
||||
2. Обратный код (редко используется)
|
||||
|
||||
Если число отрицательное, инвертируются все биты, кроме знакового:
|
||||
+21: 00010101
|
||||
-21: 11101010
|
||||
Недостатки: две записи нуля, сложная арифметика.
|
||||
|
||||
3. Дополнительный код (почти всегда используется)
|
||||
|
||||
Для отрицательного числа инвертируются все биты и прибавляется единица:
|
||||
+21: 00010101
|
||||
-21: инвертируем: 11101010, прибавляем 1: 11101011
|
||||
Преимущества: только одна запись нуля, простая арифметика (сложение и вычитание одинаковы для положительных и отрицательных чисел).
|
||||
|
||||
Почему люди пишут числа как "-10101"
|
||||
|
||||
Запись -10101 — это просто привычный способ обозначения отрицательных чисел в десятичной или любой другой системе счисления.
|
||||
В памяти компьютера знак не хранится отдельно, а закодирован в битах (обычно старший бит — знаковый).
|
||||
Для человека запись с минусом интуитивно понятна, для компьютера — это набор битов, интерпретируемый по правилам (обычно дополнительного кода).
|
||||
|
||||
Другие тонкости
|
||||
|
||||
Знаковый и беззнаковый типы:
|
||||
Например, в языке C/C++ есть int (знаковый) и unsigned int (беззнаковый).
|
||||
Переполнение:
|
||||
Если сумма двух больших положительных чисел выходит за пределы диапазона типа, возникает переполнение.
|
||||
Диапазон значений:
|
||||
В 8 битах:
|
||||
беззнаковый: 0..255
|
||||
знаковый (доп. код): -128..127
|
||||
|
||||
Пример (8 бит, дополнительный код)
|
||||
|
||||
+5: 00000101
|
||||
-5: инвертируем: 11111010, прибавляем 1: 11111011
|
||||
Сложение: 00000101 + 11111011 = 00000000 (0), перенос игнорируется
|
||||
|
||||
Мантиса, запятая и хранение дробных чисел
|
||||
|
||||
Мантиса — это дробная часть числа в позиционной системе. В двоичной мантиса хранится как последовательность битов, где k-й бит дробной части соответствует весу 2^{-k}.
|
||||
|
||||
Запятая (разделитель) в человеческом вводе обозначает границу между целой частью и мантиссой. Пример: 101,101₂ = 1*2^2 + 0*2^1 + 1*2^0 + 1*2^{-1} + 0*2^{-2} + 1*2^{-3} = 5.625.
|
||||
|
||||
В реальной памяти компьютера точка (запятая) обычно не хранится как символ. Существует два распространённых способа хранения дробных чисел:
|
||||
- Fixed-point (fixed Q-format): число хранится как целое, представляющее значение scaled = round(x * 2^{f}), где f — количество бит дробной части. Таким образом все числа интерпретируются как scaled/2^{f}.
|
||||
- Floating-point (IEEE-754): хранится знак, экспонента и мантисса; формат сложнее, даёт большой диапазон и нормализацию.
|
||||
|
||||
В этом калькуляторе дроби вводятся через запятую и обрабатываются как обычные дробные значения (float) с фиксированной точностью при выводе (frac_precision бит).
|
||||
|
||||
Практические рекомендации
|
||||
|
||||
- Если хотите работать с отрицательными целыми в двоичной системе — вводите строку ровно N бит (например, 16). Старший бит будет определять знак.
|
||||
- Для дробных значений используйте запятую и при необходимости ставьте знак '-' перед всем числом: -101,01.
|
||||
- Помните про переполнение: при выводе целого результата в двоичной системе он должен помещаться в выбранную разрядность.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
right_column.controls=[ ft.Container(
|
||||
bgcolor="#55257D",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
ft.Text(md1, size=16, color="white"),
|
||||
ft.Text("Перевод из десятичной системы в двоичную:", size=16, color="white"),
|
||||
ft.Container(
|
||||
bgcolor="#000000",
|
||||
content=ft.Image(src="./Система счисления 1.jpg", expand=True),
|
||||
border_radius=10,
|
||||
width=350,
|
||||
height=300,
|
||||
),
|
||||
ft.Text("Перевод обратно в десятичную систему:", size=16, color="white"),
|
||||
ft.Container(
|
||||
bgcolor="#000000",
|
||||
content=ft.Image(src="./Система счисления 2.png", expand=True),
|
||||
border_radius=10,
|
||||
width=580,
|
||||
height=300,
|
||||
),
|
||||
ft.Text("Работа со знаком:", size=16, color="white"),
|
||||
|
||||
],
|
||||
#width=600,
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
169
app/src/pages/tabs/calculater2.py
Normal file
@@ -0,0 +1,169 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
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.binary_left = ft.Text(value="(0₂)", size=14, color="#B0B0B0", width=300)
|
||||
#self.binary_right = ft.Text(value="(0₂)", size=14, color="#B0B0B0", width=300)
|
||||
|
||||
# Поля ввода для вычитания
|
||||
self.input_left_1 = None
|
||||
self.input_left_2 = None
|
||||
|
||||
# Поля ввода для сложения
|
||||
self.input_right_1 = None
|
||||
self.input_right_2 = None
|
||||
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def to_binary(self, num):
|
||||
"""Преобразует десятичное число в двоичное"""
|
||||
if num >= 0:
|
||||
return bin(num)[2:] # Убираем '0b'
|
||||
else:
|
||||
return "-" + bin(num)[3:] # Убираем '-0b'
|
||||
|
||||
def calculate_subtraction(self, e):
|
||||
try:
|
||||
num1 = int(self.input_left_1.value or 0)
|
||||
num2 = int(self.input_left_2.value or 0)
|
||||
result = num1 - num2
|
||||
|
||||
self.result_left.value = str(result)
|
||||
#self.binary_left.value = f"({self.to_binary(result)}₂)"
|
||||
|
||||
self.result_left.update()
|
||||
#self.binary_left.update()
|
||||
except ValueError:
|
||||
self.result_left.value = "Ошибка"
|
||||
#self.binary_left.value = "Неверный формат"
|
||||
self.result_left.update()
|
||||
#self.binary_left.update()
|
||||
|
||||
def calculate_addition(self, e):
|
||||
try:
|
||||
num1 = int(self.input_right_1.value or 0)
|
||||
num2 = int(self.input_right_2.value or 0)
|
||||
result = num1 + num2
|
||||
|
||||
self.result_right.value = str(result)
|
||||
#self.binary_right.value = f"({self.to_binary(result)}₂)"
|
||||
|
||||
self.result_right.update()
|
||||
#self.binary_right.update()
|
||||
except ValueError:
|
||||
self.result_right.value = "Ошибка"
|
||||
#self.binary_right.value = "Неверный формат"
|
||||
self.result_right.update()
|
||||
#self.binary_right.update()
|
||||
|
||||
def test_data(self, e):
|
||||
# Создаем поля ввода с валидацией
|
||||
self.input_left_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="Например: 42"
|
||||
)
|
||||
self.input_left_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="Например: 17"
|
||||
)
|
||||
|
||||
self.input_right_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="Например: 42"
|
||||
)
|
||||
self.input_right_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="Например: 17"
|
||||
)
|
||||
|
||||
right_column.controls = [ft.Container(
|
||||
bgcolor="#55257D",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
controls=[
|
||||
ft.Text("Десятичный калькулятор", size=20, color="white", weight=ft.FontWeight.BOLD),
|
||||
ft.Text("Введите целые числа (положительные или отрицательные)", size=11, color="#B0B0B0", italic=True),
|
||||
ft.Row(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
vertical_alignment=ft.CrossAxisAlignment.START,
|
||||
controls=[
|
||||
ft.Column(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
self.input_left_1,
|
||||
ft.Text("——— Вычитание", size=12, color="white"),
|
||||
self.input_left_2,
|
||||
ft.Container(
|
||||
content=ft.Column([
|
||||
self.result_left,
|
||||
#self.binary_left
|
||||
], horizontal_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
bgcolor="#3A1E51",
|
||||
padding=10,
|
||||
border_radius=5,
|
||||
),
|
||||
ft.CupertinoButton("=", on_click=self.calculate_subtraction)
|
||||
]
|
||||
),
|
||||
ft.Column(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
self.input_right_1,
|
||||
ft.Text("—|— Сложение", size=12, color="white"),
|
||||
self.input_right_2,
|
||||
ft.Container(
|
||||
content=ft.Column([
|
||||
self.result_right,
|
||||
#self.binary_right
|
||||
], horizontal_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
bgcolor="#3A1E51",
|
||||
padding=10,
|
||||
border_radius=5,
|
||||
),
|
||||
ft.CupertinoButton("=", on_click=self.calculate_addition)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
],
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
223
app/src/pages/tabs/octogon_calculeator6.py
Normal file
@@ -0,0 +1,223 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
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.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.input_left_1 = None
|
||||
self.input_left_2 = None
|
||||
|
||||
# Поля ввода для сложения
|
||||
self.input_right_1 = None
|
||||
self.input_right_2 = None
|
||||
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def validate_octal(self, value: str) -> bool:
|
||||
"""Проверяет, является ли строка корректным восьмеричным числом.
|
||||
|
||||
Допускается пустая строка, опциональный ведущий знак '-' и цифры 0..7.
|
||||
"""
|
||||
if value is None:
|
||||
return True
|
||||
v = value.strip()
|
||||
if v == "":
|
||||
return True
|
||||
if v[0] == '-':
|
||||
v = v[1:]
|
||||
return all(c in '01234567' for c in v)
|
||||
|
||||
def calculate_subtraction(self, e):
|
||||
try:
|
||||
val1 = (self.input_left_1.value or "").strip()
|
||||
val2 = (self.input_left_2.value or "").strip()
|
||||
|
||||
# Проверка корректности восьмеричных чисел
|
||||
if not self.validate_octal(val1) or not self.validate_octal(val2):
|
||||
self.result_left.value = "Ошибка: неверный формат"
|
||||
self.decimal_left.value = ""
|
||||
self.result_left.update()
|
||||
self.decimal_left.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
|
||||
|
||||
# Преобразуем обратно в восьмеричный формат (без префикса 0o)
|
||||
oct_result = ('-' if result < 0 else '') + format(abs(result), 'o')
|
||||
|
||||
self.result_left.value = oct_result
|
||||
self.decimal_left.value = f"({result}₁₀)"
|
||||
self.result_left.update()
|
||||
self.decimal_left.update()
|
||||
except ValueError as ex:
|
||||
self.result_left.value = "Ошибка"
|
||||
self.decimal_left.value = str(ex)
|
||||
self.result_left.update()
|
||||
self.decimal_left.update()
|
||||
|
||||
def calculate_addition(self, e):
|
||||
try:
|
||||
val1 = (self.input_right_1.value or "").strip()
|
||||
val2 = (self.input_right_2.value or "").strip()
|
||||
|
||||
# Проверка корректности восьмеричных чисел
|
||||
if not self.validate_octal(val1) or not self.validate_octal(val2):
|
||||
self.result_right.value = "Ошибка: неверный формат"
|
||||
self.decimal_right.value = ""
|
||||
self.result_right.update()
|
||||
self.decimal_right.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_right.value = oct_result
|
||||
self.decimal_right.value = f"({result}₁₀)"
|
||||
self.result_right.update()
|
||||
self.decimal_right.update()
|
||||
except ValueError as ex:
|
||||
self.result_right.value = "Ошибка"
|
||||
self.decimal_right.value = str(ex)
|
||||
self.result_right.update()
|
||||
self.decimal_right.update()
|
||||
|
||||
def test_data(self, e):
|
||||
# Создаем поля ввода с валидацией для двоичных чисел
|
||||
# Поля ввода для восьмеричной системы — допускаются цифры 0..7 и опциональный знак '-'
|
||||
self.input_left_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="Например: 123 (83₁₀) или -17 (-15₁₀)"
|
||||
)
|
||||
self.input_left_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="Например: 45 (37₁₀)"
|
||||
)
|
||||
|
||||
self.input_right_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_right_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",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
controls=[
|
||||
ft.Text("Восьмеричный калькулятор", size=20, color="white", weight=ft.FontWeight.BOLD),
|
||||
ft.Text("Вводите числа в системе с основанием 8 (цифры 0..7). Поддерживается знак '-' перед числом.", size=11, color="#B0B0B0", italic=True),
|
||||
ft.Text(f"Пример: 123₈ = 83₁₀. Для ввода используйте цифры 0..7 и опциональный '-' перед числом.", size=11, color="#B0B0B0"),
|
||||
ft.Row(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
vertical_alignment=ft.CrossAxisAlignment.START,
|
||||
controls=[
|
||||
ft.Column(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
self.input_left_1,
|
||||
ft.Text("——— Вычитание", size=12, color="white"),
|
||||
self.input_left_2,
|
||||
ft.Container(
|
||||
content=ft.Column([
|
||||
self.result_left,
|
||||
self.decimal_left
|
||||
], horizontal_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
bgcolor="#3A1E51",
|
||||
padding=10,
|
||||
border_radius=5,
|
||||
),
|
||||
ft.CupertinoButton("=", on_click=self.calculate_subtraction)
|
||||
]
|
||||
),
|
||||
ft.Column(
|
||||
expand=True,
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
self.input_right_1,
|
||||
ft.Text("—|— Сложение", size=12, color="white"),
|
||||
self.input_right_2,
|
||||
ft.Container(
|
||||
content=ft.Column([
|
||||
self.result_right,
|
||||
self.decimal_right
|
||||
], horizontal_alignment=ft.CrossAxisAlignment.CENTER),
|
||||
bgcolor="#3A1E51",
|
||||
padding=10,
|
||||
border_radius=5,
|
||||
),
|
||||
ft.CupertinoButton("=", on_click=self.calculate_addition)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
],
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
82
app/src/pages/tabs/octogon_data5.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
|
||||
class Button_text_data(ft.CupertinoButton):
|
||||
def __init__(self, text: str = "Восьмеричная система счисления"):
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def test_data(e, self):
|
||||
md1 = """
|
||||
Восьмерична́я (окта́льная) система счисления — позиционная система с основанием 8.
|
||||
В ней используются цифры 0, 1, 2, 3, 4, 5, 6 и 7. Каждая позиция числа имеет вес, равный степени восьми: $8^0, 8^1, 8^2.
|
||||
|
||||
Коротко о сути и преимуществах:
|
||||
- Простое представление целых чисел в альтернативах к двоичной системе (группировка по 3 бита).
|
||||
- Удобна при отображении битовых полей и правах доступа (например, 0755 в UNIX).
|
||||
|
||||
Пример записи и перевода:
|
||||
123₈ = 1*8^2 + 2*8^1 + 3*8^0 = 64 + 16 + 3 = 83₁₀.
|
||||
|
||||
Как переводить (алгоритмы):
|
||||
- Из десятичной в восьмеричную (целая часть): делите число на 8, запоминайте остатки, читайте их в обратном порядке.
|
||||
- Десятичная дробь → восьмеричная: умножайте дробную часть на 8, целая часть результата — следующая цифра; повторяйте для оставшейся дроби.
|
||||
- Из двоичной в восьмеричную: группируйте биты по три (справа для целой части, слева для дробной) и заменяйте триплеты на соответствующую одну восьмеричную цифру, т.к. $8 = 2^3$.
|
||||
|
||||
Примеры:
|
||||
- 83₁₀ → 123₈ (83:8=10 r3; 10:8=1 r2; 1:8=0 r1 → 123₈).
|
||||
- 101110₂ → группируем: 101 110 → 5 6 → 56₈.
|
||||
- 13.375₁₀ → 15.3₈ (13₁₀ = 15₈; 0.375·8 = 3.0 → .3).
|
||||
|
||||
Нотация в языках программирования и практическое применение:
|
||||
- В Python/JS и многих современных языках восьмеричные литералы записываются с префиксом `0o` или `0O`: `0o755`.
|
||||
- В старых вариантах записи (например, в C-подобных средах) литерал с ведущим нулём (`0755`) означал окталь — будьте внимательны при переносе кода.
|
||||
- Отображение прав доступа в UNIX: `rwxr-xr-x` ↔ 755, где каждая тройка битов соответствует одной восьмеричной цифре.
|
||||
|
||||
Арифметика и ограничения:
|
||||
- Арифметические операции выполняются по тем же правилам позиционной системы, но перенос происходит при достижении 8.
|
||||
- Цифры 8 и 9 недопустимы в октале — проверяйте ввод.
|
||||
- Как и в других системах, дробные представления могут быть бесконечными (периодические).
|
||||
|
||||
Рекомендации для использования в калькуляторе:
|
||||
- При вводе целых октальных чисел допускайте только символы 0..7.
|
||||
- Для удобства преобразований показывайте промежуточные шаги: деление/остатки для целой части, умножение для дробной.
|
||||
- При работе с двоичными данными предоставьте кнопку или подсказку о группировке по 3 бита.
|
||||
|
||||
"""
|
||||
|
||||
right_column.controls = [ft.Container(
|
||||
bgcolor="#55257D",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
ft.Text(md1, size=16, color="white"),
|
||||
ft.Text("Перевод из десятичной системы в восьмеричную:", size=16, color="white"),
|
||||
ft.Container(
|
||||
bgcolor="#000000",
|
||||
content=ft.Image(src="./Система счисления 3.png", expand=True),
|
||||
border_radius=10,
|
||||
),
|
||||
ft.Text("Перевод обратно в десятичную систему:", size=16, color="white"),
|
||||
ft.Container(
|
||||
bgcolor="#000000",
|
||||
content=ft.Image(src="./Система счисления 4.jpg", expand=True),
|
||||
border_radius=10,
|
||||
),
|
||||
ft.Text("Практическое применение и заметки:", size=16, color="white"),
|
||||
ft.Text("- Используйте префикс 0o в коде; следите за вводом; отображайте примеры перевода.", size=14, color="white"),
|
||||
],
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
149
app/src/pages/tabs/sedecim_data7.py
Normal file
@@ -0,0 +1,149 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
|
||||
class Button_sedecim_data(ft.CupertinoButton):
|
||||
def __init__(self, text: str = "Шестнадцатеричная система счисления"):
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def test_data(e, self):
|
||||
md1 = """
|
||||
Шестнадцатеричная (hex) система счисления — позиционная система с основанием 16.
|
||||
В ней используются символы 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; буквы A..F соответствуют значениям 10..15.
|
||||
Каждая позиция числа имеет вес 16^k, поэтому, например, 1A₁₆ = 1*16 + 10 = 26₁₀.
|
||||
|
||||
Почему hex удобен:
|
||||
- Одна hex-цифра кодирует ровно 4 бита, поэтому перевод в/из двоичного вида делается группировкой по 4 бита.
|
||||
- Компактное и читаемое представление двоичных данных (адреса, дампы, цвета и т.д.).
|
||||
|
||||
Как хранятся отрицательные числа (аналогично двоичной интерпретации):
|
||||
|
||||
1. Прямой код (sign-magnitude, редкость)
|
||||
|
||||
Старший бит используется как знак: 0 — положительное, 1 — отрицательное.
|
||||
Пример (8 бит):
|
||||
+21: 00010101₂ = 0x15
|
||||
-21: 10010101₂ = 0x95
|
||||
Недостатки: два нуля (+0 и -0), сложность арифметики.
|
||||
|
||||
2. Обратный код (ones' complement, редко)
|
||||
|
||||
Для отрицательного числа инвертируются все биты положительного представления.
|
||||
+21: 00010101₂ = 0x15
|
||||
-21 (обратный код): 11101010₂ = 0xEA
|
||||
Недостатки: две записи нуля, сложная арифметика.
|
||||
|
||||
3. Дополнительный код (two's complement, повсеместно)
|
||||
|
||||
Для отрицательного числа инвертируются все биты и прибавляется 1.
|
||||
+21: 00010101₂ = 0x15
|
||||
-21: инвертируем → 11101010₂ = 0xEA; прибавляем 1 → 11101011₂ = 0xEB
|
||||
Преимущества: единственный ноль, простая арифметика (сложение/вычитание работают одинаково).
|
||||
|
||||
Почему люди пишут "-1A" или "-0x1A":
|
||||
|
||||
Человеческая запись с минусом — удобный способ показать знак. В памяти же знак обычно кодируется битами (обычно two's complement).
|
||||
Префикс `0x` часто используется в коде (например, `0x1A`). В некоторых ассемблерах применяют суффикс `h` (1Ah).
|
||||
|
||||
Другие важные тонкости:
|
||||
|
||||
- Типы: unsigned (беззнаковый) и signed (знаковый, обычно two's complement).
|
||||
- Переполнение: при выходе за диапазон типа происходит переполнение, его надо отслеживать.
|
||||
- Диапазон (8 бит): unsigned 0..255 (0x00..0xFF); two's complement -128..127 (0x80..0x7F).
|
||||
|
||||
Пример (8 бит, two's complement):
|
||||
|
||||
+5: 00000101₂ = 0x05
|
||||
-5: инвертируем → 11111010₂ = 0xFA; прибавляем 1 → 11111011₂ = 0xFB
|
||||
Сложение: 0x05 + 0xFB = 0x100 → 0x00 (перенос игнорируется в 8-битном контексте)
|
||||
|
||||
Мантиса и дробные значения в hex:
|
||||
|
||||
Дробная hex-цифра имеет вес 16^{-k}. Например: 0xA.F = 10 + 15/16 = 10.9375₁₀.
|
||||
В двоичной связи: каждая hex-цифра = 4 двоичных разряда, поэтому дробные hex-цифры соответствуют блокам по 4 двоичных дробных бита.
|
||||
|
||||
В реальной памяти дробные числа обычно хранятся в двоичном формате (fixed-point или IEEE-754 floating-point),
|
||||
а hex чаще используется как удобный формат ввода/вывода.
|
||||
|
||||
Практические рекомендации:
|
||||
|
||||
- Используйте префикс `0x` для явной записи hex в коде.
|
||||
- При вводе фиксируйте разрядность (например, N hex-цифр) для однозначности знака.
|
||||
- Для дробей используйте разделитель, понятный интерфейсу (запятая или точка) и интерпретируйте как hex-дробь.
|
||||
- Учитывайте порядок байтов (endianness) при интерпретации многобайтовых значений.
|
||||
|
||||
Таблица соответствия (коротко):
|
||||
|
||||
0 = 0 = 0000
|
||||
1 = 1 = 0001
|
||||
2 = 2 = 0010
|
||||
3 = 3 = 0011
|
||||
4 = 4 = 0100
|
||||
5 = 5 = 0101
|
||||
6 = 6 = 0110
|
||||
7 = 7 = 0111
|
||||
8 = 8 = 1000
|
||||
9 = 9 = 1001
|
||||
A = 10 = 1010
|
||||
B = 11 = 1011
|
||||
C = 12 = 1100
|
||||
D = 13 = 1101
|
||||
E = 14 = 1110
|
||||
F = 15 = 1111
|
||||
|
||||
Примеры:
|
||||
|
||||
255₁₀ = 0xFF
|
||||
26₁₀ = 0x1A
|
||||
10101111₂ = AF₁₆
|
||||
0x1.A = 1 + 10/16 = 1.625₁₀
|
||||
|
||||
Короткая справка по Python:
|
||||
|
||||
int('1A', 16) # -> 26
|
||||
hex(255) # -> '0xff'
|
||||
format(26, 'X') # -> '1A'
|
||||
|
||||
Резюме:
|
||||
|
||||
Hex — компактный способ записи бинарных данных (1 hex = 4 бита). Отрицательные числа в памяти
|
||||
обычно представлены в two's complement; hex просто показывает битовый набор в удобном виде.
|
||||
|
||||
"""
|
||||
|
||||
right_column.controls = [ft.Container(
|
||||
bgcolor="#55257D",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
ft.Text(md1, size=16, color="white"),
|
||||
ft.Text("Перевод из десятичной системы в шестнадцатеричную:", size=16, color="white"),
|
||||
ft.Container(
|
||||
bgcolor="#000000",
|
||||
content=ft.Image(src="./Система счисления 5.png", expand=True),
|
||||
border_radius=10,
|
||||
),
|
||||
ft.Text("Перевод обратно в десятичную систему:", size=16, color="white"),
|
||||
ft.Container(
|
||||
bgcolor="#000000",
|
||||
content=ft.Image(src="./Система счисления 6.png", expand=True),
|
||||
border_radius=10,
|
||||
),
|
||||
ft.Text("Практическое применение и заметки:", size=16, color="white"),
|
||||
ft.Text("- Используйте префикс 0o в коде; следите за вводом; отображайте примеры перевода.", size=14, color="white"),
|
||||
],
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
|
||||
54
app/src/pages/tabs/start1.py
Normal file
@@ -0,0 +1,54 @@
|
||||
from designer import right_column
|
||||
import flet as ft
|
||||
|
||||
|
||||
class Button_text_data(ft.CupertinoButton):
|
||||
def __init__(self, text: str = "Начало"):
|
||||
super().__init__(
|
||||
bgcolor="#00000000",
|
||||
disabled_bgcolor="#3A1E51",
|
||||
text=text,
|
||||
color="white",
|
||||
on_click=self.test_data
|
||||
)
|
||||
|
||||
def test_data(e, self):
|
||||
md1="""
|
||||
Система счисления — это способ записи (представления) чисел.
|
||||
|
||||
Что под этим подразумевается? Например, вы видите перед собой несколько деревьев. Ваша задача — их посчитать. Для этого можно — загибать пальцы, делать зарубки на камне (одно дерево — один палец\зарубка) или сопоставить 10 деревьям какой-нибудь предмет, например, камень, а единичному экземпляру — палочку и выкладывать их на землю по мере подсчета. В первом случае число представляется, как строка из загнутых пальцев или зарубок, во втором — композиция камней и палочек, где слева — камни, а справа — палочки
|
||||
|
||||
Системы счисления подразделяются на позиционные и непозиционные, а позиционные, в свою очередь, — на однородные и смешанные.
|
||||
|
||||
Непозиционная — самая древняя, в ней каждая цифра числа имеет величину, не зависящую от её позиции (разряда). То есть, если у вас 5 черточек — то число тоже равно 5, поскольку каждой черточке, независимо от её места в строке, соответствует всего 1 один предмет.
|
||||
|
||||
Позиционная система — значение каждой цифры зависит от её позиции (разряда) в числе. Например, привычная для нас 10-я система счисления — позиционная. Рассмотрим число 453. Цифра 4 обозначает количество сотен и соответствует числу 400, 5 — кол-во десяток и аналогично значению 50, а 3 — единиц и значению 3. Как видим — чем больше разряд — тем значение выше. Итоговое число можно представить, как сумму 400+50+3=453.
|
||||
|
||||
Однородная система — для всех разрядов (позиций) числа набор допустимых символов (цифр) одинаков. В качестве примера возьмем упоминавшуюся ранее 10-ю систему. При записи числа в однородной 10-й системе вы можете использовать в каждом разряде исключительно одну цифру от 0 до 9, таким образом, допускается число 450 (1-й разряд — 0, 2-й — 5, 3-й — 4), а 4F5 — нет, поскольку символ F не входит в набор цифр от 0 до 9.
|
||||
|
||||
Смешанная система — в каждом разряде (позиции) числа набор допустимых символов (цифр) может отличаться от наборов других разрядов. Яркий пример — система измерения времени. В разряде секунд и минут возможно 60 различных символов (от «00» до «59»), в разряде часов – 24 разных символа (от «00» до «23»), в разряде суток – 365 и т. д.
|
||||
|
||||
Аксиома 1: Для каждого натурального числа (n) существует следующее за ним число, обозначаемое как (S(n)) (или (n+1)).
|
||||
|
||||
Аксиома 2: Если (S(a)=S(b)), то (a=b).
|
||||
|
||||
Аксиома 3: Если (a+b=c), то (S(a+b)=S(c)).
|
||||
|
||||
по аналогии (a-b=c) => (b+c=a)
|
||||
"""
|
||||
|
||||
right_column.controls=[ ft.Container(
|
||||
bgcolor="#55257D",
|
||||
padding=ft.padding.all(10),
|
||||
border_radius=10,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
scroll=ft.ScrollMode.AUTO,
|
||||
expand=True,
|
||||
controls=[
|
||||
ft.Text(md1, size=16, color="white")
|
||||
],
|
||||
#width=600,
|
||||
)
|
||||
)]
|
||||
e.page.update()
|
||||
7
app/src/views.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import flet as ft
|
||||
from pages.main_page import Main_page
|
||||
|
||||
def ViewsHendler(page:ft.Page):
|
||||
return {
|
||||
"/": Main_page(page)
|
||||
}
|
||||