Разбор задачки на функциональное программирование в Python
ฝัง
- เผยแพร่เมื่อ 3 ก.ย. 2022
- Разбираем ещё одну задачку с codewars на функциональное программирование в Python.
Мой курс «Хардкорная веб-разработка» - course.to.digital
Книжный клуб Ботаним!, где мы читаем хорошие ИТ-книги: botanim.to.digital/
Telegram: t0digital.t.me
/****************** about ******************/
Меня зовут Алексей Голобурдин, я программирую с 2004 года и на этом канале делюсь своим опытом. Я основатель и руководитель компаний:
- Диджитализируй digitalize.team, разрабатываем сложные IT системы для бизнеса;
- Salesbeat salesbeat.pro, комплексный модуль доставки для интернет магазинов.
Telegram канал - t.me/t0digital
ВК - digitalize.team
RuTube - rutube.ru/channel/24802975/ab...
Дзен - dzen.ru/id/6235d32cb64df01e6e...
Очень хочу ещё видео с решением задачек на codewars в вашем исполнении. Это, наверняка, будет интересно не только мне :-)
Лучшая рекламная интеграция!
Вот бы в каждым видео в ютубе было так
За булавки однозначно лайк
Откуда пошел мем?
@@symbolminded5167 какой?
@@t0digital С У(к)рюпинским заводом булавок
Ну как и всегда, отличная подача материала и простое и понятное объяснение, однозначно лайк 👍🏻
ЭТО ВЕЛИКОЛЕПНО! Смотреть и слушать ПРОЦЕСС в вашем исполнении. Со времён когда вы мне объяснили за лямбду, уже это теперь самый доходчивый способ передачи знаний.
Спасибо))) Хороший формат)))
Спасибо за Ваш труд! Я считаю Ваш канал самым лучшим в сфере программирования на Python, более понятных и атмосферных видео я не видел.
Круто! Было полезно! Спасибо!
Мощно, спасибо!
Спасибо за разбор! Определенно было полезно!
Спасибо за разбор! Интересная задачка
Спасибо за отличную подачу, лайк!
Круть! Интересное решение! Я заморочился с оператором типа add и передавал их, но Ваше решение очень элегантное 💪👍
Великолепно!
Спасибо спонсору😁
Какое совпадение. Именно и за этой задачки я бросил решать каты на codewars. Я не мог ни как её решить. Понял что ничего не понимаю в функциях. Но теперь я всё понял и могу продолжить мой путь самурая. 🤺
Спасибо Алексей! 👏
переходи на js там более наглядно с функциями работать.
@@ne4to777 Знание ФП не зависит от ЯП.
@@user-co6qk3hl9z , перечитай ещё раз мой коммент более вдумчиво.
Как раз недавно решал такую задачу на упомянутом сайте. Лайк за рекламу! Нужно больше годной рекламы в роликах!
Сам бы я до такого использования лямбда функций вряд ли дошел. Спасибо, что делишься опытом!
Спасибо!
Очень залипчивая задача. Попалась месяц назад на codewars, и просидел с ней несколько ночей. Аж голова разболелась. На удивление, ход разсуждений совпал как у автора в ролике. Решение было подобным но без лямбда, попроще.
Столько нового узнал по теории пока решал.
И как точно подметили в коментах: пока мозги правильно не повернёшь, трудно начать рассуждать как автор ролика.
Спасибо за задачу и разбор. Уже захотелось опять вернуться в codewars. 👏
очень полезно и интересно
Спасибо)
Спасибо автору и таким же авторам как и ты! Благодаря вам моя стоимость на рынке только возрастает, а предложения по работе уже начинают доставать, как спам.
Привет! Когда планируется третья часть по разработке вашей системы для донатов? Очень жду, хочется посмотреть продолжение) Спасибо за классный, полезный и увлекательный контент!
Я бы реализовал операции так
def plus(number):
return number.__add__
т.е. мы возвращаем функцию переданного аргумента. Тогда four(plus(nine())) развернётся в 9.__add__(4)
ps: кстати, в таких задачах нередко стоит знать классическую "обратная польская запись"
а с минусом/делением как? например, seven(minus(five())) развернется ведь не в ту сторону (5 - 7)
Я не эксперт, но вроде задачка про функциональное программирование, без ООП.
@@arthur_koba в питоне всё объект, и операция плюс вызывает магический метод __add__. То есть a+b и a.__add__(b) - эквивалентные записи одного и того же
@@undefinedundefined2459 отличный вопрос :)
Казалось бы, что нам нужны методы плюс __add__, минус - __sub__, целочисленное деление __floordiv__, умножение __mul__. Прелесть в том, что для не-коммутативных методов (важен порядок, типа минус и деление) есть "правосторонние" аналоги. То есть a.__sub__(b)==a-b, а есть a.__rsub__(b)==b-a. То есть буковка R в начале говорит о другом порядке операндов.
Итого берём __add__, __rsub__, __rfloordiv__, __mul__, и всё работает как планировалось
@@MrAnetto это понятно, что все объект. Но задача скорее всего ограничена применением функционального программирования, без использования магических методов. И её не обязательно решать на python, можно взять и другой язык скорее всего, и реализовать тоже самое на тех же самых лямбда функциях.
Можно еще вспомнить про пакет operator и functools, в частности про functools.partial
Thx!)
Спасибо, Алексей! Отличная подача материала, как глоток свежего воздуха, когда смотришь ролик с кодингом и не хочется заснуть!
Спасибо!
Решение кажется очевидным. Сам сразу же подумал про такое же, не вникая в синтаксис.
Но вот чтоб чз лямбда функцию сделать, никогда бы не догадался сам. Не знал что можно не передавая в функцию аргумент/число работать с ним.
Думаю про лямбда функции можно еще отдельный видос выложить, обо всех хитростях. Наверняка есть еще n+ трюков о к. я не знал
интересно будет услышать твое мнение про pyscript
Спасибо, как раз бился над этой задачей месяц назад, и так и не решил ее
Можно было вынести логику из операторов в отдельную функцию, и оттуда передавать или метод из библиотеки operator, ну или просто передавать имя магического метода, типа `__add__` и в функции просто применять его через getattr
Какая извращенная задача.
Прям как я люблю.
Где купить булавки?🙂
1:23. Я не поленился и загуглил. Так вот, в Урюпкинске есть только крановый завод ;(
Завод булавок просто ещё не раскрутился! Но мы ему поможем!
Прикольно
А через декораторы это как-то можно замутить?
Нет в Урюпинске завода булавок. Трикотажная фабрика есть.
Просто не раскрутился ещё. Поможем!
А где ссылка на булавки?
🤣 Браво
Урюпкинскому
Заводу
Булавок!
Я думал фишка задачи в том, что функции динамически в коде объявляются. И что-то вроде такого решения вижу:
from operator import mul, add, sub, floordiv
operands = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'ehgt': 8, 'nine': 9, 'zero': 0}
operators = {'times': mul, 'plus': add, 'minus': sub, 'devided_by': floordiv}
for operand, value in operands.items():
exec(f'def {operand}(param=None): return {value} if param is None else param({value})')
for operator, value in operators.items():
exec(f'def {operator}(param): return lambda param2: {value.__name__}(param2, param)')
print(one(minus(three())))
бро все твои старания в ооп это хорошо, но выходит очень много кода и не очень хорошего (читабельность, чистота и понятность ушли, закрыв за собой двеь)
@@kapitanov1025 тут посыл больше не в ооп, а в динамическом объявлении функций через exec. Поправил код без ООП. Теперь очень коротко получилось)
@@user-dz6by9gb9y exec это антипаттерн. Я не знаю нормальных сценариев его использования. Наверное, можно что-то придумать, но тут он точно не нужен.
Способы не писать отдельно определения функций one-two есть и так, в комментах здесь или в телеге упоминались
8:56 в first_operand передается 7 по причине ...?
Значение первого по порядку аргумента, переданного лямбда функции, присваивается первой по порядку переменной, объявленной в лямбда функции?
Т.е. например чтобы испортить реализацию, мы можем в _digit() вызвать operator(number, -1), тогда значение second_operand будет всегда -1?
Честно говоря, я в программировании, дв и в IT в целом полное днище, но как натолкнулся на канал Алексея - смотрю взахлёб. Это какой-то абсолютно новый опыт и мотивация для меня, спасибо большое!
Спасибо, рад слышать!
Прикольно, но хотелось бы что-то по-сложнее
Кто куда, а я в Урюпинский завод булавок прикалывать свою мечту
Для тех, кому нужна задача.
5 kuy ката, название "Calculating with Functions"
Может называлась в видео, извините.
спасибо! как раз ищу!
А второй способ где?
Не понял, где ссылка на Урюпкинский завод булавок?
А можно ссылку на саму задачу на Code wars? Хочу попробовать сам решить прежде чем смотреть разбор
www.codewars.com/kata/525f3eda17c7cd9f9e000b39/train/python
некоторые другие решения этой задачи на codewars впечатляют, оказывается подходов к решению далеко не один
Или даже так [one, two, three, four, five, six, seven, eight, nine] = ((lambda n : lambda f = (lambda x : x) : f(n))(n) for n in range(1, 10))
Решал эту задачку на js. В принципе ничего сложного, если мозг повернут на ФП. Но первый раз ломает мозг.
Замудренное какое-то решение в ролике. Я решил через строки и функцию eval. Всё просто, если у функции digit нет аргументов, возвращается само число int. Если есть, возвращается eval(str(digit) + operator)
Сами же операторы работают схоже. У них аргумент обязательный, и они возвращают строку типа str(operator) + arg.
То есть условно eight() вернёт int 8
plus(eight()) вернёт строку '+8'
А какой-нибудь one(plus(eight())) вернёт eval('1' + '+8')
Или 9
eval антипаттерн
Эта задача как раз в не решённых у меня лежала. Я про неё и забыл уже. А тут - раз! :) Спасибо, круто. А что вообще скажете на счёт Codewars и иже с ним? Я там уже три месяца. До 3 kyu дорос (на полпути ко 2-му). И вот думаю, хватит ли базы для того, чтобы переходить к каким-то фреймворкам?.. По каким критериям можно оценить свою базовую подготовку? Слышал мнение, что на hackerrank более реальные задачи... Что скажете?
давно пора) 3 кью - это уже довольно потно, особенно если получается решать задачи похожим на best practices образом. вообще для работы на фреймворках прокаченные алгоритмы не нужны, достаточно знать базовые вещи, типа big O notation. Полезнее будет прокачать понимание ООП. а вообще, работа программистом - это не столько про само программирование, сколько про инструменты вокруг этого. У бэкендеров, например, это БД, гит, контейнеризация, сети, архитектура приложений в целом.
Не питонист, но задачка интересная!
Ушел за булавками.
Непривычно видеть Алексея небритым
Хотелось бы ссылку на задание на самом Codewars. Заранее спасибо.
Поищите тут в комментах, уже давал
Здраствуйте Диджитализируй!
Я изучаю Python уже несколько месяцев но волнуюсь что не смогу найти работу в web(Django) или в других сферах.
Python и вправду используют много в профессиональной разработке?
Какие известные приложения написаны на нем?
Заранее спасибо
А что вы подразумеваете под программами? То, что на компьютер устанавливается? В таком случае - никакие. А вот какие-то сервисы, бекенды, внутренние иснтрументы компаний, прикладные задачи в различных сферах - этого очень много написано.
Запрещенный instagram на python+django, например. Но в почти любом большом веб-сервисе есть код на python, уверен в этом. Самый популярный скриптовый язык в мире потому что:)
как попасть на завод , Урюпинский, булавки нужны.
Классно, круто. Но на всякий случай, в питоне уже есть операция целочисленного деления - //
Что нравится на канале: подача, профессионализм, умение пользоваться ИДЕ. Что хочется улучшить: лоХика, проХрамма, ТАПАЛ 🤣🤣
Хочу добавить, что в данном решении лямбда-функции, которые возвращают функции-операторы (plus, minus, times, divided_by), можно классифицировать как замыкания (closures). Замыкание - это функция, которая находится внутри другой функции и ссылается на переменные объявленные в теле внешней функции.
Это они и есть. Собственно полноценно реализовать лямбда исчисление без замыканий невозможно
Урюпкинский завод булавок ❤️
А можно ссылочку на обоинку ?
to.digital/wlp/vecher-tuchi-gory-doroga-ogni-vyderzhka.jpg
Блин, как-то не могу понять, как в first_operand попадает значение?
оно берется из общего нейм спейса откуда-то?
Оно передаётся при вызове лямбды
Чем Вам lambda не угодили?
Берем функцию цифр:
def number(n: int, obj=None):
if obj is None:
return n
return obj(n)
Добавляем действие, например умножение:
def times(num):
return lambda n: number(n) * num
Расписываем цифры следующим образом:
one = lambda n=None: number(1, n)
Один из вариантов, да. У меня тоже есть лямбды, они всем мне угодили:)
Не осуждаю, а подмечаю
@@t0digital Просто расписывать однострочные функции, когда БОЖЕСТВЕННАЯ ЛЯМБДА не канонично (ирония). Решил сам без мам и пап, потом глянул решение)
Спасибо за контент)
Ответ - 42
Всё ждал, когда всплывёт "магия"... ;))) Зачем lambda, когда у int есть методы ___add__, __sub__, __mul__, __div___
В контексте простых математических операторов можно было ими воспользоваться, да. Но если задача расширится до более сложных примеров, то подход с lambda будет универсальным и позволит реализовать что-то, чего нет в магических методах.
int(a / b) не всегда равно a // b
Так, я не понял, а где фраза "ссылка в описании"? 😬😁
Надеюсь продажи у завода булавок подскочили после рекламы 😊
Уверен! Помогли заводу!
Все-таки непонятно каким образом в функции, которая реализует операцию, например minus, происходит подстановка значения переменной first_operand. Эта переменная не является параметром функции minus.
О! Я первый?
примечательна асимметрия с выносом _digit и без аналогичного выноса _function
Не понял, какой _function?
@@t0digital который подобно _digit действует но не над неизменными а над вызываемыми - об том и речь асимметрия восприятия у реализатора данных которые объект действия и функции которые субъект действия - хотя по задаче разнице нет ваще есть вызываемые имена которые имеют два поведения когда без арга и когда с аргом
А где ссылка на задачку? Может перед видосом сам решить захотел?)
Алексей, скажите, если бы вы стали делать , например, сайт знакомст, то бэкэнд и фронтенд на каком языке начали делать?
Фронт на solidjs, бэк на fastapi, но возможно с частями на других языках вроде go или rust
@@t0digital спасибо за ответ!
@@t0digital Раст на канале ждём. будет круто
Не нашёл в описании ссылки на Урюпкинский завод булавок?! За что вам только платят.
На code wars есть похожие задачи. Реализация только на лямбда функциях. Т.е реализация только в алгебре черча. Вот это сложно, по сравнению с этой задачей.
ну конечно решение не лучшее) Хардкод + повторение. мне кажется здесь неплохо можно использовать map + lambda.
Можно, да. Не стал рефачить усложнять код. Помимо DRY не стоит забывать про KISS. DRY он про то, что в случае изменений придется изменить что-то в нескольких местах. В данном случае эти несколько мест находятся непосредственно рядом друг с другом и изменения не будут проблемой. А вот нагромождения мапов и лямбд понимание кода в значительной степени усложнят. А вместе с тем и увеличится вероятность багов, к слову.
@@t0digital зато красиво) я даже видел решение вида просто импортировать операторы из питоновский библиотеки))) а цифры задать тем же мапом
Склейки мешают моему обучению Виму + нет вывода нажатых клавиш. Прошу учесть ))))))
я второй
А в Урюпинске разве есть завод булавок? Мне кажется надо тщательней спонсоров подбирать. А то и к основной теме недоверие появляется!
Конечно, есть! Специальный Урюпинский завод булавок
Хм а если я решу задачу без лямбда, и вообще без возврата функций? Интересно, а вообще часто используют возврат функций на практике?
Да, часто используют. Эту задачу можно решить без них, достаточно из функций-операторов возвращать кортеж из действия и второго операнда, а в _digit его обрабатывать.
Неплохо для процедурщика, но если начал в ФП иди до конца, хотя судя по видео ФП в пайтоне это боль. Вот то же самое на js:
const number = n => f => f ? f(n) : n
const one = number(1)
const two = number(2)
...
const plus = x => y => x + y
const minus = x => y => x - y
...
Совсем не боль )
А в JS разве нельзя сделать что-то типа:
one, two, three = map(number, (1, 2, 3)) ?
@@geri_freki , можно, конечно, так и надо делать, но я сделал, чтоб больше на то, что в видео было похоже:
const [one, two, three] = [1, 2, 3].map(number)
@@ne4to777 круто! здесь в комментах рекомендовали видео th-cam.com/video/5C6sv7-eTKg/w-d-xo.html уже неделю его частями смотрю - пытаюсь самостоятельно написать лямбда-функции, когда лектор это предлагает. Причем у него какой-то кастомный IDE - можно реально писать код в упрощенной λ-нотации и он выполняется как обычный python-код, типа: AND = λxy.xyx 😀это как lambda x: lambda y: x(y)(x)
@@geri_freki , в программировании как таковые лямбды не нужны, это просто гимнастика для ума, и выглядит как новый синтаксис для языка. Просто относись к ним как функции, которые возвращают функции и все, этого достаточно. В js это поняли и сделали новый оператор =>. В питоне, видимо, решили все усложнить и ввели грозное слово lambda, зачем непонятно.
1. Передача функции с использованием параметров из другой функции вроде называется замыканием
2. Вероятнее при решении таких задач было бы удобнее использовать конструкцию assert(не говоря уже на собеседованиях), а то сравнивать строчки по порядку вывода моветон
1. Замыкание это доступ к переменной, определённой в функции выше, ничего больше.
def outer():
some_var = 123
def inner():
print(some_var) # Это замыкание, some_var определен в outer
return inner
Вообще не понимаю, зачем под это обычное правило области видимости переменных ввели отдельное слово и так часто его используют:) LEGB правило областей видимости переменных есть, в нём есть Enclosing.
2. Область применения assert - показать пользователю твоего кода, что он его использует неверно. Не знаю, где здесь стоит использовать assert. Не вижу под него места. Ну если захочется зачем-то проверить тип в _digit, что там первое число типа int, например. Но эту проверку лучше вынести в статическую проверку типов в mypy.
@@t0digital предположим ваше высказанное "непонимание" ради накрутки
вложенность функций не покрывает замыкания - в замыканиях стек перестаёт быть достаточным для реализации исполнения
т.е замыканиями самими по себе обеспечивается переход подобный от конечных автоматам к стековым - замыкания же "делают" динамическую память с временем существования имени пока оно откуда либо видно
@@qulinxao ну вопросы видимости и времени жизни переменных связаны. Вот здесь эта переменная видна, и вот такой у нее срок жизни. Нахрена это называть замыканием, пугая этим словом бедных новичков, понятия не имею. Это просто области видимости и ничего больше, причем интуитивно понятные области видимости.
>1. Замыкание это доступ к переменной, определённой в функции выше, ничего больше.
это достаточно слабое(широкое утверждение) - в том же Паскале были вложенные функции и не было замыканий :)
Схема выкристаллизовала замыкания
в Паскале(Алголе :) ) чтение/запись выданой из функции-внука в основную программу "ссылки" на переменную в функции-родителе очевидно приводило к чудесам на стеке
замыкание это когда значения живут пока о них помнят
@@t0digital непонимание обусловленно кривизной истории не будь ответвления Алголов с их строгой вложенностью не было бы Схемы какой она стала
Зочем лямбды, когда можно сделать на partial более элегантное решение?
Зачем partial, когда можно сделать на лямбдах)? Есть тонна разных вариантов, на любой извращенческий вкус и цвет)
th-cam.com/video/5C6sv7-eTKg/w-d-xo.html - прекрасное руководство по функциональщине
Спасибо за ссылку! Смотрю сейчас - реально крутая лекция.
Если не трудно, объясни вот такой прикол в Питоне:
print(type(0b1001)) # выдаёт int
print(type('0b1001')) # выдаёт str
int('0b1001') # выдаёт xyz )))
print(type(0b1001)) # выдаёт int потому что 0b1001 это целое число (9) записанное в двоичной системе счисления
print(type('0b1001')) # выдаёт str потому что type всегда будет возвращать если аргумент строка
int('0b1001') # выдаёт xyz. нет не выдает. там только ошибка может быть. int вряд-ли когда-нибудь в жизни сможет вернуть что-либо кроме чисел. Если же ты все-таки захотел задать аргумент в виде строки, то вторым аргументом должна быть система счисления, в которой это число записано. Например print(int('0b1001')) -> ошибка, но print(int('0b1001', 2)) -> 9
Эх жаль тут "два плюс два , деленное на два " не сработает ))
Эх, как красиво решили... А я как лошпендель решил через использование eval и exec, ахах.
Хех сам решал эту задачу... Только без лямд так как для меня это сложно. Все сводилось к тому что если def one(): получает пустоту то оно возвращает число return "1" . Действия def plus(number): return "+"+number возвращает действия и число строкой "+1". Вот если в число попадает def one(number): что-то другое. То распарсиваю строку и делаю действия match number[0]: case "+": print(1+number[1]) . Пока моих умений в питоне хвататет только для этого. До лямд функций не дошел да и ООП ещё не начал изучать (((
Было бы классно больше решений задачек с код ворса на канале увидеть.
А нафига это преобразование в строку и обратно? В Питоне есть кортежи (tuple), заюзай их.
@@ArquitectoR История это умалчивает.
Как давно Медисон стал айтишником?
А где вы пишите код? Что за редактор ?
nvim. Есть на канале видео о настройках
@@t0digital нужно теперь видео про настройку Alacritty) особенно на маке)
@@misatokatsuragi9122 там настраивать то нечего, открыл example конфиг, там всё подписано что за что отвечает - выставляешь как душа просит
@@daninspace9009 на маке оно как-то через одно место работает) Кривые размеры окна и странность с дубликацией символов при вводе)
@@misatokatsuragi9122 в конфиге всего 6 значений касательно мака, и не похоже чтобы они могли такое вызывать. Попробуйте use_thin_strokes=false и поставить и разные startup_mode. Но думаю не в конфиге дело
Я один пошел гуглить продукцию Урюпинского Завода Булавок?
"five" is not defined какой смысл этого условия?
«five не определен». Какое тут условие? О чем речь?
def number_func(number):
return lambda operator = None: operator(number) if operator else number
zero, one, two, three, four, five, six, seven, eight, nine = (
number_func(i) for i in range(10)
)
def plus(second):
return lambda first: first + second
def minus(second):
return lambda first: first - second
def times(second):
return lambda first: first * second
def divide_by(second):
return lambda first: first / second
assert one(plus(three())) == 4
assert one(times(three())) == 3
assert four(times(nine())) == 36
assert nine(minus(seven())) != three()
assert nine(minus(seven(plus(two())))) == zero()
from typing import Callable
class N():
def __init__(self, n: int) -> None:
self.n = n
def __call__(self, mode: (Callable | None) = None) -> int:
if mode is None:
return self.n
return mode(self.n)
class Operation():
def __init__(self, att_name: str) -> None:
self.att_name = att_name
def __call__(self, n: int) -> Callable:
return getattr(n, self.att_name)
plus = Operation('__radd__')
minus = Operation('__rsub__')
times = Operation('__rmul__')
div = Operation('__rtruediv__')
zero = N(0)
one = N(0)
two = N(0)
three = N(3)
four = N(4)
five = N(5)
six = N(6)
seven = N(7)
eight = N(8)
nine = N(9)
print(seven(times(five())))
Имеет место быть. На кодварс стоит тег у этой задачи functional programming. Не ООП програминг:)
@@t0digital Да я это уже для себя заметил, когда пересмотрел и переосмыслил видео.
eight = lambda f = (lambda x : 8) : f(8)
fourt = lambda f = (lambda x : 4) : f(4)
div = lambda r : lambda l : l/r
eight (div (fourt ()))
Как-то так.
ваши способы нужно объединить и получится идеально. То есть добавь вспомогательную функцию, чтоб логика в числах не повторялась (_digit в видео, но только красивенько перепиши)
Чот мне кажется, что это линух
Вместо убогого None и его проверки, нужно использовать функцию identity (= lambda x: x)
Прикольная задача, но одна из предыдущих про многократный вызов функций (или объектов) была интереснее))
Я эту задачку решил без lambd'ы, просто перегонял в строку и потом через eval отдавал результат. С одной стороны нагляднее и проще, с другой стороны скучнее.
eval o_O, акстись, забудь про её существование!
@@rinaatt а чего б нет? Ей, конечно, с манипулятором типа мышь не потягаться, но тут-то чудесная вещь)
@@filippov_es Это очень не безопасная команда, если ты хочешь прийти в комерческую разработку, то нужно про неё забыть. Можешь сам погуглить почему её лучше не использовать.
@@rinaatt погоди-погоди-пгди.. тут не о комерции речь) Вообще сложно представить реализацию этой функции в комерции. Это как черепашка, чисто для фана)
Опять клавиатуру используешь!(( А как же мышь?
Вариант с классом:
named_numbers = ('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine')
class Number:
def __init__(self, value):
self.value = value
def __call__(self, func=None):
return func(self.value) if func else self.value
for num_name, num_value in zip(named_numbers, range(len(named_numbers))):
locals()[num_name] = Number(value=num_value)
def plus(value): return lambda second_value: value + second_value
print(nine(plus(five())))
Вам будет полезно узнать о функции enumerate