Python за ~~час~~ сколько-то.
Для начала я хочу пожелать всем удачи как с экзаменом, так и подготовкой к нему.
Всего будет 16 секций с вопросами (не будут рассмотрены 11, 13, 14, 17, 21-24 вопросы). В каждой секции -- краткое объяснение, варианты ответа на вопрос, а затем длинная теория с кодом. К слову, код можно будет запустить прямо в браузере!
Важно: документ в процессе написания! Большая часть теории не готова.
Пара моментов по написанию кода:
- в Python есть понятие "блока кода", то есть когда
операции принадлежат какой-то бόльшей конструкции (типа
if,for,def); и важно, чтобы новый блок кода выделялся отступом в 4 пробела. Проще говоря: видишь двоеточие -- добавляй четыре пробела перед каждой строкой, которая принадлежит конструкции с двоеточием:for a in b: ... if a: if q: ... else: ... def z(): ... class E: def __init__(self): ... # и так по нарастающей - 2.
Поехали.
| Содержимое |
|---|
| 1. Введение: переменные, |
2. Библиотека math. |
| 3. Исключения (exceptions) в Python. |
| 4. [условные] ветвления и циклы. |
| 5. Строки: базовые операции, функции и методы |
| 6. Списки: базовые операции, функции и методы. Генераторы списков. Вложенные списки. |
| 7. Кортежи: базовые операции. |
| 8. Множества: базовые операции. Генераторы множеств. |
| 9. Словари: способы создания, базовые операции и методы. |
| 10. Функции. Передача параметров в функцию. Область видимости. |
| 11. не рассматривается Доп. возможности при работе с функциями. |
| 12. Функциональные возможности: лямбда-функции. |
| 13. не рассматривается, см. 18 вопрос Файлы. |
| 14. не рассматривается Хранение структурированных данных в файлах. |
| 15. Модули и пакеты. |
| 16. Запуск программ. Установка сторонних модулей. |
| 17. не рассматривается Регулярные выражения. |
| 18. Работа с файлами и папками. |
| 19. Работа с датой и временем. |
| 20. Объектно-ориентированное программирование (ООП). |
| 21. не рассматривается Библиотека Tkinter. |
22. не рассматривается Работа с файлами .xls (таблицы Excel), .pdf (документы PDF) и .doc (документы Word). |
| 23. не рассматривается Формат JSON. |
| 24. не рассматривается Формат CSV. |
Введение: переменные, константы, типы данных, операторы, выражения, ввод-вывод.
Коротко: переменные в Python создаются с помощью записи название переменной = значение.
С помощью переменных можно хранить какое-либо значение.
В Python нет констант -- все переменные можно изменить, но можно сделать "константу", записав
название переменной большими буквами.
В Python есть несколько типов данных, среди которых целочисленный (int), вещественный (float) и строковый (str).
К переменным и типам данных можно применять операторы, например, математические -- сложение, вычитание и т. д.
Несколько операторов образуют выражение. Выражение будет вычислено во время выполнения программы. Выражение можно
присвоить переменной.
С помощью print можно вывести какие-либо данные, а с помощью input -- ввести.
Другие варианты ответа
А теперь теория.
нажми сюда
Переменные -- один из главных элементов программы. С их помощью можно сохранять какое-либо значение -- число, текст и так далее.
Определяется переменная следующим образом:
название = значение
# примеры
num = 1
text = "текст"
pi = 3.14
truth = TrueПри этом:
- можно будет изменить значение переменной на любое другое
- нельзя объявить переменную без значения
- можно присвоить переменной выражение (об этом далее)
Как таковых констант в Python нет, да и вряд ли они появятся. Любую переменную можно изменить. Вообще любую.
Однако бывает так, что константное значение сохранить надо. Для этого в Python принято такое соглашение: писать название "константы" заглавными буквами. Так что если видите переменную, название которой написано "капсом" -- лучше не изменять её.
PI = 3.14
ERROR = "ошибка"
# и т. д.Тип данных задаёт набор операций, который можно провести над данными. Например, числовой тип данных позволит нам, скажем, провести сложение.
Основные (или же "примитивные") типы данных в Python:
| тип | обозначение | что может хранить |
|---|---|---|
| целочисленный | int | целые числа (1, 42, 1024) |
| вещественный | float | дробные числа (0.5, 3.14, 999.0 |
| булев (логический) | bool | две логических константы (True, False) |
| строковый | str | любой текст (aaa, lorem ipsum) |
| комплексный | complex | комплексные числа с мнимой единицей (1j, 4j, 100j) |
(текущий тип данных у переменной или значения можно узнать с помощью функции type)
Между этими типами можно проводить конверсию или же приведение к другому типу. Проще говоря -- можно сделать из текста число, и наоборот:
a = 42
print(type(a)) # int
b = "58"
print(type(b)) # str
b = int(b)
c = a + b
print(c) # 100
d = "num: " + str(c)
print(d) # num: 100Как уже было сказано, над типами данных можно проводить некоторые операции. Для этого используются операторы. В основном это какие-то символы типа плюса или скобок. Для того, чтобы оператор выполнил своё действие, ему нужны данные. Переменные или значения. Когда они являются частью операции, то называются операндами:
# a -- операнд, b -- тоже операнд, а + -- оператор
a + bРассмотрим самые базовые из операторов:
| оператор | операция | тип данных | пример |
|---|---|---|---|
+ | сложение | числа | 1 + 2 |
- | вычитание | числа | 3 - 1 |
* | умножение | числа | 2 * 2 |
/ | деление с дробной частью | числа | 10 / 5 |
% | получение остатка | числа | 9 % 4 |
// | деление без остатка | числа | 7 // 2 |
** | возведение в степень | числа | 10**2 |
+ | конкатенация (сложение строк) | строки | "a" + 'b' + "c" |
- | повторение строки | строки | "abc" * 10 |
% | форматирование строки | строки | "text: %s" % text |
\\ | экранирование (вставка спец. символа) | строки | "\n\t tab and new line\\oh" |
f, {} | f-строка (форматирование) | строки | f'text: {text}' |
() | вызов функции | функции | func() |
. | получение свойства или вызов метода | любой | something.prop |
Сама по себе операция является выражением -- чем-то, что можно записать, а во время работы программы и вычислить. В выражение может входить сколько угодно операторов:
a = f"equation: {PI * radius + (round(h) / 2)} \t = \t {10 + var}"Ну и, наконец, самое самое. Ввод и вывод.
Вывести какое-либо значение можно с помощью функции print:
a = 28
print("hola!")
print(42)
print(a)
print(print()) # 0_oПри этом каждый новый вызов print будет печатать значения на новой строке консоли.
Если этого не нужно, просто передаём аргумент end с нужным нам концом строки:
print("the text: ", end = "")
print(text)Если же нам нужно ввести данные, то тут поможет функция input:
i = input()Нужно "подсказать" пользователю, а что ему нужно ввести? Передаём строку в input:
e = input("Введите Е: ")По умолчанию input возвращает строковый тип данных.
Если нужно число, то надо сделать приведение:
a = int(input("Введите A: "))Библиотека math.
Коротко: в библиотеке math есть куча математических функций,
например, квадратный корень, синус, модуль числа, и так далее.
Чтобы добавить эту библиотеку, надо написать import math, а затем обращаться к её функциям через точку.
К примеру, для вычисления квадратного корня можно написать math.sqrt(), а как аргумент передать число.
Другие варианты ответа
А теперь теория.
нажми сюда
math -- одна из множества стандартных библиотек. Её предназначение -- дать погромистам базовые математические
функции.
Для использования math необходимо добавить (импортировать) её:
import mathИ далее обращаться к её функциям через точку:
math.piСписок самых используемых функций из math:
| функция | пример # вывод | что делает |
|---|---|---|
pow(num, num) | math.pow(2, 10) # 1024 | возводит число в степень (аналог. 2**10) |
sqrt(num) | math.sqrt(4) # 2 | извлекает квадратный корень (аналог. 4**0.5) |
floor(float) | math.floor(2.5) # 2 | округление до ближайшего наименьшего целого (до "пола") |
ceil(float) | math.ceil(2.5) # 3 | округление до ближайшего наибольшего целого (до "потолка") |
cos(num), sin, tan, acos, asin, atan | math.sin(math.pi) # 1.0 | тригонометрические функции: косинус, синус и т. д. |
log(num, num) | math.log(9, 3) # 2 | логарифм числа по основанию |
abs(num) | abs(-10) # 10 | модуль числа (функция не из math) |
round(float) | round(3.3) # 3 | банковское округление (функция не из math) |
pi | math.pi | число пи () |
e | math.e | число Эйлера () |
Исключения (exceptions) в Python.
от себя: а накой чорт они идут третьим вопросом?
Коротко: исключениями в Python называются ошибки. Когда возникает такая ошибка (ещё говорят "поднялось исключение"),
то программа прекращает своё выполнение (если эта ошибка не была обработана). Примеры исключений: деление на ноль,
использование несуществующего индекса у списка, использование несуществующей переменной. Исключение можно обработать
с помощью конструкции try/except/finally.
Другие варианты ответа
А теперь теория.
нажми сюда
В процессе работы программы на Python может возникнуть куча ошибок. Они делятся на два типа: ошибки в синтаксисе (т. е. сам код написан криво/неверно) и ошибки выполнения. Последние как раз и называются исключениями (a. k. a. exceptions).
Пара ситуаций для примера, когда может возникнуть исключение.
- Не удалось преобразовать тип данных
a = "один два три" b = int(a) # !!! TypeError - Деление на ноль
a = 0 b = 5 / a # !!! ZeroDivisionError - Переменная не объявлена
b = a + 2 # !!! NameError - Индекс за пределами списка
a = [1, 2, 3] b = a[10] # !!! IndexError - Несуществующее свойство
a = "один два три" b = a.escaped # !!! AttributeError c = a.escaped() # !!! AttributeError - Несуществующий ключ у словаря
a = {"one": 1, "two": 2} b = a["three"] # !!! KeyError - Слишком глубокая рекурсия
def a(): a() # работает бесконечно b = a() # !!! RecursionError - ...и так далее...
Исключений можно избежать двумя способами.
Первый -- не писать такой код, что может поднять исключение.
Но бывают такие ситуации, когда "угадать" входные данные будет трудно или вовсе невозможно.
Для этого есть второй способ -- конструкция try/except/finally.
Всё просто:
- помещаем в блок
tryкод, в котором есть риск возникновения исключенияtry: a = get_a() b = 10 / a - в блоках
except(которых может быть сколько угодно) обрабатываем ошибкиexcept ZeroDivisionError: # обработает деление на ноль print("Деление на ноль") except ArithmeticError as e: # обработает любую ошибку этого типа + выведет её print("Ошибка вычислений: ", e) except: # обработает все остальные ошибки print("Неизвестная ошибка") - в блоке
finallyобрабатываем код, который выполнится послеtryи всехexceptов, даже если ошибок не былоfinally: print("Завершаем работу") free_a(a)
Полный код:
try:
a = get_a()
b = 10 / a
except ZeroDivisionError: # обработает деление на ноль
print("Деление на ноль")
except ArithmeticError as e: # обработает любую ошибку этого типа + выведет её
print("Ошибка вычислений: ", e)
except: # обработает все остальные ошибки
print("Неизвестная ошибка")
finally:
print("Завершаем работу")
free_a(a)Также можно самому поднять исключение с помощью оператора raise:
raise Exception("Моя ошибка!")[условные] ветвления и циклы.
Коротко: в Python можно делать ветвление, чтобы какой-то код выполнялся при определённых условиях.
Скажем, если число больше другого числа. Для этого используется конструкция if/else.
В блоке if пишется условие, затем в теле блока пишутся операторы, которые должны быть выполнены при истинности условия,
а в теле else пишутся операторы, которые выполнятся, если условие ложно. Можно добавить блоки elif, которые
позволят проверить несколько условий. Блоки else и elif необязательны.
#TBD
Объектно-ориентированное программирование (ООП).
Коротко: объектно-ориентированное программирование -- это такой подход к написанию программы, в котором
всё строится вокруг классов и объектов.
Класс в данном случае -- некоторое подобие чертежа для какой-то
сущности -- например, машины, животного, фигуры и так далее.
Каждый класс обладает какими либо свойствами (=переменными) и методами (=функциями).
Объект же -- конкретный пример класса, например, в случае с классом "машина" это может быть какая-либо конкретная машина.
Класс определяется ключевым словом class,
Для определения свойства класса нужно задать его в конструкторе.
У классов и объектов можно определить свойства и методы.
Свойства -- это какие-либо переменные, привязанные к объекту. Например, длина фигуры или цвет машины.
А методы -- это функции, которые выполняют действия над этим объектом. Например, поиск площади или исполнение "поездки".
Свойства определяются в функции-конструкторе (def __init__(self):), а методы -- в блоке класса.
Классы проявляют несколько общих для них свойств: возможность наследоваться (то есть перенимать свойства и методы от "родительского" класса),
инкапсулировать какие-то свойства/методы (то есть намеренно скрывать их от "чужого" кода, чтобы этот класс не сломался) и
выполнять методы полиморфно (то есть одинаковый метод у двух классов может использоваться одинаково).
А теперь теория.
нажми сюда
Итак. ООП ака Объектно-Ориентированное Программирование пришло на смену функциональному и структурному. Зачем, а главное нафига? Ну, есть несколько причин:
- рано или поздно появится нужда описывать объекты из реального мира -- с конкретными свойствами и/или действиями
- к примеру -- машина -- для простоты у неё есть марка, цвет и несколько действий
- было бы неплохо определять какой-то базовый объект, а от него делать подобие иерархии
- та же машина может быть "потомком" транспортного средства, забирая от него действие передвижения; а может быть обобщением для всех машин, которые могут различаться, например, устройством двигателя
- и чтобы ещё действия от "родителя" объекта можно было выполнять и над потомком
- машина же может перемещаться, как и любое другое транспортное средство
- и чтобы можно было скрыть какие-то особенные для этого объекта свойства от других объектов
- для всё той же машины: мы не сможем заглянуть и покопаться в двигателе, пока та едет
И вот мы как бы и подошли к главным элементам ООП -- классам, объектам, свойствам и методам.
Класс есть описание какого-то объекта. Будь то реальная сущность, или воображаемая кучка из данных.
Чтобы создать класс в Python, мы используем ключевое слово class.
Далеко не отходя от темы с машинами: есть класс Car ("машина"), который будет использоваться для описания машины.
И вот как мы бы его определили:
class Car:
... # здесь что-то будетОбъект же есть... объект, созданный по подобию этого класса! Ещё говорят, что объект -- это экземпляр класса. Его можно создать, вызвав класс как функцию.
car = Car()Как я уже сказал, в классе мы описываем свойства нашего будущего объекта. Свойства -- это просто переменные, которые привязаны к конкретному экземпляру. Мы можем получить их после создания экземпляра, или даже изменить.
Возникает вопрос: а где можно определить (т. е. создать/описать) свойства нашего объекта?
Для этого у классов существует магический метод (да, он так и называется) -- конструктор. Именно он и вызывается, когда создаётся экземпляр класса. Мы можем воспользоваться конструктором, чтобы передать какие-то данные в объект класса.
Конструктор определяется как функция с названием __init__, и первым её аргументом всегда идёт self --
это и есть создаваемый объект, который мы будем настраивать в конструкторе.
Пример для машины:
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
# ...
car = Car("Fahrzeug", "чёрный")
print(car.color) # чёрныйВ этом примере мы создали класс, конструктор которого получает марку и цвет машины. Затем мы задаём одноимённые свойства в объекте.
Конструктор -- это метод. А что такое метод?
Метод -- это функция, которая выполняет действия над конкретным экземпляром.
Все методы должны иметь как минимум один аргумент -- self, который будет представлять этот самый экземпляр.
Определим для машины метод drive, который будет как бы "перемещать" машину.
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
def drive(self):
print(f"{self.brand} едет")
car = Car("Fahrzeug", "чёрный")
car.drive()
# к слову, аналогично такой записи:
Car.drive(car)Немного усложним наш класс машины, добавив в него новое свойство -- топливо.
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
self.fuel = 5
def drive(self, speed = 1):
if self.fuel <= 0:
print("недостаточно топлива")
else:
print(f"{self.brand} едет")
self.fuel -= speed
car = Car("Fahrzeug", "чёрный")
car.drive()
# немного разгоним машину
car.drive(5)
# уже не выйдет поехать
car.drive()
# пополним топливо...
car.fuel = 10
# и снова в путь
car.drive()
С описанием класса разобрались. Что же насчёт второго пункта -- создания иерархии из объектов.
Вообще, это называется наследованием, и это -- один из трёх принципов ООП.
В наследовании мы можем создать класс на основе уже существующего. А потом использовать его свойста или методы. Или определить свои. Или переписать уже существующие. Тут уже на свой вкус.
Чтобы унаследовать какой-то класс, рядом с определением дочернего класса (в скобках) нужно указать название родителя.
Например, добавим нашей машине родительский класс -- транспортное средство. И создадим ещё одного наследника для ТС -- самолёт.
class Vehicle:
brand = "неизвестное"
def drive(self):
print(f"{self.brand} перемещается")
class Car(Vehicle):
def __init__(self, brand, color):
super().__init__()
self.brand = brand
self.color = color
def drive(self):
print(f"{self.brand} едет")
class Airplane(Vehicle):
def __init__(self, brand):
self.brand = brand
def drive(self):
print(f"{self.brand} летит")
car = Car("Fahrzeug", "чёрный")
plane = Airplane("Paperplane")
car.drive()
print(plane.brand)Как мы видим, в классе Vehicle определено свойство brand для марки ТС и метод drive для "перемещения" ТС.
Наследники Vehicle переопределяют их под себя: машина Car едет, а самолёт Airplane летит.ц
В __init__ мы видим какую-то функцию super. Она представляет собой родительский класс.
Также замечу, что оба класса имеют общий метод drive. Это значит, что мы можем использовать данный метод
в каком-то другом коде, не зная, а с каким именно классом мы сейчас работаем:
def drive_if(surface, vehicle):
if surface == "воздух":
print("поднимаем ТС на воздух")
elif surface == "земля":
print("разгоняем ТС")
vehicle.drive()
car = Car("Fahrzeug", "чёрный")
drive_if("земля", car)Это, кстати, тоже принцип ООП, и называется он полиморфизм. Под полиморфизмом имеется ввиду использование объектов дочерних классов там, где можно использовать экземпляр родительского, и при этом результат от этого использования ожидается одинаковый.
Вернёмся к варианту класса машины, в котором мы добавили свойство fuel (топливо).
Мы не хотим, чтобы пользователь класса мог свободно изменять топливо. Нам хочется скрыть это свойство. Для этого можно применить третий принцип ООП -- инкапсуляцию.
Его смысл так и значится: скрытие элементов класса для обеспечения безопасности.
В Python скрыть метод или свойство можно двумя способами:
- написав перед названием одно нижнее подчёркивание (
field->_field), но обратиться к нему извне всё ещё будет возможно (cls._field) - написав два нижних подчёркивания (
field->__field), и тогда поле точно скроется (но вариантcls._НазваниеКласса__fieldне отменяется)
Пример для топлива:
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
self.__fuel = 5
def refuel(self, amount):
if amount > 5:
print("слишком много!")
else:
print("заправляемся на ", amount)
self.__fuel += amount
def drive(self, speed = 1):
if self.__fuel <= 0:
print("недостаточно топлива")
else:
print(f"{self.brand} едет")
self.__fuel -= speed
car = Car("Fahrzeug", "чёрный")
car.drive(5) # "Fahrzeug едет" * 5
car.drive() # недостаточно топлива
# car.__fuel = 5 # ! ошибка: такого свойства нет
car.refuel(10) # слишком много!
car.refuel(5) # заправляемся на 5
car.drive() # Fahrzeug едет© Egor Bron.
Треугольник - хороший повод задуматься. Просто задуматься.