SdamMCKO 1.0.16
A Python module for preparation for mcco
Requires Python: >=3.6
Keywords: converting numbers numeral systems

# Как скачать?

1. win+r
2. cmd
3. введите команду:
    ``` bash
    pip install SdamMCKO
    # или
    python -m pip install SdamMCKO
    ```
4. для использования нужно ввсести:
    ```Python
    from SdamMCKO import q_help
    q_help(2)
    ```

    или найти файл __"GUIDE.md"__
    ![alt text](image.png)



## 1. По каналу связи передаются сообщения

Для решения задачи с каналом связи воспользуйтесь Условием Фано. Легче всего это сделать на листе используя граф

Условие Фано гласит, что: "Ни одно кодовое слово не может быть началом другого"

![image](https://github.com/user-attachments/assets/da5cbd3a-8949-483f-9a04-a4d5acdb41c7)


Как решить задание:
1. Нужно найти буквы на графе, которые уже заданы (на фото это бкуквы С В А)
2. Найти в искомом слове буквы, которые чаще всего повторяюся
3. Записать эти буквы минимальнно возможным кодом
4. ВАЖНО! Если используюся не только заданные буквы (не как в демоверсии "По каналу связи передаются сообщения, содержащие только шесть букв: А, В, Д, З, И, О."), то нужно будет оставить ещё 1 свободную ветвь для остальных букв
5. посчитать кол-во двоичных знаков для данного слова (С - 0 (1 знак), В - 101 (3 знака), и т.д.)

ВАЖНО!
При прямом условии Фано граф составляется слева на право, а при обратном, справа на лево


## 2. Автомат обрабатывает натуральное число N по следующему алгоритму

Чаще всего задание типа:
1. Строится двоичная запись числа N.
2. Преобразование двоичного числа
3. Результат переводится в десятичную систему и выводится на экран.
4. В результате работы автомата на экране появилось число, большее какого-то числа.

Это легко сделать кодом

```Python
for N in range(10**1):
    B = bin(N)[2:] # создание новой переменной т.к. чаще всего нужно будет вывести изначальное N
#       /|\     /|\         
#        |      удаление лишних знаков
#       построение двоичной записи

#--------------------------------------------------#
#       преобразование числа по условию задания    #
#--------------------------------------------------#

    ans = int(B,2) #преобразование числа в десятичное
    
    if ans > число_из_задания:
        print(N)

```


## 3.  Чему равно значение выражения в системе счисления

Вы можете делать это руками если вы уверены в себе и своих знаниях математики

Это алгоритм решения на бумаге:

![Без имени](https://github.com/user-attachments/assets/54d4601e-f6d3-429a-9128-a32dcd5edc6f)



НО! Есть стороняя библиотека BaseKit (регистр важен) которая может решить такое сама.
Для этого её нудно установить.

Если вы пользуетесь PyCharm то всё легко:
1. Напишите "from BaseKit import *"
2. PyCharm подсветит название красным
3. Нажмите ПКМ -> Show Context Action (1 строка) -> install package BaseKit
Готово!

А вот если вы не в PyCarm то сделайте это через консоль (cmd) командой "pip install BaseKit"
1. Нажмите win+r
2. в открывшемся окне напишите cmd
3. в консоль напишите: pip install BaseKit
4. после загрузки должна быть сообщение "Successfully installed BaseKit-1.0.2" (или другая версия >= 1.0.2)
Готово!


Дальше всё легко:
``` Python
import BaseKit

ans = BaseKit.rebase(Ваше_вырожение, to_base=нужная_ситема) 
# Формат выражения: строка в формате "1011.01_2 + 12345_10", где _2 это система, в которой само число, а to_base это то, в какой системе счисления вам нужен ответ

print(ans)
```

Важно! При подстановке выражения надо заменить все запятые на точки, чтобы программа работала


## 4. Нахождение информациионого веса

К сожалению у этой задачи много версий, но они все сводятся к одному - найти объём 

Для решения таких задач есть две формулы
```
N >= 2^i 
V = k * i

N - кол-во вариаций для 1 единици информации 
i - вес 1 единицы информации в битах 
V - общий объём файла 
k - кол-во единиц информации
```
Данные зависят от типов информации:
```
1. текст:
   k = символов в файле
   N = кол-во символов в алфавите

2. графика:
   k = кол-во пикселей (Ширина x Высота)
   N = кол-во видов цветов
      
   
4. видео:
   k = кол-во пикселей в 1 кадре * кадров в видео
   или
   k = кол-во пикселей в 1 кадре * кадров в секунду * время видео в секундах
   N = кол-во видов цветов

5. Аудио:
   k = Герц * время в секундах * каналы (моно, дуо, и т.д.)
   N = вес 1 секунды
```

Для заданий с сжатием файла нужно V * (1 - сжатие), где сжатие это десятичная дробь (70% -> 0,7)


## 5. Таблица истиности (логика)

Для начала нужно перевести заданое выражение в понятный коду языку

Это код, который можно скопировать для преобразования выражения:
```Python
import re

def convert_logical_expression(expr):
    # Заменяем отрицание ¬ на not
    expr = re.sub(r'¬\s*', 'not ', expr)
    
    # Заменяем эквивалентность ≡ на ==
    expr = expr.replace('≡', '==')
    
    # Заменяем И (∧) на and
    expr = re.sub(r'\s*∧\s*', ' and ', expr)
    
    # Заменяем ИЛИ (∨) на or
    expr = re.sub(r'\s*∨\s*', ' or ', expr)
    
    # Обрабатываем импликацию (→) на (not A) or B
    while True:
        new_expr = re.sub(
            r'\s*([^→]+?)\s*→\s*([^→]+?)\s*',
            r'((not \1) or \2)',
            expr,
            count=1
        )
        if new_expr == expr:
            break
        expr = new_expr
    
    # Удаляем лишние пробелы
    expr = re.sub(r'\s+', ' ', expr).strip()
    
    return expr

# Пример использования
input_expr = "(z ≡ w) ∧ (x → y) ∨ ¬w"
converted_expr = convert_logical_expression(input_expr)
print(f"Преобразованное выражение: {converted_expr}")
```
Если у вас переменные уже используюся в коде, то можно использовать команду `eval` . Она автоматически подстаит ваши значения из кода

Вот полный код-решение, который вы можете использовать:
```Python
import re, itertools
def convert_logical_expression(expr):
    # Заменяем отрицание ¬ на not
    expr = re.sub(r'¬\s*', 'not ', expr)

    # Заменяем эквивалентность ≡ на ==
    expr = expr.replace('≡', '==')

    # Заменяем И (∧) на and
    expr = re.sub(r'\s*∧\s*', ' and ', expr)

    # Заменяем ИЛИ (∨) на or
    expr = re.sub(r'\s*∨\s*', ' or ', expr)

    # Обрабатываем импликацию (→) на (not A) or B
    while True:
        new_expr = re.sub(
            r'([\( ]*)([^→()]+?)([\) ]*)\s*→\s*([\( ]*)([^→()]+?)([\) ]*)',
            r'((not (\2)) or (\5))',
            expr,
            count=1
        )
        if new_expr == expr:
            break
        expr = new_expr

    # Удаляем лишние пробелы
    expr = re.sub(r'\s+', ' ', expr).strip()

    return expr



# ВАЖНО! вместо x, y, z, w поставьте буквы, содержащиеся в вашем выражении

input_expr = "(z ≡ w) ∧ (x → y) ∨ ¬w"
converted_expr = convert_logical_expression(input_expr)
print(converted_expr, end="\n\n")

print(" ".join(["x", "y", "z", "w", "f"])) # заголовок для таблицы истинности

for x, y, z, w in itertools.product((0,1), repeat=4):
    arr = [x for x in  (map(str,[x, y, z, w, int(eval(converted_expr))]))]
    
    print(*arr)
    #-------------------------------------------------------------------#
    # Создаёт полную таблицу истинности, но если вам нужны определённые #
    # значения, то нужно прописать добавив if вместо print              #
    #                                                                   #
    #Пример:                                                            #
    #if arr[-1] == "0": # если последнее значение (f) равны 0           #
    #    print(*arr)                                                    #
    #-------------------------------------------------------------------#


```
Для работы этого кода вам понадобится:
1. Заменить input_expr на свой вариант
2. Поменять везде x, y, z, w на свои буквы

Как получить ответ:
1. Отредактируйте код как сказано наверху
2. Добавьте условие (чаще всего одна из строк заполнена полностью. использойте её как оринтир)
3. Запустите код. Вы получите фрагмент (или всю) таблицу истиности
4. Составьте соответствие данной в задании таблицы и вами полученой
5. Внесите нужные буквы в ответ


## 6. Список n-буквенных слов

Для решения такого задания вам нужен список всех таких значени. Такой список легко составить с помошью библиотеки itertools

```Python
from  itertools import product

letters = sorted(["В","Е","С","Н","А"]) # все буквы из которых состоят слова (уберите sorted если буквы не в алфавитном порядке)
n = 4 # сколько буквенное слово нужно

arr = [x for x in product(letters, repeat=n)] # лист со всеми вариантами слова
```
Дальее нужно найти первое слово в котором выполняется условие

```Python
for i in range(len(arr)):
    word = "".join(arr[i]) # создание слова
    
    if условие из задания:
        print(i+1, word)
        break
```

## 7 IP-адрес, маски и прочее

Есть универсальный код, который сам всё решит

```Python
def ip_to_list(ip_str):
    return list(map(int, ip_str.split('.')))


def list_to_ip(ip_list):
    return '.'.join(map(str, ip_list))


def calculate_network_host(ip=None, mask=None, network=None, host=None):
    try:
        if ip and mask:
            # Вычисляем адрес сети и номер узла
            ip_list = ip_to_list(ip)
            mask_list = ip_to_list(mask)
            network_list = [i & m for i, m in zip(ip_list, mask_list)]
            host_list = [i & (~m & 0xFF) for i, m in zip(ip_list, mask_list)]
            return {
                'network': list_to_ip(network_list),
                'host': list_to_ip(host_list)
            }

        elif network and mask:
            # Вычисляем возможные IP (диапазон)
            network_list = ip_to_list(network)
            mask_list = ip_to_list(mask)
            min_ip = network_list.copy()
            max_ip = [n | (~m & 0xFF) for n, m in zip(network_list, mask_list)]
            return {
                'ip_range': f"{list_to_ip(min_ip)} - {list_to_ip(max_ip)}"
            }

        elif network and host:
            # Вычисляем IP (network | host) с проверкой маски
            network_list = ip_to_list(network)
            host_list = ip_to_list(host)
            ip_list = [n | h for n, h in zip(network_list, host_list)]
            for n, h in zip(network_list, host_list):
                if (n & h) != 0:
                    raise ValueError("Network and host overlap")
            return {'ip': list_to_ip(ip_list)}

        elif ip and network:
            # Вычисляем маску (корректные маски только с префиксом)
            ip_list = ip_to_list(ip)
            network_list = ip_to_list(network)
            mask_list = []
            for i, n in zip(ip_list, network_list):
                mask_octet = 0
                for bit in range(8):
                    mask_bit = 1 << (7 - bit)
                    if (i & mask_bit) == (n & mask_bit):
                        mask_octet |= mask_bit
                    else:
                        break
                mask_list.append(mask_octet)
            return {'mask': list_to_ip(mask_list)}

        else:
            raise ValueError("Недостаточно данных")

    except Exception as e:
        return f"Ошибка: {str(e)}"

# Примеры использования:
print(calculate_network_host(ip="", mask=""))
```

В calculate_network_host() нужно вписать всё, что известно, а ответ состоит из словаря со всей неизвестной информацией


## 8. алгоритм шифрования RSA

Само задание не сложное, сложно понимание.
Внимательно прочитайте задание и поймите что куда вписывать ниже в предложеном коде

```Python

#----------------------------------------------------------------------------------#
# План работы:                                                                     #
# 1. задайте все переменные                                                        #
# 2. замените _ на искомую переменную                                              #
# 3. в return функции f(n) запишите формулу нахождения f(f)                        #
# 4. после if основного цикла запишите формулу, которая описывает создание ключей  #
# 5. запустите код                                                                 #
#----------------------------------------------------------------------------------#


#1

def f(n):
    return  #3

for _ in range(): #2
    if : # 4
        print(_) #5
        break
```


## 9. Хранение данных 

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

1. определяем i по формуле N = 2^i (N - общее число символов (цифры + спец. символы -> 10 + x))
2. находим сколько весит 1 идентификатор v1 =  i * кол-во символов в идентификаторе  ВАЖНО! если написанно "одинаковое и минимально возможное целое число байт", то делим на 8 и округляем в БОЛЬШУЮ сторону 
3. зная вес 1 кода находим максимальное кол-во объектов по формуле n = V / V1 (Не забудьте перевести значения в 1 еденицу (байты))
Готово!


## 10. Редактор

Для начала нужно перенести код в питон (к сожалению задачи могут разниться и поэтому я никак вам не помогу с этим)

D - исходная строка (комбинация разных цифр, описанная над полем ввода) 

Легче всего задать в виде строки как: "1"* 3 + "4"*5  -> 11144444

Замените команды на из эквиволенты:
- заменить(v,w) -> D.replace(v,w,1)
- нашлось (v) ->  D.count(v) == 0

в конце кода напишите print(D) для вывода ответа

## 11. пропущенная цифра

Дано выражнеие с пропущенной цифрой из n-ричного алфавита. Тут опять нам поможет библиотека BaseKit

Для решения нужно сделать цикл, который будет подставлять цифры n-ричного алфавита вместо x (обратите внимание если в строке не только x, но и другие буквы, то это уже другие цифры)


```Python
import BaseKit

alphabet = [f"{x}" for x in range(10)] + [chr(i).upper() for i in range(97, 123)] # создание алфавита (не лезь сюда)

min_base = 1 # сюда запишите минимальное основание

for x in alphabet[:min_base]:

    val = int(BaseKit.eval2dec(f"ВАШЕВЫРАЖЕНИЕ")[:-3]) # Ответ на выражение с цифрой вместо x. Пример: f"154{x}3_12 + 1{x}365_12"
    
    
    if True: # условие правильного x
        print(val) # сюда то, что нужно сделать с ответом (он уже в десятичной системе счисления)
```

## 12