Стек через LifoQueue, ПОЛИЗ, свойства классов
Стек — это структура данных, работающая по принципу LIFO (Last In, First Out): последний добавленный элемент извлекается первым. В Python можно реализовать стек с помощью queue.LifoQueue
.
Основные операции:
- Добавление элемента (
push
) — помещает элемент в стек. - Удаление элемента (
pop
) — удаляет верхний элемент из стека. - Проверка вершины (
peek
) — возвращает верхний элемент, не удаляя его. - Проверка пустоты стека — полезно, чтобы избежать ошибок при попытке
pop
на пустом стеке.
Пример
from queue import LifoQueue
# Создание стека
stack = LifoQueue()
# Операции со стеком
stack.put(10) # Добавить 10
stack.put(20) # Добавить 20
stack.put(30) # Добавить 30
# Извлечение элементов
print(stack.get()) # Вывод: 30
print(stack.get()) # Вывод: 20
# Проверка, пуст ли стек
print(stack.empty()) # Вывод: False
# Последний элемент
print(stack.get()) # Вывод: 10
print(stack.empty()) # Вывод: True
2. ПОЛИЗ (Обратная Польская Запись)
Обратная польская запись — это способ записи арифметических выражений, при котором операторы (действия) следуют за операндами. В ПОЛИЗ не требуется скобок для приоритета операций, так как операции выполняются последовательно по мере их появления.
Пример обычного выражения:
(3 + 4) * 5
В ПОЛИЗ это будет:
3 4 + 5 *
Алгоритм обработки ПОЛИЗ использует стек:
- Читаем элементы слева направо.
- Если элемент — число, помещаем его в стек.
- Если элемент — оператор, извлекаем из стека два числа, выполняем операцию и кладём результат обратно в стек.
- Когда вся строка обработана, результат находится на вершине стека.
Основные концепции свойств классов
Геттеры (
@property
)
Используются для получения значения атрибута. Вы определяете метод, который возвращает значение, и помечаете его декоратором@property
.Сеттеры (
@<имя_свойства>.setter
)
Позволяют задать логику, которая выполняется при присваивании значения атрибуту. Связываются с уже существующим свойством.Делетеры (
@<имя_свойства>.deleter
)
Логика для удаления атрибута. Связываются с существующим свойством.
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not value.strip():
raise ValueError("Имя не может быть пустым")
self._name = value
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value < 0:
raise ValueError("Возраст не может быть отрицательным")
self._age = value
@age.deleter
def age(self):
print("Возраст удален")
del self._age
# Пример использования
p = Person("Alice", 30)
print(p.name) # Alice
p.age = 35 # Устанавливаем возраст
print(p.age) # 35
del p.age # Удаляем возраст
Задачи
1. Напишите функцию для преобразования арифметического выражения из инфиксной записи (с обычным порядком операций и скобками) в обратную польскую запись (ПОЛИЗ). Требуется поддерживать приоритет операций.
Алгоритм преобразования (с использованием стека):
- Если символ — число, сразу добавляем его в выходную строку.
- Если символ — оператор, переносим операторы с более высоким или равным приоритетом из стека в выходную строку, затем помещаем оператор в стек.
- Скобки: открывающая скобка всегда помещается в стек, а при встрече закрывающей — извлекаем из стека операторы до тех пор, пока не встретим открытую скобку.
def infix_to_poliz(expression):
precedence = {'+': 1, '-': 1, '*': 2, '/': 2}
stack = LifoQueue()
output = []
for token in expression.split():
if token.isdigit():
#ваш код
elif token == '(':
#ваш код
elif token == ')':
#ваш код
else: # Это оператор
#ваш код
while not stack.empty():
#ваш код
return #что-то возвращаем
# Пример инфиксного выражения
expression = "( 3 + 4 ) * 5"
poliz = infix_to_poliz(expression)
print("ПОЛИЗ:", poliz)
2. Добавьте обработку ошибок в функцию вычисления ПОЛИЗ:
- Недостаточно операндов: если оператору не хватает операндов, выведите ошибку.
- Пустой стек после вычислений: если в стеке больше одного числа, это означает, что выражение составлено неверно.
- и т.д.
3. Напишите функцию, которая принимает инфиксное выражение, преобразует его в ПОЛИЗ и затем вычисляет результат.
4. Напишите класс Temperature
, который:
- Имеет атрибут
_celsius
. - С помощью свойства
fahrenheit
конвертирует температуру из Цельсия в Фаренгейты (_celsius * 9/5 + 32
). - При обновлении свойства
fahrenheit
пересчитывает значение_celsius
.
5. Создайте класс Employee
, который:
- Имеет свойства
name
(имя сотрудника) иsalary
(зарплата). - Использует декораторы:
- Геттер для свойства
salary
возвращает текущее значение. - Сеттер проверяет, что зарплата не ниже минимального значения (например, 30000).
- Геттер для свойства