Содержание статьи
От редакции
Недавно мы проводили опрос о том, какой курс по 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')
Отпишись в комментариях, если статья оказалась полезной!
Если тема окажется востребованной, то в следующей статье мы подробно рассмотрим работу со строками, файлами, заглянем в интернет, а также снова побалуемся написанием максимально простых хакерских скриптов.
