en
Feedback
Python Lounge: работа и стажировки для программистов

Python Lounge: работа и стажировки для программистов

Open in Telegram

Здесь можно найти интересующую вас работу и стажировки для программистов, а так же полезные статьи про Python. Размещение вакансии только - @perezvonyubot Ссылка на канал: @python_lounge Мы входим в сеть promopoisk.com Реклама: @adtgassetsbot

Show more
4 245
Subscribers
No data24 hours
-157 days
-6530 days
Posts Archive
​​Новая рубрика #кодподписчика На днях одна подписчица присала мне свой интересный и крайне необычный скрипт, поэтому я решил создать новую рубрику на своём канале, в которой буду выкладывать интересные работы своих подписчиков. В общем, суть программы в том, что берется произвольная картинка, разбивается на кусочки, создаются папки на рабочем столе и эти кусочки первоначальной картинки ставятся как иконки на папки. То есть получается некая мозаика, которую можно собрать в единую картинку прямо на рабочем столе вашего компьютера. По-моему, это отличный и вполне необычный способ отвлечься от работы, особо ничего не открывая. Теперь по технической части: скрипт написан на Python с использованием модулей win32api и pillow. Весь исходный код доступен здесь на гитхабе, советую посмотреть. Также подписчица просила в раздел Issues написать ваши идеи насчет того, что можно добавить и улучшить. Да, теперь каждый может прислать своё любое нетривиальное творение мне в личные сообщения, и я с большой вероятностью опубликую.

Дробные числа в Python могут иметь значение NaN, которое ничему не равно, включая самого себя. Один из способов получить их – использовать модуль math. >>> math.nan == math.nan False Кроме того, объект NaN не является уникальным в отличие от None, вы можете иметь несколько различных объектов NaN из разных источников: >>> float('nan') nan >>> float('nan') is float('nan') False Также это означает, что нельзя использовать NaN в качестве ключа в словаре: >>> d = dict() >>> d[float('nan')] = 1 >>> d {nan: 1} >>> d[float('nan')] Traceback (most recent call last):  File "<stdin>", line 1, in <module> KeyError: nan

uuid Стандартный модуль uuid — быстрый и простой способ сгенерировать UUID (universally unique identifier, глобально уникальный идентификатор). from uuid import uuid4 user_id = uuid4() print(user_id) Так мы создаём случайное 128-битное число, которое наверняка будет уникальным. Существует более 2¹²² возможных UUID. Это более 5 ундециллионов, то есть 36 нулей. Вероятность нахождения дубликатов в заданном наборе крайне мала. Даже при наличии триллиона UUID вероятность того, что среди них есть дубликат, гораздо меньше, чем один к миллиарду. Вполне недурно для двух строк кода.

В общем, мы создали объединенный чат нескольких каналов для взаимопомощи в программировании и просто общения – @python_chat_ru

Метод get для словарей У словарей есть метод get, который возвращает значение по ключу, переданному в аргументах функции. Однако если такого ключа в словаре нет, то исключение не выбрасывается, а возвращается значение по умолчанию, которое передаётся вторым аргументом, или же None, если второй аргумент не передан. В качестве примера создадим словарь с именами, которые можно получить по определенным значениям, и напишем функцию, которая возвращает приветственную фразу со взятием имени из этого словаря: names = { 382: 'Alice', 590: 'Bob', 951: 'Dilbert' } def greeting(user_id): name = names.get(user_id, 'there')    return f'Hi {name}!' Смотрим на результат: greeting(382) # 'Hi Alice!' Вызов функции с аргументом в виде несуществующего в словаре ключа: greeting(0) # 'Hi there!'

Python имеет ужасную репутацию, когда речь идет о возможности параллельных вычислений. Не обращая внимания на типичные рассуждения о его потоках и GIL (который обычно нормально работает), реальная проблема многопоточности Python не техническая, а педагогическая. Распространенные руководства о библиотеках threading и multiprocessing в целом неплохие, но тяжеловаты для понимания. Именно по этой причине я написал статью в которой рассматриваются возможности multiprocessing, доступные каждому. Читать статью

Операции над множествами Set – множество, в котором отсутствуют повторяющиеся элементы: >>> a = set([1,2,3,4]) >>> b = set([3,4,5,6]) >>> a | b # объединение {1, 2, 3, 4, 5, 6} >>> a & b # пересечение {3, 4} >>> a < b # подмножества False >>> a - b # разница {1, 2} >>> a ^ b # симметрическая разность {1, 2, 5, 6}

Функция map На вход принимает два обязательных аргмумента: функция-обработчик и итерируемый объект, чаще всего это список. Суть map’a заключается в том, что он применяет переданную функцию к каждому элементу последовательности. А возвращает так называемый map-объект, который в дальнейшем можно конвертировать в обычный список и не только. def add_five(a): return a + 5 old_nums = [1, 2, 3, 4, 5] new_nums = map(add_five, old_nums) print(list(new_nums)) # Output: [6, 7, 8, 9, 10] Обратите внимание, мы не пишем скобки у функции add_five при вызове map – это означает то, что мы передаем объект функции, а не результат её выполнения. Тоже самое мы могли записать через анонимую функцию прямо в map'e. old_nums = [1, 2, 3, 4, 5] new_nums = map(lambda a: a + 5, old_nums) print(list(new_nums)) # Output: [6, 7, 8, 9, 10] Однако в данном примере нагляднее использовать генератор списка. old_nums = [1, 2, 3, 4, 5] new_nums = [a + 5 for a in old_nums] print(new_nums) # Output: [6, 7, 8, 9, 10] Хоть map и мощная функция, но лучше исходить от конкретных случаев. А вот вам действительно полезный пример из практики. Мы можем считать несколько чисел с консоли, которые вводят через пробел, разделив всё это функцией split. a, b, c = map(int, input().split())

Распознавание лиц и верификация пользователей по ним – будущее или уже существующая реальность? Даже больше, каждый уже может написать свою подобную программу. Это настолько просто, что требуется буквально двадцать строк кода и всего лишь полчаса времени для понимания. Читать статью

Заходит однажды тестировщик программного обеспечения в бар. Забегает в бар. Пролезает в бар. Танцуя, проникает в бар. Крадется в бар. Врывается в бар. Прыгает в бар. И заказывает 0 пива. Заказывает 99999 пив. Заказывает -1 пиво. Заказывает ящерицу в стакане. Заказывает "qwertyuiop". Заказывает одно пиво каждую милисекунду. Заказывает пиво, но отменяет заказ. Заказывает пиво вместе с 10000 посетителями одновременно. Заказывает пиво не заходя в бар. Заказывает drop table. А кульминация этого анекдота находится на моем новом канале @dank_code

Перечисления Python 3 поддерживает, благодаря классу Enum, простой механизм работы с перечислениями. Перечисления удобно использовать для хранения списков констант. Константы, в противном случае, оказываются беспорядочно разбросанными в коде. from enum import Enum, auto class Monster(Enum):    ZOMBIE = auto()    WARRIOR = auto()    BEAR = auto()     print(Monster.ZOMBIE) # Monster.ZOMBIE Из документации по Python 3 можно узнать о том, что перечисление — это набор символических имён, привязанных к уникальным, неизменным значениям. Члены одного перечисления можно сравнивать на идентичность. Перечисления можно обходить. for monster in Monster:    print(monster) # Monster.ZOMBIE # Monster.WARRIOR # Monster.BEAR

yield from Рассмотрим одну страшную конструкцию в Python 3.3+. Для начала напомню, генератор – это объект, который можно проитерировать только однажды. Записывается так: def gen():   for x in range(100):     yield x # Или покороче вот так f = (x for x in range(100))  Когда всего лишь один генератор – всё хорошо. Используем его как итератор и радуемся. Но не редки ситуации, в которых есть несколько генераторов: gen_1 = (x for x in range(5)) gen_2 = (x for x in range(5, 10)) И стоит задача – проитерировать сначала один генератор, потом второй. Но вернуть значения не в виде списка, а в виде нового генератора. Здесь на помощь приходит следующая конструкция: yield from <expr>, где <expr> - выражение, вычисление которого даёт итерируемый объект, из которого и вычленяется итератор.  Используя yield form, поставленная выше задача решается так: def generator(): yield from gen_1 yield from gen_2 gen = generator() И теперь можно просто проитерироваться по полученному генератору, в итоге получив результаты обоих первоначальных генераторов. Воспользуемся генератором списка, работа которого показана в предыдущем посте. result = [n for n in gen] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Генераторы коллекций В Python есть специальная конструкция, позволяющая быстрее и удобнее создавать заполненные коллекции на основе имеющихся, при этом применяя какое-либо выражение к каждому элементу. 1. Генератор списка (list comprehension) word = 'hello' new_list = [c.upper() for c in word] # ['H', 'E', 'L', 'L', 'O'] 2. Генератор множества (set comprehension) elements = [1, 2, 1, 3, 2] new_set = {n * 0.1 for n in elements} # {0.1, 0.2, 0.3} 3. Генератор словаря (dictionary comprehension) numbers = {'one': 1, 'two': 2, 'three': 3} new_dict = {v: k for k, v in numbers.items()} # {1: 'one', 2: 'two', 3: 'three'}

Генераторы Выглядят функции-генераторы также как и обычные, но содержат выражения с ключевым словом yield для последовательного генерирования значений, которые могут быть использованы в циклах for, либо их получения при помощи функции next. На каждой yield работа функции временно приостанавливается, при этом сохраняется состояние исполнения, включая локальные переменные, указатель на текущую инструкцию, внутренний стек и состояние обработки исключения. При последующем обращении к итератору генератора функция продолжает своё исполнение с места, на котором была приостановлена. Этим функции-генераторы отличаются от обычных функций, при вызове которых исполнение всякий раз начинается с начала. Если функция достигает инструкции return, либо конца, возбуждается исключение StopIteration и итератор исчерпывает себя. def generator(): for item in ('first', 'second', 'third'): yield item Теперь можно вызывать эту функцию и использовать функцию next. gen = generator() value = next(gen) print(value) # Output: first Достаточно часто, а точнее практически всегда, генераторы используют в циклах for. Преимущество такого подхода в том, что можно получить все возможные значения и не словить ошибку StopIteration. for item in gen: print(item, end=' ') # Output: second third Теперь если вызвать функцию next еще раз, то получим то самое исключение. next(gen) # Output: Traceback (most recent call last): File "main.py", line 12, in <module>   next(gen) StopIteration

Аннотации типов Всем известно, что Python – язык с динамической типизацией. Аннотации типов нужны для того, чтобы повысить информативность исходного кода, но они никак не влияют на поведение программы. Для примера потребуется импортировать типы List (список) и Dict (словарь) из модуля typing: from typing import List, Dict Типы данных указывается через двоеточие после именно переменной после её создания. Создадим словарь с числами и сразу же список, состоящий из значений этого словаря: numbers: Dict[str, int] = {'one': 1, 'two': 2} values: List[int] = numbers.values() Потом создадим функцию, возвращающую сумму переданных значений. В аргументах точно так же можно указывать их типы, а также через стрелочку можно указать типа возвращаемого значения: def sum(a: int, b: int) -> int: return a + b Теперь используем эту функцию, передав туда распакованный список: sum(*values) # Output: 3 Однако помните, что аннотации типов не влияют на ход исполнения программы, поэтому в ранее написаную функцию мы с таким же успехом можем передать и строки, хотя указывали целочисленный типа данных: sum('Python ', 'Lounge') # Output: 'Python Lounge'

Поясняю, это была не очередная реклама, а анонс нашего авторского совместного с @programming_python курса. Сфера чат-ботов активно развивается, однако разработчиков там не хватает, а платят очень даже неплохо. Так что советуем спешить, пока действует эксклюзивная скидка 20%, начало уже 1 сентября )

​​Telegram боты Простая в освоении и практически не занятая ниша – разработка чат-ботов для мессенджеров. Платят за одного такого в среднем от 5 до 20 тысяч рублей, а время создания занимает как правило всего лишь несколько дней.  1 сентября начинается 3-недельный курс по разработке Telegram ботов на Python от программистов с солидным опытом в этой сфере. Обучение будет происходить в закрытом канале. Базовый (1190 рублей) – доступ ко всему самому свежему и практичному материалу. Стандартный (1490 рублей) – добавляется доступ в чат, в котором появляется возможность получить кейсы от программистов с опытом, узнать вопросы на интересующие вопросы и получить помощь. Продвинутый (2190 рублей) – помимо всех перечисленных выше прелестей, у вас есть возможность получить личные консультации и код ревью от мастеров в своем деле. Для записи пишите в бота @bots_course_bot. Специально для подписчиков этого канала скидка 20% по промокоду PYTHONLOUNGE.

Форматирование строк В этом посте разберем доступные в Python методы форматирования строк. Для начала определим две переменные, которые потом и будем вставлять в строки. name = 'Adrian' age = 17 Самый древний и уже редко используемый способ – с помощью оператора %. Написание %s и %d зависит от того, что мы туда передаем и что хотим увидеть в итоге, но это уже тема отдельного поста. 'My name is %s and I am %d years old' % (name, age) В Python 2.6 появился метод .format() с немного отличающимся синтаксисом от существующего оператора %. К слову, этот метод активно используется и по сей день, в отличии от его предшественника. 'My name is {} and I am {} years old'.format(name, age) Начиная с версии Python 3.6, доступны f-строки – свежий и наиболее производительный способ форматирования строк. f'My name is {name} and I am {age} years old'

Изменение списка во время итерации по нему Предположим, что требуется удалить все нечетные числа из списка. Проблема со следующим кодом должна быть довольно очевидной: odd = lambda x: bool(x % 2) # функция проверки числа на нечетность numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] for i in range(10):   if odd(numbers[i]):     del numbers[i] # удаление элемента из списка во время итерации по нему # Output: Traceback (most recent call last): if odd(numbers[i]): IndexError: list index out of range Удаление элемента из списка во время его итерации – это проблема, которая хорошо известна любому опытному разработчику. К счастью, Python включает в себя ряд элегантных парадигм программирования, которые при правильном использовании могут привести к значительному упрощению и оптимизации кода. Одна из таких парадигм – list comprehensions. Генераторы списков часто используют именно для решение подобных проблем, что и показывает реализация кода ниже: odd = lambda x: bool(x % 2) # функция проверки числа на нечетность numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] numbers = [n for n in numbers if not odd(n)] # генератор нового списка print(numbers) # Output: [2, 4, 6, 8, 10]