Done✅
Что могу сказать. Сделал задание часа за три🫠 Сначала пытался понять, что от меня хотят. По сути — обычная схема передачи данных через сеть. В первый час разобрался в требуемых методах и свойствах, накидал их, оформил 80+ процентов кода. Дальше начался тупняк из-за некоторых непонятных моментов. Пошёл отдыхать))
Когда вернулся — разобрался с теми сложными местами. Каюсь, всё-таки подглядел в комменты, чтобы выяснить один ньюанс интерпретации метода. Как-то очень абстрактно он был описан, не было до конца понятно, что конкретно нужно сделать... Затем ещё 2 часа ушло на допиливание 2.78 методов и проверок. И наконец — загорается зелёный цвет. А потом....
Потом случились "Страх и ненависть в Лас-Вегасе", когда посмотрел решение автора😂😂😂 Тут не так, там не эдак. Но... работает🙃 Сделал всё по ТЗ, а про расширяемость — не, не слышали😐 Хотя для этого надо не так много поменять.
В этом задании действительно есть моменты, определённые неоднозначно. И непонятно — то ли описание немного кривоватое, то ли мой мозг ещё не привык мыслить в ООП-стиле. Но ничего, движемся вперёд. Дальше будет только лучше!
Что могу сказать. Сделал задание часа за три🫠 Сначала пытался понять, что от меня хотят. По сути — обычная схема передачи данных через сеть. В первый час разобрался в требуемых методах и свойствах, накидал их, оформил 80+ процентов кода. Дальше начался тупняк из-за некоторых непонятных моментов. Пошёл отдыхать))
Когда вернулся — разобрался с теми сложными местами. Каюсь, всё-таки подглядел в комменты, чтобы выяснить один ньюанс интерпретации метода. Как-то очень абстрактно он был описан, не было до конца понятно, что конкретно нужно сделать... Затем ещё 2 часа ушло на допиливание 2.78 методов и проверок. И наконец — загорается зелёный цвет. А потом....
Потом случились "Страх и ненависть в Лас-Вегасе", когда посмотрел решение автора😂😂😂 Тут не так, там не эдак. Но... работает🙃 Сделал всё по ТЗ, а про расширяемость — не, не слышали😐 Хотя для этого надо не так много поменять.
В этом задании действительно есть моменты, определённые неоднозначно. И непонятно — то ли описание немного кривоватое, то ли мой мозг ещё не привык мыслить в ООП-стиле. Но ничего, движемся вперёд. Дальше будет только лучше!
**✅Викторина. Что выведет код ? **
Cмотрите в комментарий под постом
Cмотрите в комментарий под постом
Anonymous Quiz
26%
2
35%
TypeError: object of type 'Person' has no len()
26%
0
12%
6
🤔4❤1
🔐 Режимы доступа: public, private, protected. Сеттеры и геттеры
Это последняя пройденная тема. Коротко об этом. Есть три типа доступа для атрибутов/свойств и методов класса/экземпляра класса:
📌
📌
📌
🤔 Формально 3, но фактически 2
Второй тип режима никак не запрещает программисту обращаться к данным класса. Это лишь напоминание, что лучше не изменять. Третий же способ фактически не дает ничего делать с атрибутами и методами.
😁 Но есть одно но
Если очень хочется, то можно))
Допустим у нас есть класс User. Мы создали экземпляр класса, в init-e прописав его возраст(__age) как приватную(private) переменную:
Можно обратиться к атрибуту __age так:
А если напрямую через u.age или u.__age - будет ошибка. Но вообще лучше так не делать)
🛠 Сеттеры и геттеры
Это просто такие методы в классе, которые что-то делают с приватными атрибутами:
📌
📌
Методы класса так же могут иметь разные режимы доступа.
💬 Есть вопросы или хотите поделиться опытом?
Присоединяйтесь к обсуждению в чате!
Это последняя пройденная тема. Коротко об этом. Есть три типа доступа для атрибутов/свойств и методов класса/экземпляра класса:
📌
attribute (без подчёркиваний) - публичное свойство (public)📌
_attribute (с одним подчёркиванием) - protected (внутри класса и дочерних классов) 📌
__attribute (с двумя подчёркиваниями) - private (только внутри класса)🤔 Формально 3, но фактически 2
Второй тип режима никак не запрещает программисту обращаться к данным класса. Это лишь напоминание, что лучше не изменять. Третий же способ фактически не дает ничего делать с атрибутами и методами.
😁 Но есть одно но
Если очень хочется, то можно))
Допустим у нас есть класс User. Мы создали экземпляр класса, в init-e прописав его возраст(__age) как приватную(private) переменную:
u = User(27)Можно обратиться к атрибуту __age так:
u._User__ageА если напрямую через u.age или u.__age - будет ошибка. Но вообще лучше так не делать)
🛠 Сеттеры и геттеры
Это просто такие методы в классе, которые что-то делают с приватными атрибутами:
📌
set_age(self, age) - изменить значение возраста📌
get_age(self) - вернуть значение возрастаМетоды класса так же могут иметь разные режимы доступа.
💬 Есть вопросы или хотите поделиться опытом?
Присоединяйтесь к обсуждению в чате!
✍5
😶😶😶Связные списки 👿👿👿
Не люблю я эти связные списки... А тут еще и двунаправленные! 🫠
Было так:
- Накидал код → отошел → вернулся → снова ничего не понял 🫡
- Немного подсмотрел решение, не до конца → ничего нового не узнал, закрыл видео😁
- Пошел дальше делать... но не получилось до конца!
Пришлось достать "тяжелую артиллерию" — старый дедовский метод с тетрадкой! 📝
Начал расписывать вручную: что, куда, зачем и почему. Давно так не запаривался!
А вот и главным врагом неожиданно оказался метод `remove()`
Думал: "ну удаление, что сложного?"
А оказалось:
- Целых три случая удаления!
- Общий случай не проходил
- Пришлось звать на помощь ИИ 🆘
🤔 А вам как дались связные списки?
- Было так же сложно?
- Или для вас это было просто?
- Есть свои лайфхаки для понимания?
P.S.
Вот ссылка на теорию по этой теме: урок
Надеюсь, таких задач больше не встретится! А то я еще неделю буду сниться сам себе с указателями next-prev 🔁
💬 Делитесь опытом в чате — интересно узнать ваши истории!
Не люблю я эти связные списки... А тут еще и двунаправленные! 🫠
Было так:
- Накидал код → отошел → вернулся → снова ничего не понял 🫡
- Немного подсмотрел решение, не до конца → ничего нового не узнал, закрыл видео😁
- Пошел дальше делать... но не получилось до конца!
Пришлось достать "тяжелую артиллерию" — старый дедовский метод с тетрадкой! 📝
Начал расписывать вручную: что, куда, зачем и почему. Давно так не запаривался!
А вот и главным врагом неожиданно оказался метод `remove()`
Думал: "ну удаление, что сложного?"
А оказалось:
- Целых три случая удаления!
- Общий случай не проходил
- Пришлось звать на помощь ИИ 🆘
🤔 А вам как дались связные списки?
- Было так же сложно?
- Или для вас это было просто?
- Есть свои лайфхаки для понимания?
P.S.
Вот ссылка на теорию по этой теме: урок
Надеюсь, таких задач больше не встретится! А то я еще неделю буду сниться сам себе с указателями next-prev 🔁
💬 Делитесь опытом в чате — интересно узнать ваши истории!
😱3
😵💫 Застрял в режиме "Лебедь, рак и щука"
Последние две недели сильно просел объем занятий. Причина — на фото 👆
Как вы помните, я говорил, что не собираюсь разветвляться и уходить в другие направления. План простой:
- Завершить курс по Базе, ООП, Django
- Подтянуть требования из вакансий
- Искать работу
Но не знаю, почему именно сейчас мне в голову взбрело создание задач! 🤷♂️ Создаю задачки по разным темам — по сути, та же рубрика "викторина", но местами сложнее.
Выходит:
- Это отнимает **много времени и сил
- После 3 дней плотной работы + курс по ООП — полный выгорание
- Не хотелось возвращаться вообще ни к чему
Об этом и был мой последний пост про отдых в 3-4 дня — просто без конкретных причин.
Чувствую, что это меня сильно тормозит, но и отказываться не хочется...
Как в басне Крылова 🦢🦀🦐
И то хочу, и это, и пятое-десятое.
А по факту — "А воз и ныне там" 😮💨
Как вам удавалось бороться с таким распылением? Или я один такой?)
💬 Буду рад вашим советам в чате — как вы удерживаете фокус?
Последние две недели сильно просел объем занятий. Причина — на фото 👆
Как вы помните, я говорил, что не собираюсь разветвляться и уходить в другие направления. План простой:
- Завершить курс по Базе, ООП, Django
- Подтянуть требования из вакансий
- Искать работу
Но не знаю, почему именно сейчас мне в голову взбрело создание задач! 🤷♂️ Создаю задачки по разным темам — по сути, та же рубрика "викторина", но местами сложнее.
Выходит:
- Это отнимает **много времени и сил
- После 3 дней плотной работы + курс по ООП — полный выгорание
- Не хотелось возвращаться вообще ни к чему
Об этом и был мой последний пост про отдых в 3-4 дня — просто без конкретных причин.
Чувствую, что это меня сильно тормозит, но и отказываться не хочется...
Как в басне Крылова 🦢🦀🦐
И то хочу, и это, и пятое-десятое.
А по факту — "А воз и ныне там" 😮💨
Как вам удавалось бороться с таким распылением? Или я один такой?)
💬 Буду рад вашим советам в чате — как вы удерживаете фокус?
👀4
Сегодня же Хэллоуин. Празднуете?
А может кто-то еще нарядился и накрасился, есть такие?) Скидывайте фотки кто в каком образе находится, будет интересно посмотреть😈
А может кто-то еще нарядился и накрасился, есть такие?) Скидывайте фотки кто в каком образе находится, будет интересно посмотреть😈
😈3
Интересная задачка дня
Условие, тесты
Вспоминаем match-case. 🫣
Вводятся данные по книге в виде строки через запятую в формате (некоторые значения могут отсутствовать):
id, автор, название, цена, год издания с помощью команд:
С помощью оператора match/case необходимо определить шаблоны для выделения следующей информации с дополнительными проверками:
• автор, название (автор - не менее 6 символов, название - не менее 10 символов)
• автор, название, цена (автор не менее 6 символов, цена - положительное число)
• автор, название, год издания (год издания от 2020 и выше)
• автор, название, цена, год издания (цена - положительное число и год издания от 2020 и выше)
Первый шаблон срабатывает, если есть только автор и название; второй, если появляется еще и цена; третий, если есть автор, название, год издания, но нет цены; последний, если имеются все данные.
При срабатывании шаблона вывести на экран строку "Yes". Если ни один из шаблонов не сработал, то вывести строку "No"
💬 Присылайте свои варианты решений. 😏
Я чет глянул как сам делал - уже не особо помню всю логику конструкции.😢 Ужс, как vsё быстро забывается, если это редко используешь.
Условие, тесты
Вспоминаем match-case. 🫣
Вводятся данные по книге в виде строки через запятую в формате (некоторые значения могут отсутствовать):
id, автор, название, цена, год издания с помощью команд:
t = (int, str, str, float, int)
book = [t[i](x) if t[i] != str else x.strip() for i, x in enumerate(input().split(","))]
С помощью оператора match/case необходимо определить шаблоны для выделения следующей информации с дополнительными проверками:
• автор, название (автор - не менее 6 символов, название - не менее 10 символов)
• автор, название, цена (автор не менее 6 символов, цена - положительное число)
• автор, название, год издания (год издания от 2020 и выше)
• автор, название, цена, год издания (цена - положительное число и год издания от 2020 и выше)
Первый шаблон срабатывает, если есть только автор и название; второй, если появляется еще и цена; третий, если есть автор, название, год издания, но нет цены; последний, если имеются все данные.
При срабатывании шаблона вывести на экран строку "Yes". Если ни один из шаблонов не сработал, то вывести строку "No"
💬 Присылайте свои варианты решений. 😏
Я чет глянул как сам делал - уже не особо помню всю логику конструкции.😢 Ужс, как vsё быстро забывается, если это редко используешь.
🤔3
✅Викторина. Что выведет код ?
Cмотрите в комментарий под постом
Cмотрите в комментарий под постом
Anonymous Quiz
6%
Ошибку
42%
Ключ не определен
36%
Ключ не подходит
17%
Ключ подходит
🤔3
привет, кое-что нашел для вас ⤵️
💙🛠 Kickresume.com/en/ats-resume-checker/ ATS-чекер для вашего резюме
➕
-- Бесплатно даст оценку (0-100) и покажет, по каким категориям (Дизайн, Структура, Содержание) у вас провал.
--Загружайте, правьте, перезагружайте резюме. Следите, как растет ваш балл после каждого изменения. Это главный лайфхак.
--Сравнивайте с резюме из топ-компаний. У них есть реальные примеры - смотрите, как структурируют опыт другие.
⚡️ Краткий план действий:
Выберите ATS-дружественный шаблон (есть в самом Kickresume).
Пройдите бесплатную проверку.
Исправьте всё, что подсветилось красным.
Повторите пункты 2 и 3, пока не получите 80+ баллов.
Используйте чекер как детектор слабых мест, а не как панацею.
Всем удачи и оферов🍀
💙🛠 Kickresume.com/en/ats-resume-checker/ ATS-чекер для вашего резюме
➕
-- Бесплатно даст оценку (0-100) и покажет, по каким категориям (Дизайн, Структура, Содержание) у вас провал.
--Загружайте, правьте, перезагружайте резюме. Следите, как растет ваш балл после каждого изменения. Это главный лайфхак.
--Сравнивайте с резюме из топ-компаний. У них есть реальные примеры - смотрите, как структурируют опыт другие.
⚡️ Краткий план действий:
Выберите ATS-дружественный шаблон (есть в самом Kickresume).
Пройдите бесплатную проверку.
Исправьте всё, что подсветилось красным.
Повторите пункты 2 и 3, пока не получите 80+ баллов.
Используйте чекер как детектор слабых мест, а не как панацею.
Всем удачи и оферов🍀
👏7🔥1
prodigy 🔥 PROPERTY в ООП - РАЗБИРАЕМ НА ПАЛЬЦАХ! 🔥
Опишу кратко суть, наверно проще будет на примере. Вспомните - если забыли, либо узнаете новое для себя.
Например у нас есть класс 👇 с защищенной переменной.
И чтобы с ней работать вне этого класса, как вы помните, необходимо создать доп. методы в классе. Например:
property - упрощает создание сеттеров и геттеров(чтобы не писать/запоминать 100500 различных методов)
Один из вариантов создания такой:
Где get_old, set_old - соотествтенно гетер и сетер.
Как видим из синтаксиса - это декоратор, можно записать как выше, но лучше и практичней делать вот так вот:
То, что мы сделали, эквивалентно предыдущему варианту с тем лишь отличием, что теперь напрямую вызывать сеттер или геттер для локального свойства __old не получится. У нас остался один интерфейс взаимодействия – объект-свойство old. Именно так чаще всего делают на практике.
Так же есть еще один интересный момент в этом👇 Но не буду захламлять этим голову) Особо познавательным - скрытый текст в самом низу.
Ставьте реакции, спрашивайте в комментах, чтобы понять нравится, интересно, полезно или же нет😑:
знал это → 😎
узнал новое → 🤔
полезно → ❤️
есть вопросы → пишите
Та самая муть - можно не читать:
p = Person('ВАся', 25)
p.old = 35
p.__dict__['old'] = 45
print(p.__dict__)
print(p.old) # - что тут выведется, как думаете? кто знает?)
Например, можем создавать локальное свойство old в экземпляре класса, но при выводе и взаимодействии с ним будет использоваться то, что в защищенной переменной. Хотя, казалось бы, по логике должно же меняться локальное свойство old.
И ТАКОЕ СВОЙСВТВО БЕРЕТСЯ ВПЕРЕД( В ПРИОРИТЕТЕ НАД ДАЖЕ НАД СВОЙСТВОМ ЭКЗЕМПЛЯРА КЛАССА)
Опишу кратко суть, наверно проще будет на примере. Вспомните - если забыли, либо узнаете новое для себя.
Например у нас есть класс 👇 с защищенной переменной.
class Person:
def __init__(self, name, old):
self.__name = name
self.__old = old
И чтобы с ней работать вне этого класса, как вы помните, необходимо создать доп. методы в классе. Например:
def get_old(self):
return self.__old
def set_old(self, old):
self.__old = old
property - упрощает создание сеттеров и геттеров(чтобы не писать/запоминать 100500 различных методов)
Один из вариантов создания такой:
old = property(get_old, set_old) .
Где get_old, set_old - соотествтенно гетер и сетер.
Как видим из синтаксиса - это декоратор, можно записать как выше, но лучше и практичней делать вот так вот:
class Person:
def __init__(self, name, old):
self.__name = name
self.__old = old
@property
def old(self):
return self.__old
@old.setter
def old(self, old):
self.__old = old
@old.deleter
def old(self):
del self.__old
То, что мы сделали, эквивалентно предыдущему варианту с тем лишь отличием, что теперь напрямую вызывать сеттер или геттер для локального свойства __old не получится. У нас остался один интерфейс взаимодействия – объект-свойство old. Именно так чаще всего делают на практике.
Так же есть еще один интересный момент в этом👇 Но не буду захламлять этим голову) Особо познавательным - скрытый текст в самом низу.
Ставьте реакции, спрашивайте в комментах, чтобы понять нравится, интересно, полезно или же нет😑:
знал это → 😎
узнал новое → 🤔
полезно → ❤️
есть вопросы → пишите
Та самая муть - можно не читать:
p.old = 35
p.__dict__['old'] = 45
print(p.__dict__)
print(p.old) # - что тут выведется, как думаете? кто знает?)
Например, можем создавать локальное свойство old в экземпляре класса, но при выводе и взаимодействии с ним будет использоваться то, что в защищенной переменной. Хотя, казалось бы, по логике должно же меняться локальное свойство old.
И ТАКОЕ СВОЙСВТВО БЕРЕТСЯ ВПЕРЕД( В ПРИОРИТЕТЕ НАД ДАЖЕ НАД СВОЙСТВОМ ЭКЗЕМПЛЯРА КЛАССА)
❤2🤔2
🤯 ДЕСКРИПТОРЫ: КАК Я ИЗБЕЖАЛ КОПИПАСТЫ В 3 СТРОКИ
Потратил 2.5 часа на 20-минутную тему из видео, но выжимку даю за 3 минуты чтения. Сколько раз пересматривал и пытался понять? - ДА
О чем тут вообще речь:
Мы создаем еще один другой класс, чтобы в нашем исходном классе его использовать и писать меньше одинакового кода в нем, но при этом чтобы он работал так же как и раньше. Лучше это или нет - судить вам. Речь про гетеры и сетеры (+"делеторы😁) Я бы сказал, просто вынос логики в другой класс. Так ли?🤔 А это даже наследование не проходилось еще🫠🫠🫠 Если не понятно о чем я - смотрите пример:
Задача: Класс для 3D точек в пространстве. Создать в нем приватные координаты и методы чтобы с ними можно было взаимодействовать.
❌ БЫЛО (20+ строк кода):
⚡️ СТАЛО (магия дескрипторов):
Теперь класс Point3D выглядит таким образом, гораздо лучше ж?
💡 СУТЬ ПРОСТЫМИ СЛОВАМИ:
Дескрипторы = "фабрики property". Один раз написал логику - используй для любого количества атрибутов!
🎯 КОГДА ПРИМЕНЯТЬ:
•Больше 2 property с одинаковой логикой
• Хочешь сделать код чище
• Устал от копипасты
🤔 СПОЙЛЕР ДЛЯ ЛЮБОЗНАТЕЛЬНЫХ:
А знаете, что дескрипторы бывают двух типов?
Non-data vs Data дескрипторы...
Как думаете, в чем между ними разница?
И какой тип мы использовали в примере выше? 🤔
💬 Пишите ваши версии в комментах!
А вы сталкивались с дескрипторами в работе?
Или предпочитаете "старый добрый" copy-paste?
Делитесь опытом - интересно, кому это реально пригодилось!
P.S. Если тема зашла - лайкните, допишу пару моментов с тонкостями! Или не допишу, как хотите😈
Потратил 2.5 часа на 20-минутную тему из видео, но выжимку даю за 3 минуты чтения. Сколько раз пересматривал и пытался понять? - ДА
О чем тут вообще речь:
Мы создаем еще один другой класс, чтобы в нашем исходном классе его использовать и писать меньше одинакового кода в нем, но при этом чтобы он работал так же как и раньше. Лучше это или нет - судить вам. Речь про гетеры и сетеры (+"делеторы😁) Я бы сказал, просто вынос логики в другой класс. Так ли?🤔 А это даже наследование не проходилось еще🫠🫠🫠 Если не понятно о чем я - смотрите пример:
Задача: Класс для 3D точек в пространстве. Создать в нем приватные координаты и методы чтобы с ними можно было взаимодействовать.
❌ БЫЛО (20+ строк кода):
class Point3D:
def __init__(self, x, y, z):
self._x = x
self._y = y
self._z = z
@staticmethod
def verify_coord(coord):
if type(coord) != int:
raise TypeError('Координата должна быть целым числом')
@property
def x(self):
return self._x
@x.setter
def x(self, coord):
self.verify_coord(coord)
self._x = coord
# и так еще 2 раза для y, z... а если их больше будет?!
⚡️ СТАЛО (магия дескрипторов):
class Integer:
@staticmethod
def verify_coord(coord):
if type(coord) != int:
raise TypeError('Координата должна быть целым числом')
def __set_name__(self, owner, name): # а это что еще за зверь?!
self.name = '_' + name
# еще один вариант установки имени, как в property, аналог
# self.__name = f'_{owner.__name__}__{name}'
def __get__(self, instance, owner): # геттер
return getattr(instance, self.name)
# return instance.__dict__[self.name] # другой способ для примера
def __set__(self, instance, value): # сеттер
self.verify_coord(value)
setattr(instance, self.name, value)
# instance.__dict__[self.name] = value # другой способ для примера
Теперь класс Point3D выглядит таким образом, гораздо лучше ж?
class Point3D:
x = Integer()
y = Integer()
z = Integer()
def __init__(self, x, y ,z):
self.x = x
self.y = y
self.z = z
💡 СУТЬ ПРОСТЫМИ СЛОВАМИ:
Дескрипторы = "фабрики property". Один раз написал логику - используй для любого количества атрибутов!
🎯 КОГДА ПРИМЕНЯТЬ:
•Больше 2 property с одинаковой логикой
• Хочешь сделать код чище
• Устал от копипасты
🤔 СПОЙЛЕР ДЛЯ ЛЮБОЗНАТЕЛЬНЫХ:
А знаете, что дескрипторы бывают двух типов?
Как думаете, в чем между ними разница?
И какой тип мы использовали в примере выше? 🤔
💬 Пишите ваши версии в комментах!
А вы сталкивались с дескрипторами в работе?
Или предпочитаете "старый добрый" copy-paste?
Делитесь опытом - интересно, кому это реально пригодилось!
P.S. Если тема зашла - лайкните, допишу пару моментов с тонкостями! Или не допишу, как хотите😈
❤3🔥3
👁👁Тема на картинке, впечатления ниже. На этом всё.👁👁
Название одно, а смысл кажется другой, будто бы повторение пошло. Ну да ладно. Про атрибуты и свойства класса и экземпляра класса - окей. Это мы проходили, это мы знаем и помним(вроде)🫣Затем началась какая-то возня, на данном этапе не особо нужная, но может я не прав...
Да сколько этих вообще магических методов есть? Ладно то их количество, но что потом пригодится для использования на практике? Что надо запоминать лучше, а про какие можно знать что существуют и потом к ним вернуться? В голове сейчас только одно - АААААААААААААА.
Так же вчера чуть пару раз не сдался, хотел пойти смотреть решение. Точнее тот малый кусок, который у меня не получался. Но тогда какой смысл в этом всем, если так делать? Программист должен уметь решать проблемы сам, иначе какой от него толк).
Но с другой стороны, вначале можно посмотреть как это делается, чтобы потом много раз использовать повторно. А вы как считаете?! Кто на какой стороне медали стоит?)
Название одно, а смысл кажется другой, будто бы повторение пошло. Ну да ладно. Про атрибуты и свойства класса и экземпляра класса - окей. Это мы проходили, это мы знаем и помним(вроде)🫣Затем началась какая-то возня, на данном этапе не особо нужная, но может я не прав...
Да сколько этих вообще магических методов есть? Ладно то их количество, но что потом пригодится для использования на практике? Что надо запоминать лучше, а про какие можно знать что существуют и потом к ним вернуться? В голове сейчас только одно - АААААААААААААА.
Так же вчера чуть пару раз не сдался, хотел пойти смотреть решение. Точнее тот малый кусок, который у меня не получался. Но тогда какой смысл в этом всем, если так делать? Программист должен уметь решать проблемы сам, иначе какой от него толк).
Но с другой стороны, вначале можно посмотреть как это делается, чтобы потом много раз использовать повторно. А вы как считаете?! Кто на какой стороне медали стоит?)
❤4
☎️📞🤙 Call me maybe ☎️📞🤙
Классы в Python можно вызывать как функции. Да, те самые обычные две скобки () при создании экземпляра.
В этот момент вызывается "магический метод" `__call__` 🧙♂️. По умолчанию он вызывает ошибку TypeError, если применяется к экземпляру класса без реализации.
Классы, которые так себя ведут, называют "функторы" 🧠. Странное название, ну да ладно 😁.
Но зачем это надо? 🤔 Давайте разберемся на примерах.
1) Простой счетчик
2) Счетчик с параметром:
Можем немножко изменить код, чтобы туда можно было передавать аргументы, Что выведется в последней строчке тогда, как думаете?
Еще пару вариантов:
3) Замена замыканий функций:
+ в чат если помните что это такое 🙃. Пример для обработки строки через strip(). Но можно придумать что угодно другое.
4) Реализация декораторов, с помощью классов.
Математика вошла в чат 📊. Здесь вычисляется значение производной функции в конкретной точке х.
Итог: Функторы — это мощный инструмент, когда нужно сохранять состояние между вызовами или создавать умные декораторы! 🚀
А вы используете функторы в своих проектах? Делитесь в комментариях! 👇
P.S. Кто угадал результат во втором примере? 😄
Классы в Python можно вызывать как функции. Да, те самые обычные две скобки () при создании экземпляра.
В этот момент вызывается "магический метод" `__call__` 🧙♂️. По умолчанию он вызывает ошибку TypeError, если применяется к экземпляру класса без реализации.
Классы, которые так себя ведут, называют "функторы" 🧠. Странное название, ну да ладно 😁.
Но зачем это надо? 🤔 Давайте разберемся на примерах.
1) Простой счетчик
class Counter:
def __init__(self):
self.__counter = 0
def __call__(self, *args, **kwargs):
print('__call__')
self.__counter += 1
return self.__counter
c = Counter()
c()
c()
res = c()
print(res) # 3 🎯
2) Счетчик с параметром:
Можем немножко изменить код, чтобы туда можно было передавать аргументы, Что выведется в последней строчке тогда, как думаете?
class Counter:
def __init__(self):
self.__counter = 0
def __call__(self, step=1, *args, **kwargs):
print('__call__')
self.__counter += step
return self.__counter
c = Counter()
c2 = Counter()
c()
c(10)
res = c(3)
res2 = c2(-5)
print(res, res2) # что выведет? 🧠
Еще пару вариантов:
3) Замена замыканий функций:
+ в чат если помните что это такое 🙃. Пример для обработки строки через strip(). Но можно придумать что угодно другое.
class StripChars:
def __init__(self, chars):
# символы для удаления в конце и начале строки
self.__chars = chars
def __call__(self, *args, **kwargs):
if not isinstance(args[0], str):
raise ValueError("Аргумент должен быть строкой")
return args[0].strip(self.__chars)
s1 = StripChars("?:!.; ")
res = s1("; Hello World! ")
print(res) # "Hello World" ✨
4) Реализация декораторов, с помощью классов.
Математика вошла в чат 📊. Здесь вычисляется значение производной функции в конкретной точке х.
import math
class Derivate:
def __init__(self, func):
self.__fn = func
def __call__(self, x, dx=0.0001, *args, **kwargs):
return (self.__fn(x + dx) - self.__fn(x)) / dx
@Derivate
def df_sin(x):
return math.sin(x)
# df_sin = Derivate(df_sin) # в "лоб"
print(df_sin(math.pi/3)) # производная синуса 🧮
Итог: Функторы — это мощный инструмент, когда нужно сохранять состояние между вызовами или создавать умные декораторы! 🚀
А вы используете функторы в своих проектах? Делитесь в комментариях! 👇
P.S. Кто угадал результат во втором примере? 😄
🤯2🔥1
Всем доброе утро!☺️
А я пойду наверно скоро спать🤣 Восстановить режим пока не оч. получается.
Встал в 2 ночи и всё...не могу заснуть. Ну думаю что делать? пойду дорешаю несколько задачек по простой теме(позже пост). А среди них..опять прокрался злосчастный двусвязный список и нагородили новых методов еще.😬
Коротко о задаче:
Наверно 2.5+ часа решал.🫠🫠🫠
Часа полтора логика где-то + написание. Пошел ее проверил по своим тестам. Всё ок ✅
И еще где-то час ушло на то, что я решил "сэкономить" время, пропивав data-decriptor вместо трёх одинаковых property . Ну а че? Думал так красивее, быстрее и правильнее. Ага...🤡
Какого же было моё удивление, когда assert-ы в итоговой проверке не проходят. Хотя казалось бы...все случаи предусмотрел.
И в чем проблема была, как думаете???😢
Т.е....
В первом способе вручную создавалась имя атрибута, которое начиналось с двух подчеркиваний, например, __next.
➡️ Имя атрибута в словаре объекта: __next ⛔️
➡️ Что ожидали ассерты: _ObjList__next ✅
Почему не работало: Ассерты искали атрибут с именем
И вот из-за такой, казалось бы мелочи, тратится много времени и нервов на решение задач. Про уставшие глаза, желание забросить всё и сейчас я вообще молчу🧠Ну ничего движемся дальше.
Это мне напомнило момент про "генераторы списков". Раньше их тоже не любил, скорее даже не навидел. А все просто, потому что не понимал как ими пользоваться и тратил кучу времени на решение через такой способ. Проще было написать трёхэтажный цикл с условиями, чем один генератор. Но сейчас всё изменилось и пихаю это много где, и даже когда не надо😂
Вопрос к вам:
А какие у вас сейчас темы сложно даются? Интересно узнать, делитесь, не стеснятесь😼
А я пойду наверно скоро спать🤣 Восстановить режим пока не оч. получается.
Встал в 2 ночи и всё...не могу заснуть. Ну думаю что делать? пойду дорешаю несколько задачек по простой теме(позже пост). А среди них..опять прокрался злосчастный двусвязный список и нагородили новых методов еще.😬
Коротко о задаче:
Верно решили 3 114 учащихся
Из всех попыток 22% верных
Наверно 2.5+ часа решал.🫠🫠🫠
Часа полтора логика где-то + написание. Пошел ее проверил по своим тестам. Всё ок ✅
И еще где-то час ушло на то, что я решил "сэкономить" время, пропивав data-decriptor вместо трёх одинаковых property . Ну а че? Думал так красивее, быстрее и правильнее. Ага...🤡
Какого же было моё удивление, когда assert-ы в итоговой проверке не проходят. Хотя казалось бы...все случаи предусмотрел.
И в чем проблема была, как думаете???😢
def __set_name__(self, owner, name): # а это что еще за зверь?!
self.name = '__' + name # 1 способ - не подошел (хотя так показывали в теории)
self.name = f'_{owner.__name__}__{name}' # 2 cпособ(верный в моем случае)
Т.е....
В первом способе вручную создавалась имя атрибута, которое начиналось с двух подчеркиваний, например, __next.
➡️ Имя атрибута в словаре объекта: __next ⛔️
➡️ Что ожидали ассерты: _ObjList__next ✅
Почему не работало: Ассерты искали атрибут с именем
_ObjList__next, но дескриптор создал атрибут с именем __next. Python считает эти два имени абсолютно разными. Выходит обращался не по тому "адресу".И вот из-за такой, казалось бы мелочи, тратится много времени и нервов на решение задач. Про уставшие глаза, желание забросить всё и сейчас я вообще молчу🧠Ну ничего движемся дальше.
Это мне напомнило момент про "генераторы списков". Раньше их тоже не любил, скорее даже не навидел. А все просто, потому что не понимал как ими пользоваться и тратил кучу времени на решение через такой способ. Проще было написать трёхэтажный цикл с условиями, чем один генератор. Но сейчас всё изменилось и пихаю это много где, и даже когда не надо😂
Вопрос к вам:
А какие у вас сейчас темы сложно даются? Интересно узнать, делитесь, не стеснятесь😼
😱2
Прощаемся с <object at 0x...> раз и навсегда! 👋
Надоело видеть в консоли нечитабельную ерунду вроде <__main__.Cat object at 0x000002359011C160>? 🤔
Давайте сделаем вывод объектов Python понятным и информативным для человека!
В этом нам помогут магические методы
1️⃣
2️⃣
Пара важных нюансов: если не определен первый, то вызывается второй, иначе просто будет не совсем понятная лабуда в выводе.
Пример с котиками😼
И еще два довольно простых метода
По умолчанию они не определены, и их при их вызове получим ошибку. Но мы можем их легко переделать по себя, например вот так:
Надеюсь, этот мини-урок поможет вашему коду стать чуточку понятнее и красивее! ✨ Если было полезно, буду рад вашим реакциям — это лучшая мотивация для новых полезных постов.
Как вам такие "магические" методы? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
🐱 — Котики — топ!
Надоело видеть в консоли нечитабельную ерунду вроде <__main__.Cat object at 0x000002359011C160>? 🤔
Давайте сделаем вывод объектов Python понятным и информативным для человека!
В этом нам помогут магические методы
__str__ и __repr__. Они "отрабатывают" в момент отображения объекта и превращают технический мусор в красивую строку. В чем разница между ними?1️⃣
__str__ — для пользователей (когда вы делаете print() или str()).2️⃣
__repr__ — для разрабов (в режиме отладки или консоли).Пара важных нюансов: если не определен первый, то вызывается второй, иначе просто будет не совсем понятная лабуда в выводе.
Пример с котиками😼
class Cat:
def __init__(self, name):
self.name = name
def __repr__(self):
return f'{self.__class__}: {self.name}'
def __str__(self):
return f'Имя кошки: {self.name}'
cat = Cat('Василий')
cat # в консоле выведет: <class '__main__.Cat'>: Василий
print(cat) # Имя кошки: Василий
str(cat) # Имя кошки: Василий
И еще два довольно простых метода
__len__, __abs__. По умолчанию они не определены, и их при их вызове получим ошибку. Но мы можем их легко переделать по себя, например вот так:
class Point:
def __init__(self, *args):
self.__coords = args
def __len__(self):
return len(self.__coords)
def __abs__(self):
return list(map(abs, self.__coords))
p = Point(1, -2)
print(len(p)) # 2
print(abs(p)) # [1, 2]
Надеюсь, этот мини-урок поможет вашему коду стать чуточку понятнее и красивее! ✨ Если было полезно, буду рад вашим реакциям — это лучшая мотивация для новых полезных постов.
Как вам такие "магические" методы? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
🐱 — Котики — топ!
🔥5❤2
Симуляция работы программиста 👨💻
Если есть тут те, кто реально работает, скажите, насколько я попал? 🤔
В общем, вчера проснулся в 4 утра. Дальше — все как в тумане, неожиданно наступило 8 часов 😶 Время ехать в офис. Но так как я «работаю» удаленно, до 9:30 еще валялся и досыпал. Кайф!
Дальше открываю Jira Stepik. Смотрю задачи, беру ту, что «горит». Пару дней назад кое-что отложил, вот пришлось срочно доделывать. Разобрался с этим и приступаю.
В итоге просидел до 17:30, не считая перерывов на кофе и что-то сделать покушать. Получился целый рабочий день. Не думал, что может так затянуть! Раньше вообще размышлял, как можно столько часов подряд сидеть и кодить? А нет, оказывается, можно))
Пошел четко по плану. К моему удивлению, задача, которая на первый взгляд казалась самой легкой, отняла больше всего времени (целых 2.5 часа!). А самая непонятная (по описанию) была не такой уж и трудной.
В общей сложности сделал 7 задач. Забудьте про те 25 в день, про которые писал раньше 😂 Важно, сколько времени ты уделяешь работе, а не количество. Просто прошлым способом проще заставить себя начать.
Как только прошло 8 рабочих часов, ни минуты не задерживаясь, закрыл всё к чертям! 😎 Теоретически мог бы заниматься дальше, но чувствую, продуктивность была бы уже около-нулевая.
А у вас как проходят рабочие будни? Делитесь в комментах! 👇🙃
Узнали себя? - Ставьте лайк😈
Если есть тут те, кто реально работает, скажите, насколько я попал? 🤔
В общем, вчера проснулся в 4 утра. Дальше — все как в тумане, неожиданно наступило 8 часов 😶 Время ехать в офис. Но так как я «работаю» удаленно, до 9:30 еще валялся и досыпал. Кайф!
Дальше открываю
В итоге просидел до 17:30, не считая перерывов на кофе и что-то сделать покушать. Получился целый рабочий день. Не думал, что может так затянуть! Раньше вообще размышлял, как можно столько часов подряд сидеть и кодить? А нет, оказывается, можно))
Пошел четко по плану. К моему удивлению, задача, которая на первый взгляд казалась самой легкой, отняла больше всего времени (целых 2.5 часа!). А самая непонятная (по описанию) была не такой уж и трудной.
В общей сложности сделал 7 задач. Забудьте про те 25 в день, про которые писал раньше 😂 Важно, сколько времени ты уделяешь работе, а не количество. Просто прошлым способом проще заставить себя начать.
Как только прошло 8 рабочих часов, ни минуты не задерживаясь, закрыл всё к чертям! 😎 Теоретически мог бы заниматься дальше, но чувствую, продуктивность была бы уже около-нулевая.
А у вас как проходят рабочие будни? Делитесь в комментах! 👇🙃
Узнали себя? - Ставьте лайк😈
🔥5
Магические методы для арифметических операторов в Python 🔢
Знакомьтесь с основными магическими методами:
• add() – сложение
• sub() – вычитание
• mul() – умножение
• truediv() – обычное деление
• floordiv() – целочисленное деление
• mod() – остаток от деления
Лучше один раз увидеть, чем 100500 раз прочитать! 👀Внимание - очень много букв😁😁😁
Возьмем класс для работы со временем. Время храним в секундах (макс. 86400 - секунд в сутках):
Добавляем сложение ➕
Сначала научим складывать с числами:
Теперь работает:
Усложняем - складываем два объекта Clock:
Теперь:
Закончили? Неа! ❌
Добавляем обратное сложение 🔄
Теперь 100 + c1 работает. Почему кидает в add? Честно - я не до конца понял 😅
Но метод выше можно еще реализовывать например таким способом, тут всraddее:
Ну теперь уж точно всё, подумали вы. Нет😂😂 все еще не работает такой стиль c1 += c2🙈
Точнее работает, но не так. как хотелось бы. Мы пока что возвращаем(создаем) новый объект, а здесь новый эзкемпляр создавать не надо. Надо просто изменять на месте, для этого напишем так.
Изменяем объект на месте (не iadd новый)
Теперь c1 += c2 изменяет сам c1 🎯
Важный нюанс:
🟡 + создает новый объект
🟡 += изменяет существующий
Для изменяемых классов (как списки) можно всегда возвращать старый объект.
Другие методы делаются абсолютно аналогично.
Итог:
Теперь вы знаете, как работают операции в int, float, str! Все ошибки, которые вы видели - это как раз проверки в этих dunder методах.
Как вам такие "магические" методы? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
🐍 — Здесь притаился питон.raddто объясниaddму
Знакомьтесь с основными магическими методами:
• add() – сложение
• sub() – вычитание
• mul() – умножение
• truediv() – обычное деление
• floordiv() – целочисленное деление
• mod() – остаток от деления
Лучше один раз увидеть, чем 100500 раз прочитать! 👀
Возьмем класс для работы со временем. Время храним в секундах (макс. 86400 - секунд в сутках):
class Clock:
__DAY = 86400 # секунд в сутках
def __init__(self, seconds: int):
if not isinstance(seconds, int):
raise TypeError("Секунды должны быть целым числом")
self.seconds = seconds % self.__DAY
def get_time(self):
s = self.seconds % 60 # секунды
m = (self.seconds // 60) % 60 # минуты
h = (self.seconds // 3600) % 24 # часы
return f"{h:02}:{m:02}:{s:02}"
Добавляем сложение ➕
Сначала научим складывать с числами:
def __add__(self, other): #
if not isinstance(other, int):
raise ArithmeticError("Правый операнд должен быть типом int")
return Clock(self.seconds + other)
Теперь работает:
с1 = Clock(1000)
с1 = с1 + 100
print(с1.get_time()) # 00:18:20
Усложняем - складываем два объекта Clock:
def __add__(self, other):
if not isinstance(other, (int, Clock)):
raise ArithmeticError("Правый операнд должен быть типом int или объектом Clock")
sc = other if isinstance(other, int) else other.seconds
return Clock(self.seconds + sc)
Теперь:
c1 = Clock(1000)
c2 = Clock(100)
c3 = c1 + c2
print(c3.get_time()) # # 00:18:20
Закончили? Неа! ❌
Не работает: c1 = 100 + c1 # Ошибка!
Добавляем обратное сложение 🔄
def __radd__(self, other):
return self + other # перекидывает в __add__(self, other) .
Теперь 100 + c1 работает. Почему кидает в add? Честно - я не до конца понял 😅
c1 = Clock(1000)
c1 = 100 + c1
print(c1.get_time()) # 00:18:20
Но метод выше можно еще реализовывать например таким способом, тут всraddее:
def __radd__(self, other):
return self.__add__(other)
Ну теперь уж точно всё, подумали вы. Нет😂😂 все еще не работает такой стиль c1 += c2🙈
Точнее работает, но не так. как хотелось бы. Мы пока что возвращаем(создаем) новый объект, а здесь новый эзкемпляр создавать не надо. Надо просто изменять на месте, для этого напишем так.
Изменяем объект на месте (не iadd новый)
def __iadd__(self, other):
print("__iadd__")
if not isinstance(other, (int, Clock)):
raise ArithmeticError("Правый операнд должен быть типом int или объектом Clock")
sc = other if isinstance(other, int) else other.seconds
self.seconds += sc
return self # возвращаем тот же объект!
Теперь c1 += c2 изменяет сам c1 🎯
Важный нюанс:
🟡 + создает новый объект
🟡 += изменяет существующий
Для изменяемых классов (как списки) можно всегда возвращать старый объект.
Другие методы делаются абсолютно аналогично.
Итог:
Теперь вы знаете, как работают операции в int, float, str! Все ошибки, которые вы видели - это как раз проверки в этих dunder методах.
Как вам такие "магические" методы? 👇
🔥 — Огонь, приму на вооружение!
🤔 — Знал, но освежил память.
🐍 — Здесь притаился питон.raddто объясниaddму
__radd__ вызывает __add__ в первом варианте реализации этого метода? Жду в комментах! 👇🤔3🔥1