Hello World – Telegram
Hello World
1.68K subscribers
71 photos
6 videos
3 files
161 links
Be so good that you cannot be ignored. And then, go one step beyond.
Download Telegram
Python’s slices

Срезы в листах Python могут быть использованы и без индексов
Вот несколько забавных и полезных вещей:

# Очистка всех элементов листа:
>>> lst = [1, 2, 3, 4, 5]
>>> del lst[:]
>>> lst
[]


# Замена всех элементов листа
# без создания нового объекта:
>>> a = lst
>>> lst[:] = [7, 8, 9]
>>> lst
[7, 8, 9]
>>> a
[7, 8, 9]
>>> a is lst
True


# Создание копии листа:
>>> b = lst[:]
>>> b
[7, 8, 9]
>>> b is lst
False


#tips #list
Argument unpacking

Небольшой пример того, почему пайтон так хорош:
def myfunc(x, y, z):
print(x, y, z)


tuple_vec = (1, 0, 1)
dict_vec = {'x': 1, 'y': 0, 'z': 1}


Теперь мы можем распаковать кортеж (да и любой другой итерируемый объект) с помощью оператора *
>>> myfunc(*tuple_vec)
1, 0, 1


Распаковка словарей происходит с помощью **
>>> myfunc(**dict_vec)
1, 0, 1


#tips
Collections

Находим наиболее часто встречающийся элемент в контейнере:

>>> import collections
>>> c = collections.Counter('helloworld’)


>>> c
Counter({'l': 3, 'o': 2, 'e': 1, 'd': 1, 'h': 1, 'r': 1, 'w': 1})


>>> c.most_common(3)
[('l', 3), ('o', 2), ('e', 1)]


#tips #collections
Permutations

itertools.permutations() генерирует перестановки, возвращая итерируемый объект. Полагаю, не надо объяснять как с их помощью вы можете сбрутить чей-то пароль?

>>> import itertools
>>> for p in itertools.permutations('ABCD'):
... print(p)

('A', 'B', 'C', 'D')
('A', 'B', 'D', 'C')
('A', 'C', 'B', 'D')
('A', 'C', 'D', 'B')
('A', 'D', 'B', 'C')
('A', 'D', 'C', 'B')
('B', 'A', 'C', 'D')
('B', 'A', 'D', 'C')
('B', 'C', 'A', 'D')
('B', 'C', 'D', 'A')
('B', 'D', 'A', 'C')
('B', 'D', 'C', 'A')
('C', 'A', 'B', 'D')
('C', 'A', 'D', 'B')
('C', 'B', 'A', 'D')
('C', 'B', 'D', 'A')
('C', 'D', 'A', 'B')
('C', 'D', 'B', 'A')
('D', 'A', 'B', 'C')
('D', 'A', 'C', 'B')
('D', 'B', 'A', 'C')
('D', 'B', 'C', 'A')
('D', 'C', 'A', 'B')
('D', 'C', 'B', ‘A’)


4! = 24

#tips #permutations
itertools

Допустим, мы хотим получить какой то конечный список элементов из бесконечного генератора. В модуле itertools есть удобная функция islice, позволяющая осуществить срез генератора fib.

from itertools import islice

def fib():
a, b = 0, 1
while True:
yield b
a, b = b, a + b

In : list(islice(fib(), 6))
Out: [1, 1, 2, 3, 5, 8]


#itertools
reduce

Продолжая тему itertools. Например, нужно написать функцию, которая принимает список чисел и перемножает их. То есть [1,2,3,4,5,6] даст 1*2*3*4*5*6.

📌Способ 1.

from functools import reduce

In : reduce(lambda x, y: x*y, [1, 2, 3, 4, 5, 6])
Out: 720


📌Способ 2.

import operator
import functools

In : functools.reduce(operator.mul, [1, 2, 3, 4, 5, 6], 1)
Out: 720


📌Способ 3.

import numpy as np

In : np.prod(np.array([1, 2, 3, 4, 5, 6]))
Out: 720


#tips #itertools #reduce
Что выведет следующий код?

In[1]: qwe = ‘qwe’
In[2]: qwe[0] = ‘a’
In[3]: print(qwe)
Правильный ответ

Строки — это неизменяемый тип данных, поэтому произойдет ошибка в строке 2 (простите за тавтологию). Когда вы пытаетесь сделать например вот это:
a = ‘a’
a += ‘b’


переменная a на второй строчке заменяется уже другой переменной.

📎изменять строки нельзя, можно только заменять их новыми

#string
Целые числа.

Пользователей Python зачастую привлекает его простота, важной частью которой является динамическая типизация. В то время как в языках со статической типизацией, таких как С, необъодимо явным образом объявлять все переменные, языки с динамической типизацией этого не требуют.
Например, в языке С можно описать операцию так:
int result = 0;
for(int i=0; i<100; ++i){
result += i;
}


На языке Python это запишется так:
result = 0
for i in range(100):
result += i


Главное отличие: в языке С типы данных каждой переменной объявлены явным образом.
В Python мы можем сделать так:
x = 4
x = “four”


В С это могло бы привести к ошибке компиляции или же неопределенному поведению:
int x = 4;
x = “four” // сбой


Подобная гибкость делает Python таким удобным и простым в использовании. Однако такая гибкость при работе с типами указывает на то, что переменные Python представляют собой нечто большее, чем просто значение, они содержат также информацию о типе значения.

Стандартная реализация языка Python написана на С. Это значит, что каждый объект Python — замаскированная структура С. Посмотрев на исходный код Python 3.4, можно узнать что описание целого типа (long), фактически выглядит так:
struct _longobject {
long ob_refcnt;
PyTypeObject *ob_type;
size_t ob_size;
long ob_digit[1];


Отдельное целое число в языке Python 3.4 состоит из 4 частей:
📌 ob_refcnt - счетчик ссылок, с помощью которого происходит выделение и освобождение памяти
📌 ob_type - тип переменной
📌 ob_size - задает размер следующих элементов данных
📌 ob_digit - содержит фактическое целочисленное значение

Это значит, что существует некоторая избыточность при хранении целого числа в языке Python по сравнению с целыми числами в компилируемых языках.
📎 Целое число в Python — указатель на место в памяти, где хранится вся информация об объекте, включая байты, содержащие само целочисленное значение.
📎 Это влечет за собой последствия в виде дополнительных расходов памяти и/или вычислительного времени, что становится заметно в структурах, объединяющих значительное количество таких объектов.
# Python 3 имеет модуль
# для работы с ip адресами:

>>> import ipaddress

>>> ipaddress.ip_address('192.168.1.2')
IPv4Address('192.168.1.2')

>>> ipaddress.ip_address('2001:af3::')
IPv6Address('2001:af3::’)


# Подробности здесь:
# https://docs.python.org/3/library/ipaddress.html
Теоретический_миниму.pdf
10.3 MB
Отличная книга по CS, рекомендую к прочтению.
Luhn algorithm

Алгоритм Луна — алгоритм вычисления контрольной цифры номера пластиковой карты. Не является криптографическим средством, а предназначен в первую очередь для выявления ошибок, вызванных непреднамеренным искажением данных (например, при ручном вводе номера карты).

📎 Алгоритм разработан сотрудником фирмы IBM Гансом Питером Луном.

Наиболее распространённые применения для подсчёта контрольной цифры:
• Номера всех банковских карт
• Номера некоторых дисконтных карт
• Коды социального страхования
• IMEI-коды.
• Расчёт контрольного знака единого 8-значного номера железнодорожного вагона на РЖД.
• Расчёт ICCID — уникальный серийный номер SIM-карты.

Оригинальный алгоритм, описанный разработчиком:
📌Шаг 1.
Цифры проверяемой последовательности нумеруются справа налево.

📌Шаг 2.
Цифры, оказавшиеся на нечётных местах, остаются без изменений.

📌Шаг 3.
Цифры, стоящие на чётных местах, умножаются на 2.

📌Шаг 4.
Если в результате такого умножения возникает число больше 9, оно заменяется суммой цифр получившегося произведения — однозначным числом, то есть цифрой.

📌Шаг 5.
Все полученные в результате преобразования цифры складываются. Если сумма кратна 10, то исходные данные верны.

Попробуем реализовать его на Python.
for i in range(len(digits) - 1, -1, -1):
for c in str((double + 1) * int(digits[i])):
total += int(c)
double = (double + 1) % 2

Основных циклов два. Первый пробегает по всем цифрам в номере (справа налево), второй отвечает за умножение на 2 цифр, стоящих на четных позициях. Переменная total отвечает за сумму цифр — контрольное число.

Вся функция целиком.
def validate_card(card_num):
"""
Input: Card number, integer or string
Output: Valid?, boolean
"""
double = 0
total = 0

digits = str(card_num)

for i in range(len(digits) - 1, -1, -1):
for c in str((double + 1) * int(digits[i])):
total += int(c)
double = (double + 1) % 2

return (total % 10) == 0


#algorithms #python
# Ты можешь проверить наследование
# в классах с помощью встроенной
# функции issubclass()

>>> class BaseClass: pass
>>> class SubClass(BaseClass): pass


>>> issubclass(SubClass, BaseClass)
True
>>> issubclass(SubClass, object)
True
>>> issubclass(BaseClass, SubClass)
False


#tips
Давно не было новостей.

Во-первых, мы создали бота @ninebetbot. Да, это ставки. Нет, это не реклама. Это полностью созданный нами продукт и я ни копейки не получу за такую “рекламу”, увы. Это был очень интересный опыт работы с различными платежными системами, парсерами, веб-хуками и базами данных. В своей разработке мы использовали апи QIWI как наиболее простую платежную систему. Плюс базы данных mongodb и sqlite3. Можете потыкаться, буду вам очень признателен, если вы все перейдете в бота, а мы в свою очередь проверим его стрессоустойчивость.

Во-вторых, я помню многие из вас жаловались на отсутствие денег. Python разработка открывает перед вами целое многообразие возможностей, одной из которых является разработка ботов в телеграме, а другой — заработок на трейдинге криптовалют. Для последней нужны хорошие знания data science, умение анализировать, а также некоторые знания из математики и статистики. Да и в принципе это довольно таки интересно. В телеграме полно каналов по крипте и “заработку” на ней, и я не собираюсь превращать свой канал в подобие этого. Однако, я могу разбирать некоторые алгоритмы, относящиеся к торговле, на языке Python. Если вам это интересно, прожмите огонек под постом.

В-третьих, для людей, которым торговля не интересна от слова совсем, мы собираемся создать специального бота для обучения написанию собственных ботов и для их монетизации. В планах это давно есть, но пока нет времени. Если вам это интересно, поставьте огонек под постом.
Else в циклах for

# Циклы for и while в Python
# поддерживают кляузу else
# только если цикл завершается
# без вызова break
def contains(haystack, needle):
"""
Бросаем ValueError если needle не
находится в haystack.
"""
for item in haystack:
if item == needle:
break
else:
# else здесь выполнится только
# если цикл не будет прерван break
raise ValueError('Needle not found')


Вывод:
>>> contains([23, 'needle', 0xbadc0ffee], 'needle')
None


>>> contains([23, 42, 0xbadc0ffee], 'needle')
ValueError: "Needle not found"



# Хотя использование else в циклах
# не запрещается, можно написать так
def better_contains(haystack, needle):
for item in haystack:
if item == needle:
return
raise ValueError('Needle not found')


# Но если вы хотите писать более
# ‘Pythonic’, лучше всего будет сделать так
if needle not in haystack:
raise ValueError('Needle not found’)