Cool and Fun Python
540 subscribers
30 photos
8 videos
1 file
33 links
Крутой и весёлый Python. Случаи из практики и не только.
Download Telegram
Немного Python Fun 😂🤣😂

Оживить канал. Напомнить о нём подписчикам. Заодно и админу. Чтобы за выходные подготовил свежий пост. До скорой встречи
👍5❤‍🔥2🔥2
О Markdown и Телеграм

Если простыми словами, то Markdown превращает символы в оформление. Это язык разметки, как и HTML. Например двойное подчеркивание ➡️ __ ⬅️ до и после слова делает его курсивным. Как видите Телеграм поддерживает Markdown.

После очередного обновления в Телеграм появилась подсветка синтаксиса. Работает так:

\\ \\ \\` python # три открывающих апострофа и название вашего ЯП
Ваш код
\
\ \ # три закрывающих апострофа

python
print('Hello world!')



Пишите свои примеры в комментариях

P.S. В прошлых статьях также улучшено форматирование
👍6🆒1
Итоги голосования. Python на втором месте 🥈 Не хватило всего 30 голосов. Мы могли это сделать. Но сделаем в следующем году
А пока всех с наступающими праздниками. Да прибудет с вами любимый язык программирования ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
2👏1👨‍💻1
Добрый вечер, коллеги!
С наступившим 2024 годом. Как ваше самочувствие? Может хотите маринованных огурчиков, огуречного рассола? 🥒

Модуль pickle
Помимо всем привычного и безопасного JSON для сериализации и десериализации данных в Python есть модуль pickle, выполняющий аналогичные действия с питоновскими объектами

Важно! Модуль pickle небезопасен. Распаковывайте только те данные, которым вы доверяете.

Держите простой пример маринования трёх объектов в один файл:
import pickle

obj1 = {'name': 'Alice', 'age': 25}
obj2 = [1, 2, 3, 4, 5]
obj3 = ('a', 'b', 'c')

with open('data.pickle', 'wb') as f:
pickle.dump(obj1, f)
pickle.dump(obj2, f)
pickle.dump(obj3, f)
В результате получим бинарный data.pickle с неудобным для чтения человеком содержимым, примерно таким:
 �        }�(� name�� Alice�� age�K u.� �        ]�(K K K K K e.� �        � a�� b�� c���.
Но если спустя время нам понадобятся наши словари и списки, достаём разносолы из файла:
import pickle

with open('data.pickle', 'rb') as f:
loaded_obj1 = pickle.load(f)
loaded_obj2 = pickle.load(f)
loaded_obj3 = pickle.load(f)

print(loaded_obj1) # {'name': 'Alice', 'age': 25}
print(loaded_obj2) # [1, 2, 3, 4, 5]
print(loaded_obj3) # ('a', 'b', 'c')
Успехов в новом году. И не только в консервациях 😉
👍6🔥1😈1
Продолжаем мариновать объекты Python. Начало тут

Чем же так небезопасен pickle? В первую очередь программистом, который его использует неправильно.
Ловите пример:
import pickle

res = pickle.loads(b"cos\nsystem\n(S'echo Hello world!'\ntR.")
В результате загрузки данных из строки байт в терминал отправится сообщение "Hello world!". Немного не то, для чего создавался модуль. Кстати, в переменной res будет хранится ноль, а не текст или команда.

Но почему так? Дело в том, что модуль выполняет дандер __reduce__ замаринованного объекта в процессе преобразования файла/строки в объекты Python.
import pickle
import os


class MaliciousCode:
def __reduce__(self):
# При вызове функции pickle.load() будет выполнена команда удаления всех файлов в текущей директории
return (os.system, ('rm -rf *',))


malicious_object = MaliciousCode()

with open('data.pickle', 'wb') as file:
pickle.dump(malicious_object, file)

with open('data.pickle', 'rb') as file:
loaded_object = pickle.load(file)
Отличных новогодних праздников. И не стреляйте себе в ногу 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🍾1
Праздники подходят к концу. А идеи для канала регулярно появляются 💡

Начнём пост с функции генерации уникальных токенов:
# Импортируем функцию token_urlsafe из модуля secrets
from secrets import token_urlsafe

# Определяем функцию generate_token с параметрами n и prefix, по умолчанию n=5, prefix='/'
def generate_token(n=5, prefix="/"):
"""Генерирует токен с префиксом для короткого url размерностью n без символа "-" в токене."""
# Входим в бесконечный цикл
while True:
# Генерируем случайный токен и добавляем префикс
token = f"{prefix}{token_urlsafe(n)}"
# Проверяем, содержит ли токен символ "-"
if "-" not in token:
# Если не содержит, то выходим из цикла
break
# Возвращаем значение переменной token
return token
А теперь вспомним про моржовый оператор в Python. Писал про него 🔗тут и 🔗тут.
Вспомнили? Тогда перепишем код покороче:
from secrets import token_urlsafe

def generate_token(n=5, prefix="/"):
while "-" in (token := f"{prefix}{token_urlsafe(n)}"):
pass
return token
Цикл, который ничего не делает в теле цикла, много чего делает в условии цикла.
Забирайте лайфхак в копилку 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
Для начала признаюсь, что не люблю однострочники. Особенно те, которые уходят за край второго 😱 монитора. Код должен быть в первую очередь читаемым и понятным. Но моржовый оператор из прошлого поста вызывал бурную активность в узких кругах. Поэтому ловите финальную версию:
from secrets import token_urlsafe

def generate_token(n=5, prefix="/"):
"""Генерирует токен с префиксом для короткого url размерностью n, исключая символы двойного прочтения."""
while (token := token_urlsafe(n)) and any(char in token for char in ("-", "_", "O", "l", "I", "0", "1",)):
pass
return f"{prefix}{token}"

Финальная версия, из прода. Ещё тёплая. Тёплых вам выходных 🫶

✍️ - беру на вооружение
🤯 - как это работает?
🎉 - пятница, время отдохнуть от кода
Please open Telegram to view this post
VIEW IN TELEGRAM
6🤯4🎉3
👍3
Сейчас PyCharm активно вошёл в мою жизнь. Python основной ЯП, поэтому нет смысла изобретать велосипед. Но даже для Python вполне можно использовать Visual Studio Code или IntelliJ IDEA. А можно покодить в Sublime Text, Atom или Notepad++.
Если же выйти за рамки змеиного языка, вспоминаются другие продукты JetBrains, а также Eclipse, Nano и Vim.

А какими IDE и редакторами кода пользуетесь вы? Чем пользовались раньше? Пиши в комментариях и голосуйте в опросе выше

Продолжение в комментах...
👍2🔥1
Очевидное рядом или проверка длинны коллекции без использования функции проверки длинны коллекции 🫣

Посмотрите на два простых примера кода. Какой из них работает быстрее и почему?

Вариант 1
my_list = []
...
# наполняем список данными
...
while my_list:
print(my_list.pop())
Вариант 2
my_list = []
...
# наполняем список данными
...
while len(my_list) > 0:
print(my_list.pop())
Для опытного разработчика очевидно, что оптимален первый вариант.

Почему?
Список, как и другие коллекция Python - объект. Внутри объекта хранятся не только данные (на самом деле не данные, а указатели на данные), но и полезная информация. Одна из таких полезностей - количество элементов коллекции. Это целое число, которое автоматически меняется при добавлении и удалении элементов. Объект коллекции всегда помнит сколько в нём элементов.

Вариант 1 обращается к количеству напрямую, получает целое число и если оно ноль, у нас False. А если не ноль - True.

Вариант 2 вызывает функцию len(), которая обращается к счётчику количества элементов в коллекции и получает целое число. Если число больше нуля, у нас True. А если нет - False.

Очевидно, что получение int и его преобразование к bool работает быстрее, чем вызов функции, которая возвращает int для сравнения с другим int и получения bool 🧐

P.S. Для любителей асимптотики. Оба варианта работают за O(1) 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
👍611
This media is not supported in your browser
VIEW IN TELEGRAM
Угадайте кто из великодушных диктаторов сегодня отмечает свой день рождения? 🤔
Поздравляем Гвидо Ван Россума с 0b1000100 летием🎂
Please open Telegram to view this post
VIEW IN TELEGRAM
3🍾2
Какие числовые типы данных есть в Python?

Отличный вопрос для начала собеседования. Забавно, но большинство отвечают на него: «float и int». И это хороший, но неполный ответ новичка.
Что же творится с числами в Python на самом деле?

- float - вещественные числа. Точнее они хотят казаться вещественными. Но фиксированное число байт для их хранения не позволяет добиться желаемой точности. float - имеют ограниченную точность для хранения вещественных чисел. Зато умеют быть бесконечностью - float("inf") и даже не числом - float("Nan").

- int - целые числа. В Python они "резиновые". Для хранения целого выделяется столько байт, сколько нужно для его хранения. Никаких big int, long и т.п. в Python нет, потому что обычный int их заменяет.

- bool - логический тип, который в Python частный случай int. Представлен в двух вариантах: True и False. При приведению к int превращаются в 1 и 0 соответственно. Преобразование int -> bool даёт True для любых целых кроме нуля.

- complex - комплексные числа, они же числа с мнимой единицей. Особенностью является то, что в математике мнимая единица записывается как i, а в Python как j. Впрочем, к записям подобным 3+2j быстро привыкаешь.

- decimal - отдельный модуль для хранения вещественных чисел без проблем с точностью. Выделяет столько памяти, сколько нужно для хранения мантиссы и основания. Обязательно заменяет float везде, где важна каждая цифра после запятой: деньги, расчёты с высокой точностью и т.п.

- fraction - дробные числа. Если надо посчитать ⅓+⅘ и вообще работать с дробями, не нужно изобретать велосипед. Модуль отлично справляется с дробной математикой.
👍7🔥3🤓1
Раскладываем по полочкам очевидное (как показывает практика не для всех)

CRUD расшифровывается как:
- create (создать);
- read (прочитать);
- update (обновить);
- delete (удалить).

Когда речь идёт о работе с базой данных используются следующие команды:
- INSERT (вставить);
- SELECT (выбрать);
- UPDATE (обновить);
- DELETE (удалить).

Как видим есть схожие с CRUD команды, а есть отличные.

Идём дальше. При взаимодействии клиента с сервером часто используют REST API, отправляют следующие запросы:
- POST (опубликовать)
- GET (получить);
- PUT (положить);
- DELETE (удалить).

Так, удаление есть и тут. Хоть где-то стабильность.

Смотрим в код, а там функции с именами вида:
- add (добавить);
- get (получить);
- change (изменить);
- delete (удалить).

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

P.S. Спасибо Кэпу за post. Надеюсь он поможет новичкам найти свой put в мире IT 😉
👍5🆒2
Воскресный привет!

На связи морж и его оператор. Ловите вариант использования := внутри if
def func(num: str):
if num.isdigit() and (index := int(num)) < MAX_INDEX:
...
Как вам?

✍️ - беру на вооружение
🤯 - как это работает?
🎉 - выходные для отдыха, а не кода
🤯105🎉3🔥1😁1
Изначально планировал давать поясняющий пост (ПП), если основной наберёт ≈10% взрывных мозгов 🤯 Получилось не 10%, а 5 ÷ 101 ≈ 4.95%. Но ПП готов, поэтому ловите и изучайте.

Давайте детально разберём код:

def func(num: str):
0). Определяем функцию func, которая принимает один аргумент num строкового типа.
Нам нужно число, а не строка, чтобы корректно сравнить num с MAX_INDEX

    if num.isdigit()
1). num.isdigit() проверяет, является ли строка num числом. Метод isdigit() возвращает True, если в строке есть только цифры. Т.е. там записано натуральное число или ноль.

Познавательная минутка 🤓
Натура‌льные чи‌сла (от лат. naturalis «естественный») - числа, возникающие естественным образом при счёте (1, 2, 3, 4, 5, 6, 7 и так далее).

    if num.isdigit() and ...
2). Если в num есть символы помимо цифр, isdigit возвращает False. В этом случае команда and не выполняет код справа. Нас автоматом перекидывает в блок else. Happy end

    ... (index := int(num))
3). Преобразуем строку num в целое число и присваиваем его переменной index. Ошибку ValueError при преобразовании мы исключили левой проверкой.
Конструкция в скобках называется оператором присваивания с объявлением переменной (walrus operator). Моржовый оператор или просто морж доступен с Python 3.8+

...(index := int(num)) < MAX_INDEX:
4). Благодаря круглым скобкам вокруг моржового присваивания, код "волшебным" образом превращается в обычное сравнение:
index < MAX_INDEX
сравниваем значение index с некоторой константой MAX_INDEX.


Общий смысл этого кода заключается в проверке строки num на то, что она является натуральным числом или нулём и что это число меньше чем константа MAX_INDEX 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥61👍1
В Python всё объект. И иногда надо убедиться, что объект именно того типа, который нам нужен. Как же проверить тип объекта?

Допустим у нас есть переменная spam. И мы хотим убедится, что она указывает на объект типа int.
spam = 42

0. Способ новичка-принтовичка
print(type(spam))
Простой и понятный способ для новичков. Но не подходит для использования в продакшн-коде, так как выводит информацию на экран.

1. Сравнительный
if type(spam) == int:
...
Простой способ сравнить тип переменной с конкретным типом.

2. Сравнительный +
if type(spam) is int:
...
Более строгая проверка на совпадение объектов.

Познавательная минутка🤓
Оператор is проверяет не только тип, но и идентичность объекта. И когда вы прочитали в начале статьи: «В Python всё объект», речь шла действительно обо всём в Python.
Да, тип объекта так же является объектом:
- 42 - объект типа int
- int - объект типа type
- type - объект типа type

В Python type является базовым типом, от которого наследуются другие типы.
Так вот, is проверяет являются ли объекты справа и слева от оператора одним и тем же объектом или нет

3. Функциональный
if isinstance(spam,  int):
    ...
Гибкий способ проверить, является ли объект экземпляром определенного класса или его подкласса. One love forever ❤️

4. Бонусный способ. Проверка на несколько типов, or
if isinstance(spam,  (int, float, complex,)):
    ...
Передача кортежа позволяет проверить объект на принадлежность к нескольким типам одновременно. Работает как цепочка сравнений через or. Достаточно совпасть с одним из типов, чтобы получить истину
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍3🤯1
О чём питоническом написать на следующей неделе?
Anonymous Poll
45%
Регулярные выражения
9%
Строки
36%
Мультимножества
11%
Свой вариант в комментариях
This media is not supported in your browser
VIEW IN TELEGRAM
Благодарю всех проголосовавших 🤝
На следующей неделе выйдет пост про мультимножества. Пожелания в комментариях так же будут учтены.

А пока у всех воскресенье, ловите немного Python кода со строками. Судя по голосованию с ними (строками) и так всё ясно. Поэтому только код и результат, no comments

from os.path import getsize as gs
from sys import getsizeof as gso


words = ("АВТОМЕХАТРОН", "AВТOМEХAТРOН", "АBTОMЕXАTPОH", "ABTOMEXATPOH")
for i, word in enumerate(words):
path = f"word_{i}.txt"
with open(path, "w", encoding="utf-8") as file:
file.write(word)
print(f"{len(word) = }, {gso(word) = }, {gs(path) = }")


Результат
len(word) = 12, gso(word) = 98, gs(path) = 24
len(word) = 12, gso(word) = 98, gs(path) = 19
len(word) = 12, gso(word) = 98, gs(path) = 17
len(word) = 12, gso(word) = 61, gs(path) = 12
👍3🎉3🤯21
Мультимножество. Часть 1, теоретическая

Для начала немного теории о множествах не только в Python, но и в математике в целом.

Множество - это набор уникальных элементов, которые могут быть любого типа (числа, буквы, предметы и т.д.). В множестве каждый элемент может встречаться только один раз.

Пример множества: 1, 2, 3, 4, 5. В этом множестве каждое число встречается только один раз. А если вы посмотрите вокруг себя и перечислите окружающие предметы (без повторов), то тоже получите множество: компьютер, телефон, кресло, стол.

Мультимножество - это набор элементов, где элементы могут повторяться. То есть в мультимножестве одинаковые элементы могут встречаться несколько раз.

Пример мультимножества: 1, 2, 2, 3, 3, 3. В этом мультимножестве число 2 встречается два раза, а число 3 - три раза.

👍 - отличное начало, продолжай
🥱 - долой теорию, давай код
👍23🥱2
Всем привет 👋

Увидел в одном канале вот такой код на картинке И немного загрустил. Ведь в нём куча повторяющихся блоков кода

Познавательная минутка 🤓
Принцип DRY (don't repeat yourself) рекомендует программистам не писать повторяющиеся строчки кода. И современные высокоуровневые языки программирования легко с этим справляются. Можно использовать функции и методы классов. А иногда достаточно обычного цикла.

Немного магии и картинка превращается в улучшению версию кода, в лучших традициях DRY
import time


def happy_birthday(name):
name = name.capitalize()
data = [("Happy Birthday to you.", 2, 1),
(f"Happy Birthday to {name}!", 1, 1),
("Happy Birthday to you.", 1, 1),
("Hip Hip Hooray!", 3, 0)]

for text, count, delay in data:
for step in range(count):
print(text)
time.sleep(delay)


happy_birthday("Python")

Кстати, с днём рождения языка. Python исполнилось 0b100001 годиков 🎂🍾🎉
Please open Telegram to view this post
VIEW IN TELEGRAM
🎉8🍾3❤‍🔥1