TGViewer
Channel Public Channel
Кодим вместе: Путь к IT-Успеху

Кодим вместе: Путь к IT-Успеху

@it_success_path

🌟Всем привет! Я начинающий Python-разработчик, вернувшийся к обучению. Здесь делюсь своими планами и достижениями, чтобы мотивировать вас и себя заниматься программированием каждый день! 🚀
Subscribers
541
Photos
115
Videos
1
Links
106

Showing posts older than #201 · Back to latest

Older Posts 20 shown
Post #200 324
  • ❤ 11
  • 👍 1
Post #199 373
Прощаемся с <object at 0x...> раз и навсегда! 👋

Надоело видеть в консоли нечитабельную ерунду вроде <__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
Post #198 328
Всем доброе утро!☺️

А я пойду наверно скоро спать🤣 Восстановить режим пока не оч. получается.

Встал в 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
Post #197 287
☎️📞🤙 Call me maybe ☎️📞🤙

Классы в 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
Post #196 277
  • 😁 7
Post #195 307
👁👁Тема на картинке, впечатления ниже. На этом всё.👁👁

Название одно, а смысл кажется другой, будто бы повторение пошло. Ну да ладно. Про атрибуты и свойства класса и экземпляра класса - окей. Это мы проходили, это мы знаем и помним(вроде)🫣Затем началась какая-то возня, на данном этапе не особо нужная, но может я не прав...

Да сколько этих вообще магических методов есть? Ладно то их количество, но что потом пригодится для использования на практике? Что надо запоминать лучше, а про какие можно знать что существуют и потом к ним вернуться? В голове сейчас только одно - АААААААААААААА.

Так же вчера чуть пару раз не сдался, хотел пойти смотреть решение. Точнее тот малый кусок, который у меня не получался. Но тогда какой смысл в этом всем, если так делать? Программист должен уметь решать проблемы сам, иначе какой от него толк).

Но с другой стороны, вначале можно посмотреть как это делается, чтобы потом много раз использовать повторно. А вы как считаете?! Кто на какой стороне медали стоит?)
  • ❤ 4
Post #194 298
Держите немного буржуйской мотивации с ютуба🙃

P.S.
Буржуи были в моём понимании - это те, кто говорят на английскийском языке, не более того) не знаю откуда это так запомнилось, но смысл этого слова лишь в этом🙃
  • 👍 5
Post #193 326
🤯 ДЕСКРИПТОРЫ: КАК Я ИЗБЕЖАЛ КОПИПАСТЫ В 3 СТРОКИ

Потратил 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 с одинаковой логикой
• Хочешь сделать код чище
• Устал от копипасты

🤔 СПОЙЛЕР ДЛЯ ЛЮБОЗНАТЕЛЬНЫХ:
А знаете, что дескрипторы бывают двух типов?

Non-data vs Data дескрипторы...

Как думаете, в чем между ними разница?
И какой тип мы использовали в примере выше? 🤔

💬 Пишите ваши версии в комментах!

А вы сталкивались с дескрипторами в работе?
Или предпочитаете "старый добрый" copy-paste?
Делитесь опытом - интересно, кому это реально пригодилось!

P.S. Если тема зашла - лайкните, допишу пару моментов с тонкостями! Или не допишу, как хотите😈
  • ❤ 3
  • 🔥 3
Post #192 289
Вот как оказывается выглядит утро, когда встаёшь не в 12+, а вместе с рассветом🙀
  • 👏 6
  • 😍 4
  • ❤ 1
Post #191 325
prodigy 🔥 PROPERTY в ООП - РАЗБИРАЕМ НА ПАЛЬЦАХ! 🔥

Опишу кратко суть, наверно проще будет на примере. Вспомните - если забыли, либо узнаете новое для себя.

Например у нас есть класс 👇 с защищенной переменной.

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 = Person('ВАся', 25)
p.old = 35
p.__dict__['old'] = 45
print(p.__dict__)
print(p.old) # - что тут выведется, как думаете? кто знает?)

Например, можем создавать локальное свойство old в экземпляре класса, но при выводе и взаимодействии с ним будет использоваться то, что в защищенной переменной. Хотя, казалось бы, по логике должно же меняться локальное свойство old.
И ТАКОЕ СВОЙСВТВО БЕРЕТСЯ ВПЕРЕД( В ПРИОРИТЕТЕ НАД ДАЖЕ НАД СВОЙСТВОМ ЭКЗЕМПЛЯРА КЛАССА)
  • ❤ 2
  • 🤔 2
Post #190 365
привет, кое-что нашел для вас ⤵️
💙🛠 Kickresume.com/en/ats-resume-checker/ ATS-чекер для вашего резюме

➕
-- Бесплатно даст оценку (0-100) и покажет, по каким категориям (Дизайн, Структура, Содержание) у вас провал.

--Загружайте, правьте, перезагружайте резюме. Следите, как растет ваш балл после каждого изменения. Это главный лайфхак.

--Сравнивайте с резюме из топ-компаний. У них есть реальные примеры - смотрите, как структурируют опыт другие.

⚡️ Краткий план действий:

Выберите ATS-дружественный шаблон (есть в самом Kickresume).

Пройдите бесплатную проверку.

Исправьте всё, что подсветилось красным.

Повторите пункты 2 и 3, пока не получите 80+ баллов.

Используйте чекер как детектор слабых мест, а не как панацею.

Всем удачи и оферов🍀
  • 👏 7
  • 🔥 1
Post #189 328
  • 🤔 3
Post #188 387
Интересная задачка дня

Условие, тесты

Вспоминаем 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
Post #187 344
Сегодня же Хэллоуин. Празднуете?

А может кто-то еще нарядился и накрасился, есть такие?) Скидывайте фотки кто в каком образе находится, будет интересно посмотреть😈
  • 😈 3
Post #186 377
😵‍💫 Застрял в режиме "Лебедь, рак и щука"

Последние две недели сильно просел объем занятий. Причина — на фото 👆

Как вы помните, я говорил, что не собираюсь разветвляться и уходить в другие направления. План простой:
- Завершить курс по Базе, ООП, Django
- Подтянуть требования из вакансий
- Искать работу

Но не знаю, почему именно сейчас мне в голову взбрело создание задач! 🤷‍♂️ Создаю задачки по разным темам — по сути, та же рубрика "викторина", но местами сложнее.

Выходит:

- Это отнимает **много времени и сил
- После 3 дней плотной работы + курс по ООП — полный выгорание
- Не хотелось возвращаться вообще ни к чему

Об этом и был мой последний пост про отдых в 3-4 дня — просто без конкретных причин.

Чувствую, что это меня сильно тормозит, но и отказываться не хочется...

Как в басне Крылова 🦢🦀🦐
И то хочу, и это, и пятое-десятое.
А по факту — "А воз и ныне там" 😮‍💨

Как вам удавалось бороться с таким распылением? Или я один такой?)

💬 Буду рад вашим советам в чате — как вы удерживаете фокус?
  • 👀 4
Post #185 338
😶😶😶Связные списки 👿👿👿

Не люблю я эти связные списки... А тут еще и двунаправленные! 🫠

Было так:
- Накидал код → отошел → вернулся → снова ничего не понял 🫡
- Немного подсмотрел решение, не до конца → ничего нового не узнал, закрыл видео😁
- Пошел дальше делать... но не получилось до конца!

Пришлось достать "тяжелую артиллерию" — старый дедовский метод с тетрадкой! 📝
Начал расписывать вручную: что, куда, зачем и почему. Давно так не запаривался!

А вот и главным врагом неожиданно оказался метод `remove()`
Думал: "ну удаление, что сложного?"
А оказалось:
- Целых три случая удаления!
- Общий случай не проходил
- Пришлось звать на помощь ИИ 🆘

🤔 А вам как дались связные списки?
- Было так же сложно?
- Или для вас это было просто?
- Есть свои лайфхаки для понимания?

P.S.
Вот ссылка на теорию по этой теме: урок
Надеюсь, таких задач больше не встретится! А то я еще неделю буду сниться сам себе с указателями next-prev 🔁

💬 Делитесь опытом в чате — интересно узнать ваши истории!
  • 😱 3
Post #184 317
🔐 Режимы доступа: public, private, protected. Сеттеры и геттеры

Это последняя пройденная тема. Коротко об этом. Есть три типа доступа для атрибутов/свойств и методов класса/экземпляра класса:

📌 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
Post #183 324
  • 🤔 4
  • ❤ 1
Post #182 359
Done✅

Что могу сказать. Сделал задание часа за три🫠 Сначала пытался понять, что от меня хотят. По сути — обычная схема передачи данных через сеть. В первый час разобрался в требуемых методах и свойствах, накидал их, оформил 80+ процентов кода. Дальше начался тупняк из-за некоторых непонятных моментов. Пошёл отдыхать))

Когда вернулся — разобрался с теми сложными местами. Каюсь, всё-таки подглядел в комменты, чтобы выяснить один ньюанс интерпретации метода. Как-то очень абстрактно он был описан, не было до конца понятно, что конкретно нужно сделать... Затем ещё 2 часа ушло на допиливание 2.78 методов и проверок. И наконец — загорается зелёный цвет. А потом....

Потом случились "Страх и ненависть в Лас-Вегасе", когда посмотрел решение автора😂😂😂 Тут не так, там не эдак. Но... работает🙃 Сделал всё по ТЗ, а про расширяемость — не, не слышали😐 Хотя для этого надо не так много поменять.

В этом задании действительно есть моменты, определённые неоднозначно. И непонятно — то ли описание немного кривоватое, то ли мой мозг ещё не привык мыслить в ООП-стиле. Но ничего, движемся вперёд. Дальше будет только лучше!
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →