Треки
/
Python
Python
/
Вправи
/
Кільцевий буфер
Кільцевий буфер

Кільцевий буфер

Легка

Вказівки

Кільцевий буфер, циклічний буфер або ring buffer - це структура даних, яка використовує єдиний буфер фіксованого розміру так, ніби його зʼєднано кінець у кінець.

Спочатку кільцевий буфер порожній і має певну заздалегідь визначену довжину. Наприклад, ось буфер на 7 елементів:

[ ][ ][ ][ ][ ][ ][ ]

Припустімо, що в середину буфера записують 1 (точне початкове розташування для кільцевого буфера не має значення):

[ ][ ][ ][1][ ][ ][ ]

Далі припустімо, що додають ще два елементи, 2 і 3, які дописуються після 1:

[ ][ ][ ][1][2][3][ ]

Якщо після цього з буфера вилучити два елементи, вилучаються найстаріші значення в буфері. У цьому випадку вилучено 1 і 2, і в буфері залишається лише 3:

[ ][ ][ ][ ][ ][3][ ]

Коли в буфері 7 елементів, він заповнений повністю:

[5][6][7][8][9][3][4]

Коли буфер заповнений, виникає помилка, яка повідомляє клієнта, що подальші записи заблоковано, доки не звільниться місце.

Коли буфер заповнений, клієнт може на власний розсуд перезаписати найстаріші дані примусовим записом. У цьому випадку додають ще два елементи, A і B, які перезаписують 3 і 4:

[5][6][7][8][9][A][B]

3 і 4 замінено на A і B, тож найстарішими даними в буфері тепер стає 5. Нарешті, якщо вилучити два елементи, то повернуться 5 і 6, і в результаті буфер матиме такий вигляд:

[ ][ ][7][8][9][A][B]

Оскільки є вільне місце, якщо клієнт знову скористається перезаписом, щоб зберегти C і D, то використано буде місце, де раніше зберігалися 5 і 6, а не позицію 7 і 8. 7, як і раніше, найстаріший елемент, і буфер знову заповнений повністю.

[C][D][7][8][9][A][B]

Налаштування та породження винятків

Іноді в коді виникає потреба і налаштувати винятки, і raise їх. Коли ми це робимо, завжди варто додавати змістовне повідомлення про помилку, яке вказує на джерело цієї помилки. Це робить код зрозумілішим і суттєво допомагає з налагодженням.

Власні винятки можна створити через нові класи винятків (докладніше дивіться в classes), які зазвичай є підкласами Exception.

Якщо відомо, що джерело помилки буде похідним від певного типу винятків, можна успадкуватися від одного з built in error types під класом Exception. Породжуючи помилку, все одно варто додати змістовне повідомлення.

У цій вправі потрібно створити два власні винятки. Один виняток, який слід породити/«кинути», коли наш кільцевий буфер повний, і один, коли він порожній. Тести пройдуть лише тоді, коли ми створимо належні власні винятки, породимо ці винятки і додамо належні повідомлення про помилки.

Щоб налаштувати built-in exception, створіть class, який успадковується від цього винятку. Породжуючи власний виняток із повідомленням, передайте повідомлення як аргумент типу exception:

# subclassing the built-in BufferError to create BufferFullException
class BufferFullException(BufferError):
    """Exception raised when CircularBuffer is full.

    message: explanation of the error.

    """
    def __init__(self, message):
        self.message = message

        
# raising a BufferFullException
raise BufferFullException("Circular buffer is full")

Джерело

WikipediaПосилання відкривається в новому вікні або вкладці
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Python Exercism

Час розпочати Кільцевий буфер?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Python, а також 17 концепцій146 вправ та справжнє наставництво від людей, і все це безкоштовно.

Глибоке занурення у Кільцевий буфер!

У цьому відео ми розглянемо кільцевий буфер: що це таке, де його застосовують і які бувають реалізації, зокрема черги, статичні й динамічні масиви, незмінні структури даних і цікаву реалізацію на основі агентів.