Загрузка данных


import tkinter as tk
from tkinter import ttk, messagebox
import sqlite3


# =========================
# Настройки алфавитов
# =========================
RUS_LOWER = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
RUS_UPPER = RUS_LOWER.upper()

ENG_LOWER = "abcdefghijklmnopqrstuvwxyz"
ENG_UPPER = ENG_LOWER.upper()


def shift_char(char, step):
    """Сдвигает один символ по соответствующему алфавиту."""
    for alphabet in (RUS_LOWER, RUS_UPPER, ENG_LOWER, ENG_UPPER):
        if char in alphabet:
            index = alphabet.index(char)
            return alphabet[(index + step) % len(alphabet)]
    return char


def caesar_encrypt(text, step):
    """Шифрование слова/текста шифром Цезаря."""
    return "".join(shift_char(char, step) for char in text)


def caesar_decrypt(text, step):
    """Дешифрование слова/текста шифром Цезаря."""
    return caesar_encrypt(text, -step)


# =========================
# Работа с БД
# =========================
DB_NAME = "caesar.db"


def init_db():
    connection = sqlite3.connect(DB_NAME)
    cursor = connection.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS words (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            word TEXT NOT NULL,
            step INTEGER NOT NULL
        )
    """)
    connection.commit()
    connection.close()


def save_to_db(word, step):
    connection = sqlite3.connect(DB_NAME)
    cursor = connection.cursor()
    cursor.execute(
        "INSERT INTO words (word, step) VALUES (?, ?)",
        (word, step)
    )
    connection.commit()
    connection.close()


def load_from_db():
    connection = sqlite3.connect(DB_NAME)
    cursor = connection.cursor()
    cursor.execute("SELECT word, step FROM words ORDER BY id")
    rows = cursor.fetchall()
    connection.close()
    return rows


# =========================
# GUI
# =========================
class CaesarApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Шифр Цезаря")
        self.root.geometry("760x600")
        self.root.minsize(650, 500)

        init_db()
        self.create_widgets()

    def create_widgets(self):
        main = ttk.Frame(self.root, padding=20)
        main.pack(fill="both", expand=True)

        title = ttk.Label(
            main,
            text="Шифр Цезаря",
            font=("Arial", 20, "bold")
        )
        title.pack(pady=(0, 20))

        # Ввод слова
        word_frame = ttk.LabelFrame(main, text="Исходное слово")
        word_frame.pack(fill="x", pady=5)

        self.word_entry = ttk.Entry(word_frame, font=("Arial", 14))
        self.word_entry.pack(fill="x", padx=10, pady=10)

        # Ввод шага
        step_frame = ttk.LabelFrame(main, text="Шаг шифрования")
        step_frame.pack(fill="x", pady=5)

        self.step_entry = ttk.Entry(step_frame, font=("Arial", 14))
        self.step_entry.insert(0, "3")
        self.step_entry.pack(fill="x", padx=10, pady=10)

        # Кнопки
        buttons = ttk.Frame(main)
        buttons.pack(fill="x", pady=15)

        ttk.Button(
            buttons,
            text="Зашифровать",
            command=self.encrypt
        ).pack(side="left", expand=True, fill="x", padx=4)

        ttk.Button(
            buttons,
            text="Расшифровать",
            command=self.decrypt
        ).pack(side="left", expand=True, fill="x", padx=4)

        ttk.Button(
            buttons,
            text="Сохранить в БД",
            command=self.save
        ).pack(side="left", expand=True, fill="x", padx=4)

        ttk.Button(
            buttons,
            text="Загрузить из БД",
            command=self.load
        ).pack(side="left", expand=True, fill="x", padx=4)

        # Результат
        result_frame = ttk.LabelFrame(main, text="Результат")
        result_frame.pack(fill="x", pady=5)

        self.result_var = tk.StringVar()
        self.result_label = ttk.Label(
            result_frame,
            textvariable=self.result_var,
            font=("Arial", 15)
        )
        self.result_label.pack(padx=10, pady=12)

        # Список из БД
        list_frame = ttk.LabelFrame(
            main,
            text="Слова, загруженные из БД"
        )
        list_frame.pack(fill="both", expand=True, pady=10)

        columns = ("encrypted", "original", "step")

        self.tree = ttk.Treeview(
            list_frame,
            columns=columns,
            show="headings"
        )

        self.tree.heading(
            "encrypted",
            text="Зашифрованное слово"
        )
        self.tree.heading(
            "original",
            text="Оригинальное слово"
        )
        self.tree.heading(
            "step",
            text="Шаг"
        )

        self.tree.column("encrypted", width=250)
        self.tree.column("original", width=250)
        self.tree.column("step", width=100, anchor="center")

        scrollbar = ttk.Scrollbar(
            list_frame,
            orient="vertical",
            command=self.tree.yview
        )
        self.tree.configure(yscrollcommand=scrollbar.set)

        self.tree.pack(
            side="left",
            fill="both",
            expand=True,
            padx=(5, 0),
            pady=5
        )
        scrollbar.pack(
            side="right",
            fill="y",
            padx=(0, 5),
            pady=5
        )

    def get_input(self):
        word = self.word_entry.get().strip()

        if not word:
            messagebox.showwarning(
                "Ошибка",
                "Введите слово."
            )
            return None

        try:
            step = int(self.step_entry.get())
        except ValueError:
            messagebox.showerror(
                "Ошибка",
                "Шаг шифрования должен быть целым числом."
            )
            return None

        return word, step

    def encrypt(self):
        data = self.get_input()
        if data is None:
            return

        word, step = data
        encrypted = caesar_encrypt(word, step)

        self.result_var.set(
            f"{word} → {encrypted}"
        )

    def decrypt(self):
        data = self.get_input()
        if data is None:
            return

        word, step = data
        decrypted = caesar_decrypt(word, step)

        self.result_var.set(
            f"{word} → {decrypted}"
        )

    def save(self):
        data = self.get_input()
        if data is None:
            return

        word, step = data
        save_to_db(word, step)

        messagebox.showinfo(
            "Сохранение",
            "Слово и шаг успешно сохранены в БД."
        )

    def load(self):
        # Очистить старый список
        for item in self.tree.get_children():
            self.tree.delete(item)

        rows = load_from_db()

        for word, step in rows:
            encrypted = caesar_encrypt(word, step)

            self.tree.insert(
                "",
                "end",
                values=(encrypted, word, step)
            )

        if not rows:
            messagebox.showinfo(
                "База данных",
                "В БД пока нет сохранённых слов."
            )


if __name__ == "__main__":
    root = tk.Tk()
    app = CaesarApp(root)
    root.mainloop()