Программирование на языке Python: младшая группа¶
Введение: объекты, переменные, основы ввода и вывода данных¶
Основные определения¶
- Интерпретатор
Программа, реализующая построчный анализ, обработку и выполнение исходного кода программы.
- IDLE (читается — айдл)
(Integrated Development and Learning Environment) — это интегрированная среда разработки и обучения на языке Python.
Данные в языке Python представлены в форме объектов.
Каждый объект имеет идентификатор, тип и значение.
- Литерал
Форма записи для «фиксированного» представления значения объекта. Примеры литералов:
42
,4.2
,"Hello, World!"
.- Идентификатор
Однозначно идентифицирует объект. Его можно считать адресом области в памяти компьютера, где хранится объект.
- Тип данных
Тип определяет возможные значения и их смысл, операции, а также способы хранения значений типа.
- Переменная
Именованная ссылка на конкретный объект.
Оператор присваивания связывает переменную и объект. Пример:
>>> x = 5Первую привязку переменной к объекту в программе называем определением и инициализацией переменной.
Базовые конструкции языка¶
Вывод на экран: print¶
Функция print позволяет вывести любое сообщение на экран. Для этого нужно в скобках указать сообщение или переменную с данными:
print("Привет мир!") message = "Hello world!" print(message)В результате будет выведено 2 приветствия мира на разных языка
Также можно передавать несколько параметров, чтобы вевести их друг за другом в одной строке:
a = 2 print(1, a, 3)
Переменные¶
Переменные позволяют записывать в себя значение, чтобы после этого им можно было пользоваться в любом месте программы:
a = "Hi!" print(a) print(a)Полезным свойством является возможность изменения значения в одном месте, чтобы изменить поведение всей программы
Ввод данных: input¶
Функция
input
используется для получения данных от пользователя:x = input() print("Hi,", x)Чтобы пользователь знал, что его просят ввести, можно предоставить строку приглашения:
name = input("Введите имя: ") print("Привет,", name)Если хотим работать с данными как с числами, нужно использовать функцию
int
:age = int(input("Введите ваш возраст: ")) print("Сейчас вам", age, "лет")
Арифметические действия¶
В питоне можно производить арифметические вычисления:
a = 12 b = 3 print(a + b) # 15 print(a - b) # 12 print(a * b) # 36 print(a / b) # 4
Цикл for¶
Цикл позволяет многократно повторять какое-либо действие:
for i in range(4): print("Сообщение в цикле!") print("Вышел из цикла!")В данном случае мы просим 4 раза вывести первое сообщение на экран и после этого вевести второе сообщение. Результат будет следующим:
Сообщение в цикле! Сообщение в цикле! Сообщение в цикле! Сообщение в цикле! Вышел из цикла!
Turtle¶
Черепашья графика впервые появилась вместе с языком Logo (1967 г.) и являлась его частью. Суть заключается в наличие исполнителя черепашки, который может передвигаться в разных направлениях и оставлять за собой след
Пример рисования треугольника:
from turtle import * color("blue") forward(100) left(120) forward(100) left(120) forward(100) done()Для создания сложных фигур можно использовать циклы:
from turtle import * for i in range(5): fd(100) lt(72) done()
Управление пером¶
Задачи¶
Напишите программу, которая будет говорить, сколько вам будет лет в следующем году. Она должна получить на вход ваш текущий возраст
Написать алгоритм для черепашки, который будет рисовать правильный многоугольник. На вход программа должна принимать сколько сторон должно быть у фигуры.
Написать программу для рисования круга
Домашнее задание¶
Установить Python на домашний ПК. Официальный сайт: https://www.python.org/
Реализовать приложение для вычисления периметра и площади прямоугольника. Приложение запрашивает у пользователя два целых числа — длины сторон прямоугольника. Пример работы приложения:
Input a: 5 Input b: 4 P = 18 S = 20
Функции¶
Функции – это многократно используемые фрагменты программы. Они позволяют дать
имя определенному блоку команд для того, чтобы выполнять этот блок поуказанному
имени в любом месте программы и сколь угодно много раз. Это называется вызовом
функции. Мы уже использовали встроенные функции: print
, input
, fd
.
Пример создания функции:
def say_hello():
print('Hello')
say_hello() # вызов функции
say_hello() # ещё один вызов функции
Параметры функций¶
Функции могут принимать параметры, т.е. некоторые значения, передаваемые функции для того, чтобы она что-либо сделала с ними.
Параметры указываются в скобках при объявлении функции и разделяются запятыми. Аналогично мы передаём значения, когда вызываем функцию. Обратите внимание на терминологию: имена, указанные в объявлении функции, называются параметрами, тогда как значения, которые передаются в функцию при её вызове – аргументами.
Пример:
from turtle import *
def star(s):
for i in range(5):
fd(s)
lt(144)
star(200) # вызов функции с аргументом s = 200
Управление черепашкой¶
-
goto
(x, y)¶ Перемещает черепашку в заданные координаты. Если перо опущено, черепашка будет оставлять след при перемещении
-
begin_fill
()¶ Заставляет черепашку начинать отслеживать замкнутые фигуры
-
end_fill
()¶ Закрашивает все замкнутые фигуры, которая создала черепашка при рисовании
-
pencolor
(color)¶ Устанавливает цвет следа черепашки в
color
-
fillcolor
(color)¶ Устанавливает цвет закрашивания фигур черепашкой в
color
Задачи¶
Напишите функцию для рисования треугольника.
Создадите функцию, которая будет рисовать закрашенный треугольник
Напишите функцию
sgoto(x, y)
, которая будет перемещать черепашку в заданные координаты, так чтобы при этом она не оставляла следОбъединив функции выше, нарисуйте еловый лес
Нарисуйте пейзаж ночного леса со звёздным небом и луной
Домашнее задание¶
Напишите программу, которая будет рисовать правильный шестиугольник из шести правильных треугольников. Создание треугольника вынести в отдельную функцию, рисовать шестиугольник через цикл
Нарисуйте улыбающийся смайлик. Для этого вынесите в отдельную функцию рисование круга заданного размера.
Ветвление¶
Ветвления это способ изменить поведение программы в завивимости от каких-либо условий. Например, если пользователь ввёл логин и пароль, мы можем пустить его дальше, иначе мы просим ввести его данные заново:
login = input("Логин: ")
password = input("Пароль: ")
if len(login) > 6 and len(password) > 8:
print("Приветствуем!")
else:
print("Введите данные полностью")
Здесь мы просим пользователя ввести свой логин и пароль. Пока что ограничимся простой проверкой - если длина логина больше шести символов и вместе с этим длина пароля больше восьми, мы его приветствуем.
Здесь есть сразу несколько новых вещей, во первых это len
, во вторых это
главное за чем мы здесь собрались - конструкция ветвления.
-
len
(s)¶ Возвращает длину переданной строки:
word = "Condition" word_length = len(word) print(word_length)
Условный оператор¶
Условный оператор позволяет выполнить какое-либо действие если выполняется
условие. В результате проверки порождается особый тип данных bool
булевый.
Данный тип способен принимать всего 2 значения - истина и ложь.
>>> 20 > 15
True
>>> 20 < 15
False
Оператор if
проверяет условие и если оно истинно, выполняет действие:
price = 32.5
cash = 50
if cash > price:
print("Вам хватит денег для покупки")
Блок else
выполняется в том случае, если результат проверки оказался ложным:
your_age = int(input("Введите ваш возраст: "))
required_age = 18
if your_age < required_age:
print("Вы слишком юны для вождения автомобиля")
else:
print("Вы можете водить автомобиль")
Блок elif
выполняется если предыдущая проверка не увенчалась успехом, но
есть ещё другие варианты проверок. В данной программе предлагается ввести
имеющееся у вас количество денег чтобы узнать что стоит покупать:
cash = int(input("Введите имеющееся количество денег: "))
if cash > 100:
print("Купить шоколадку")
elif cash > 50:
print("Купить чипсы")
else:
print("Не брать ничего")
Здесь программа просит вас ввести ваш возраст возраст и говорит, можно ли вам
водить автомобиль. Когда введёте число, будет произведена проверка - если
ваш возраст меньше 18, результат будет истина и тогда выполнится код,
написанный внутри блока if
. Если же вы ввели число 18 или больше, то в
результате проверки получится ложь и тогда выполнится код внутри блока else
.
Объединение проверок¶
Если мы с вами хотим проверить несколько вещей и на их основе выполнить
действие, то нам придётся использовать 2 ключевых слова: and
и or
.
Они позволяют объединить результаты нескольких проверок вместе. Например,
если пользователь вводит или свою почту или номер телефона, он будет получать
уведомления с новостями:
email = input("Введите электронную почту: ")
phone = input("Введите номер телефона:")
if len(email) > 8 or len(phone) > 10:
print("Мы уведомим вас о наших обновлениях")
else:
print("Мы не сможем уведомить вас, поскольку не знаем ваших данных")
Логическое «И» (конъюнкция, логическое умножение)
A |
B |
A and B |
---|---|---|
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
Логическое «ИЛИ» (дизъюнкция, логическое сложение)
A |
B |
A or B |
---|---|---|
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
Логическое «НЕ» (инверсия, отрицание)
A |
not A |
---|---|
0 |
1 |
1 |
0 |
Задачи¶
Получить от пользователя число и сообщить является оно положительным, отрицательным или нулём.
Фирма набирает сотрудников и ей нужны молодые кадры со стажем. Возраст от 20 лет, стаж от трёх. Приложение запрашивает у пользователя его возраст и стаж и говорит, подходит ли тот под требования фирмы.
Написать программу, которая будет запрашивать у пользователя 6 раз направление движения и передвигать черепашку в указанном направлении. Должны поддерживаться команды “вверх”, “вниз”, “влево”, “вправо”. Для реализации движения в заданных направлениях предлагается создать соответствующие функции. Для установки нужного угла использовать функцию
seth(angle)
.Пользователь вводит номер месяца, приложение сообщает, какое это время года. Весна (3,4,5), лето (6,7,8), осень (9,10,11) зима (12,1,2)).
Пример:
Номер месяца: 6 Лето Номер месяца: 12 Зима Номер месяца: 13 Такого месяца нет
Списки¶
Список - изменяемая упорядоченная коллекция объектов
Работа со списками¶
Для создания списков имеется специальный синтаксис:
s = [1, 2, 3, 4, 5, 6]
print(s)
Здесь мы создаём список из шести элементов - чисел от 1 до 6 и выводим его.
Основные методы работы со списками¶
-
s[i]
Обращение к элементу под индексом
i
в спискеs
. Индексация начинается с нуля:s = ["answer", "to", "question"] print(s[2])
-
x in s
Проверяет, находится ли элемент
x
в спискеs
:if 4 in [1, 2, 3, 4]: print("Четвёрка есть в этом списке") else: print("Четвёрки в этом списке нет")
-
s.
append
(x)¶ Добавляет элемент
x
в конец спискаs
-
s.
extend
(x)¶ Добавляет все элементы из списка
x
в списокs
:s = [1, 2, 3] li = [20, 21, 22] s.extend(li) print(s)
-
s.
pop
()¶
-
s.
pop
(x) Извлекает элемент под индексом
x
из списка. Если индекс не указан, извлекает последний элемент из списка.s = [1, 2, 3] b = s.pop()
print(b, s) # 3 [1, 2]
По спискам можно удобно проходить с помощью цикла for
:
li = ["Colors:", "red", "crimson"]
for s in li:
print(s)
Задачи¶
В цикле получите от пользователя названия четырёх цветов и сохраните их в список. Выведите получившийся список на экран.
Объедините 2 списка, недопуская при этом дублирования элементов.
Вам дан список чисел. Напишите функцию для подсчёта сумму всех эелементов и произведения.
Нарисуйте квадрат, у которого цвета каждой стороны будут различаться.
Напишите функцию для сортировки списка методом пузырька.
Строки¶
Строка - неизменяемая последовательность символов
Способы создания строк¶
Самый распространённый способ создания строк - с помощью двойных кавычек:
s = "Hello"
print(s)
Однако есть несколько других способов, которые имееются в языке:
s = 'Hello'
s = """Hello"""
s = '''Hello'''
Все 3 способа записи приводят к одному результату - созданию строки hello
Разные способы записи нужны для удобного создания строк с специальными символами:
q = "What's your name"
t = 'He said: "Bond, James Bond"'
Если бы в языке не было разных способов создания данных строк, то пришлось бы использовать экранирование:
t = "He said: \", James Bond\""
Некоторые специальные символы, которые могут находиться внутри строки:
Последовательность |
Описание |
---|---|
|
Обратный слеш ( |
|
Апостроф |
|
Кавычка |
|
Символ табуляции |
|
Перевод строки |
Тройные кавычки используются для создания больших строк:
s = """
Здесь может быть написан текст,
занимающий любое количество строк
"""
Операции со строками¶
-
len
(s)¶ Получение длины строки:
>>> len("Hello") 5
-
s1 + s2
Конкатенация (объединение) строк:
>>> "Hello " + "World" 'Hello World'
-
s * n
Повторение строки
n
раз:>>> "python " * 3 'python python python '
-
s[i]
Обращение к символу
i
строкиs
. Индексация начинается с нуля. Индексы могут быть отрицательными, тогда отсчет ведется с конца строки:>>> s = 'abcdef' >>> s[0] 'a' >>> s[5] 'f' >>> s[-1] 'f' >>> s[-2] 'e'
-
s[begin:end:step]
Получение среза строки от позиции
begin
до позицииend
с шагомstep
. Любой параметр может быть пропущен:>>> s = "abcdef" >>> s[1:] 'bcdef' >>> s[:-1] 'abcde' >>> s[1:-1] 'bcde' >>> s[1::2] 'bdf' >>> s[::2] 'ace' >>> s[::-2] 'fdb'
Задачи¶
Получите от пользователя 2 строки, объедините их и выведите экран
Получите от пользователя слово, выведите первую и последнюю букву
Получение от пользователя строку и выведите количество цифр в данный строке
Получите от пользователя строку, в которой будет несколько слов, выведите их количество. Считать что слова отделены друг от друга одним пробелом
Дана строка, содержащая путь к файлу:
C:\Python3\python.exe
С помощью срезов вывести отдельно имя файла, его расширение, имя каталога и полный путь к каталогу. Пример вывода:
Имя файла: python.exe Расширение: exe Имя каталога: Python3 Полный путь к каталогу: C:\Python3\
Получите от пользователя несколько строк, занесите их в список, с помощью циклов найдите самую длинную строку и выведите её на экран
Домашнее задание¶
На вход программе подается строка. Необходимо вывести:
Сначала выведите третий символ этой строки.
Во второй строке выведите предпоследний символ этой строки.
третьей строке выведите первые пять символов этой строки.
В четвертой строке выведите всю строку, кроме последних двух символов.
В пятой строке выведите все символы с четными индексами (считая, что индексация начинается с 0, поэтому символы выводятся начиная с первого).
В шестой строке выведите все символы с нечетными индексами, то есть начиная со второго символа строки.
В седьмой строке выведите все символы в обратном порядке.
В восьмой строке выведите все символы строки через один в обратном порядке, начиная с последнего.
В девятой строке выведите длину данной строки.
Пример:
Input: Abrakadabra
Output:
r
r
Abrak
Abrakadab
Arkdba
baaar
arbadakarbA
abdkrA
11
Методы строк¶
-
s.
lower
()¶ -
s.
upper
()¶ -
s.
title
()¶ Методы приводят строку к нижнему, верхнему и title регистру соответственно:
>>> 'world'.upper() 'WORLD' >>> 'HELLO'.lower() 'hello' >>> 'hello'.upper() 'HELLO' >>> 'hello'.title() 'Hello'
-
s.
count
(sub)¶ Возвращает количество вхождений подстроки
sub
в строкуs
.
-
s.
find
(sub)¶ Возвращает минимальный индекс вхождения подстроки
sub
в строкуs
:>>> 'otto'.find('t') 1
-
s.
rfind
(sub)¶ Возвращает максимальный индекс вхождения подстроки
sub
в строкуs
:>>> 'otto'.rfind('t') 2
-
s.
ljust
(width)¶ Возвращает строку, выровненную по левой границе поля ширины
width
. Строка дополняется пробелами справа:>>> 'hello'.ljust(10) 'hello '
-
s.
rjust
(width)¶ Возвращает строку, выровненную по правой границе поля ширины
width
. Строка дополняется пробелами слева:>>> 'hello'.rjust(10) ' hello'
-
s.
replace
(old, new)¶ Возвращает строку, в которой все вхождения подстроки
old
заменены на подстрокуnew
.
Задачи¶
Пользователь вводит фамилию, имя и отчество. Приложение должно вывести фамилию и инициалы. Пример:
Фамилия: Ершов Имя: Андрей Отчество: Петрович Ершов А. П.
Доработать приложение из предыдущей задачи так, чтобы программа исправляла регистр символов. Пример:
Фамилия: ерШоВ Имя: андрей Отчество: петрович Ершов А. П.
Пользователь вводит слово. Подсчитать количество символов ‘a’ в нем. Пример:
word: abracadabra 5
Пользователь вводит строку и два слова. Приложение заменяет все вхождения первого слова на второе. Пример:
> To be or not to be. Find: be Replace: eat To eat or not to eat.
Приложение принимает на вход строку и заменяет все вхождения буквы «ё» на букву «е».
Пользователь вводит строку. Нужно удалить из нее первое слово. Разделителем слов считать пробел. Пример:
> Hello, World! World
Пользователь вводит строку. Нужно удалить из нее последнее слово.
Пользователь вводит строку, содержащую два слова. Приложение выводит их в обратном порядке. Пример:
Harry Potter Potter Harry
Написать приложение, выполняющее транслитерацию введенного слова. Пример:
> Привет Privet
Ветвления продолжение¶
-
str.
isalpha
()¶ Возвращает
True
, если строкаstr
состоит из букв:s = "hi" print(s.isalpha())
-
str.
isnumeric
()¶ Возвращает
True
, если строкаstr
состоит из цифр.
-
str.
isalnum
()¶ Возвращает
True
, если строкаstr
состоит из букв и/или цифр.
-
str.
islower
()¶ -
str.
isupper
()¶ -
str.
istitle
()¶ Методы возвращают
True
, если строкаstr
записана в нижнем, верхнем или title регистре соответственно.
Задачи¶
Пользователь вводит имя. Приложение сообщает, является ли имя корректным. Имя считается корректным, если записано в title case и состоит только из букв.
Пользователь вводит двузначное число. Определить:
Какой из его разрядов больше: старший или младший.
Одинаковы ли разряды.
По длинам трех отрезков, введенных пользователем, определить возможность существования треугольника, составленного из этих отрезков. Если такой треугольник существует, то определить, является ли он разносторонним, равнобедренным или равносторонним.
Пользователь вводит слово. Проверить, является ли оно палиндромом, то есть читается слева направо и справо налево одинаково. Пример:
Слово: шалаш Это палиндром Слово: карандаш Это не палиндром
Доработать предыдущую задачу так, чтобы приложение игнорировало регистр символов.
Пользователь вводит число. Приложение сообщает количество хомячков в с учетом падежа. Пример:
Число: 21 21 хомячок Число: 42 42 хомячка Число: 12 12 хомячков
Приложение запрашивает имя пользователя. Если пользователь вводит «admin», то дополнительно запрашивает пароль. Если пароль равен «123», то приветствует пользователя. Если пользователь представляется другим именем, то приложение приветствует его без запроса пароля.
Пользователь вводит пароль. Приложение сообщает, надежен ли он. Пароль считается надежным, если:
Его длина более 6 символов
Есть символы как в верхнем, так и в нижнем регистре
Есть цифры или специальные символы (пока считаем, что достаточно проверить наличие любых символов помимо букв)
Пользователь вводит два числа: день и месяц невисокосного кода. Вывести дату следующего дня.
Циклы¶
Цикл while
¶
Цикл while
позволяет многократно выполнять блок команд до тех пор, пока
выполняется некоторое условие. Пример:
n = 5
while n > 0:
print(f'n = {n}')
n -= 1
Вывод:
n = 5
n = 4
n = 3
n = 2
n = 1
Цикл for
¶
Цикл for..in
осуществляет итерацию по последовательности объектов, т.е.
проходит через каждый элемент в последовательности. Мы узнаем больше о
последовательностях на следующих уроках, а пока просто запомните, что
последовательность – это упорядоченный набор элементов.
Пример:
for i in range(1, 6):
print(f'i = {i}')
Вывод:
i = 1
i = 2
i = 3
i = 4
i = 5
В этом примере функция range
возвращает объект последовательнсоти. Обратите
внимание, что правая граница не включается.
Есть несколько способов создания последовательности с помощью функции range
.
-
range
(stop)¶ -
range
(start, stop) -
range
(start, stop, step) Возвращает последовательность от
start
доstop
(не включительно) с шагомstep
.
Оператор break
¶
Оператор break
служит для прерывания цикла, т.е. остановки выполнения
команд даже если условие выполнения цикла ещё не приняло значения False
или последовательность элементов не закончилась.
Пример:
while True:
command = input('> ')
if command == 'exit':
break
Оператор continue
¶
Оператор continue
используется, чтобы пропустить все оставшиеся команды
в текущем блоке цикла и продолжить со следующей итерации цикла. Пример:
for i in range(5):
if i == 2 or i == 3:
continue
print(i)
Задачи¶
В задачах указано, какой цикл рекомендуется использовать для их решения.
[for] Пользователь вводит числа
a
иb
. Вывести все целые числа, расположенные между ними.[for] Доработать предыдущую задачу так, чтобы выводились только числа, делящиеся на 5 без остатка.
[for] Пользователь вводит число. Вывести таблицу умножения на это число
[for] В цикле получать от пользователя оценки по четырём экзаменам. Вывести сумму набранных им баллов.
[while] В бесконечном цикле приложение запрашивает у пользователя числа. Ввод завершается, как только пользователь вводит слово ‘end’. После завершения ввода приложение выводит сумму чисел.
[while] Получить от пользователя натуральное число, посчитать сумму цифр в нём.
Пользователь вводит число
n
и цифруa
. Определить, сколько раз цифра встречается в числе. (не использовать методcount
)
Easygui¶
Easygui - библиотека, которая используется для быстрого создания простых графичеческих интерфейсов
Функции¶
-
msgbox
(message)¶ Создаёт новое окно, в котором будет написано сообщение
message
и кнопка ok
Создаёт новое окно с заданными кнопками. В возвращает текст кнопки, которая была нажата
-
integerbox
(message, lowerbound=0, upperbound=99)¶ Создаёт новое окно, в котором можно вводить числа в диапозоне от
lowerbound
доupperbound
, возвращает введённое пользователем число
Официальная документация: https://easygui.readthedocs.io/en/master/api.html
Задание¶
Используя шаблон проекта, реализуйте игры «Камень, ножницы, бумага» и «Угадай число»:
import easygui
def rock_paper_scissors():
easygui.msgbox('Здесь будет игра "Камень, ножницы, бумага"')
def guess_the_number():
easygui.msgbox('Здесь будет игра "Угадай число"')
games = [
'Камень, ножницы, бумага',
'Угадай число'
]
games_entry_points = [
rock_paper_scissors,
guess_the_number
]
while True:
res = easygui.buttonbox('Выбери игру!', choices=games)
if res is None:
break
games_entry_points[games.index(res)]()
Шаблон проекта в архиве: games.zip
Инструкция по установке¶
Запустить программу “командная строка” (cmd.exe)
Ввести команду “python -m pip install easygui”
Где:
python
- интерпретатор питона;
-m
- команда на запуск другой программы;
pip
- менеджер пакетов;
install
- команда на установку какой-либо библиотеки;
easygui
- название библиотеки.
Игра Города¶
Классическая игра “Города”
Игра начинается с того что один из игроков называет город и следующему игроку нужно назвать город, который будет начинаться на последнюю букву предыдущего:
- Новосибирск
- Кемерово
- Оренбург
Задание¶
Реализовать версию, в которой будет возможность вводить любые слова и будет проверка на совпадение первой и последней буквы
Сделать так чтобы можно было вводить слова в любом регистре
Добавить проверку на существование города, который введёт пользователь
Сделать чтобы города не могли повторяться
Добавить графический интерфейс с помощью библиотеки
easygui
Добавить возможность играть с компьютером. Для этого потребуется библиотека
random
и функцияchoice
Модули с подготовленными списками городов:
Файловый ввод-вывод¶
Обычно работа с файлами состоит из следующих этапов:
Открыть файл. При открытии следует указать режим: чтение или запись.
Выполнить чтение или запись данных.
Закрыть файл.
Рассмотрим функции для выполнения этих действий.
-
open
(file_path, mode='r')¶ Открыть файл
file_path
в режимеmode
. Функция возвращаетfile object
. Полная сигнатура функции приведена в официальной документации: open. Режим может принимать значения:'r'
— read, чтение'w'
— write, запись
-
f.
write
(text)¶ Записать строку
text
в файл.
-
f.
read
()¶ Прочитать все данные из файла
-
f.
close
()¶ Закрыть файл
f
.
Пример работы с файлом:
# Открываем файл для записи
out_file = open('data.txt', 'w')
# Пишем в файл две строки
out_file.write('Hello\n')
out_file.write('World\n')
# Закрываем файл
out_file.close()
# Снова открываем этот же файл, но уже для чтения
in_file = open('data.txt', 'r')
# Файл — итерируемый объект. Следовательно, для
# его построчного чтения можно использовать цикл for
for line in in_file:
print(f'Got line: {line}')
in_file.close()
Задачи¶
Написать программу, которая будет получать у пользователя строку и записывать её в файл “data.txt”
Разработать приложение, которое записывает в файл все строки, введенные пользователем. Признак конца ввода — пустая строка. Пример:
Введите имя файла: data.txt Начните вводить строки > one > two > three > Файл записан.
После выполнения программы должен появиться файл
data.txt
, содержащий три строки:one two three
Написать программу, которая будет получать у пользователя путь к файлу и выводить его содержимое на экран
Доработать предыдущее приложение для нумерации строк в файле. Приложение принимает на вход имя файла и выводит его построчно, добавляя к каждой строке её номер. Если использовать файл, созданный в предыдущей задаче, то результат работы программы будет выглядеть так:
Введите имя файла: data.txt 1 one 2 two 3 three
Используйте метод строки
rstrip()
, чтобы избавиться от лишних переносов сток. После этого результат работы программы примет вид:Введите имя файла: data.txt 1 one 2 two 3 three
Разработать приложение для разделения файла на части. Приложение принимает на вход имя файла для разделения и целое число N. На выходе у приложения множество файлов, каждый из которых содержит не более, чем N строк из исходного файла.
Пусть на вход программе подается файл
data.txt
, со следующим текстом:one two three four five six seven eight nine ten
Будем разделять его на несколько файлов, в каждом из которых окажется не более трех строк:
Введите имя входного файла: data.txt Введите максимальное количество строк: 3
После выполнения программы должны быть созданы файлы
1.txt
,2.txt
и так далее. В файле1.txt
будут сроки:one two three
В файле
2.txt
:four five six
И так далее.
Разработать приложение для объединения файлов. Приложение принимает на вход имена файлов для объединения (можно использовать файлы, полученные из предыдущего задания) и имя выходного файла.
Дополнительные задачи¶
Разработайте приложение, которое выводит
N
первых строк файла.Разработайте приложение, которое выводит
N
последних строк файла.
Шифр Цезаря¶
Шифр Цезаря — это вид шифра подстановки, в котором каждый символ в открытом тексте заменяется символом, находящимся на некотором постоянном числе позиций левее или правее него в алфавите. Например, в шифре со сдвигом вправо на 3, A была бы заменена на D, B станет E, и так далее.
Для кодирования одного символа используется формула:
encoded_symbol = first + (symbol - first + key) % (last - first + 1)
Здесь:
encoded_symbol — код зашифрованного символа
symbol — код исходного символа
key — ключ шифрования
first — код первого символа алфавита
last — код последнего символа алфавита.
Для преобразования символа в код и обратно используются функции:
-
ord
(c)¶ Возвращает код символа
с
.
-
chr
(i)¶ Возвращает символ, соответствующий коду
i
.
Задание¶
Каждая задача — отдельный этап реализации приложения для шифрования.
Напишите функцию
encode_symbol
. Функция принимает символ и число, на которое его нужно сдвинуть, а также первую и последнюю буквы алфавита.Используя функцию из предыдущего задания, доработайте программу, чтобы она могла шифровать строки, введённые пользователем. Для удобства можно написать функцию
encode_str
. Функция принимает строку и ключ шифрования и возвращает зашифрованную строку.Добавьте возможность шифрования текстовых файлов. Для этого напишите функцию
encode_file(input_file_path, output_file_path, key)
.Напишите для приложения графический интерфейс с помощью
easygui
. Для открытия шифруемого файла используйте функциюeasygui.fileopenbox(msg=None, title=None)
. Для сохранения зашифрованного файла используйтеeasygui.filesavebox(msg=None, title=None)
. Для ввода ключа —easygui.integerbox(msg="", title=" ")
.
Словари¶
Основные определения¶
- Словарь
Неупорядоченная коллекция объектов произвольного типа с доступом по ключу. Представлены типом
dict
.- Множество
Неупорядоченная коллекция объектов произвольного типа, в которой не имеются дубликаты. Представлены типом
set
.- Неупорядоченная коллекция
Коллекция, в которой элементы не индексируются и нельзя делать срезы
Создание словарей¶
>>> d = {}
>>> type(d)
<class 'dict'>
>>> d = {"Name": "John", "Last Name": "Connor"}
>>> d
{'Name': 'John', 'Last Name': 'Connor'}
Динамическое создание словарей:
# Словарь можно создать, передав список пар ключ-значение
pairs = [('Name', 'John'), ('Age', 19)]
d = dict(pairs)
print(d)
{'Name': 'John', 'Age': 19}
# Можно создавать такие пары с помощью функции zip
id = (1, 2, 3, 4,)
logins = ('Vasya', 'Petya', 'Lera')
# Функция zip упаковывает несколько последовательностей в кортежи
d = dict(zip(logins, id))
print(d)
{'Vasya': 1, 'Petya': 2, 'Lera': 3}
Добавление элементов осуществляется с помощью фигурных скобок:
>>> d['Age'] = 19
Получение элемента по ключу:
>>> d['Age']
19
Методы словарей¶
-
d.
get
(key)¶ Получение элемента по заданному ключу:
>>> d.get('Name') 'John' >>> d.get('Not Presented Key') None
-
d.
keys
()¶ Получение списка всех ключей
>>> d.keys() dict_keys(['Name', 'Last Name'])
-
d.
values
()¶ Получение списка всех значений в словаре
>>> d.values() dict_values(['John', 'Connor'])
-
d.
items
()¶ Получение списка пар ключ-значение, представленных в виде кортежей:
>>> d.items() dict_items([('Name', 'John'), ('Last Name', 'Connor')])
-
d.
pop
(key)¶ Извлечение элемента из словаря:
>>> d = {'Name': 'John', 'Last Name': 'Connor'} >>> d.pop('Name') 'John' >>> d {'Last Name': 'Connor'}
-
dict.
fromkeys
(seq, value)¶ Создаёт новый словарь, в котором ключи взяты из последовательности
seq
и им установлены значения по умолчаниюvalue
:>>> lst = ['uesr1', 'user2', 'user3'] >>> user_logins_with_passwords = dict.fromkeys(lst, 123456) >>> user_logins_with_passwords {'user1': 123456, 'user2': 123456, 'user3': 123456}
Задачи¶
Напишите программу, которая получает на вход набор слов и выводит на экран только уникальные. Использовать тип
set
.Доработать программу, чтобы она получала от пользователя путь до файла со словами
Написать программу, которая на вход получает файл и выводит на экран какое слово сколько раз встречалось. Использовать тип
dict
. Содержимое файла:слово фраза предложение слово
Пример вывода:
Путь к файлу: words.txt слово: 2 фраза: 1 предложение: 1
Создайте функцию
compute_bill
, считающаю итоговую сумму товаров в чеке. Функция должна принимать 1 параметр - словарь, в котором указано количество едениц товара. Цены хранятся в словаре:prices = { "banana": 4, "apple": 2, "orange": 1.5, "pear": 3 }
Создайте программу, которая будет выводить все возможные комбинации при броске 2 игральных костей и сумму их значений. Пример вывода:
2: [(1, 1)] 3: [(1, 2), (2, 1)] ...
Основы работы с библиотекой requests¶
В основе ежедневной работы пользователей в сети Интернет лежит обмен данными между клиентскими приложениями (например браузер) и веб-серверами. В соответствии с прикладным протоколом HTTP, клиент отправляет запрос (request) на получение определенного ресурса к серверу и получает от него ответ (response). Ответ, помимо самого запрошенного ресурса, содержит также служебную информацию.
Библиотека requests
предоставляет удобный способ отправки HTTP-запросов и
обработки ответов от сервера.
Рассмотрим функцию get
, которая нам потребуются для отправки простых
запросов.
-
requests.
get
(url, params=None, **kwargs)¶ Отправить GET-запрос. Функция принимает URL-адрес запрашиваемого ресурса и возвращает объект типа
Response
. Также возможна передача в функцию дополнительных параметров запроса.Пример отправки запроса на получение ресурса:
url = 'http://api.forismatic.com/api/1.0/' payload = {'method': 'getQuote', 'format': 'json', 'lang': 'ru'} res = requests.get(url, params=payload))
Теперь мы можем получить все необходимые данные из Response-объекта res.
Проверяем URL ресурса:
>>> res.url 'http://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=ru'
Проверяем код ответа HTTP:
>>> res.status_code 200
Получаем заголовки ответа:
>>> res.headers {'Date': 'Tue, 19 Feb 2019 19:27:34 GMT', 'Content-Type': 'application/json' ... }
Получаем содержимое ответа в текстовом формате:
>>> res.text
В случае бинарного содержимого ответа воспользуемся атрибутом
content
:>>> res.content
Если данные в ответе представлены в формате json их можно декодировать и получить словарь:
>>> data = res.json() >>> data['quoteText'] 'Тот, кто не смотрит вперед, оказывается позади' >>> data['quoteAuthor'] 'Герберт Уэллс '
Подробная документация к библиотеке доступна по адресу: http://docs.python-requests.org/en/master/api/
Множество интернет-сервисов предоставляют программистам API (Application programming interface) — интерфейс получения данных посредством запросов, а также документацию к нему.
Задачи¶
Реализовать приложение для получения случайных цитат.
Шаг 1. Изучите API сервиса forismatic.com: http://forismatic.com/en/api/
Шаг 2. С помощью модуля
easygui
разработайте приложение с графическим интерфейсом для получения цитат на русском и английском языках.Реализовать приложения для загрузки картинок с котиками:
Шаг 1. Изучите API сервиса cataas.com: https://cataas.com/#/
Шаг 2. С помощью модуля
easygui
разработайте приложение для загрузки случайных картинок с котиками. Картинка содержится в ответе от сервера в бинарном виде.
Игра ‘Лабиринт’¶
Лабиринт - игра в которой нужно выйти из помещения сложной формы с большим количеством разветвлений.
Пример игрового поля:
maze = [
"## #########",
"## ##",
"####### ####",
"#F## # ## #",
"# ## ## #",
"### ##",
"#########@##"
]
В данном игровом поле ‘#’ обозначает стену, ‘F’ - ключ, а ‘@’ - дверь
Задание¶
Написать функцию для рисования игрового поля
Добавить возмонжость пользовательского ввода для перемещения персонажа
Добавить проверки на столкновение со стеной
Доработать игру, чтобы можно было подбирать ключ с его помощью открывать дверь
Классы¶
Класс — шаблон, описывающий правила создания и поведение объекта.
Объект — экземпляр, созданный на основе шаблона.
Поле — используется для хранения значения.
Метод — функция, связанная с классом.
Магический метод — зарезервированные методы, отвечающие за поведение объекта.
Название |
Применение |
---|---|
|
Инициализация объекта |
|
Преобразование к строке str(obj) |
|
Проверка на равенство |
|
Оператор доступа к элементам
some_dict[“item”]
|
Пример:
class Person: # Объявление класса
def __init__(self, name, age): # Метод инициализации или по другому конструктор
self.age = age # Установка значений полей
self.name = name
def __str__(self):
return f"{self.name} is {self.age} years old"
person = Person('John', 20) # Создание экземпляра
person.name = 'James' # Установка значения поля
print(person)
Здесь __init__
определяет как будет создаваться новый объект и какие
параметры будет принимать при создании.
__str__
определяет как экземпляр будет печататься на экране с помощью
функции print
и преобразовываться к строке с помощью str
.
Задачи¶
Создать класс, описывающий человека. Должны быть поля для имени, фамилии и возраста. Создать экземпляр и вывести информацию о человеке.
Доработать предыдущий класс, чтобы вся информация о человеке была доступна при вызове
str
над экземпляром.Добавить метод greet, вызов которого будет выводить в консоль информацию о человеке в формате
"Привет! Меня зовут Петров Василий, мне 12 лет"
.Добавить поле
grades
, в котором будет храниться список оценок. Создать список учеников, заполняя оценки каждого случайными числами.Вывести информацию об учениках в порядке убывания среднего балла. Подсчёт среднего балла вынести в отдельный метод.
Создайте класс
Point
, экземпляры которого будут создаваться из координатx
иy
.Создайте класс прямоугольник —
Rectangle
. Метод__init__
принимает две точки — левый нижний и правый верхний угол. Каждая точка представлена экземпляром классаPoint
. Реализуйте методы вычисления площади и периметра прямоугольника.Добавьте в класс
Rectangle
методcontains
. Метод принимает точку и возвращаетTrue
, если точка находится внутри прямоугольника иFalse
в противном случае.
Инкапсуляция¶
В объектно-ориентированных языках программирования есть спецификаторы, ограничивающие доступ к аттрибутам. Главной задачей является отделение деталей реализации логики объекта от того как с ним надо взаимодействовать.
В языке Python в отличие от многих других языков вместо ключевых слов используется знак нижнего подчёркивания.
public
- Данный аттрибут доступен всем:
class Person:
def __init__(self, name):
self.name = name # публичный аттрибут
p = Person("John")
p.name = "Mark"
private
- Аттрибут сокрыт от посторонних глаз и доступен только
самому объекту:
class Person:
def __init__(self, name, age):
self.name = name
self.set_age(age)
def get_age(self):
return self.__age
def set_age(self, age):
if age >= 0:
self.__age = int(age) # __age - приватный аттрибут
else:
self.__age = 0
print("Возраст не может быть отрицательным!")
p = Person("John", 19)
print(p.get_age()) # 19
p.set_age(20)
print(p.get_age()) # 20
p.__age = 21 # Error
p._Person__age = 21
print(p.get_age()) # 21
Задачи¶
Описать класс десятичного счётчика. Он должен обладать внутренней переменной, хранящей текущее значение, методами повышения значения (
increment
) и понижения (decrement
), получения текущего значенияget_counter
. Учесть, что счётчик не может опускаться ниже 0.Создать класс для часов. Должна быть возможность установить время при создании объекта. Также необходимо реализовать методы, с помощью которых можно добавлять по одной минуте/секунде или по одному часу к текущему времени. Помнить, что значения минут и секунд не могут превышать 59, а часов 23.
Доработать предыдущую задачу, чтобы можно было складывать двое часов друг с другом. Для перегрузки оператора
+
использовать метод__add__(self, other)
.Создать классы для травоядного животного и травы. Животное должно уметь поедать траву, если испытывает голод, в противном случае отказываться от лакомства. Трава должна обладать питательностью, в зависимости от которой животное будет насыщаться.
Основы PyGame¶
Pygame — библиотека, предназначенная для разработки мультимедийных приложений с графическим интерфейсом, например игр.
Документация, обучающие материалы и дополнительная информация доступна разработчикам на сайте проекта: https://www.pygame.org/docs/
Начало работы¶
Начнем знакомство с библиотекой непосредственно с разбора примера простого приложения:
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((1200, 800))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
В первую очередь импортируем модуль pygame в наш файл с исходным кодом:
import pygame
Затем вызываем функцию init()
для подготовки модулей pygame к работе:
pygame.init()
После этого создаем графическое окно, передав в качестве аргумента в функцию
set_mode()
его разрешение в виде пары целых чисел. В свою очередь функция
вернет нам объект типа Surface, используемый для представления изображений:
screen = pygame.display.set_mode((1200, 800))
Далее, запускаем основной цикл программы, в котором, среди всех событий, происходящих в нашем приложении, перехватываем событие закрытия основного графического окна пользователем:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
После того как ожидаемое событие наступило, завершаем работу с библиотекой
pygame вызовом функции pygame.quit()
и нашей программы вызовом функции
exit()
из модуля sys
.
Рисование геометрических фигур¶
Разместим в окне нашего приложения прямоугольник. Прямоугольные объекты
представлены типом Rect
:
Rect(left, top, width, height)
Rect((left, top), (width, height))
Для создания объекта этого типа нам необходимо указать координаты левого верхнего угла прямоугольника и длины его сторон:
r = Rect(0, 0, 100, 200)
Обратите внимание, что начало координат (0, 0) находится в левом верхнем углу окна.
В библиотеке pygame функции отображения геометрических фигур находятся
в модуле draw
. Нарисуем прямоугольник c помощью функции rect()
:
rect(Surface, color, Rect, width=0) -> Rect
Для этого передадим в функцию в качестве аргументов поверхность, на которой мы размещаем прямоугольник, его цвет, сам прямоугольник и толщину линии — стороны прямоугольника. Если толщина равна нулю прямоугольник закрашивается сплошным цветом.
Рассмотрим готовый пример:
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((1000, 800))
r = pygame.Rect(50, 50, 100, 200)
pygame.draw.rect(screen, (255, 0, 0), r, 0)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.flip()
Обратите внимание на последнюю строку нашей программы. На самом деле
графические объекты которые мы хотим разместить на основном экране сначала
попадают в специальный буфер. Чтобы отобразить изменения стали видны вызываем
функцию flip()
.
Функции для рисования графических фигур¶
-
pygame.draw.
rect
(Surface, color, Rect, width=0)¶ Нарисовать прямоугольник
Rect
на поверхностиSurface
, цветомcolor
. Если толщина линииwidth
равна нулю, прямоугольник закрашивается.
-
pygame.draw.
line
(Surface, color, start_pos, end_pos, width=1)¶ Нарисовать линию на поверхности
Surface
, цветомcolor
, с началом в точкеstart_pos
, концом в точке end_pos и толщиной линии width.
-
pygame.draw.
lines
(Surface, color, closed, pointlist, width=1)¶ Нарисовать линию, соединяющую точки из последовательности
pointlist
на поверхностиSurface
, цветомcolor
, с толщиной линииwidth
. Каждая точка представлена парой координат. Если параметрclosed
равенTrue
, конечная точка соединяется с начальной.
-
pygame.draw.
circle
(Surface, color, pos, radius, width=0)¶ Нарисовать окружность на поверхности Surface, цветом
color
, с центром в точкеpos
и радиусомradius
. Если толщина линииwidth
равна нулю, окружность закрашивается.
-
pygame.draw.
ellipse
(Surface, color, Rect, width=0)¶ Нарисовать эллипс, ограниченный прямоугольником
Rect
, на поверхностиSurface
, цветомcolor
. Если толщина линииwidth
равна нулю, эллипс закрашивается.
-
pygame.draw.
polygon
(Surface, color, pointlist, width=0)¶ Нарисовать многоугольник по точкам из последовательности
pointlist
на поверхностиSurface
, цветомcolor
, с толщиной линииwidth
. Каждая точка представлена парой координат. Если толщина линииwidth
равна нулю многоугольник закрашивается.
Цвет¶
Цвета в библиотеке pygame представлены в соответствии с моделью RGB: https://ru.wikipedia.org/wiki/RGB
Значение для цвета можно задать тройкой чисел, каждое из которых лежит в диапазоне от 0 до 255. Первое значение в последовательности определяет, какое количество красного содержится в данном оттенке, второе - зеленого, третье - голубого. Чем меньше значение числа, тем темнее будет оттенок. Например, красный цвет можно представить как (255, 0, 0), белый как (255, 255, 255), а черный как (0, 0, 0).
Помимо этого, в модуле color
из библиотеки pygame содержится словарь
THECOLORS, ключами которого являются названия различных цветовых оттенков.
Подключить его можно с помощью команды:
from pygame.color import THECOLORS
Закрасим основной экран c помощью метода fill()
:
screen = pygame.display.set_mode((1200, 800))
screen.fill(THECOLORS['orange'])
Текст и шрифты¶
При работе с текстом мы будем использовать шрифты - группы символов
объединенных по стилистическому или иному признаку. Шрифты в библиотеке pygame
представлены типом Font
Чтобы создать объект Font
на основе имеющегося в системе шрифта вызовем
следующую функцию:
SysFont(name, size, bold=False, italic=False)
С помощью параметра name
передаем в функцию имя шрифта, параметр
size
- размер шрифта в пунктах. Параметры bold
и italic
отвечают за
начертание шрифта.
Список имеющихся в системе шрифтов можно получить с помощью функции
get_fonts()
:
pygame.font.get_fonts() -> list of strings
Далее, с помощью метода render()
нашего объекта типа Font
получаем
изображение с текстом, которое передаем на вход методу blit()
для отрисовки
на нашем основном экране:
screen = pygame.display.set_mode(size)
screen.fill(THECOLORS['white'])
font = pygame.font.SysFont('couriernew', 40)
text = font.render(str('HELLO'), True, THECOLORS['green'])
screen.blit(text, (50, 50))
Текст размещается в на основном экране по координатам (50, 50)
Задания¶
1. Используя функции для работы с графикой библиотеки pygame, нарисуйте дом с квадратным основанием и треугольной крышей.
2. Используя функции для работы с графикой библиотеки pygame, нарисуйте белый флаг с олимпийскими кольцами.
3. Разработайте программу, которая разбивает основное игровое окно на клетки заданного размера.
4. Доработайте программу так, чтобы в каждой клетке был записан её порядковый номер.
5. Доработайте в программу возможность закрашивания клетки с произвольным номером случайным цветом. Номера клеток которые необходимо закрасить считывать из файла.
Обработка ввода и анимации¶
События¶
Взаимодействие пользователя с компьютером основано на событиях, любые действия производимые пользователем порождают события - движение мыши, нажатия клавиш, специальных кнопок. Внутри библиотеки PyGame есть инструменты для обратки событий, которые происходят внутри приложений.
Мы с вами уже знакомы с методом получения всех произошедших событий -
pygame.event.get()
, который возвращает события, произошедшие с последнего
обращения.
Помимо событий выхода из приложения pygame.QUIT
, есть множество других -
например, нажатия клавиш pygame.KEYDOWN
или отпускания pygame.KEYUP
.
Рассмотрим взаимодействие с событиями на примере небольшой программы, в которой по нажатию клавиш показывается квадрат:
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
rect = pygame.Rect(40, 40, 120, 120)
color = (0, 0, 0)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
color = (255, 255, 255)
pygame.draw.rect(screen, color, rect, 0)
pygame.display.flip()
В данном блоке программа занимется обработкой нажатия клавиш. Сначала мы получаем список всех событий, после чего начинаем последовательно проверять их. Если одно из событий соответствует сигналу к завершению программы, закрываем окно. Если же это нажатие клавиши - перекрашиваем прямоугольник в белый цвет.
События |
Когда генерируется |
---|---|
KEYDOWN |
При нажатии клавиш |
KEYUP |
При отпускании клавиш |
QUIT |
При нажатии кнопки закрытия программы |
MOUSEMOTION |
При движении мыши |
Обработка нажатий клавиш¶
Когда мы нажимаем клавишу, в систему передаётся не только информация о том, что какая-то кнопка нажата, но и её код.
- Есть два способа получить нажатые клавиши:
pygame.event.get()
pygame.key.get_pressed()
С первым мы уже знакомы, поэтому стоит внимательнее рассмотреть второй. Он позволяет получить список клавиш, которые нажаты в данный момент в виде кортежа булевых значений. Чтобы узнать нажата ли интересующая нас кнопка, необходимо проверить значение, которе содержится в данном кортеже:
keys = pygame.key.get_pressed()
if keys[pygame.K_RETURN]:
print("Нажата клавиша enter")
Перемещение объектов¶
Умея получать от пользователя ввод, мы можем реализовать движения наших фигур на экране:
import sys
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
rect = pygame.Rect(40, 40, 120, 120)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
rect.move_ip(-40, 0)
elif event.key == pygame.K_RIGHT:
rect.move_ip(40, 0)
elif event.key == pygame.K_UP:
rect.move_ip(0, -40)
elif event.key == pygame.K_DOWN:
rect.move_ip(0, 40)
pygame.draw.rect(screen, (255, 0, 0), rect, 0)
pygame.display.flip()
Для движения объектов используются методы move()
и move_ip()
, которыми
обладают объекты, созданные с помощью функций из pygame.draw
. Первый создаёт
новую фигуру такого же типа, находящуюся по заданному смещению, второй непосредственно
изменяет положение имеющейся фигуры.
Запустив данный код, вы можете заметить, что при перемещении фигуры от неё остаётся “след”. Это связано с тем, что при перемещении объекта, мы его не перемещаем на экране, а рисуем на новом месте поверх старого кадра.
Чтобы избежать данной проблемы, надо добавить вызов метода fill()
у нашего
экрана, на котором мы рисуем и передать ему цвет, которым надо закрасить фон.
Данное действие надо проводить каждый раз перед отрисовкой кадра:
# здесь могла быть ваша проверка событий
screen.fill((0, 0, 0))
pygame.draw.rect(screen, (255, 0, 0), rect, 0)
pygame.display.flip()
Использование спрайтов¶
Спрайт - двумерное изображение, используемое в играх.
-
pygame.image.
load
(path)¶ Функция для загрузки спрайта из картинки.
Path
- путь до изображения, возвращает объект типа Surface, который можно использовать для рисования.
Для отрисовки спрайта на экране надо вызвать метод blit()
у поверхности
на которой производится отрисовка и передать объект спрайта вместе с координатами
на которых необходимо отрисовать:
screen = pygame.display.set_mode((640, 480))
sprite = pygame.image.load("sprite.png")
screen.blit(sprite, (20, 20))
pygame.quit()
Анимации¶
В pygame анимации создаются при помощи набора спрайтов, которые последовательно отрисовываются:
animation_set = [pygame.image.load(f"r{i}.png") for i in range(1, 6)]
window = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
i = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
window.fill((0,0,0))
window.blit(animation_set[i // 12], (100, 20))
i += 1
if i == 60:
i = 0
pygame.display.flip()
clock.tick(60)
Создаём список спрайтов, каждый из которых будет отдельным кадром анимации:
animation_set = [pygame.image.load(f"r{i}.png") for i in range(1, 6)]
Создаём часы, для ограничения количества кадров в секунду:
clock = pygame.time.Clock()
Вспомогательная переменная, которая поможет выбирать нужную анимацию в зависимости от номера кадра:
i = 0
Выбор анимации в зависимости от номера кадра и его отрисовка:
window.blit(animation_set[i // 12], (100, 20))
Изменение переменной, помогающей выбрать нужный кадр:
i += 1
if i == 60:
i = 0
Ограничение количества кадров в секунду, благодаря чему становится проще просчитывать анимации и синхронизировать события:
clock.tick(60)
Задания¶
Написать программу, которая будет писать в консоль названия нажатых клавиш. Реализовать поддержку enter, space, w, a, s, d, esc. Названия кнопок внутри библиотеки доступны в официальной документации: https://www.pygame.org/docs/ref/event.html
С помощью циклов, используя квадрат 10х10 пикселей и его след, нарисовать рамку 100х100 пикселей.
Написать программу, в которой по нажатию клавиш будет двигаться квадрат размером 20х20 пикселей. Учесть, что квадрат не должен выходить за границы экрана.
Доработать программу, чтобы квадрат при каждом движении менял свой цвет на случайный.
Реализовать анимацию движения персонажа. При движении влево или вправо должны показываться соответствующие анимации. Кадры для них взять из архива animations.zip
Обработка столкновений¶
Реализуйте игровую сцену, состоящую из движущейся цели и пушки, стреляющей снарядами.
"""
+-----------------------+
| |||||| | <- target
| |
| |
| * | <- bullet
| |
| |
| /'\ | <- cannon
+-----------------------+
"""
import random
import sys
import pygame
from pygame.color import THECOLORS
pygame.init()
WIDTH = 640
HEIGHT = 480
screen = pygame.display.set_mode((WIDTH, HEIGHT))
class Cannon:
def __init__(self):
# TODO(1.1): создайте атрибуты пушки:
# * Цвет
# * Список точек
# Пусть пушка отображается как равнобедренный треугольник с высотой
# и основанием по 50px. Отображается в середине окна
# на нижней границе, см. схему в начале файла.
...
def draw(self):
# TODO(1.2): отобразите созданную в __init__ последовательность точек
# заданным цветом.
...
class Bullet:
def __init__(self):
# TODO(2.1): создайте атрибуты снаряда.
# * Центр окружности снаряда
# * Радиус
# * Цвет
# * Скорость (для тестов использовать значение 3)
...
def draw(self):
# TODO(2.2): отобразите снаряд.
...
def move(self):
# TODO(2.3): реализуйте перемещение снаряда.
# Для этого нужно создать его новый центр со смещением speed по оси OY
# к началу коориднат.
...
class Target:
def __init__(self):
# TODO(3.1): создайте атрибуты мишени.
# * Цвет
# * Скорость
# * Прямоугольник
...
def draw(self):
# TODO(3.2): отобразите мишень.
...
def move(self):
# TODO(3.3): реализуйте движение мишени.
# При достижении края окна мишень должна менять направление движения
# на противположное. Это можно реализовать сменой знака сокрости.
...
colors = list(THECOLORS.values())
def get_random_color():
return random.choice(colors)
cannon = Cannon()
target = Target()
bullet = Bullet()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(THECOLORS['black'])
target.move()
bullet.move()
# TODO(2.4): если снаряд достиг верхней границы окна, создать новый снаряд.
# TODO(4.1): если мишень и снаряд пересеклись, сменить цвет мишени на
# случайный, создать новй снаряд.
# Для определения пересечения используйте метод прямоугольника:
# Rect.collidepoint(point)
cannon.draw()
target.draw()
bullet.draw()
pygame.display.flip()
pygame.time.wait(33)
Реализуйте простейший тир, в котором игрок должен кликать по цели.
import math
import random
import sys
import pygame
from pygame.color import THECOLORS
pygame.mixer.init(22050, -16, 2, 64)
pygame.init()
WIDTH = 640
HEIGHT = 480
screen = pygame.display.set_mode((WIDTH, HEIGHT))
color = THECOLORS['purple1']
circle_radius = 50
def distance(p1, p2):
# TODO(3.3): Реализуйте функцию, которая вычисляет
# расстояние между точками p1 и p2.
...
def point_in_circle(p, circle_center, circle_radius):
# TODO(3.2): Реализуйте функцию, которая возвращает True,
# если точка находится внутри круга.
# Для полноценной работы функции вам понадобится
# реализовать функцию distance, но написать определение
# принадлежности точки кругу вы можете уже сейчас.
...
def place_circle():
# TODO(1.1): Функция должна вернуть кортеж, состоящий из
# координат центра круга: (x, y)
...
# TODO(1.2): инициализируйте центр круга
circle_center = ...
# TODO(5.1): Загрузите звук выстрела.
# Воспользуйтесь конструктором
# pygame.mixer.Sound(file_path: str) -> Sound
shot = ...
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# TODO(2.1): Обработайте событие нажатия кнопки мыши
# pygame.MOUSEBUTTONDOWN
# TODO(2.2): При нажатии кнопки мыши смените цвет круга.
# TODO(3.1): Доработайте приложение так, чтобы круг менял цвет только
# если вы кликаете по нему. Для этого вам понадобирся реализовать
# функции point_in_circle и distance.
# TODO(4.1): доработайте приложение так, чтобы при
# клике по кругу он появлялся в случайной точке
# экрана.
# TODO(5.2): Воспроизведите звук выстрела в случае попадания по кругу.
# Используйте метод play() объекта класса Sound.
# TODO(6.1): Реализуйте подсчет очков. Если игрок попал в круг за
# секунду, то он получает 100 очков. За 2 секунды - 50. Дольше - 1.
...
screen.fill(THECOLORS['black'])
# TODO(1.3) Нарисуйте круг выбранного цвета.
...
pygame.display.flip()
pygame.time.wait(33)
Реализуйте движущийся шар, отскакивающий от стен.
import math
import sys
import pygame
from pygame.color import THECOLORS
pygame.init()
WIDTH = 1280
HEIGHT = 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
circle_center = (WIDTH // 2, HEIGHT // 2)
circle_radius = 50
circle_color = THECOLORS['purple2']
SPEED = 20
current_angle = -10
def get_move(angle):
angle = angle / 180. * math.pi
return (
int(SPEED * math.cos(angle)),
int(SPEED * math.sin(angle)))
def move_circle(center, move):
# TODO(1): функция возвращает новый центр окружности после смещения.
...
def get_angle(center):
# TODO(2): Функция принимает текущий центр круга и определяет,
# под каким углом он должен продолжать движение.
...
move = get_move(current_angle)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(THECOLORS['black'])
# TODO(3):
# * Вычислить угол движения круга.
# * Вычислить вектор движения
# * Вычислить новый центр окружности
pygame.draw.circle(screen, circle_color, circle_center, circle_radius)
pygame.display.flip()
pygame.time.wait(33)
Звук выстрела: shot.wav.
Змейка¶
Скачать шаблон: snake.py
import pygame
import random
import sys
# Размеры окна в пикселях
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 480
CELL_SIZE = 20
# Размеры сетки в ячейках
WIDTH = int(WINDOW_WIDTH / CELL_SIZE)
HEIGHT = int(WINDOW_HEIGHT / CELL_SIZE)
# Цвета
BG_COLOR = (0, 0, 0)
GRID_COLOR = (40, 40, 40)
APPLE_COLOR = (255, 0, 0)
APPLE_OUTER_COLOR = (155, 0, 0)
SNAKE_COLOR = (0, 255, 0)
SNAKE_OUTER_COLOR = (0, 155, 0)
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
HEAD = 0
FPS = 15
class Cell:
def __init__(self, x, y):
self.x = x
self.y = y
def main():
global FPS_CLOCK
global DISPLAY
pygame.init()
FPS_CLOCK = pygame.time.Clock()
DISPLAY = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('Wormy')
while True:
# Мы всегда будем начинать игру с начала. После проигрыша сразу
# начинается следующая.
run_game()
def run_game():
# TODO(2.1): создать яблоко в позиции (20, 10)
# TODO(3.1): создать змейку. Пусть она состоит из трех ячеек
# в строке 10 и столбцах 3, 4, 5.
# Какой тип данных удобен для представления змейки?
# TODO(4.1): задать исходное направление движения змейки.
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
terminate()
# TODO(7.1): обработайте событие pygame.KEYDOWN
# и при необходимости измените направление движения змейки.
# TODO(5.1): если змейка достигла границы окна, завершить игру.
# Для проверки воспользуйтесь функцией snake_hit_edge.
# TODO(8.1): если змейка задела свой хвост, завершить игру.
# Для проверки восппользуйтесь функцией snake_hit_self.
# TODO(6.1): обработайте ситуацию столкновения змейки с яблоком.
# В этом случае нужно:
# * Увеличить размер змейки
# * Создать новое яблоко.
# TODO(4.2): сдвинуть змейку в заданном направлении
# TODO(2.2): передать яблоко в функцию отрисовки кадра
# TODO(3.2): передать змейку в функцию отрисовки кадра
draw_frame(None, None)
FPS_CLOCK.tick(FPS)
def draw_frame(snake, apple):
DISPLAY.fill(BG_COLOR)
draw_grid()
draw_snake(snake)
draw_apple(apple)
pygame.display.update()
def draw_grid():
# TODO(1.2): нарисовать сетку.
# Шаг CELL_SIZE
# Цвет GRID_COLOR
# https://www.pygame.org/docs/ref/draw.html#pygame.draw.line
...
def draw_apple(apple):
# TODO(2.3): нарисовать яблоко.
...
def draw_snake(snake):
# TODO(3.3): нарисовать змейку.
...
def draw_cell(cell, outer_color, inner_color):
# TODO(2.4): вспомогательная функция для рисования ячейки.
# Ячейка будет состоять из двух квадратов разных цветов:
# Больший квадрат закрашивается цветом outer_color,
# меньший - inner_color.
# Расстояние между внешним и внутренним квадратом
# принять за 4 пикселя.
...
def move_snake():
# TODO(4.3): реализовать перемещение змейки на одну ячейку
# в заданном направлении.
# * Какие параметры будет принимать функция?
# * Из каких действий будет состоять перемещение змейки?
...
def get_snake_new_head():
# TODO(4.4): реализовать функцию определения нового
# положения головы змейки.
# * Какие параметры будет принимать функция?
# * Что функция будет возвращать?
...
def snake_hit_edge():
# TODO(5.2): функция возвращает True,
# если змейка пересекла одну из границ окна.
...
def snake_hit_apple():
# TODO(6.2): функция возвращает True, если голова
# змейки находится в той же ячейке, что и яблоко.
...
def snake_grow():
# TODO(6.3): предложите максимально простой
# способ увеличения длины змейки.
...
def new_apple():
# TODO(6.4): функция возвращает случайную ячейку,
# в которой будет располагаться яблоко.
# Для генерации случайной координаты воспользуйтесь
# функцией random.randint(a, b)
...
def get_direction():
# TODO(7.3): функция возвращает направление движения
# в зависимости от нажатой клавиши:
# * pygame.K_LEFT
# * pygame.K_RIGHT
# * pygame.K_UP
# * pygame.K_DOWN
# Если нажата клавиша противоположного направления движения,
# то не менять направление.
...
def snake_hit_self():
# TODO(8.2): функция возвращает True, если голова змеи
# пересеклась хотя бы с одним блоком хвоста.
...
def terminate():
pygame.quit()
sys.exit()
if __name__ == '__main__':
main()