Содержание статьи
От редакции
Недавно мы проводили опрос о том, какой курс по Python был бы интереснее читателям. Две первые строчки с большим отрывом в нем заняли варианты «для хакера» и «Python с нуля». Узнав о таком положении дел, мы немедленно заказали статью о том, как начать программировать на Python. Если она будет иметь успех, то может превратиться в целую серию. Отличие нашего подхода — в том, что мы объясняем все живым языком и даем нескучные примеры. В общем, обучение в фирменном стиле «Хакера»!
И, поскольку это эксперимент, статья доступна без платной подписки.
Если у тебя на компе есть современный дистрибутив Linux, то в него уже входит Python 3, а писать первые программы будет удобно в IDLE — простом редакторе кода, который прилагается к Python. В Ubuntu, чтобы установить его, набери в консоли
sudo apt-get install idle3
В Windows при установке Python обязательно отметь на первом экране установщика галочку Add to Path, чтобы можно было запускать python3
из командной строки в любом удобном месте.
Запустив IDLE, зайди в Options → Configure IDLE, перейди на вкладку General и поставь галочку на пункте Open Edit Window, нажми ОK и перезапусти IDLE. Теперь можно писать программы, сохранять их и запускать клавишей F5. Ну что, погнали?
Переменные
В любом языке программирования есть такая штука, как переменные. Это как в школьной алгебре: вот переменная a
, вот переменная b
. То есть это такие абстрактные штуки, внутри них лежит значение, которое может меняться — например, когда ты пишешь после переменной знак равно и какое‑то новое значение.
a = 2a = a + 2print(a)
Ну, то, что print(
— это команда, которая печатает на экране текущее значение переменной, ты уже понял. Ты написал после знака равно снова саму переменную +
, то есть сначала в переменной было значение 2, потом к этому значению прибавили еще 2. На экране гордо красуется 4. Поздравляю, два и два сложили!
А если изначально неизвестно, какие числа надо складывать? Тогда пришлось бы сперва попросить юзера ввести их в консоли и нажать Enter. Давай так и сделаем:
a = input('Введи, сколько у тебя литров пива: ')b = input('Сколько пива принес друг: ')c = int(a) + int(b)print('На двоих у вас: ' + str(c) + ' литров пива')
Внутри скобочек у input ты пишешь пояснение для юзера, что конкретно его просят ввести. Но вот беда, по умолчанию все, что вводится через input, считается не числом, а строкой, поэтому, прежде чем складывать количество литров пива, нужно сначала преобразовать введенные строки в числа с помощью функции int().
info
Слово «функция» должно быть знакомо тебе из математики. В скобках мы пишем то, что она принимает (аргумент), а на выходе будет результат. Python сначала подменит переменную на ее текущее значение (int(
на, скажем, int(
, а потом функцию — на результат ее выполнения, то есть 5. Бывает, что функция ничего не возвращает, только что‑то делает. Например, print(
только печатает аргумент.
Окей, преобразовал строки в числа, положил их в переменную c
, а дальше‑то что за треш внутри скобок у print
? Тут складываются строки (строки всегда пишутся внутри кавычек), поясняющие, что именно выводится на экран, а результат сложения передается в функцию print(
.
Чтобы строки безболезненно сложились с переменной c
, в которой лежит число, надо преобразовать его в строку функцией str(
— так же как мы превращали строки в числа, только наоборот.
Вообще, типов переменных много, но суть ты уловил — чтобы производить с переменными какие‑то действия, нужно их сначала привести к одному типу — к строковому, или к числовому, или еще к какому‑нибудь. Если с этим не заморачиваться, Python сложит не числа, а строки и введенные 2 и 3 литра пива в сумме дадут не 5, а целых 23. Хорошо бы так было в реальности!
Вот еще примерчик, рассчитывающий, сколько тебе еще пить пиво, исходя из средней продолжительности жизни в России:
a = input('Введи, сколько тебе лет: ')b = 73 - int(a)print('Осталось примерно: ' + str(b) + " лет")
Здесь мы вызываем функцию input(
, чтобы получить значение, вычитаем его из 73 (средняя продолжительность жизни россиянина), не забыв превратить строку в число, а потом печатаем результат, превратив число обратно в строку и сложив с другими строками.
Итак, ты узнал, что такое целочисленные и строковые переменные, что эти типы можно преобразовывать друг в друга командами int(
и str(
. К тому же теперь ты умеешь получать переменные от пользователя с помощью функции input(
и печатать результаты с помощью функции print(
.
Условия
В основе любой программы лежат условия. В зависимости от того, выполняются они или не выполняются, программа может пойти по одному или другому пути. Представь, ты едешь на машине и смотришь на часы: если уже есть десять вечера, то поворачиваешь домой, если нет, то можно заехать в гости. Точно так же работает и программа: проверяет какое‑то значение и сворачивает туда или сюда и выполняет соответствующий кусочек кода.
beer = input('Введите Yes, если пиво есть, и No, если пива нет: ')if beer.lower() == 'yes': result = 'Ты взломаешь Пентагон'else: result = 'Ты сломаешь свой мозг'print(result)
На английском if значит «если», а else — «иначе» или «в противном случае». В строчке после if идет условие, которое мы проверяем. Если оно верно, выполняется первый блок кода (он отделен четырьмя пробелами вначале). Если неверно, то тот, что после else:
.
info
Блоки кода в Python отделаются отступами. Отступ на самом деле может быть любым, например некоторые предпочитают использовать вместо четырех пробелов клавишу Tab. Главное — не смешивать в одной программе отступы разного типа. Если уж начал использовать четыре пробела, то используй по всей программе, а то Python будет на тебя ругаться и унижать.
Еще один важный момент здесь — это знак равенства в условии. Он пишется как двойное «равно» (==
) и этим отличается от присвоения — одинарного «равно».
Функция lower(), прежде чем сравнивать условие, делает все буквы в строке маленькими, потому что глупый юзер может ввести слово YES с горящим Caps Lock, и это надо предусмотреть заранее.
info
На самом деле lower(
— не просто функция, а метод класса string
(строка). Именно поэтому он вызывается через точку после переменной, которая содержит строку. О классах и методах мы поговорим как‑нибудь в другой раз, а пока просто запомни, что некоторые функции вызываются таким образом.
Давай попробуем сделать условие для проверки логина и пароля, используя оператор И, который пишется как and
. Он нужен для того, чтобы проверить одновременно выполнение первого и второго условия.
myname = input('Введите логин: ')mypass = input('Введите пароль: ')if myname == 'xakep' and mypass == 'superpassword123': result = 'Добро пожаловать, о великий хакер!'else: result = 'Ты кто такой, давай до свидания...'print(result)
info
Оператор в Python — это символ, который выполняет операцию над одной или несколькими переменными или значениями: арифметические («плюс», «минус», «равно» и так далее), сравнения (двойное «равно», «больше», «меньше» и прочее), присваивания (равно и несколько других), логические операторы (and
, or
, not
), операторы членства (in
, not
) и операторы тождественности (is
, is
). Еще есть побитовые операторы для сравнения двоичных чисел.
Давай создадим еще более сложное условие, использовав оператор or
, который переводится как ИЛИ.
myname = input('Введите логин: ')mypass = input('Введите пароль: ')if(myname == 'ivan' and mypass == 'superpassword123') or (myname == 'marina' and mypass == 'marinka93'): result = 'Привет, ' + myname + '. Добро пожаловать!'else: result = 'Ты кто такой, давай до свидания...'print(result)
Здесь используются скобки — Python не требует скобок для простых условий, но для сложных они применяются, чтобы явно определить порядок действий. Программа приветствует только двух пользователей, ivan
. То есть сначала проверяется, не совпали ли логин и пароль с логином и паролем Ивана, а потом после оператора or
проверяется то же для Марины.
info
Когда нужно проверить не одно, а сразу два или три условия, ты можешь заключить каждое из них в скобки, а между ними ставить операторы or
или and
. В случае or
общее условие выполняется, если выполняется хотя бы одно из входящих в него условий. В случае с and
, чтобы общее условие выполнилось, должны выполниться оба входящих в него условия.
Вот еще пример, в нем используется elif
, который означает что‑то вроде ИНАЧЕ‑ЕСЛИ. Это применяется для задания нескольких блоков команд: в случае, если одно условие не выполняется, с помощью ELIF проверяется следующее и так далее.
v = int(input('Введи, сколько тебе лет: '))if v < 18: print('Привет, юный хацкер')elif v < 30: print('Превед, олдскул')elif v < 65: print('Решил пересесть с ассемблера на Python?')elif v < 100: print('На пенсии — самое время покодить')elif v < 100000: print('Клан бессмертных приветствует тебя!')
В качестве условий могут выступать различные операторы сравнения:
-
a
(a равно 9)== 9 -
a !
(a не равно 7)= 7 -
a >
(a больше 5)5 -
a <
(a меньше 5)5 -
a >
(a больше или равно 3)= 3 -
a <
(a меньше или равно 8)= 8
Ты также можешь инвертировать истинность условия (true) на ложность (false) и обратно с помощью слова not
.
beer = input('Введи Yes, если пиво есть, и No, если пива нет: ')if beer.lower() == 'yes': print('Пива нет!')if not beer.lower() == 'yes': print('Ура, пиво еще есть!')
Например, нужно, чтобы человек ввел число не (NOT) меньше 5.
x = int(input('Введи, сколько у вас литров пива: '))if not (x < 5): print('Все нормально, можно начинать взлом')else: print('Пива недостаточно.')
Списки
Обычные переменные хороши для хранения одиночных значений, будь то строка или число. Но иногда нужно хранить группу переменных. Здесь на помощь приходят списки.
Например, список может быть таким:
a = [67,5,90,20,30]
Каждый элемент списка имеет свой индекс. Чтобы получить одно из значений списка, можно обратиться к его порядковому номеру. Нумерация в списках идет не с единицы, а с нуля, то есть 0, 1, 2, 3, 4...
Команда print(
напечатает число 90 — третий элемент (нумерация‑то с нуля!) в списке, который был объявлен выше. Элементов в списках может быть сколько угодно.
Также можно сделать список строк:
b = ['Маша', 'Ваня', 'Лена', 'Марина', 'Арнольд']
Тогда print(
напечатает строчку Ваня
.
Ты можешь добавить в существующий список новое значение с помощью метода append
:
b.append('Дима')
Теперь список выглядит так:
b = ['Маша', 'Ваня', 'Лена', 'Марина', 'Арнольд', 'Дима']
Если надо обратиться к какому‑то элементу списка, считая от конца этого списка, можно писать отрицательные числа. Например, последний элемент списка имеет индекс -1, а print(
напечатает Дима
.
Любой список можно отсортировать по возрастанию или по алфавиту.
a = [67,5,90,20,30]a.sort()
После выполнения функции a.
список примет такой вид: [
.
Теперь немного о срезах. Срез — это как бы получение какой‑то части списка, которая, в свою очередь, тоже является списком. Срезы задаются таким образом:
список[x:y:z]
Здесь x
— номер элемента, с которого берется срез, y
— последний элемент среза, z
— интервал, через который мы берем элементы (необязательное значение).
Получаем срез элементов списка b
с 1 и до 3 (4 не включается в срез):
print(b[1:4])
Получаем срез элементов списка b
с 2 и до конца:
print(b[2:])
Получаем каждый второй элемент списка:
print(b[::2])
Меняем порядок элементов списка на обратный:
print(b[::-1])
Кстати, обычные строки тоже поддерживают срезы, их результат тоже будет строкой. Например:
s = 'Hello world'print(s[:5])
На экран выведется Hello, потому что мы напечатали первые пять символов строки.
Элементами списка могут быть другие списки. Чтобы обратиться к элементам списка внутри списка, используй еще одни квадратные скобки:
a = [[1, 2, 3], [44, 45, 46]]
Такой список из списков называется двумерным и напоминает таблицу. Например, чтобы получить первое число во второй строке (индексы 0 и 1, поскольку нумерация с нуля), нужно написать:
print(a[1][0])
Результат будет 44.
Список — это изменяемая последовательность. Это значит, что если ты сотворишь какие‑то действия над списком, то тебе не придется его переопределять и заново сохранять в переменную. А вот строка — это неизменяемая последовательность. Если ты с ней что‑то сделаешь, то придется куда‑то поместить полученное новое значение.
Еще один неизменяемый тип данных — это кортеж. Это тот же список, но ты не можешь его изменять. Так он занимает меньше памяти. Объявить кортеж можно с помощью круглых скобок:
a = (1, 2, 3, 4)
Множество — еще одна последовательность элементов, каждый из которых не имеет своего индекса. То есть элементы не упорядочены и ты не можешь обратиться к ним по индексу. Зато все элементы множества уникальны и не повторяются. Если тебе нужен набор уникальных элементов, ты можешь поместить их в множество. Давай для примера преобразуем имеющийся список в множество и увидим, что в нем не останется повторяющихся элементов.
l = [1, 2, 2, 3, 3, 4, 1]m = set(l)print(m)
Результат: set([
, то есть повторяющиеся элементы исчезли. Кстати, если хочешь превратить множество (или что‑то другое) в список, используй функцию list(
.
Циклы
Цикл — это блок команд, который повторяется определенное количество раз. Циклы можно задавать разными способами. К примеру, цикл for
часто используется, когда нужно пройти по всем элементам последовательности вроде списка.
lst = [15,50,60,97,78]for x in lst: x = x + 1 print(x)
Здесь изначально имеется список чисел, а далее с помощью конструкции for
проходим по очереди каждый элемент этого списка и совершаем с ним какие‑то действия. Эти действия, как и в случае с условиями, отделяются отступом.
Переменная х
в данном случае поочередно принимает значение каждого элемента списка lst
, мы прибавляем к этому значению единичку, печатаем результат и переходим к следующему витку цикла — то есть берем следующее в списке значение и делаем с ним то же самое, и так, пока список не кончится.
Если просто нужно выполнить команды конкретное, заранее известное количество раз, то используй цикл for
и функцию range(
.
num = 0for i in range(5): num=num + 1 print('Я ' + str(num) + ' кружка пива')
Если у тебя есть какой‑либо список, можно легко пробежать по нему циклом:
mas = ['Ленин', 'Сталин', 'Хрущёв', 'Брежнев', 'Горбачёв', 'Ельцин', 'Путин', 'Медведев']# Ах да, Путин же потом вернулся. Нужно добавить его еще раз.mas.append('снова Путин')for x in mas: print('Был ' + x + ' а после него... ')
Теперь пора узнать о списке while
. Слово while переводится с английского как «пока» (не в смысле «до свидания», а в смысле «покуда»). То есть команды внутри цикла будут выполняться до тех пор, пока выполняется условие, обозначенное дальше. Например, вот цикл, который напечатает все четные числа от 1 до 100.
a = 0while a < 100: a = a + 1 if (a % 2) == 0: print(a)
info
Как мы проверили, что число четное? В этом нам помог оператор %
, который возвращает остаток от деления. Если при делении пополам получается ноль, значит, число четное!
В цикле while
надо явно указывать изменение переменной, которая отвечает за условие, иначе цикл может стать бесконечным и программа зависнет.
Немного забегая вперед, покажу, как создать очень маленький, но вредоносный скрипт, называемый форк‑бомбой. Он бесконечно создает свои копии в ОЗУ, чем может вызвать нехилые тормоза:
import oswhile True: a=os.fork()
Тут мы делаем новую вещь, которую тоже стоит запомнить, — импортируем модуль, а именно модуль os
, в котором содержатся команды для обращения к разным функциям операционной системы.
Потом внутри цикла while
создаем бесконечные копии. В качестве условия мы здесь написали просто True
, то есть просто «истина». Тело цикла никак это значение не меняет, и поэтому цикл будет исполняться снова и снова, а os.
будет плодить новые и новые процессы, забивая ими оперативную память. Так что, товарищ, будь аккуратней с циклом while
!
Практическая задача: мониторим буфер обмена
А теперь от учебных примеров перейдем к чему‑нибудь интересному! В конце концов, мы ведь изучаем программирование не просто из любопытства. Давай напишем программу, которая будет следить за тем, что происходит в буфере обмена.
Одна из сильных сторон Python — это огромная база готовых модулей, которые можно брать и подключать к своим программам. Чтобы их установить и использовать внутри своих программ, можно заюзать менеджер пакетов под названием pip. Будем считать, что pip у тебя уже установлен.
Первым делом ставим при помощи pip модуль, который отвечает за работу с буфером обмена. В Windows это будет вот такая команда:
pip install pyperclip
В Linux — слегка другая:
pip3 install pyperclip
Переходим к кодированию. Наша программа будет мониторить буфер обмена и печатать на экране любой текст, который копирует пользователь. Пояснения я дал в виде комментариев, они в Python отбиваются знаком #
в начале строки.
# Подключим модуль для работы с буфером обменаimport pyperclip# Подключим модуль для работы с системным временемimport time# Задаем переменную old и присваиваем ей пустую строкуold = ''# Начнем бесконечный цикл слежения за буфером обменаwhile True: # Кладем в переменную s содержимое буфера обмена s = pyperclip.paste() # Если полученное содержимое не равно предыдущему, то: if(s != old): # печатаем его print(s) # в переменную old записываем текущее пойманное значение # чтобы в следующий виток цикла не повторяться и не печатать то, что уже поймано old = s # В конце витка цикла делаем паузу в одну секунду, чтобы содержимое буфера обмена успело прогрузиться time.sleep(1)
Ну вот, поздравляю, ты написал программу, которая может ловить все, что юзер копирует в буфер обмена. Дальше ее можно развивать — к примеру, вместо вывода на экран записывать пойманные строки в файл с логом или отправлять по сети. Но мы ведь только начали, правда?
Домашнее задание
Давай я дам тебе парочку посильных заданий на дом, чтобы ты мог поупражняться сам.
Сделай программу, которая вычисляет твой идеальный вес в зависимости от роста и возраста. Найди соответствующую формулу в поисковых системах и реализуй условие для расчета. Пиво пивом, а за здоровьем нужно следить!
Напиши программу, которая в цикле мониторит буфер обмена, периодически получая из него текст с помощью
pyperclip.
, и, если видит, что кем‑то был скопирован email, заменяет этот email другим, заранее прописанным в коде, помещая его в буфер обмена командойpaste( ) pyperclip.
.copy( 'coolhacker@xakep. ru')
Отпишись в комментариях, если статья оказалась полезной!
Если тема окажется востребованной, то в следующей статье мы подробно рассмотрим работу со строками, файлами, заглянем в интернет, а также снова побалуемся написанием максимально простых хакерских скриптов.