Ну что, дорогие мои детишечки, пришло время заняться серьезными вещами и немножечко напрячь свой мозг, который у вас большой, огромный, как у доцентов.
Давайте-ка начнем с чего-нибудь простого и всем известного. Так сказать, разомнем ваши пальчики. Хорошо? нет
Вот вам первый вопрос в качестве тренировки. Давайте думать вместе. Рассуждения и обсуждения, конечно же, происходят в комментариях. Потому что тс может нести хуйню... Уже начал есичо
Но если вы не хотите обсуждать и рассуждать, то просто молча ткните кнопку и идите по своим делам дальше, скролить бесконечную ленту.
Итак.
Фая!
ВикторинаВыберите 1 вариант
Правильный ответ задан автором.
Что из перечисленного, согласно самой строгой лингвистической трактовке, НЕ является исконно русским матерным корнем (основой трёхэтажной конструкции)?
Пост не рекомендуется для лиц с тонкой душевной организацией и для тех, кто совершенен в своем деле...
.
.
...и вообще не читайте его.
Понятненько?
.
.
.
.
.
а теперь?
Тут глупости, написанные таким же глупым человеком. Поэтому считайте, что пост написал умственно отсталый инвалид, который заслуживает снисхождения.
Каждый, думающий, что он умеет в программирование, должен нацарапать калькулятор и безумно гордиться своей поделкой(С) выпячив грудь, ибо его шэдэвор неповторим, уникален (нет) и вапще я у мамы самый красивый.
Но думать что ты Гуру кодинга вовосе необязательно, достаточно верить в себя и быть настолько смелым, чтобы показать свои высеры публике, подставив панамку.
Ну и главное не забывать делать вид, что ты во всём этом разбираешься, и сделать содержимое ниже - это как два пальца об асфальт, оставив за кадром сопли, слёзы и прочие выделения человеческого организма.
Ну штош, пришло время приступить и надеяться на то, что всё было предусмотрено, любая ситуация была смоделирована, тесты прошли успешно и, казалось бы, можно уже начать заниматься математикой.
Самое главное при создании какой-либо программулины - это диалог с тем, кто пользуется вашими поделками. Но, как вы понимаете, это вовсе не обязательно, поэтому в первой версии вычислительного скрипта поздороваемся сдержанно и без всяких там панибратств.
Поприветствуем юзверя)))
# Ты запустил эту хуйню. Теперь обратного пути нет.
print("Простой калькулятор. Введи q, чтобы выйти.") # Тебе дан шанс пойти по своим делам или воспользоваться каклькуляторов в тефоне
# ---------------- Погнали в бесконечный цикл!!! Или тебе надо два плют два сложить?? ----------------
while True: # Игра началась. Хули смотришь? Действуй.Про вайл тру - после кода ниж)))
# Пытаемся вытянуть из пользователя первое число. Стрип на случай, если он долбоёб и понаставил пробелов.
first = input("Первое число (или q для выхода): ").strip()
if first.lower() == "q": # Умный выбор. Всё бросить и уйти. Завидую.
print("Пока!") # Прощай, свободный человек!
break # Вырываемся из ада бесконечного цикла. УРА!
# ---------------- ловим чуш на вводе ----------------
try:
a = float(first) # Попытка превратить введённый бред в число. Молимся.
except ValueError: # А вот и нет, тут не число! Типуля за капмуктером опять что-то наклацал.
print("Это не число. Попробуй ещё раз.") # Терпеливо объясняем очевидное. Опять.А можно было бы и матом
continue # Отматываем плёнку и заставляем его страдать с начала.
# ---------------- че делаем-то? ----------------
op = input("Операция (+ - * /): ").strip() # Выбор, от которого зависит всё.
# Проверяем, не долбоёб ли пользователь, который ввёл знак из другого математиичкского мирв.
if op != "+" and op != "-" and op != "*" and op != "/":
print("Нужна одна из операций: + - * /") # Говорим по-русски, что мы тут умеем.
continue # Назад, в начало, учить матешу!
# ---------------- а теперь фторой кондедат ----------------
second = input("Второе число: ").strip() # Снова пытаемся добыть цифру из дикого зверя по имени Пользователь.
try:
b = float(second) # Вторая попытка. Пальцы скрещены.
except ValueError: # Блядь! Опять провал. Он неисправим.
print("Это не число. Попробуй ещё раз.") #вздох Повторяем мантру.
continue
# ----------------смотрим че получилось ----------------
if op == "+": # Если выбрал плюс — всё просто, как два пальца обоссать
result = a + b # Складываем. Надеемся, числа не слишком большие.
elif op == "-": # Вычитание. Уносим готовенькое.
result = a - b
elif op == "*": # Умножение. Всё растёт, как на дрожжах.
result = a * b
else: # А вот и деление... Наше всё, источник вечных ошибок.
if b == 0: # ОПАСНОСТЬ! Пользователь пытается разделить на ноль и схлопнуть вселенную кхуям
print("Ошибка: деление на ноль") # Срочно останавливаем это безумие.
continue # И отправляем его в начало без результата. Пусть думает над своим преступлением.
result = a / b # Если ноля нет — делим спокойно. Фух.
# ---------------- ФИНАЛ. ПОКАЗЫВАЕМ, НА ЧТО СПОСОБНА ЭТА ХУЙНЯ ----------------
print("Результат:", result) # Выводим то, ради чего всё это начиналось. Наслаждайся, мамкин математик.
Как видите это вообще такое простое скучное и беспонтовое решение, и на первый взгляд самодостаточное.
но!!!!
Это фигня собачачья!!! Потому что делает пользование калькулятором невохможным, ибо взаимодействие с ним выглядит так:
Первое число (или q для выхода): 12
Операция (+ - * /): +
Второе число: 85
Результат: 97.0
Первое число (или q для выхода): 23
Операция (+ - * /): *
Второе число: 45879
Результат: 1055217.0
Первое число (или q для выхода):
После ввода каждого числа нада жмать Интер, а это тупо, садомазохично и не юзерфрендли. Юзер не секретарша на клавиатуре. Он царь и бог, который хочет ввести 5 + 3 и сразу, блять, получить ответ, а не участвовать в этом концерте одинокого пианиста для трёх рук - число-энтер-оператор-энтер-число-энтер.
Логичным будет задать вопрос: "асхуяле?" Потому что консольный ввод (input()) в питоне это тупой, линейный идиот. Он читает строку только до переноса строки. Он не умеет в реальном времени, как человек в калькуляторе. Он слепой старик, который просит тебя говорить по одному слову и стучать палкой по голове после каждого.
Можно отказаться от input() и читать всё одной строкой, как нормальные люди. Потом самому разбирать, где числа, где операторы.
Это круто, мощно, молодёжно, но это уже не 10 строк кода, а отдельная ёбля.
# Примерно так выглядит вход в лигу крутых типочков
expression = input("Введи весь пример (например, 5+3): ").replace(" ", "")
# А дальше надо эту строку распетушить на числа и знаки внимания
# проверить, что там нет букв, обработать приоритеты (приоритеты - это
# што вычисляется вначаеле - сложение или умножение, в скопках или за ними
# думаю со школы помните)
# Короче, адский труд для ТСа. Но зато одной строкой!
Есть два стула
Есть несколько путей:
Путь Воина (сделать свою дичь) - сложна...
Путь хитросделанного и рационального (найти готовую библиотеку) - просто
Ну или воспользоваться тем, который есть в вашей, простигосподи, винде - но тогда и пост нахуй не нужен.
Путь воена, Света:
Итак, блять, путь воина. Это не для слабаков. Это когда ты говоришь стандартному input(): иди нахуй со своим энтером и начинаешь парсить (левои или правой - не важно) всё сам, разрывая строку голыми зубами.
Зырим
Отказываемся от пошагового опроса. Берем всё выражение одной строкой: "5 + 3 * 2". А потом начинается адский труд (для ТС конечно же, ибо тру программистам - это как в носе ковырять): надо превратить эту строку в числа и операторы, понять приоритет, посчитать. Это как узнать рецепт кокаколы с помощью масспектрометра и наколотить такую же с газиками. Ну почти.
Первым делом надо выкинуть из строки пробелы, чтобы они не мешались. Пользователь мог написать и 5+3, и 5 + 3, и 5 + 3 - а нам похуй.
expression = input("Введи выражение, герой (типа 5+3 или 2*4): ").replace(" ", "")
# теперь тут голая строка без пробелов "5+3*2"
Теперь разбираем на хапчасти эту строку (числа и операторы), это самый ебучий момент. Надо пройтись по строке символ за символом и понять, где кончается одно число и начинается оператор. Число может быть 5, а может быть -12.5. Оператор, если что это +, -, *, /. Может быть даже ** для степени.
Делается это обычно через конченный автомат (state machine). Грубо говоря идём по строке и включив размышлительниншну бурчим себе под нос:
Сейчас я читаю цифру - это часть числа. Встретил точку - это тоже часть числа (дробная). Встретил плюс/минус/умножить/поделить - всё, число закончилось. Запоминаем число, запоминаем оператор, начинаем собирать новое число.
вот простой пример:
primer = [] # Сюда будем складывать то, шо нашли
current_number = '' # Здесь накапливаем цифры текущего числа
for char in expression:
if char.isdigit() or char == '.': # Если это цифра или точка то это часть числа
current_number += char
else: # Если это не цифра (значит, имератор)
if current_number: # Если до этого собирали число
primer.append(float(current_number)) # записать число
current_number = '' # обнулить сборшык
primer.append(char) # записать сам оператор
# не забыть про последнее число в строке
if current_number:
primer.append(float(current_number))
# Теперь вся хуйня для "5+3*2" будет выглядеть так: [5.0, '+', 3.0, '*', 2.0]
Помните про уроки матепатики и приоритеты считания? Вот тут пиздец. Есть список, который primer - это [5.0, '+', 3.0, '*', 2.0]. Если выполнять слева направо, получится (5+3)*2 = 16. Но математика говорит, что умножение приоритетнее!!!!111 Должно быть 5 + (3*2) = 11.
Значит, нужно пройти по списку несколько раз. Сначала найти все умножения и деления (*, /), выполнить их, и заменить в списке тройку элементов (число, оператор, число) на одно число (результат). Потом повторить для сложения и вычитания (+, -).
Это можно делать на месте, изменяя список primer, пока в нём не останется одно число которое итоговый результат.
например
i = 0
while i < len(primer):
if primer[i] == '*':
# умножение детектед. ьерём предыдущее и следующее числа
result = primer[i-1] * primer[i+1]
# меняем тройку элементов на результат: [..., a, '*', b, ...] -> [..., result, ...]
primer[i-1:i+2] = [result] # заменить нада
i -= 1 # откатитть индекс, потому что список стал короче
i += 1
# и анал огично для '/', затем для '+', '-'
Обрабатываем нештатное ситуфциё - без этого никуда. Юзер непредсказуем! А что, если он ввёл 5++3 или 12.*7 или просто "у меня большой хуй"? Парсер должен не сломаться, а красиво послать нахуй. Нужны проверки на каждом шагу, например в строке только разрешённые символы (цифры, точка, операторы), число точек в числе не больше одной, после оператора идёт число (а не другой оператор), деления на ноль нет, список primer в итоге имеет правильную структуру - чередование число-оператор-число или 2 + хуй?
в итоге получается полный (нет) контроль. Можно добавить скобки (), унарные минусы -5, степени **, функции sin(). Но цена этого огромная, ебучая работа, тонны кода для разбора и валидации, и постоянные баги на ёбнутых случаях вроде -.5 + .3).
Это путь для тех, кому надо понять, как всё устроено изнутри, или для тех, кому нужна кастомная, очень специфичная штука некакувсех. Для обычного калькулятора это избыточное оверкилл-масло, высеченное из гранита ногтяме Кукухи.
Но, резюмируя, это не для пользы, а это про силу воли, упрямство и желание сделать всё своими руками, даже если для этого придётся изобрести свою велик срулём. Удачи че, воен. Ты её, блять, заслужил.
Собствено вот, зырьте какая большая ебала получается:
# арём главной функцией, дескать она тут правит бал!!!111
def calculate_warrior_style():
"""
Калькулятор ниибического вида.
Принимает примерчики типа "5+3*2" и считает с учётом приоритета вычислкний.
Поддерживает скобки, минусы и степень (**).
"""
# вводим в курс дела, юзер должен понять, куда он попал.
print("=== КАЛЬКУЛЯТОР ===")
print("пеши выражение одной строкой. Поддерживаются + - * / **, скобки и числа с точкой.")
print("Пример: 5+3*2 или 10.5 / 2 - 1 или -(2+3)**2") #юзер всё равно чтото сломает....
print("Введи 'q' для выхода. Удачи, ёпта.\n")
# Бесконечный цикл. Выход только через break или смерть.
while True:
# спрашиваем "че надо?".
raw_input = input("Твоё выражение (или q): ").strip() # strip() отрезает пробелы по краям, на случай если он долбоёб.
if raw_input.lower() == 'q': # Если ввёл q (даже заглавную) это капитуляция.
print("пока, слабак") # Прощаемся с честью.
break # Ломаем цикл. Свобода. теперь питание компьютера можно отключить
# наведем порядок, уберем хлам
expression = raw_input.replace(" ", "") # выкуриваем ВСЕ пробелы из середины. Они нам не нужны.
if not expression: # Если после чистки осталась пустота...
print("Ты ввёл пустоту. Великий воин молчит.") # ...сообщаем о творческом кризисе.
continue # Отматываем цикл назад, пусть вводит заново, ёбаный хуй
# превращаем строку в запчасти).
try:
primer = primerize(expression) # Вызываем функцию-ошибалку. Она может выплюнуть ошибку.
except ValueError as exc: # Если мясорубка сломалась и выплюнула ValueError...
print(f"Ошибка: {exc}") # ...показываем пользователю, в чём он мудак.
continue # И заставляем его страдать с начала.
# гля прикол - делаем из (5+3) в обратную польскую запись (5 3 +). Так легче считать.лол
try:
rpn = to_rpn(primer) # косплей сортировочной станции. Мозголомно, но работает.
except ValueError as exc: # Если алгоритм нашел кривые скобки...
print(f"Ошибка: {exc}") # ...тыкаем пользователя в его же косяк.
continue # Нахуй иди исправляй.
# смотрим что наваяла обратная польская запись.
try:
result = eval_rpn(rpn) # Берём и начинаем жать.
except ValueError as exc: # Если не хватило чисел или деление на ноль...
print(f"Ошибка: {exc}") # ...объясняем, что он натворил.
continue # И отправляем в начало.
# неужели написал правильно??? ахуеть - выдаем результат.
print(f"Результат твоего высера: {result}") # Пользователь доволен. Мы измотаны.
print("-" * 40) # Рисуем разделитель. Эстетика, блять.
# ========== функция primerize о которой была речь выше) ==========
# Берёт строку и с остервенением кромсает её на числа, операторы и скобки.
def primerize(expression):
primer = [] # Сюда будем складывать добычу: числа и операторы.
i = 0 # Указатель. Бежит по строке, как алкаш по бутылкам.
prev_type = None # Следим, что было прошлым: число('num'), оператор('op'), скобка. Чтобы отличить унарный минус.
# Главный цикл чтения строки. Пока не кончится.
while i < len(expression):
char = expression[i] # Берём текущий символ.
# Если пробел то игнорируем, их уже вырезали, но на всякий.
if char.isspace():
i += 1
continue
# Если символ цифра или точка, значит, это начало чилса
if char.isdigit() or char == ".":
start = i # Запоминаем, где число началось.
dots = 0 # Щёчик точек в числе (больше одной это ошибка).
digits = 0 # Счётчик цифр (ноль цифр это тоже ошибка).
# Пока не кончилась строка и идут цифры/точки, собираем число.
while i < len(expression) and (expression[i].isdigit() or expression[i] == "."):
if expression[i] == ".":
dots += 1 # Нашли точку и запомнели
else:
digits += 1 # Нашли цифру. Тоже запоминаем.
i += 1 # Переходим к следующему символу.
# Вырезаем кусок строки от start до i это наше число в виде строки.
number_str = expression[start:i]
# Проверяем фсю хуйню: если точек >1 или цифр нет, то это не число.
if dots > 1 or digits == 0:
raise ValueError(f"это не число блять!!!! '{number_str}'") # Выбрасываем ошибку наверх.
primer.append(float(number_str)) # Превращаем строку в float и кладём в список.
prev_type = "num" # Запоминаем, что последним было число.
continue # Переходим к следующему символу.
# Если символ звёздочка и следующая за ней тоже звёздочка, это оператор степени '**'.
if char == "*" and i + 1 < len(expression) and expression[i + 1] == "*":
op = "**" # Это оператор.
i += 2 # Перепрыгиваем сразу два символа.
# Иначе, если символ,то один из разрешённых операторов или скобок...
elif char in "+-*/()":
op = char # Это наш оператор или скобка.
i += 1 # Переходим к следующему символу.
else:
# Если символ не опознан это пиздец. Выбрасываем ошибку.
raise ValueError(f"че за хуйня? '{char}'")
# ----- Обработка ЛЕВОЙ скобки ( -----
if op == "(":
# в нашем случае цобка не может идти после числа или другой правой скобки без оператора. Пример: 5( или )(.
if prev_type in ("num", ")"):
raise ValueError("пропущен оператор перед '('")
primer.append(op) # Кладём скобку в список.
prev_type = "(" # Запоминаем, что была скобка.
continue # Едем дальше.
# ----- Обработка ПРАВОЙ скобки ')' -----
if op == ")":
# Скобка не может идти после оператора или другой левой скобки. Пример: +) или ().
if prev_type in (None, "op", "("):
raise ValueError("лишняя ')' или пустые скобки, повнимательнее там")
primer.append(op) # Кладём скобку в список.
prev_type = ")" # Запоминаем.
continue # Едем дальше.
# ----- Обработка УНАРНОГО МИНУСА (например, -5 или -(2+3)) -----
# Если текущий оператор '-' и перед ним ничего не было (начало строки) или был оператор/левая скобка...
if op == "-" and (prev_type is None or prev_type in ("op", "(")):
primer.append("u-") # Кладём специальный "унарный минус".
prev_type = "op" # Запоминаем, что был оператор.
continue # Едем дальше.
# ----- Обработка ОБЫЧНЫХ БИНАРНЫХ ОПЕРАТОРОВ (+, -, *, /, **) -----
# Оператор не может быть в начале или после другого оператора/левой скобки. Пример: +5 или (*.
if prev_type in (None, "op", "("):
raise ValueError(f"оператор '{op}' стоит не на месте")
primer.append(op) # Всё зоебок, кладём оператор в список.
prev_type = "op" # Запоминаем.
# Проверка после разбора всей строки. Выражение не может кончиться оператором или открытой скобкой.
if prev_type in (None, "op", "("):
raise ValueError("так примеры не пишут! выражение не может заканчиваться оператором или '('")
return primer # Возвращаем гордый список токенов.
# ========== ФУНКЦИЯ-ПЕРЕВОДЧИК (to_rpn) ==========
# Превращает обычную запись в обратную польскую с помощью сортировочной станции.
def to_rpn(primer):
output = [] # Сюда пойдёт итоговая RPN-последовательность.
stack = [] # Временный стек для операторов и скобок.
# Словарь приоритетов: чем больше цифра, тем круче оператор.
precedence = {"u-": 3, "**": 4, "*": 2, "/": 2, "+": 1, "-": 1}
right_assoc = {"u-", "**"} # Множество право-ассоциативных операторов (для степени и унарного минуса).
# Идём по каждому primer на входе.
for token in primer:
# Если оно число, сразу отправляем его на выход.
if isinstance(token, float):
output.append(token)
continue
# Если оно левая скобка, пихаем её в стек.
if token == "(":
stack.append(token)
continue
# Если правая скобка, выталкиваем из стека ВСЁ до левой скобки в output.
if token == ")":
while stack and stack[-1] != "(": # Пока стек не пуст и наверху не '('...
output.append(stack.pop()) # ...выталкиваем операторы в output.
if not stack: # Если стек опустел, а '(' так и не нашли...
raise ValueError("скобки не совпадают") # ...скобки кривые.
stack.pop() # Выкидываем саму '(' из стека.
continue
# Если это оператор (унарный или бинарный)...
if token in precedence:
# Пока в стеке есть операторы с БОЛЬШИМ ИЛИ РАВНЫМ (для лево-ассоциативных) приоритетом...
while stack and stack[-1] in precedence:
top = stack[-1] # Смотрим на верхний оператор в стеке.
# Сравниваем приоритеты с учётом ассоциативности.
if (token not in right_assoc and precedence[token] <= precedence[top]) or (
token in right_assoc and precedence[token] < precedence[top]
):
output.append(stack.pop()) # Выталкиваем старый оператор в output.
else:
break # Иначе останавливаемся.
stack.append(token) # Кладём текущий оператор в стек.
continue
# Сюда попасть не должны. На всякий — ошибка.
raise ValueError(f"непонятно че вапще'{token}'")
# Когда все эти штуки обработаны, выталкиваем оставшиеся в стеке операторы в output.
while stack:
top = stack.pop() # Берём верхний элемент.
if top in ("(", ")"): # Если это скобка значит, они не совпали.
raise ValueError("скобки не совпадают")
output.append(top) # Иначе отправляем в output.
return output # Возвращаем чистую, прекрасную рпн.
# ========== ФУНКЦИЯ-ВЫЧИСЛИТЕЛЬ (eval_rpn) ==========
# Считает результат по обратной польской записи.
def eval_rpn(primer):
stack = [] # Рабочий стек для чисел.
# Идём по каждому токену в RPN-последовательности.
for token in primer:
# Если токен число, просто пихаем его в стек.
if isinstance(token, float):
stack.append(token)
continue
# Если токен унарный минус, берём одно число из стека, меняем знак и кладём обратно.
if token == "u-":
if len(stack) < 1: # Проверяем, что в стеке есть хотя бы одно число.
raise ValueError("унарный минус без числа")
stack.append(-stack.pop()) # Берём число, меняем знак, кладём обратно.
continue
# Для бинарных операторов нужно ДВА числа из стека.
if len(stack) < 2:
raise ValueError("недостаточно чисел для операции")
b = stack.pop() # Второй аргумент (справа).
a = stack.pop() # Первый аргумент (слева).
# Смотрим, какой оператор, и делаем соответствующую хуйню.
if token == "+":
stack.append(a + b)
elif token == "-":
stack.append(a - b)
elif token == "*":
stack.append(a * b)
elif token == "/":
if b == 0: # Проверяем святое деление на ноль.
raise ValueError("еблан - деление на ноль")
stack.append(a / b)
elif token == "**":
stack.append(a ** b)
else:
raise ValueError(f"че надо-то? '{token}'")
# В конце в стеке должно остаться РОВНО ОДНО число результат.
if len(stack) != 1:
raise ValueError("ошибка вычисления")
return stack[0] # Возвращаем это число плод наших трудов.
# ========== ТОЧКА ВХОДА ==========
if __name__ == "__main__":
calculate_warrior_style() # ...запуск шайтан машыны
Оно трудное, большое и никому нахуй неужное, но существует))) и с дружелюбным "интерфейсом"
=== КАЛЬКУЛЯТОР ===
пеши выражение одной строкой. Поддерживаются + - * / **, скобки и числа с точкой.
Пример: 5+3*2 или 10.5 / 2 - 1 или -(2+3)**2
Введи 'q' для выхода. Удачи, ёпта.
Твоё выражение (или q): (2+9*458)-148*789/36987
Результат твоего высера: 4120.842890745397
----------------------------------------
ну и на больших степенях не охуевайте - эта хуёва туча, умноженная сама на себя 4545 рази в результате это число с десятками тысяч цифр. Вот нахуя оно вам? Оно настолько огромное, что стандартный тип float (число с плавающей запятой) в питоне просто не может его в себя вместить. У float есть максимальный предел, после которого он говорит "Идите нахуй Извини, ботан, я сдаюсь, это бесконечность и мы такого еще не проходили"
Твоё выражение (или q): 5 + 7 + (4895875/785545+987565 )**789 + 78798**4545
Traceback (most recent call last):
File "/calc.py", line 248, in <module>
calculate_warrior_style() # ...запуск шайтан машыны
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/calc.py", line 44, in calculate_warrior_style
result = eval_rpn(rpn) # Берём и начинаем жать.
^^^^^^^^^^^^^
File "/calc.py", line 235, in eval_rpn
stack.append(a ** b)
~~^^~~
OverflowError: (34, 'Numerical result out of range')
Так что вот вам ещё доза ненужной информации на сегодня, ну для разнообразия, думаю, пойдёт. Ах да, и наверняка в комментарии придут специалисты в данной области которые скажут что в ТС мудак - собственно ради этого всё и писалось 🥹
Решила продолжить именно с ними, ага))
Мне так интереснее:D
Кажется это снег, и судя по углу падения с ветром (мимо проходил капитан очевидность)
это только начало. она будет активным участником событий. и очень важным
последний котик прямо я))