From 998e06507977de026f13b236ae09e8980d741e44 Mon Sep 17 00:00:00 2001 From: Cinnamonness Date: Thu, 12 Dec 2024 22:53:55 +0700 Subject: [PATCH 1/5] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D1=8B=20=D1=8D=D1=84=D1=84=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D0=B2=D0=BD=D0=B5=D0=B5=20=D0=BF=D0=BE=20=D0=BF=D0=B0?= =?UTF-8?q?=D0=BC=D1=8F=D1=82=D0=B8=20=D0=B2=D1=81=D0=B5=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BD=D1=82=D0=BD=D1=8B?= =?UTF-8?q?=D0=B5=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- persistent_data_structures/base_persistent.py | 120 ++++++++-- .../persistent_array.py | 120 +++++----- persistent_data_structures/persistent_list.py | 212 ++++++++++-------- persistent_data_structures/persistent_map.py | 75 ++++--- tests/test_array.py | 131 ++++++++--- tests/test_list.py | 201 ++++++++++------- tests/test_map.py | 71 +++++- 7 files changed, 603 insertions(+), 327 deletions(-) diff --git a/persistent_data_structures/base_persistent.py b/persistent_data_structures/base_persistent.py index a4b967b..e36fd8d 100644 --- a/persistent_data_structures/base_persistent.py +++ b/persistent_data_structures/base_persistent.py @@ -1,44 +1,118 @@ from copy import deepcopy +from typing import Optional, Dict + + +class NodeState: + """Класс, представляющий состояние узла. Он может быть определен + в зависимости от структуры данных.""" + def __init__(self, data: Optional['NodeState'] = None): + self.data = data + self.next_node: Optional['NodeState'] = None + + +class Node: + """Класс узла для хранения состояния в B-дереве.""" + def __init__(self, state: Optional[NodeState]) -> None: + """ + Инициализирует узел с заданным состоянием. + + :param state: Состояние узла. + """ + self.state: Optional[NodeState] = state + self.children: Dict[int, 'Node'] = {} class BasePersistent: - """Базовый класс для персистентных стркутур данных. - - Каждая персистентная структура будет хранить в себе историю изменений в виде словаря с ключами - версиями и значениями - состояниями. Также персистентная структура будет хранить номер ткущей - и номер последней версии. - """ - def __init__(self, initial_state=None) -> None: - """Инициализирует персистентную структуру данных. + """Базовый класс для персистентных структур данных с использованием B-дерева.""" + + def __init__(self, initial_state: Optional[NodeState] = None) -> None: + """ + Инициализирует персистентную структуру данных. + :param initial_state: Начальное состояние персистентной структуры данных. """ - self._history = {0: initial_state} - self._current_state = 0 - self._last_state = 0 + self.root: Node = Node(initial_state) + self._current_version: int = 0 + self._last_version: int = 0 + self._version_map: Dict[int, Node] = {0: self.root} - def get_version(self, version): - """Возвращает состояние персистентной структуры данных на указанной версии. + def get_version(self, version: int) -> NodeState: + """ + Возвращает состояние персистентной структуры данных на указанной версии. :param version: Номер версии. :return: Состояние персистентной структуры данных на указанной версии. :raises ValueError: Если указанная версия не существует. """ - if version < 0 or version >= len(self._history): + if version not in self._version_map: + raise ValueError(f'Version "{version}" does not exist') + return self._version_map[version].state + + def set_version(self, version: int) -> None: + """ + Обновляет текущую версию персистентной структуры данных до указанной. + + :param version: Номер версии. + :raises ValueError: Если указанная версия не существует. + """ + if version not in self._version_map: raise ValueError(f'Version "{version}" does not exist') - return self._history[version] + self._current_version = version + self.root = self._version_map[version] - def update_version(self, version): - """Обновляет текущую версию персистентной структуры данных до указанной. + def set_version_doubly_linked_list(self, version: int) -> None: + """ + Обновляет текущую версию персистентной структуры данных до + указанной для двусвязного списка. :param version: Номер версии. :raises ValueError: Если указанная версия не существует. """ - if version < 0 or version >= len(self._history): + if version not in self._version_map: raise ValueError(f'Version "{version}" does not exist') - self._current_state = version + self._current_version = version + self.root = self._version_map[version] + head = self._version_map[self._current_version].state + self.size: int = 0 + current = head + while current: + self.size += 1 + current = current.next_node + self._version_map[self._current_version].state = head def _create_new_state(self) -> None: - """Создает новую версию.""" - self._last_state += 1 - self._history[self._last_state] = deepcopy(self._history[self._current_state]) - self._current_state = self._last_state + """ + Создает новую версию персистентной структуры данных с + минимальным дублированием данных. + + Этот метод копирует текущее состояние структуры данных и создает + новую версию, добавляя ее в карту версий. + Дублирование данных минимизируется путем использования глубокого + копирования состояния узла. + + :raises ValueError: Если текущая версия не существует в карте версий. + """ + self._last_version += 1 + parent_node = self._version_map[self._current_version] + new_state = deepcopy(parent_node.state) + new_node = Node(new_state) + parent_node.children[self._last_version] = new_node + self._version_map[self._last_version] = new_node + self._current_version = self._last_version + self.root = new_node + + def _create_new_state_doubly_linked_list(self) -> None: + """ + Создает новую версию состояния для двусвязного списка, + минимизируя дублирование данных. + + Этот метод копирует состояние двусвязного списка, создавая + новый узел с минимальным дублированием + данных, чтобы сохранить версионность структуры данных. + + :raises ValueError: Если текущая версия не существует в карте версий. + """ + self._current_version += 1 + head = self._version_map[self._current_version - 1].state + new_head = self._deep_copy_list(head) + self._version_map[self._current_version] = Node(new_head) diff --git a/persistent_data_structures/persistent_array.py b/persistent_data_structures/persistent_array.py index cee913f..7558152 100644 --- a/persistent_data_structures/persistent_array.py +++ b/persistent_data_structures/persistent_array.py @@ -1,30 +1,28 @@ import numpy as np - -from persistent_data_structures.base_persistent import BasePersistent +from base_persistent import BasePersistent class PersistentArray(BasePersistent): - """Персистентный массив. - Класс PersistentArray реализует неизменяемый массив с - возможностью хранения нескольких версий, где каждая - версия является изменением предыдущей. - """ + """Персистентный массив с использованием B-дерева.""" def __init__(self, size: int = 1024, default_value: int = 0) -> None: - """Инициализирует новый массив с несколькими версиями. + """ + Инициализирует новый массив с несколькими версиями. Создается первая версия массива, которая состоит из элементов, равных default_value. + :param size: Начальный размер массива (по умолчанию 1024). :param default_value: Значение по умолчанию для элементов массива (по умолчанию 0). """ - self.size = size - self.default_value = default_value - initial_state = np.full(size, default_value) + self.size: int = size + self.default_value: int = default_value + initial_state: np.ndarray = np.full(size, default_value) super().__init__(initial_state) def __getitem__(self, index: int) -> any: - """Получение значения из текущей версии массива по индексу. + """ + Получение значения из текущей версии массива по индексу. :param index: Индекс элемента в текущей версии массива. :return: Значение элемента в текущей версии массива по заданному индексу. @@ -32,65 +30,54 @@ def __getitem__(self, index: int) -> any: """ if index < 0 or index >= self.size: raise ValueError("Invalid index") - return self._history[self._current_state][index] + return self.root.state[index] - def get(self, version: int, index: int) -> any: - """Получение значения элемента для определенной версии массива по индексу. + def __setitem__(self, index: int, value: any) -> None: + """ + Обновление значения элемента в новой версии массива. - :param version: Номер версии, из которой нужно получить элемент. - :param index: Индекс элемента в указанной версии массива. - :return: Значение элемента в указанной версии массива по заданному индексу. - :raises ValueError: Если версия или индекс выходят за пределы допустимого диапазона. + Обновляет значение элемента из текущей версии массива по индексу + и помещает получившийся массив в новую версию. + + :param index: Индекс элемента, который необходимо обновить. + :param value: Новое значение для обновляемого элемента. + :raises ValueError: Если индекс выходит за пределы допустимого диапазона. """ - if version > self._current_state or version < 0: - raise ValueError(f'Version "{version}" does not exist') if index < 0 or index >= self.size: raise ValueError("Invalid index") - return self._history[version][index] + self._create_new_state() + self.root.state[index] = value def add(self, value: any) -> None: - """Добавление нового элемента в конец массива в новую версию. + """ + Добавление нового элемента в конец массива в новую версию. - :param value (int): Значение нового элемента, который добавляется в массив. + :param value: Значение нового элемента, который добавляется в массив. """ self._create_new_state() - self._history[self._last_state] = np.append(self._history[self._last_state], value) + self.root.state = np.append(self.root.state, value) self.size += 1 def pop(self, index: int) -> any: - """Удаление элемента в новой версии массива и возвращение его значения. + """ + Удаление элемента в новой версии массива и возвращение его значения. - :param index (int): Индекс элемента, который необходимо удалить. - :return int: Значение удаленного элемента. + :param index: Индекс элемента, который необходимо удалить. + :return: Значение удаленного элемента. :raises ValueError: Если индекс выходит за пределы допустимого диапазона. """ if index < 0 or index >= self.size: raise ValueError("Invalid index") - removed_element = self._history[self._current_state][index] self._create_new_state() - self._history[self._last_state] = np.delete(self._history[self._last_state], index) + removed_element = self.root.state[index] + self.root.state = np.delete(self.root.state, index) self.size -= 1 return removed_element - def __setitem__(self, index: int, value: any) -> None: - """Обновление значения элемента в новую версии массива. - - Обновляет значение элемента из текущей версии массива по индексу - и помещает получившийся массив в новую версию. - :param index: Индекс элемента, который необходимо обновить. - :param value: Новое значение для обновляемого элемента. - :raises ValueError: Если индекс выходит за пределы допустимого диапазона. - """ - if index < 0 or index >= self.size: - raise ValueError("Invalid index") - self._create_new_state() - self._history[self._last_state][index] = value - def insert(self, index: int, value: any) -> None: - """Вставка нового элемента в массив в указанную позицию в новой версии. + """ + Вставка нового элемента в массив в указанную позицию в новой версии. - Вставляет новый элемент в указанную позицию в текущей версии массива и помещает - получившийся массив в новую версию. :param index: Позиция, в которую нужно вставить новый элемент. :param value: Значение нового элемента, который нужно вставить. :raises ValueError: Если индекс выходит за пределы допустимого диапазона. @@ -98,13 +85,31 @@ def insert(self, index: int, value: any) -> None: if index < 0 or index > self.size: raise ValueError("Invalid index") self._create_new_state() - self._history[self._last_state] = np.insert(self._history[self._last_state], index, value) + self.root.state = np.insert(self.root.state, index, value) self.size += 1 + def get(self, version: int, index: int) -> any: + """ + Получение значения элемента для определенной версии массива по индексу. + + :param version: Номер версии, из которой нужно получить элемент. + :param index: Индекс элемента в указанной версии массива. + :return: Значение элемента в указанной версии массива по заданному индексу. + :raises ValueError: Если версия или индекс выходят за пределы допустимого диапазона. + """ + if version < 0 or version > self._last_version: + raise ValueError(f'Version "{version}" does not exist') + state = self.get_version(version) + if index < 0 or index >= len(state): + raise ValueError("Invalid index") + return state[index] + def remove(self, index: int) -> None: - """Удаление элемента в новой версии массива по индексу. + """ + Удаление элемента в новой версии массива по индексу. Удаляет элемент из текущей версии массива по индексу и помещает результат в новую версию. + :param index: Индекс элемента, который необходимо удалить. :raises ValueError: Если индекс выходит за пределы допустимого диапазона. """ @@ -112,15 +117,26 @@ def remove(self, index: int) -> None: raise ValueError("Invalid index") self.pop(index) + def get_version_state(self, version: int) -> np.ndarray: + """ + Получение состояния массива для указанной версии. + + :param version: Номер версии. + :return: Состояние массива для указанной версии. + """ + return self.get_version(version) + def get_size(self) -> int: - """Получение текущего размера массива. + """ + Получение текущего размера массива. :return: Количество элементов в текущей версии массива. """ return self.size - def check_is_empty(self): - """Проверка, является ли массив пустым в текущей версии. + def check_is_empty(self) -> bool: + """ + Проверка, является ли массив пустым в текущей версии. :return: True, если массив пуст, иначе False. """ diff --git a/persistent_data_structures/persistent_list.py b/persistent_data_structures/persistent_list.py index 75b4fa0..6a82a71 100644 --- a/persistent_data_structures/persistent_list.py +++ b/persistent_data_structures/persistent_list.py @@ -1,44 +1,41 @@ -from persistent_data_structures.base_persistent import BasePersistent +from base_persistent import BasePersistent, Node +from typing import Any, Optional -class Node: - """ - Класс для узлов двусвязного списка. - """ +class ListNode: + """Класс узла для хранения состояния в двусвязном списке.""" - def __init__(self, value: any = None, prev: 'Node' = None, next_node: 'Node' = None) -> None: + def __init__(self, value: Any = None, prev: Optional['ListNode'] = None, + next_node: Optional['ListNode'] = None) -> None: """ - Инициализирует новый узел. + Инициализация узла списка. - :param value: Значение для хранения в узле (по умолчанию None). + :param value: Значение, которое будет храниться в узле. :param prev: Ссылка на предыдущий узел (по умолчанию None). :param next_node: Ссылка на следующий узел (по умолчанию None). """ self.value = value self.prev = prev self.next_node = next_node + self.children = {} class PersistentLinkedList(BasePersistent): - """Персистентный двусвязный список. - Класс PersistentLinkedList реализует неизменяемый двусвязный список - с возможностью хранения нескольких версий, где каждая - версия является изменением предыдущей. - """ + """Персистентный двусвязный список, использующий базовый класс для версионирования.""" - def __init__(self, initial_state: list = None) -> None: + def __init__(self, initial_state: Optional[list[Any]] = None) -> None: """ - Инициализирует персистентный двусвязный список. + Инициализация персистентного списка. - :param initial_state: Начальное состояние списка, если оно передано. - :return: None + :param initial_state: Начальный список данных для создания состояния (по умолчанию None). """ - super().__init__(None) + super().__init__(initial_state) self.size = 0 head = tail = None + if initial_state: for data in initial_state: - node = Node(data) + node = ListNode(data) if head is None: head = tail = node else: @@ -46,61 +43,62 @@ def __init__(self, initial_state: list = None) -> None: node.prev = tail tail = node self.size = len(initial_state) - self._history[0] = (head, tail) - def add(self, data: any) -> None: - """ - Добавляет элемент в конец списка в новой версии. + self._version_map[0] = Node(head) - :param data: Данные, которые нужно добавить в список. - :return: None - """ - self._create_new_state() - head, tail = self._history[self._last_state] - new_node = Node(data) - if tail is None: - head = tail = new_node - else: + def add(self, data: Any) -> None: + """Добавляет элемент в конец списка в новой версии.""" + self._create_new_state_doubly_linked_list() + head = self._version_map[self._current_version].state + tail = self._get_tail(head) + new_node = ListNode(data) + + if tail: tail.next_node = new_node new_node.prev = tail - tail = new_node + else: + head = new_node + + self._version_map[self._current_version].state = head self.size += 1 - self._history[self._last_state] = (head, tail) - def add_first(self, data: any) -> None: + def add_first(self, data: Any) -> None: """ Добавляет элемент в начало списка в новой версии. :param data: Данные, которые нужно добавить в начало списка. :return: None """ - self._create_new_state() - head, tail = self._history[self._last_state] - new_node = Node(data, next_node=head) + self._create_new_state_doubly_linked_list() + head = self._version_map[self._current_version].state + new_node = ListNode(data, next_node=head) + if head: head.prev = new_node + head = new_node - if tail is None: - tail = new_node + self._version_map[self._current_version].state = head self.size += 1 - self._history[self._last_state] = (head, tail) - def insert(self, index: int, data: any) -> None: - """ - Вставляет элемент в список по указанному индексу. - - :param index: Индекс, на котором нужно вставить элемент. - :param data: Данные, которые нужно вставить. - :return: None - :raises IndexError: Если индекс выходит за пределы списка. - """ - self._create_new_state() - head, tail = self._history[self._last_state] + def insert(self, index: int, data: Any) -> None: + """Вставляет элемент в список по указанному индексу.""" + self._create_new_state_doubly_linked_list() + head = self._version_map[self._current_version].state current = head count = 0 + + if index == 0: + new_node = ListNode(data, next_node=head) + if head: + head.prev = new_node + head = new_node + self._version_map[self._current_version].state = head + self.size += 1 + return + while current: if count == index: - new_node = Node(data, prev=current.prev, next_node=current) + new_node = ListNode(data, prev=current.prev, next_node=current) if current.prev: current.prev.next_node = new_node current.prev = new_node @@ -112,9 +110,10 @@ def insert(self, index: int, data: any) -> None: current = current.next_node else: raise IndexError("Index out of range") - self._history[self._last_state] = (head, tail) - def pop(self, index: int) -> any: + self._version_map[self._current_version].state = head + + def pop(self, index: int) -> Any: """ Удаление элемента в новой версии списка и возвращение его значения. @@ -122,9 +121,11 @@ def pop(self, index: int) -> any: :return: Значение удаленного элемента. :raises IndexError: Если индекс выходит за пределы списка. """ - head, tail = self._history[self._current_state] + self._create_new_state_doubly_linked_list() + head = self._version_map[self._current_version].state current = head count = 0 + while current: if count == index: value = current.value @@ -134,26 +135,28 @@ def pop(self, index: int) -> any: current.next_node.prev = current.prev if current == head: head = current.next_node - if current == tail: - tail = current.prev - self._create_new_state() self.size -= 1 - self._history[self._last_state] = (head, tail) - return value + break count += 1 current = current.next_node - raise IndexError("Index out of range") + else: + raise IndexError("Index out of range") + + self._version_map[self._current_version].state = head + return value - def remove(self, value: any) -> None: + def remove(self, value: Any) -> None: """ Удаляет элемент из списка в новой версии. - :param data: Данные элемента для удаления. + :param value: Данные элемента для удаления. :return: None :raises ValueError: Если элемент не найден в списке. """ - head, tail = self._history[self._current_state] + self._create_new_state_doubly_linked_list() + head = self._version_map[self._current_version].state current = head + while current: if current.value == value: if current.prev: @@ -162,16 +165,15 @@ def remove(self, value: any) -> None: current.next_node.prev = current.prev if current == head: head = current.next_node - if current == tail: - tail = current.prev - self._create_new_state() self.size -= 1 - self._history[self._last_state] = (head, tail) - return + break current = current.next_node - raise ValueError(f"Value {value} not found in the list") + else: + raise ValueError(f"Value {value} not found in the list") + + self._version_map[self._current_version].state = head - def get(self, version: int = None, index: int = None) -> any: + def get(self, version: int = None, index: int = None) -> Any: """ Возвращает элемент по индексу из указанной версии. @@ -182,32 +184,36 @@ def get(self, version: int = None, index: int = None) -> any: :raises IndexError: Если индекс выходит за пределы списка. """ if version is None: - version = self._current_state - if version > self._current_state or version < 0: + version = self._current_version + + if version not in self._version_map: raise ValueError(f"Version {version} does not exist") - head, tail = self._history[version] - if head is None: - raise IndexError("Index out of range") + head = self._version_map[version].state current = head count = 0 + while current: if count == index: return current.value count += 1 current = current.next_node + raise IndexError("Index out of range") - def clear(self) -> None: - """ - Очищает список, создавая новую версию. + def _get_tail(self, head: ListNode) -> Optional[ListNode]: + """Возвращает последний узел в списке.""" + current = head + while current and current.next_node: + current = current.next_node + return current - :return: None - """ - self._create_new_state() + def clear(self) -> None: + """Очищает список, создавая новую версию.""" + self._create_new_state_doubly_linked_list() + self._version_map[self._current_version].state = None self.size = 0 - self._history[self._last_state] = (None, None) - def __getitem__(self, index: int) -> any: + def __getitem__(self, index: int) -> Any: """ Получение значения элемента из текущей версии списка по индексу. @@ -215,7 +221,7 @@ def __getitem__(self, index: int) -> any: :return: Значение элемента в текущей версии списка по заданному индексу. :raises IndexError: Если индекс выходит за пределы списка. """ - head, tail = self._history[self._current_state] + head = self._version_map[self._current_version].state current = head count = 0 while current: @@ -225,7 +231,7 @@ def __getitem__(self, index: int) -> any: current = current.next_node raise IndexError("Index out of range") - def __setitem__(self, index: int, value: any) -> None: + def __setitem__(self, index: int, value: Any) -> None: """ Обновление значения элемента в новой версии списка по индексу. @@ -245,7 +251,25 @@ def __setitem__(self, index: int, value: any) -> None: current = current.next_node else: raise IndexError("Index out of range") - self._history[self._last_state] = (head, tail) + self._version_map[self._last_state] = (head, tail) + + def _deep_copy_list(self, head: ListNode) -> Optional[ListNode]: + """Глубокое копирование списка с его узлами.""" + if not head: + return None + + new_head = ListNode(head.value) + current = head.next_node + new_current = new_head + + while current: + new_node = ListNode(current.value) + new_current.next_node = new_node + new_node.prev = new_current + new_current = new_node + current = current.next_node + + return new_head def get_size(self) -> int: """ @@ -261,5 +285,15 @@ def check_is_empty(self) -> bool: :return: True, если список пуст, иначе False. """ - head, tail = self._history[self._current_state] + head = self._version_map[self._current_version].state return head is None + + def __str__(self) -> str: + """Отображение списка для вывода.""" + head = self._version_map[self._current_version].state + result = [] + current = head + while current: + result.append(current.value) + current = current.next_node + return '->'.join(map(str, result)) diff --git a/persistent_data_structures/persistent_map.py b/persistent_data_structures/persistent_map.py index 9efb825..7a159ff 100644 --- a/persistent_data_structures/persistent_map.py +++ b/persistent_data_structures/persistent_map.py @@ -1,66 +1,69 @@ -from persistent_data_structures.base_persistent import BasePersistent +from base_persistent import BasePersistent +from typing import Any, Dict class PersistentMap(BasePersistent): - """Персистентный ассоциативный массив. + """A persistent associative array. - Представляет собой словарь, который сохраняет историю изменений. + Represents a dictionary that preserves the history of changes. """ - def __init__(self, initial_state: dict = {}) -> None: - """Инициализирует персистентный ассоциативный массив. - :param initial_state: Начальное состояние персистентной структуры данных. + def __init__(self, initial_state: Dict[Any, Any] = {}) -> None: + """Initializes a persistent associative array. + + :param initial_state: The initial state of the persistent data structure. """ super().__init__(initial_state) - def __setitem__(self, key: any, value: any) -> None: - """Обновляет или создает элемент по указанному ключу в новой версии. + def __setitem__(self, key: Any, value: Any) -> None: + """Updates or creates an item by the specified key in the new version. - :param key: Ключ - :param value: Значение + :param key: The key to be updated or created. + :param value: The value associated with the key. """ self._create_new_state() - self._history[self._last_state][key] = value + self._version_map[self._last_version].state[key] = value - def __getitem__(self, key: any) -> any: - """Возвращает элемент текущей версии по указанному ключу. + def __getitem__(self, key: Any) -> Any: + """Returns the item of the current version by the specified key. - :param key: Ключ - :return: Значение сответствующее указанному ключу или None, если ключ не существует.""" - return self._history[self._current_state][key] + :param key: The key of the item to be fetched. + :return: The value corresponding to the specified key or None if the key does not exist. + """ + return self._version_map[self._current_version].state.get(key) - def get(self, version: int, key: any) -> any: - """Возвращает элемент с указанной версией и ключом. + def get(self, version: int, key: Any) -> Any: + """Returns the item from the specified version and key. - :param version: Номер версии - :param key: Ключ - :return: Значение сответствующее указанному ключу или None, если ключ не существует. - :raises ValueError: Если версия не существует - :raises KeyError: Если ключ не существует + :param version: The version number. + :param key: The key of the item to be fetched. + :return: The value corresponding to the specified key. + :raises ValueError: If the version does not exist. + :raises KeyError: If the key does not exist. """ - if version > self._current_state or version < 0: + if version not in self._version_map: raise ValueError(f'Version "{version}" does not exist') - if key not in self._history[version]: + if key not in self._version_map[version].state: raise KeyError(f'Key "{key}" does not exist') - return self._history[version] + return self._version_map[version].state[key] - def pop(self, key: any) -> any: - """Удаляет элемент по указанному ключу и возвращает его. + def pop(self, key: Any) -> Any: + """Removes and returns the item by the specified key. - :param key: Ключ - :return: Удаленный элемент + :param key: The key of the item to be removed. + :return: The removed item. """ self._create_new_state() - return self._history[self._last_state].pop(key) + return self._version_map[self._last_version].state.pop(key) - def remove(self, key: any) -> None: - """Удаляет элемент по указанному ключу в новой версии. + def remove(self, key: Any) -> None: + """Removes an item by the specified key in the new version. - :param key: Ключ + :param key: The key of the item to be removed. """ self.pop(key) def clear(self) -> None: - """Очищает ассоциативный массив в новой версии.""" + """Clears the associative array in the new version.""" self._create_new_state() - self._history[self._current_state] = {} + self._version_map[self._current_version].state.clear() diff --git a/tests/test_array.py b/tests/test_array.py index 00b2cca..7391072 100644 --- a/tests/test_array.py +++ b/tests/test_array.py @@ -1,5 +1,4 @@ import pytest - from persistent_array import PersistentArray @@ -11,14 +10,19 @@ def persistent_array(): def test_initial_state(persistent_array): - """Тест1. Проверка начального состояния массива""" + """Тест 1. Проверка начального состояния массива""" assert persistent_array.get_size() == 5 assert persistent_array[0] == 0 assert persistent_array[4] == 0 +def test_initial_size(persistent_array): + """Тест 2. Проверка начального размера массива""" + assert persistent_array.get_size() == 5 + + def test_get_version(persistent_array): - """Тест 2. Проверка получения состояния на определенной версии""" + """Тест 3. Проверка извлечения элемента по версии""" persistent_array.add(1) persistent_array.add(2) @@ -27,26 +31,37 @@ def test_get_version(persistent_array): assert persistent_array.get(2, 6) == 2 -def test_update_version(persistent_array): - """Тест 3. Проверка обновления текущей версии""" +def test_set_version(persistent_array): + """Тест 4. Проверка обновления текущей версии""" persistent_array.add(1) persistent_array.add(2) - persistent_array.update_version(1) + persistent_array.set_version(1) assert persistent_array[5] == 1 - persistent_array.update_version(2) + persistent_array.set_version(2) assert persistent_array[6] == 2 def test_add_element(persistent_array): - """Тест 4. Проверка добавления элемента в массив""" + """Тест 5. Проверка добавления элемента в массив""" persistent_array.add(10) assert persistent_array.get_size() == 6 assert persistent_array[5] == 10 +def test_multiple_add_elements(persistent_array): + """Тест 6. Проверка добавления нескольких элементов""" + persistent_array.add(10) + persistent_array.add(20) + persistent_array.add(30) + assert persistent_array.get_size() == 8 + assert persistent_array[5] == 10 + assert persistent_array[6] == 20 + assert persistent_array[7] == 30 + + def test_pop_element(persistent_array): - """Тест 5. Проверка удаления элемента из массива""" + """Тест 7. Проверка удаления элемента из массива""" persistent_array.add(10) persistent_array.add(20) removed_value = persistent_array.pop(1) @@ -56,7 +71,7 @@ def test_pop_element(persistent_array): def test_insert_element(persistent_array): - """Тест 6. Проверка вставки элемента в массив по индексу""" + """Тест 8. Проверка вставки элемента по указанному индексу""" persistent_array.add(10) persistent_array.insert(2, 15) assert persistent_array.get_size() == 7 @@ -64,55 +79,97 @@ def test_insert_element(persistent_array): def test_remove_element(persistent_array): - """Тест 7. Проверка удаления элемента по индексу""" + """Тест 9. Проверка удаления элемента из массива по индексу""" persistent_array.add(10) persistent_array.add(20) - persistent_array.remove(0) + persistent_array.remove(1) assert persistent_array.get_size() == 6 - assert persistent_array[0] == 0 + assert persistent_array[1] == 0 + +def test_add_and_remove_elements(persistent_array): + """Тест 10. Проверка добавления и удаления элементов""" + persistent_array.add(10) + persistent_array.add(20) + persistent_array.add(30) + assert persistent_array.get_size() == 8 + persistent_array.remove(5) + assert persistent_array.get_size() == 7 + + +def test_versioning(persistent_array): + """Тест 11. Проверка работы с версиями массива""" + persistent_array.add(10) + persistent_array.add(20) + assert persistent_array.get_version_state(1)[5] == 10 + assert persistent_array.get_version_state(2)[6] == 20 + persistent_array.set_version(1) + assert persistent_array[5] == 10 + persistent_array.set_version(2) + assert persistent_array[6] == 20 + + +def test_invalid_index_in_version(persistent_array): + """Тест 12. Проверка недействительного индекса для версии""" + persistent_array.add(10) + persistent_array.add(20) + persistent_array.add(30) + with pytest.raises(ValueError): + persistent_array.get(1, 10) -def test_set_item(persistent_array): - """Тест 8. Проверка обновления элемента в массиве по индексу""" - persistent_array[0] = 99 - assert persistent_array[0] == 99 + +def test_get_size(persistent_array): + """Тест 13. Проверка размерности массива""" assert persistent_array.get_size() == 5 + persistent_array.add(10) + assert persistent_array.get_size() == 6 def test_check_is_empty(persistent_array): - """Тест 9. Проверка, является ли массив пустым""" + """Тест 14. Проверка на пустоту""" assert not persistent_array.check_is_empty() - persistent_array.remove(0) - persistent_array.remove(0) - persistent_array.remove(0) - persistent_array.remove(0) + persistent_array.remove(4) + persistent_array.remove(3) + persistent_array.remove(2) + persistent_array.remove(1) persistent_array.remove(0) assert persistent_array.check_is_empty() -def test_invalid_index_get(persistent_array): - """Тест 10. Проверка на исключение для недопустимого индекса при получении""" +def test_single_element_operations(persistent_array): + """Тест 15. Проверка операций с массивом из одного элемента""" + persistent_array.add(10) + persistent_array.remove(0) + assert persistent_array.get_size() == 5 + assert persistent_array[0] == 0 + + +def test_invalid_index_getitem(persistent_array): + """Тест 16. Проверка недействительного доступа по индексу для getitem""" with pytest.raises(ValueError): persistent_array[10] -def test_invalid_index_set(persistent_array): - """Тест 11. Проверка на исключение для недопустимого индекса при обновлении""" +def test_invalid_index_setitem(persistent_array): + """Тест 17. Проверка недействительного доступа по индексу для setitem""" with pytest.raises(ValueError): - persistent_array[10] = 5 + persistent_array[10] = 10 -def test_invalid_version_get(persistent_array): - """Тест 12. Проверка на исключение для недопустимой версии при получении""" - persistent_array.add(1) - persistent_array.add(2) +def test_invalid_index_pop(persistent_array): + """Тест 18. Проверка недействительного доступа по индексу для pop""" with pytest.raises(ValueError): - persistent_array.get(10, 0) + persistent_array.pop(10) -def test_invalid_version_update(persistent_array): - """Тест 13. Проверка на исключение для недопустимой версии при обновлении""" - persistent_array.add(1) - persistent_array.add(2) +def test_invalid_index_insert(persistent_array): + """Тест 19. Проверка недействительного доступа по индексу для insert""" with pytest.raises(ValueError): - persistent_array.update_version(10) + persistent_array.insert(10, 10) + + +def test_invalid_version_get(persistent_array): + """Тест 20. Проверка недействительного доступа по индексу для get""" + persistent_array.add(10) + with pytest.raises(ValueError): + persistent_array.get(10, 0) diff --git a/tests/test_list.py b/tests/test_list.py index 75f6742..8ec1a24 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -1,97 +1,138 @@ import pytest - from persistent_list import PersistentLinkedList # Тестирование методов класса PersistentLinkedList @pytest.fixture -def linked_list(): - """ - Фикстура для создания экземпляра персистентного двусвязного списка. - """ - return PersistentLinkedList([1, 2, 3, 4, 5]) +def persistent_list(): + """Инициализация персистентного двусвязного списка с начальными данными""" + return PersistentLinkedList([1, 2, 3, 4]) + + +def test_initial_state(persistent_list): + """Тест 1. Проверка начального состояния списка""" + assert persistent_list.get_size() == 4 + assert persistent_list.get(version=0, index=0) == 1 + + +def test_add(persistent_list): + """Тест 2. Проверка добавления элемента в конец списка""" + persistent_list.add(5) + assert persistent_list.get_size() == 5 + assert persistent_list.__getitem__(4) == 5 + + +def test_add_first(persistent_list): + """Тест 3. Проверка добавления элемента в начало списка""" + persistent_list.add_first(0) + assert persistent_list.get_size() == 5 + assert persistent_list.__getitem__(0) == 0 + + +def test_insert(persistent_list): + """Тест 4. Проверка вставки элемента в список по индексу""" + persistent_list.insert(2, 99) + assert persistent_list.get_size() == 5 + assert persistent_list.__getitem__(2) == 99 + assert persistent_list.__getitem__(3) == 3 + + +def test_pop(persistent_list): + """Тест 5. Проверка удаления элемента по индексу""" + removed_value = persistent_list.pop(1) + assert removed_value == 2 + assert persistent_list.get_size() == 3 + with pytest.raises(IndexError): + persistent_list.get(1) + + +def test_remove(persistent_list): + """Тест 6. Проверка удаления элемента по значению""" + persistent_list.remove(3) + assert persistent_list.get_size() == 3 + with pytest.raises(ValueError): + persistent_list.remove(10) + + +def test_add_multiple(persistent_list): + """Тест 7. Проверка добавления нескольких элементов в конец списка""" + persistent_list.add(5) + persistent_list.add(6) + persistent_list.add(7) + assert persistent_list.get_size() == 7 + assert persistent_list.__getitem__(4) == 5 + assert persistent_list.__getitem__(5) == 6 + assert persistent_list.__getitem__(6) == 7 + + +def test_insert_at_start(persistent_list): + """Тест 8. Проверка вставки элемента в начало списка""" + persistent_list.insert(0, -1) + assert persistent_list.get_size() == 5 + assert persistent_list.__getitem__(0) == -1 + + +def test_insert_out_of_range(persistent_list): + """Тест 9. Проверка вставки элемента за пределами допустимого диапазона индексов""" + with pytest.raises(IndexError): + persistent_list.insert(10, 100) + + +def test_remove_non_existing_value(persistent_list): + """Тест 10. Проверка удаления несуществующего элемента из списка""" + with pytest.raises(ValueError): + persistent_list.remove(99) + + +def test_pop_multiple(persistent_list): + """Тест 11. Проверка удаления нескольких элементов по индексу""" + persistent_list.pop(0) + persistent_list.pop(1) + assert persistent_list.get_size() == 2 + assert persistent_list.__getitem__(0) == 2 + assert persistent_list.__getitem__(1) == 4 + + +def test_set_version(persistent_list): + """Тест 12. Проверка переключения между версиями""" + persistent_list.add(5) + persistent_list.add(6) + persistent_list.set_version_doubly_linked_list(0) + assert persistent_list.get_size() == 4 + persistent_list.set_version_doubly_linked_list(2) + assert persistent_list.get_size() == 6 -def test_add(linked_list): - """Тест 1. Проверка добавления элемента в конец списка""" - linked_list.add(6) - assert linked_list.get(index=5) == 6 +def test_get_invalid_index(persistent_list): + """Тест 12. Проверка ошибки при попытке получить элемент по недопустимому индексу""" + with pytest.raises(IndexError): + persistent_list.get(index=100) -def test_add_first(linked_list): - """Тест 2. Проверка добавления элемента в начало списка""" - linked_list.add_first(0) - assert linked_list.get(index=0) == 0 +def test_get_version(persistent_list): + """Тест 13. Проверка получения состояния списка на определенной версии""" + persistent_list.add(5) + persistent_list.add(6) + assert persistent_list.get(version=0, index=3) == 4 + assert persistent_list.get(version=2, index=4) == 5 -def test_insert(linked_list): - """Тест 3. Проверка вставки элемента по индексу""" - linked_list.insert(2, 10) - assert linked_list.get(index=2) == 10 - assert linked_list.get(index=3) == 3 +def test_clear(persistent_list): + """Тест 14. Проверка очистки списка""" + persistent_list.clear() + assert persistent_list.get_size() == 0 + with pytest.raises(IndexError): + persistent_list.get(0) -def test_pop(linked_list): - """Тест 4. Проверка удаления элемента по индексу""" - removed_value = linked_list.pop(2) - assert removed_value == 3 - assert linked_list.get(index=2) == 4 +def test_check_is_empty(persistent_list): + """Тест 15. Проверка пуст ли список""" + assert not persistent_list.check_is_empty() + persistent_list.clear() + assert persistent_list.check_is_empty() -def test_remove(linked_list): - """Тест 5. Проверка удаления элемента по значению""" - linked_list.remove(4) +def test_get_invalid_version(persistent_list): + """Тест 16. Проверка ошибки при попытке получить версию, которой не существует""" with pytest.raises(ValueError): - linked_list.remove(4) - - -def test_get(linked_list): - """Тест 6. Проверка получения элемента по индексу""" - assert linked_list.get(index=0) == 1 - assert linked_list.get(index=4) == 5 - - -def test_get_version(linked_list): - """Тест 7. Проверка получения версии списка""" - linked_list.add(6) - linked_list.add(7) - version_1 = linked_list.get_version(1) - assert version_1[0] is not None - version_0_values = [] - current = version_1[0] - while current: - version_0_values.append(current.value) - current = current.next_node - assert version_0_values == [1, 2, 3, 4, 5, 6] - - -def test_update_version(linked_list): - """Тест 8. Проверка обновления версии списка""" - linked_list.add(6) - linked_list.add(7) - linked_list.update_version(1) - assert linked_list.get(index=5) == 6 - linked_list.update_version(0) - assert linked_list.get(index=4) == 5 - - -def test_clear(linked_list): - """Тест 9. Проверка очистки списка""" - linked_list.clear() - assert linked_list.get_size() == 0 - assert linked_list.check_is_empty() - - -def test_get_size(linked_list): - """Тест 10. Проверка получения размера списка""" - assert linked_list.get_size() == 5 - linked_list.add(6) - assert linked_list.get_size() == 6 - - -def test_check_is_empty(linked_list): - """Тест 11. Проверка метода для проверки пустоты списка""" - linked_list.clear() - assert linked_list.check_is_empty() is True - linked_list.add(10) - assert linked_list.check_is_empty() is False + persistent_list.get_version(999) diff --git a/tests/test_map.py b/tests/test_map.py index 580e6b6..5daee00 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -1,5 +1,4 @@ import pytest - from persistent_map import PersistentMap @@ -13,18 +12,18 @@ def persistent_map(): def test_get_version(persistent_map): """Тест 1. Проверка получения состояния на определенной версии""" persistent_map['c'] = 3 - persistent_map.update_version(1) + persistent_map.set_version(1) assert persistent_map['c'] == 3 - persistent_map.update_version(0) + persistent_map.set_version(0) with pytest.raises(KeyError, match='Key "c" does not exist'): persistent_map.get(0, 'c') -def test_update_version(persistent_map): +def test_set_version(persistent_map): """Тест 2. Проверка обновления версии""" persistent_map['c'] = 3 - persistent_map.update_version(1) + persistent_map.set_version(1) assert persistent_map['c'] == 3 @@ -56,28 +55,80 @@ def test_pop(persistent_map): """Тест 7. Проверка удаления элемента с использованием pop""" value = persistent_map.pop('a') assert value == 1 - assert 'a' not in persistent_map._history[persistent_map._current_state] + assert 'a' not in persistent_map._version_map[persistent_map._current_version].state def test_remove(persistent_map): """Тест 8. Проверка удаления элемента с использованием remove""" persistent_map.remove('a') - assert 'a' not in persistent_map._history[persistent_map._current_state] + assert 'a' not in persistent_map._version_map[persistent_map._current_version].state def test_clear(persistent_map): """Тест 9. Проверка очистки структуры данных""" persistent_map.clear() - assert persistent_map._history[persistent_map._current_state] == {} + assert persistent_map._version_map[persistent_map._current_version].state == {} def test_version_history(persistent_map): """Тест 10. Проверка истории версий""" persistent_map['c'] = 3 - persistent_map.update_version(1) + persistent_map.set_version(1) persistent_map['d'] = 4 - persistent_map.update_version(2) + persistent_map.set_version(2) assert persistent_map.get_version(0) == {'a': 1, 'b': 2} assert persistent_map.get_version(1) == {'a': 1, 'b': 2, 'c': 3} assert persistent_map.get_version(2) == {'a': 1, 'b': 2, 'c': 3, 'd': 4} + + +def test_create_new_state(persistent_map): + """Тест 11. Проверка создания новой версии с минимальным дублированием данных""" + initial_state = persistent_map._version_map[persistent_map._current_version].state.copy() + persistent_map['c'] = 3 + assert persistent_map._version_map[persistent_map._current_version].state != initial_state + assert initial_state == {'a': 1, 'b': 2} + + +def test_multiple_versions(persistent_map): + """Тест 12. Проверка изменения на несколько версий""" + persistent_map['c'] = 3 + persistent_map.set_version(1) + persistent_map['d'] = 4 + persistent_map.set_version(2) + + persistent_map['e'] = 5 + persistent_map.set_version(3) + + assert persistent_map.get_version(1) == {'a': 1, 'b': 2, 'c': 3} + assert persistent_map.get_version(2) == {'a': 1, 'b': 2, 'c': 3, 'd': 4} + assert persistent_map.get_version(3) == {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} + + +def test_setitem_overwrite(persistent_map): + """Тест 13. Проверка перезаписи существующего элемента""" + persistent_map['a'] = 10 + assert persistent_map['a'] == 10 + + persistent_map['a'] = 20 + assert persistent_map['a'] == 20 + + +def test_persistent_state_integrity(persistent_map): + """Тест 14. Проверка целостности состояния после последовательных изменений""" + persistent_map['c'] = 3 + version_1 = persistent_map.get_version(1) + + persistent_map['d'] = 4 + version_2 = persistent_map.get_version(2) + + assert version_1 == {'a': 1, 'b': 2, 'c': 3} + assert version_2 == {'a': 1, 'b': 2, 'c': 3, 'd': 4} + assert version_1 != version_2 + + +def test_get_non_existing_key_version(persistent_map): + """Тест 15. Проверка получения несуществующего ключа в существующей версии""" + persistent_map.set_version(0) + with pytest.raises(KeyError, match='Key "c" does not exist'): + persistent_map.get(0, 'c') From d808b576039d96c43859820130f60a90dab0bc0c Mon Sep 17 00:00:00 2001 From: Cinnamonness Date: Sun, 15 Dec 2024 17:53:41 +0700 Subject: [PATCH 2/5] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20README=20=D0=B4=D0=BB=D1=8F=20=D1=8D=D1=84=D1=84?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 377 +++++------------------------------------------------ b-tree.png | Bin 0 -> 158326 bytes 2 files changed, 34 insertions(+), 343 deletions(-) create mode 100644 b-tree.png diff --git a/README.md b/README.md index 556de0f..cbe4c29 100644 --- a/README.md +++ b/README.md @@ -1,372 +1,63 @@ -# Persistent-Data-Structures +# Эффективность по памяти -Курсовой проект по дисциплине "Современные методы программирования" - "Persistent data structures" - -## Разработчики: -* *Карицкая Полина, 24225.1* -* *Пучков Дмитрий, 24225.1* +Реализация дополнительного требования курсовой работы по дисциплине "Современные методы программирования" - "Persistent data structures" --- ## Оглавление -- [Persistent-Data-Structures](#persistent-data-structures) - - [Разработчики:](#разработчики) - - [Оглавление](#оглавление) - - [Описание задания](#описание-задания) - - [Базовые требования](#базовые-требования) - - [Дополнительные требования](#дополнительные-требования) - - [Календарный план](#календарный-план) - - [Ожидаемое решение](#ожидаемое-решение) - - [Теоретическая часть](#теоретическая-часть) - - [Персистентные структуры данных](#персистентные-структуры-данных) - - [Fat node](#fat-node) - - [Path copying](#path-copying) - - [Более эффективное по скорости доступа представление структур данных](#более-эффективное-по-скорости-доступа-представление-структур-данных) - - [API](#api) - - [Примеры использования](#примеры-использования) - - [Массив (Persistent Array)](#массив-persistent-array) - - [Список (Persistent Linked List)](#список-persistent-linked-list) - - [Aссоциативный массив (Persistent Map)](#aссоциативный-массив-persistent-map) - - [Используемые источники](#используемые-источники) +- [Эффективность по памяти](#эффективность-по-памяти) + - [B-деревья](#B-деревья) + - [Чем эффективнее простого копирования?](#чем-эффективнее-простого-копирования) + - [Когда выгодно использовать B-деревья?](#когда-выгодно-использовать-B-деревья) + - [Ограничения](#ограничения) --- -## Описание задания - -Реализовать библиотеку в Python со структурами данных в persistent-вариантах. - ---- -## Базовые требования -- [x] Массив (константное время доступа, переменная длина) -- [x] Двусвязный список -- [x] Ассоциативный массив (на основе Hash-таблицы, либо бинарного дерева) - ---- -## Дополнительные требования -- [ ] Реализовать более эффективное по памяти представление структур данных; -- [ ] Реализовать универсальный undo-redo механизм для перечисленных структур с поддержкой каскадности (для вложенных структур); -- [ ] Реализовать поддержку транзакционной памяти (STM). - ---- -## Календарный план - -| **Сроки** | **Этап работы** | **Разделение ответственностей** | -|--------------------|----------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| -| **до 23.11.2024** | - Создание каркаса проекта
- Создание репозитория на GitHub | - Ответственный за настройку проекта и репозитория: *Полина*
- Ответственный за организацию структуры файлов и начальную настройку CI/CD: *Дмитрий* | -| **до 07.12.2024** | **Реализация базовой функциональности:**
- Массив (Persistent Array)
- Двусвязный список (Persistent Linked List)
- Ассоциативный массив (Persistent Map)
- Создание единого API | - Ответственный за реализацию Persistent Array: *совместно*
- Ответственный за реализацию Persistent Linked List: *Полина*
- Ответственный за реализацию Persistent Map: *Дмитрий*
- Ответственный за создание API: *совместно* | -| **до 21.12.2024** | **Реализация дополнительной функциональности:**
- Реализовать более эффективное по скорости доступа представление структур данных, чем fat-node
- Обеспечить произвольную вложенность данных (по аналогии с динамическими языками)
- Реализовать универсальный undo-redo механизм для перечисленных структур с поддержкой каскадности | - Ответственный за улучшение представления структур данных: *совместно*
- Ответственный за реализацию вложенности данных: *совместно*
- Ответственный за разработку механизма undo-redo: *совместно* | - ---- -## Ожидаемое решение - -Ожидаемое решение состоит в разработке библиотеки, которая будет поддерживать следующие структуры данных: - -1. **Persistent Array** - массив с возможностью добавления элементов без изменения предыдущих состояний. Операции должны поддерживать константное время доступа. - -2. **Persistent Linked List** - двусвязный список с поддержкой добавления и удаления элементов, при этом сохраняется возможность обратиться к предыдущим состояниям списка. - -3. **Persistent Map** - ассоциативный массив, реализованный на основе хеш-таблицы или бинарного дерева поиска. Это будет позволять эффективно работать с данными, при этом поддерживать возможность обращения к предыдущим версиям данных. - -4. **Оптимизация доступа к данным** - предложим более эффективное представление данных для ускорения операций доступа по сравнению с fat-node. - -5. **Типизация данных** - обеспечим произвольную вложенность данных, при этом не отказываясь от строгой типизации через generic или template. - -6. **Undo/Redo Механизм** - реализуем механизм для всех структур данных, который позволит отменять и повторять изменения, причем для вложенных структур будет поддерживаться каскадность. - - -Каждая из структур данных будет поддерживать все основные операции: вставку, удаление, обновление, а также предоставлять возможность работы с предыдущими версиями данных через персистентность данных. Вся библиотека будет иметь единый API для работы с данными и их модификацией. Также будет обеспечена возможность взаимодействия с данными в виде вложенных структур. - ---- -## Теоретическая часть - -### Персистентные структуры данных - -**Персистентные структуры данных** сохраняют предыдущие версии при изменении. Структура называется *fully persistent*, если все её версии доступны для изменений. В *partially persistent* структурах можно изменять только последнюю версию, но доступ к предыдущим возможен. Эти структуры часто реализуются с использованием алгоритмов, таких как path copying, node copying и fat node, а также с применением бинарных деревьев поиска и красно-черных деревьев. - -Персистентные структуры используются в вычислительной геометрии, объектно-ориентированном программировании, текстовых редакторах, симуляциях и системах контроля версий, таких как Git. - -### Fat node - -*Fat node* используется для создания персистентных структур данных, где изменения сохраняются только в измененных узлах дерева, а сами узлы могут расширяться, чтобы хранить все версии. Основной принцип заключается в том, чтобы хранить обновления и версии данных в списках, что позволяет эффективно отслеживать изменения в структуре. - -**Преимущества:** - -* Экономия памяти, так как изменяются только те части данных, которые действительно изменились; -* Быстрая работа с историей изменений. - -**Недостатки:** - -* Может быть менее эффективен для структур с частыми изменениями, так как увеличение размера узлов приводит к дополнительным затратам на память. - -Можно посмотреть [визуализацию метода *fat node*](https://kumom.io/persistent-bst). - -### Path copying - -Метод *path copying* используется для создания персистентных структур данных, где при изменении узла создается его копия, и нужно пройти по всем узлам от измененного до корня, чтобы обновить ссылки на новый узел. Этот метод упрощает доступ к данным, так как для поиска нужной версии достаточно пройти путь от корня. +## B-деревья -**Преимущества:** +**B-дерево(B-tree)** - сбалансированное дерево поиска, в котором каждый узел содержит множество ключей и имеет более двух потомков. -* Быстрый доступ к данным; -* Простота в реализации. +**B-дерево порядка m обладает следующими свойствами:** -**Недостатки:** +*Свойство 1:* Глубина всех листьев одинакова. +*Свойство 2:* Все узлы, кроме корня должны иметь как минимум (m/2) – 1 ключей и максимум m-1 ключей. +*Свойство 3:* Все узлы без листьев, кроме корня (т.е. все внутренние узлы), должны иметь минимум m/2 потомков. +*Свойство 4:* Если корень – это узел не содержащий листьев, он должен иметь минимум 2 потомка. +*Свойство 5:* Узел без листьев с n-1 ключами должен иметь n потомков. +*Свойство 6:* Все ключи в узле должны располагаться в порядке возрастания их значений. -* Большие затраты на память, поскольку изменения могут потребовать копирования всей структуры; -* Могут возникать дополнительные накладные расходы при частых модификациях. +На иллюстрации продемонстрировано B-дерево 4 порядка. -Метод *path copying* также используется для создания полностью персистентных структур данных. +![B-дерево 4 порядка](b-tree.png) -На иллюстрации продеминстрирован пример использования *path copying* на бинарном дереве поиска. При внесении изменения создается новый корень, при этом старый корень сохраняется для дальнейшего использования (он показан темно-серым цветом). Заметим также, что старое и новое деревья частично делят общую структуру. - -![Пример использования path copying](path_copying.png) - -### Более эффективное по скорости доступа представление структур данных - -Поскольку одно из требований — использование более эффективного подхода по сравнению с методом *fat-node*, в проекте будет применяться подход ... +Представленная реализация с использованием B-деревьев позволяет сэкономить память по сравнению с простым копированием всей структуры данных для каждой новой версии. Экономия достигается за счет общего использования неизмененных данных, вместо создания полного дубликата при каждом изменении. --- -## API - -Для работы с персистентными структурами данных используйте следующий API: - -Создание объекта: -```python -from persistent_data_structure import PersistentLinkedList, PersistentArray, PersistentMap - -lst = PersistentLinkedList() -arr = PersistentLinkedList() -dct = PersistentMap() -``` - -Обращение к элементу текщей версии: -```python -lst[index] -arr[index] -dct[key] -``` - -Обращение по индексу к элементу произвольной версии для массива и списка: -```python -arr.get(version, index) -lst.get(version, index) -``` - -Обращение по ключу к элементу произвольной версии для мапы: -```python -dct.get(version, key) -``` - -Добавление элемента в конец в новую версию для массива и списка: -```python -arr.add(element) -lst.add(element) -``` - -Добавление элемента в начало в новую версию списка: -```python -lst.add_first(element) -``` - -Удаление элемента по индексу для массива и списка в новой версии и возвращение элемента: -```python -arr.pop(index) -lst.pop(index) -``` - -Удаление элемента по ключу для мапы в новой версии и возвращение элемента: -```python -dct.pop(key) -``` - -Обновление элемента по индексу в новой версии массива или списка: -```python -arr[index] = element -lst[index] = element -``` - -Обновление элемента по ключу в новой версии мапы: -```python -dct['key'] = element -``` - -Вставка элемента в новую версию по указанному индексу для массива или списка: -```python -arr.insert(index, element) -lst.insert(index, element) -``` - -Удаление элемента в новой версии массива или списка по индексу: -```python -arr.remove(index) -lst.remove(index) -``` +## Чем эффективнее простого копирования? -Удаление элемента в новой версии мапы по ключу: -```python -dct.remove(key) -``` +1. Экономия памяти: -Получение размера массива или списка для текущей версии: -```python -arr.get_size() -lst.get_size() -``` + * При каждом обновлении создается копия только измененной части состояния, а неизмененные данные продолжают разделяться между версиями; + * В простом копировании для каждой новой версии полностью дублируется все состояние, даже если изменения затрагивают лишь малую часть. -Проверка на пустоту для массива или списка: -```python -arr.check_is_empty() -lst.check_is_empty() -``` +2. Скорость: -Возвращение состояние объекта для указанной версии: -```python -arr.get_version(version) -lst.get_version(version) -dct.get_version(version) -``` + * Благодаря копированию только измененной части, создание новой версии работает быстрее, чем дублирование всего состояния. -Обновление текущей версии объекта до указанной: -```python -arr.update_version(version) -lst.update_version(version) -dct.update_version(version) -``` +3. Хранение данных: -Получение элемента текущей версии массива или списка по указанному индексу. -```python -arr.__getitem__(index) -lst.__getitem__(index) -``` - -Получение элемента текущей версии мапы по указанному ключу. -```python -dct.__getitem__(key) -``` - -Обновление или создание элемента по указанному индексу в новой версии для массива или списка. -```python -arr.__setitem__(index) -lst.__setitem__(index) -``` - -Обновление или создание элемента по указанному ключу в новой версии для мапы. -```python -dct.__setitem__(key) -``` - -Очистка объекта, при этом создается новая версия. -```python -arr.clear() -lst.clear() -dct.clear() -``` + * B-дерево позволяет организовать состояние версий так, что поддержка множества изменений становится управляемой и эффективной. --- -## Примеры использования - -### Массив (Persistent Array) - -**Примеры использования:** - -``` - >>> array = PersistentArray(size=5, default_value=0) # Создаем массив из 5 элементов, заполненных нулями - >>> array[0] # Получаем значение первого элемента - 0 - >>> array[0] = 10 # Обновляем значение первого элемента в новой версии - >>> array[0] # Проверяем значение первого элемента в текущей версии - 10 - >>> array.add(20) # Добавляем новый элемент в конец массива в новую версию - >>> array[5] # Проверяем значение нового элемента - 20 - >>> array.pop(1) # Удаляем элемент с индексом 1 в новой версии - 0 - >>> array.insert(2, 15) # Вставляем значение 15 на индекс 2 в новой версии - >>> array[2] # Проверяем вставленное значение - 15 - >>> array.remove(3) # Удаляем элемент с индексом 3 - >>> array.get(1, 0) # Получаем значение элемента с индексом 0 из версии 1 - 0 - >>> array.clear() # Очищаем массив, создавая новую версию - >>> array.get_size() # Проверяем размер массива в текущей версии - 0 - >>> array.check_is_empty() # Проверяем, пуст ли массив - True - >>> array.get(0, 2) # Пытаемся получить элемент из очищенного массива в версии 0 - Traceback (most recent call last): - ... - ValueError: Invalid index -``` - -### Список (Persistent Linked List) +## Когда выгодно использовать B-деревья? -**Примеры использования:** +1. Частичные изменения состояния: -``` - >>> linked_list = PersistentLinkedList([1, 2, 3]) # Создаем список с начальными элементами - >>> linked_list.add(4) # Добавляем элемент в конец списка - >>> linked_list[3] # Получаем элемент по индексу в текущей версии - 4 - >>> linked_list.add_first(0) # Добавляем элемент в начало списка - >>> linked_list[0] # Получаем элемент в текущей версии по индексу - 0 - >>> linked_list.insert(2, 1.5) # Вставляем элемент на индекс 2 - >>> linked_list[2] # Проверяем значение вставленного элемента - 1.5 - >>> linked_list.get(1, 2) # Получаем элемент из версии 1 по индексу 2 - 3 - >>> linked_list.pop(1) # Удаляем элемент по индексу 1 в новой версии - 2 - >>> linked_list.remove(3) # Удаляем элемент - >>> linked_list.clear() # Очищаем список, создавая новую версию - >>> linked_list.get(0, 2) # Пытаемся получить элемент из очищенной версии - Traceback (most recent call last): - ... - IndexError: Index out of range - >>> linked_list.update_version(2) # Возвращаемся к версии 2 - >>> linked_list[0] # Получаем элемент по индексу в версии 2 - 1 - >>> linked_list.get_size() # Получаем размер списка в текущей версии - 4 - >>> linked_list.check_is_empty() # Проверяем, пуст ли список в текущей версии - False -``` + * Когда изменения касаются лишь небольшой части состояния, а остальное остается неизменным. -### Aссоциативный массив (Persistent Map) +2. Множество версий: -**Примеры использования:** - -``` - >>> map = PersistentMap({'foo': 'bar'}) # Создаем пустой ассоциативный массив - >>> map['key'] = 'value' # Добавляем элемент - >>> map['key'] = 'value2' # Изменяем элемент в следующей версии - >>> map['key'] # Получаем элемент последней версии - 'value2' - >>> map.get(1, 'key') - {'key': 'value'} - >>> map.remove('key') # Удаляем элемент в новой версии - >>> map.clear() # Очищаем ассоциативный массив в новой версии - >>> map.get(0, 'key') # Пытаемся получить элемент отсутствующий в переданной версии - Traceback (most recent call last): - ... - KeyError: Key "key" does not exist -``` + * Если нужно поддерживать большое количество версий состояния. --- -## Используемые источники - -1. Milan Straka, "Functional Data Structures and Algorithms", Computer Science Institute of Charles University, Prague 2013 - -2. Крис Окасаки, "Чисто функциональные структуры данных", 2018 - -3. Статья на Geeks for geeks ["Persistent data structures"](https://www.geeksforgeeks.org/persistent-data-structures/) - -4. Несколько статей по персистентным векторам: - - * [Understanding Clojure's Persistent Vectors, pt. 1](https://hypirion.com/musings/understanding-persistent-vector-pt-1) - * [Understanding Clojure's Persistent Vectors, pt. 2](https://hypirion.com/musings/understanding-persistent-vector-pt-2) - * [Understanding Clojure's Persistent Vectors, pt. 3](https://hypirion.com/musings/understanding-persistent-vector-pt-3) - -5. Driscoll J. R. et al. Making data structures persistent //Proceedings of the eighteenth annual ACM symposium on Theory of computing. – 1986. – С. 109-121. - -6. Серия видео-лекций по персистентным структурам данных: +## Ограничения - * ["Visualizing Persistent Data Structures" by Dann Toliver](https://www.youtube.com/watch?v=2XH_q494U3U) - * [Persistent Data Structures, MIT](https://www.youtube.com/watch?v=T0yzrZL1py0) \ No newline at end of file +* Если изменения охватывают большую часть структуры данных (или всю), память перестает экономиться, поскольку почти весь массив нужно будет копировать. \ No newline at end of file diff --git a/b-tree.png b/b-tree.png new file mode 100644 index 0000000000000000000000000000000000000000..9eb0995a3304fc52d51a680e1c7d31de5eb35730 GIT binary patch literal 158326 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 literal 0 HcmV?d00001 From 63891d395f010975c75714301aca86f34ab00143 Mon Sep 17 00:00:00 2001 From: Cinnamonness Date: Sun, 15 Dec 2024 17:55:12 +0700 Subject: [PATCH 3/5] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B5=D0=B4=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BE=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index cbe4c29..bc57e97 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,15 @@ **B-дерево порядка m обладает следующими свойствами:** *Свойство 1:* Глубина всех листьев одинакова. + *Свойство 2:* Все узлы, кроме корня должны иметь как минимум (m/2) – 1 ключей и максимум m-1 ключей. + *Свойство 3:* Все узлы без листьев, кроме корня (т.е. все внутренние узлы), должны иметь минимум m/2 потомков. + *Свойство 4:* Если корень – это узел не содержащий листьев, он должен иметь минимум 2 потомка. + *Свойство 5:* Узел без листьев с n-1 ключами должен иметь n потомков. + *Свойство 6:* Все ключи в узле должны располагаться в порядке возрастания их значений. На иллюстрации продемонстрировано B-дерево 4 порядка. From 89f0cf9fa1abb5cb237184277a7c39165f1ec120 Mon Sep 17 00:00:00 2001 From: Cinnamonness Date: Wed, 18 Dec 2024 13:01:12 +0700 Subject: [PATCH 4/5] =?UTF-8?q?=D0=A0=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=BE=20=D0=BF=D0=BE=D1=81=D0=BB?= =?UTF-8?q?=D0=B5=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- persistent_data_structures/base_persistent.py | 51 +++---------------- persistent_data_structures/persistent_list.py | 48 ++++++++++++++--- persistent_data_structures/persistent_map.py | 48 ++++++++--------- 3 files changed, 73 insertions(+), 74 deletions(-) diff --git a/persistent_data_structures/base_persistent.py b/persistent_data_structures/base_persistent.py index e36fd8d..c96db26 100644 --- a/persistent_data_structures/base_persistent.py +++ b/persistent_data_structures/base_persistent.py @@ -1,10 +1,9 @@ from copy import deepcopy -from typing import Optional, Dict +from typing import Optional, Any class NodeState: - """Класс, представляющий состояние узла. Он может быть определен - в зависимости от структуры данных.""" + """Класс, представляющий состояние узла.""" def __init__(self, data: Optional['NodeState'] = None): self.data = data self.next_node: Optional['NodeState'] = None @@ -12,14 +11,14 @@ def __init__(self, data: Optional['NodeState'] = None): class Node: """Класс узла для хранения состояния в B-дереве.""" - def __init__(self, state: Optional[NodeState]) -> None: + def __init__(self, state: NodeState | None) -> None: """ Инициализирует узел с заданным состоянием. :param state: Состояние узла. """ - self.state: Optional[NodeState] = state - self.children: Dict[int, 'Node'] = {} + self.state: NodeState | None = state + self.children: dict[int, Node] = {} class BasePersistent: @@ -34,9 +33,9 @@ def __init__(self, initial_state: Optional[NodeState] = None) -> None: self.root: Node = Node(initial_state) self._current_version: int = 0 self._last_version: int = 0 - self._version_map: Dict[int, Node] = {0: self.root} + self._version_map: dict[int, Node] = {0: self.root} - def get_version(self, version: int) -> NodeState: + def get_version(self, version: int) -> dict[Any, Any]: """ Возвращает состояние персистентной структуры данных на указанной версии. @@ -60,26 +59,6 @@ def set_version(self, version: int) -> None: self._current_version = version self.root = self._version_map[version] - def set_version_doubly_linked_list(self, version: int) -> None: - """ - Обновляет текущую версию персистентной структуры данных до - указанной для двусвязного списка. - - :param version: Номер версии. - :raises ValueError: Если указанная версия не существует. - """ - if version not in self._version_map: - raise ValueError(f'Version "{version}" does not exist') - self._current_version = version - self.root = self._version_map[version] - head = self._version_map[self._current_version].state - self.size: int = 0 - current = head - while current: - self.size += 1 - current = current.next_node - self._version_map[self._current_version].state = head - def _create_new_state(self) -> None: """ Создает новую версию персистентной структуры данных с @@ -100,19 +79,3 @@ def _create_new_state(self) -> None: self._version_map[self._last_version] = new_node self._current_version = self._last_version self.root = new_node - - def _create_new_state_doubly_linked_list(self) -> None: - """ - Создает новую версию состояния для двусвязного списка, - минимизируя дублирование данных. - - Этот метод копирует состояние двусвязного списка, создавая - новый узел с минимальным дублированием - данных, чтобы сохранить версионность структуры данных. - - :raises ValueError: Если текущая версия не существует в карте версий. - """ - self._current_version += 1 - head = self._version_map[self._current_version - 1].state - new_head = self._deep_copy_list(head) - self._version_map[self._current_version] = Node(new_head) diff --git a/persistent_data_structures/persistent_list.py b/persistent_data_structures/persistent_list.py index 6a82a71..a1b7f5f 100644 --- a/persistent_data_structures/persistent_list.py +++ b/persistent_data_structures/persistent_list.py @@ -48,7 +48,7 @@ def __init__(self, initial_state: Optional[list[Any]] = None) -> None: def add(self, data: Any) -> None: """Добавляет элемент в конец списка в новой версии.""" - self._create_new_state_doubly_linked_list() + self._create_new_state() head = self._version_map[self._current_version].state tail = self._get_tail(head) new_node = ListNode(data) @@ -69,7 +69,7 @@ def add_first(self, data: Any) -> None: :param data: Данные, которые нужно добавить в начало списка. :return: None """ - self._create_new_state_doubly_linked_list() + self._create_new_state() head = self._version_map[self._current_version].state new_node = ListNode(data, next_node=head) @@ -82,7 +82,7 @@ def add_first(self, data: Any) -> None: def insert(self, index: int, data: Any) -> None: """Вставляет элемент в список по указанному индексу.""" - self._create_new_state_doubly_linked_list() + self._create_new_state() head = self._version_map[self._current_version].state current = head count = 0 @@ -121,7 +121,7 @@ def pop(self, index: int) -> Any: :return: Значение удаленного элемента. :raises IndexError: Если индекс выходит за пределы списка. """ - self._create_new_state_doubly_linked_list() + self._create_new_state() head = self._version_map[self._current_version].state current = head count = 0 @@ -153,7 +153,7 @@ def remove(self, value: Any) -> None: :return: None :raises ValueError: Если элемент не найден в списке. """ - self._create_new_state_doubly_linked_list() + self._create_new_state() head = self._version_map[self._current_version].state current = head @@ -209,7 +209,7 @@ def _get_tail(self, head: ListNode) -> Optional[ListNode]: def clear(self) -> None: """Очищает список, создавая новую версию.""" - self._create_new_state_doubly_linked_list() + self._create_new_state() self._version_map[self._current_version].state = None self.size = 0 @@ -271,6 +271,42 @@ def _deep_copy_list(self, head: ListNode) -> Optional[ListNode]: return new_head + def set_version(self, version: int) -> None: + """ + Обновляет текущую версию персистентной структуры данных до + указанной для двусвязного списка. + + :param version: Номер версии. + :raises ValueError: Если указанная версия не существует. + """ + if version not in self._version_map: + raise ValueError(f'Version "{version}" does not exist') + self._current_version = version + self.root = self._version_map[version] + head = self._version_map[self._current_version].state + self.size: int = 0 + current = head + while current: + self.size += 1 + current = current.next_node + self._version_map[self._current_version].state = head + + def _create_new_state(self) -> None: + """ + Создает новую версию состояния для двусвязного списка, + минимизируя дублирование данных. + + Этот метод копирует состояние двусвязного списка, создавая + новый узел с минимальным дублированием + данных, чтобы сохранить версионность структуры данных. + + :raises ValueError: Если текущая версия не существует в карте версий. + """ + self._current_version += 1 + head = self._version_map[self._current_version - 1].state + new_head = self._deep_copy_list(head) + self._version_map[self._current_version] = Node(new_head) + def get_size(self) -> int: """ Получение текущего размера списка. diff --git a/persistent_data_structures/persistent_map.py b/persistent_data_structures/persistent_map.py index 7a159ff..41e629d 100644 --- a/persistent_data_structures/persistent_map.py +++ b/persistent_data_structures/persistent_map.py @@ -1,45 +1,45 @@ from base_persistent import BasePersistent -from typing import Any, Dict +from typing import Any class PersistentMap(BasePersistent): - """A persistent associative array. + """Персистентный ассоциативный массив. - Represents a dictionary that preserves the history of changes. + Представляет собой словарь, сохраняющий историю изменений. """ - def __init__(self, initial_state: Dict[Any, Any] = {}) -> None: - """Initializes a persistent associative array. + def __init__(self, initial_state: dict[Any, Any] = {}) -> None: + """Инициализирует персистентный ассоциативный массив. - :param initial_state: The initial state of the persistent data structure. + :param initial_state: Начальное состояние персистентной структуры данных. """ super().__init__(initial_state) def __setitem__(self, key: Any, value: Any) -> None: - """Updates or creates an item by the specified key in the new version. + """Обновляет или создаёт элемент по указанному ключу в новой версии. - :param key: The key to be updated or created. - :param value: The value associated with the key. + :param key: Ключ, который нужно обновить или создать. + :param value: Значение, связанное с указанным ключом. """ self._create_new_state() self._version_map[self._last_version].state[key] = value def __getitem__(self, key: Any) -> Any: - """Returns the item of the current version by the specified key. + """Возвращает элемент текущей версии по указанному ключу. - :param key: The key of the item to be fetched. - :return: The value corresponding to the specified key or None if the key does not exist. + :param key: Ключ элемента, который нужно получить. + :return: Значение, соответствующее указанному ключу, или None, если ключ не существует. """ return self._version_map[self._current_version].state.get(key) def get(self, version: int, key: Any) -> Any: - """Returns the item from the specified version and key. + """Возвращает элемент из указанной версии по ключу. - :param version: The version number. - :param key: The key of the item to be fetched. - :return: The value corresponding to the specified key. - :raises ValueError: If the version does not exist. - :raises KeyError: If the key does not exist. + :param version: Номер версии. + :param key: Ключ элемента, который нужно получить. + :return: Значение, соответствующее указанному ключу. + :raises ValueError: Если версия не существует. + :raises KeyError: Если ключ не существует. """ if version not in self._version_map: raise ValueError(f'Version "{version}" does not exist') @@ -48,22 +48,22 @@ def get(self, version: int, key: Any) -> Any: return self._version_map[version].state[key] def pop(self, key: Any) -> Any: - """Removes and returns the item by the specified key. + """Удаляет и возвращает элемент по указанному ключу. - :param key: The key of the item to be removed. - :return: The removed item. + :param key: Ключ элемента, который нужно удалить. + :return: Удалённый элемент. """ self._create_new_state() return self._version_map[self._last_version].state.pop(key) def remove(self, key: Any) -> None: - """Removes an item by the specified key in the new version. + """Удаляет элемент по указанному ключу в новой версии. - :param key: The key of the item to be removed. + :param key: Ключ элемента, который нужно удалить. """ self.pop(key) def clear(self) -> None: - """Clears the associative array in the new version.""" + """Очищает ассоциативный массив в новой версии.""" self._create_new_state() self._version_map[self._current_version].state.clear() From df6e54a20283a787ff68f4338255fea7a1783e99 Mon Sep 17 00:00:00 2001 From: Cinnamonness Date: Wed, 18 Dec 2024 13:12:05 +0700 Subject: [PATCH 5/5] =?UTF-8?q?=D0=9E=D1=82=D1=80=D0=B5=D0=B4=D0=B0=D0=BA?= =?UTF-8?q?=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_list.py b/tests/test_list.py index 8ec1a24..eacfd6a 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -97,9 +97,9 @@ def test_set_version(persistent_list): """Тест 12. Проверка переключения между версиями""" persistent_list.add(5) persistent_list.add(6) - persistent_list.set_version_doubly_linked_list(0) + persistent_list.set_version(0) assert persistent_list.get_size() == 4 - persistent_list.set_version_doubly_linked_list(2) + persistent_list.set_version(2) assert persistent_list.get_size() == 6