Основы Python

Введение в написание программ

Программа на языке Python состоит из набора инструкций. Каждая инструкция помещается на новую строку. Например:

print(2+3) print("Hello")

Большую роль в Python играют отступы. Неправильно поставленный отступ фактически является ошибкой. Например, в следующем случае мы получим ошибку, хотя код будет практически аналогичен приведенному выше:

print(2+3) print("Hello")

Поэтому стоит помещать новые инструкции сначала строки. В этом одно из важных отличий пайтона от других языков программирования, как C# или Java.

Однако стоит учитывать, что некоторые конструкции языка могут состоять из нескольких строк. Например, условная конструкция if:

if 1< 2: print("Hello")

В данном случае если 1 меньше 2, то выводится строка "Hello". И здесь уже должен быть отступ, так как инструкция print("Hello") используется не сама по себе, а как часть условной конструкции if. Причем отступ, согласно руководству по оформлению кода, желательно делать из такого количество пробелов, которое кратно 4 (то есть 4, 8, 16 и т.д.) Хотя если отступов будет не 4, а 5, то программа также будет работать.

Таких конструкций не так много, поэтому особой путаницы по поводу где надо, а где не надо ставить пробелы, не должно возникнуть.

Регистрозависимость

Python - регистрозависимый язык, поэтому выражения print и Print или PRINT представляют разные выражения. И если вместо метода print для вывода на консоль мы попробуем использовать метод Print:

Print("Hello World")

то у нас ничего не получится.

Комментарии

Для отметки, что делает тот или иной участок кода, применяются комментарии. При трансляции и выполнении программы интерпретатор игнорирует комментарии, поэтому они не оказывают никакого влияния на работу программы.

Комментарии в Python бывают блочные и строчные. Все они предваряются знаком решетки (#).

Блочные комментарии ставятся в начале строки.

Строчные комментарии располагаются на той же строке, что и инструкции языка:

print("Hello World") # Вывод сообщения на консоль

Основные функции

Python предоставляет ряд встроенных функций. Некоторые из них используются очень часто, особенно на начальных этапах изучения языка, поэтому рассмотрим их.

Основной функцией для вывода информации на консоль является функция print(). В качестве аргумента в эту функцию передается строка, которую мы хотим вывести:

print("Hello Python")

Если же нам необходимо вывести несколько значений на консоль, то мы можем передать их в функцию print через запятую:

print("Full name:", "Tom", "Smith")

В итоге все переданные значения склеятся через пробелы в одну строку:

Full name: Tom Smith

Если функция print отвечает за вывод, то функция input отвечает за ввод информации. В качестве необязательного параметра эта функция принимает приглашение к вводу и возвращает введенную строку, которую мы можем сохранить в переменную:

name = input("Введите имя: ") print("Привет", name)

Консольный вывод:

Введите имя: Евгений

Привет Евгений

Переменные и типы данных

Переменная хранит определенные данные. Название переменной в Python должно начинаться с алфавитного символа или со знака подчеркивания и может содержать алфавитно-цифровые символы и знак подчеркивания. И кроме того, название переменной не должно совпадать с названием ключевых слов языка Python. Ключевых слов не так много, их легко запомнить: and, as, assert, break, class, continue, def, del, elif, else, except, False, finally, for, from, global, if, import, in, is, lambda, None, nonlocal, not, or, pass, raise, return, True, try, while, with, yield.

Например, создадим переменную:

name = "Tom"

Здесь определена переменная name, которая хранит строку "Tom".

В пайтоне применяется два типа наименования переменных: camel case и underscore notation.

Camel case подразумевает, что каждое новое подслово в наименовании переменной начинается с большой буквы. Например:

userName = "Tom"

Underscore notation подразумевает, что подслова в наименовании переменной разделяются знаком подчеркивания. Например:

user_name = "Tom"

И также надо учитывать регистрозависимость, поэтому переменные name и Name будут представлять разные объекты.

Переменная хранит данные одного из типов данных. В Python существует множество различных типов данных, которые подразделяются на категории: числа, последовательности, словари, наборы:

  • boolean - логическое значение True или False
  • int - представляет целое число, например, 1, 4, 8, 50.
  • float - представляет число с плавающей точкой, например, 1.2 или 34.76
  • complex - комплексные числа
  • str - строки, например "hello". В Python 3.x строки представляют набор символов в кодировке Unicode
  • bytes - последовательность чисел в диапазоне 0-255
  • byte array - массив байтов, аналогичен bytes с тем отличием, что может изменяться
  • list - список
  • tuple - кортеж
  • set - неупорядоченная коллекция уникальных объектов
  • frozen set - то же самое, что и set, только не может изменяться (immutable)
  • dict - словарь, где каждый элемент имеет ключ и значение

Python является языком с динамической типизацией. Он определяет тип данных переменной исходя из значения, которое ей присвоено. Так, при присвоении строки в двойных или одинарных кавычках переменная имеет тип str. При присвоении целого числа Python автоматически определяет тип переменной как int. Чтобы определить переменную как объект float, ей присваивается дробное число, в котором разделителем целой и дробной части является точка. Число с плавающей точкой можно определять в экспоненциальной записи:

x =3.9e3 print(x) # 3900.0 x =3.9e-3 print(x) # 0.0039

Число float может иметь только 18 значимых симолов. Так, в данном случае используются только два символа - 3.9. И если число слишком велико или слишком мало, то мы можем записывать число в подобной нотации, используя экспоненту. Число после экспоненты указывает степень числа 10, на которое надо умножить основное число - 3.9.

При этом в процессе работы программы мы можем изменить тип переменной, присвоив ей значение другого типа:

user_id = "12tomsmith438" # тип str print(user_id)
user_id = 234 # тип int print(user_id)

С помощью функции type() динамически можно узнать текущий тип переменной:

user_id ="12tomsmith438" print(type(user_id)) # user_id =234 # <class 'str'> print(type(user_id)) # <class 'int'>

Операции с числами

Арифметические операции

Python поддерживает все распространенные арифметические операции:

  • +

Сложение двух чисел:

​print(6 + 2) # 8
  • -

Вычитание двух чисел:

​print(6 - 2) # 4
  • *

Умножение двух чисел:

​print(6 * 2) # 12
  • /

Деление двух чисел:

​print(6 / 2) # 3.0
  • //

Целочисленное деление двух чисел:

print(7 / 2) # 3.5 print(7 // 2) # 3​

Данная операция возвращает целочисленный результат деления, отбрасывая дробную часть

  • **

Возведение в степень:

print(6 ** 2) # Возводим число 6 в степень 2. Результат - 36
  • %

Получение остатка от деления:

print(7 % 2) # Получение остатка от деления числа 7 на 2. Результат - 1

В данном случае ближайшее число к 7, которое делится на 2 без остатка, это 6. Поэтому остаток от деления равен 7 - 6 = 1

При последовательном использовании нескольких арифметических операций их выполнение производится в соответствии с их приоритетом. В начале выполняются операции с большим приоритетом. Приоритеты операций в порядке убывания приведены в следующей таблице.

Операции

Направление

**

Справо налево

* / // %

Слева направо

+ -

Слева направо

Пусть у нас выполняется следующее выражение:

number = 3 + 4 * 5 ** 2 + 7 print(number) # 110

Здесь начале выполняется возведение в степень (5 ** 2) как операция с большим приоритетом, далее результат умножается на 4 (25 * 4), затем происходит сложение (3 + 100) и далее опять идет сложение (103 + 7).

Чтобы переопределить порядок операций, можно использовать скобки:

number = (3 + 4) * (5 ** 2 + 7) print(number) # 224

Следует отметить, что в арифметических операциях могут принимать участие как целые, так и дробные числа. Если в одной операции участвует целое число (int) и число с плавающей точкой (float), то целое число приводится к типу float.

Арифметические операции с присвоением

Ряд специальных операций позволяют использовать присвоить результат операции первому операнду:

  • +=

Присвоение результата сложения

  • -=

Присвоение результата вычитания

  • *=

Присвоение результата умножения

  • /=

Присвоение результата от деления

  • //=

Присвоение результата целочисленного деления

  • **=

Присвоение степени числа

  • %=

Присвоение остатка от деления

Примеры операций:

number = 10 number += 5 print(number) # 15 number -= 3 print(number) # 12 number *= 4 print(number) # 48

Функции преобразования чисел

Ряд встроенных функций в Python позволяют работать с числами. В частности, функции int() и float() позволяют привести значение к типу int и float соответственно.

Например, пусть у нас будет следующий код:

first_number = "2" second_number = 3 third_number = first_number + second_number

Мы ожидаем, что "2" + 3 будет равно 5. Однако этот код сгенерирует исключение, так как первое число на самом деле представляет строку. И чтобы все заработало как надо, необходимо привести строку к числу с помощью функции int():

first_number = "2" second_number = 3 third_number = int(first_number) + second_number print(third_number) # 5

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

first_number = 2.0001 second_number = 5 third_number = first_number / second_number print(third_number) # 0.40002000000000004

В данном случае мы ожидаем получить число 0.40002, однако в конце через ряд нулей появляется еще какая-то четверка. Или еще одно выражение:

print(2.0001 + 0.1) # 2.1001000000000003

В этот случае для округления результата мы можем использовать функцию round():

first_number = 2.0001 second_number = 0.1 third_number = first_number + second_number print(round(third_number, 4)) # 2.1001

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

Представление числа

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

Для определения числа в двоичной системе перед его значением ставится 0 и префикс b:

x = 0b101 # 101 в двоичной системе равно 5

Для определения числа в восьмеричной системе перед его значением ставится 0 и префикс o:

a = 0o11 # 11 в восьмеричной системе равно 9

Для определения числа в шестнадцатеричной системе перед его значением ставится 0 и префикс x:

y = 0x0a # a в шестнадцатеричной системе равно 10

И с числами в других системах измерения также можно проводить арифметические операции:

x = 0b101 # 5 y = 0x0a # 10 z = x + y # 15 print("{0} in binary {0:08b} in hex {0:02x} in octal {0:02o}".format(z))

Для вывода числа в различных системах исчисления используются функция format, которая вызывается у строки. В эту строку передаются различные форматы. Для двоичной системы "{0:08b}", где число 8 указывает, сколько знаков должно быть в записи числа. Если знаков указано больше, чем требуется для числа, то ненужные позиции заполняются нулями. Для шестнадцатеричной системы применяется формат "{0:02x}". И здесь все аналогично - запись числа состоит из двух знаков, если один знак не нужен, то вместо него вставляется ноль. А для записи в восьмеричной системе испольуется формат "{0:02o}".

Результат работы скрипта:

15 in binary 00001111 in hex 0f in octal 17

Условные выражения

Ряд операций представляют условные выражения. Все эти операции принимают два операнда и возвращают логическое значение, которое в Python представляет тип boolean. Существует только два логических значения - True (выражение истинно) и False (выражение ложно).

Операции сравнения

Простейшие условные выражения представляют операции сравнения, которые сравнивают два значения. Python поддерживает следующие операции сравнения:

  • ==

Возвращает True, если оба операнда равны. Иначе возвращает False.

  • !=

Возвращает True, если оба операнда НЕ равны. Иначе возвращает False.

  • > (больше чем)

Возвращает True, если первый операнд больше второго.

  • < (меньше чем)

Возвращает True, если первый операнд меньше второго.

  • >= (больше и равно)

Возвращает True, если первый операнд больше или равен второму.

  • <= (меньше и равно)

Возвращает True, если первый операнд меньше или равен второму.

Примеры операций сравнения:

a = 5 b = 6 result = 5 == 6 # сохраняем результат операции в переменную print(result) # False - 5 не равно 6 print(a != b) # True print(a > b) # False - 5 меньше 6 print(a < b) # True bool1 = True bool2 = False print(bool1 == bool2) # False - bool1 не равно bool2

Операции сравнения могут сравнивать различные объекты - строки, числа, логические значения, однако оба операнда операции должны представлять один и тот же тип.

Логические операции

Для создания составных условных выражений применяются логические операции. В Python имеются следующие логические операторы:

  • and (логическое умножение)

Возвращает True, если оба выражения равны True

age = 22 weight = 58 result = age > 21 and weight == 58 print(result) # True

В данном случае оператор and сравнивает результаты двух выражений: age > 21 weight == 58. И если оба этих выражений возвращают True, то оператор and также возвращает True. Причем в качестве одно из выражений необязательно выступает операция сравнения: это может быть другая логическая операция или просто переменная типа boolean, которая хранит True или False.

age = 22 weight = 58 isMarried = False result = age > 21 and weight == 58 and isMarried print(result) # False, так как isMarried = False
  • or (логическое сложение)

Возвращает True, если хотя бы одно из выражений равно True

age = 22 isMarried = False result = age > 21 or isMarried print(result) # True, так как выражение age > 21 равно True
  • not (логическое отрицание)

Возвращает True, если выражение равно False

age = 22 isMarried = False print(not age > 21) # False print(not isMarried) # True

Если один из операндов оператора and возвращает False, то другой операнд уже не оценивается, так как оператор в любом случае возвратит False. Подобное поведение позволяет немного увеличить производительность, так как не приходится тратить ресурсы на оценку второго операнда.

Аналогично если один из операндов оператора or возвращает True, то второй операнд не оценивается, так как оператор в любом случае возвратит True.

Операции со строками

Строка представляет последовательность символов в кодировке Unicode, заключенных в кавычки. Причем в Python мы можем использовать как одинарные, так и двойные кавычки:

name = "Tom" surname = 'Smith' print(name, surname) # Tom Smith

Одной из самых распространенных операций со строками является их объединение или конкатенация. Для объединения строк применяется знак плюса:

name = "Tom" surname = 'Smith' fullname = name + " " + surname print(fullname) # Tom Smith

С объединением двух строк все просто, но что, если нам надо сложить строку и число? В этом случае необходимо привести число к строке с помощью функции str():

name = "Tom" age = 33 info = "Name: " + name + " Age: " + str(age) print(info) # Name: Tom Age: 33

Эскейп-последовательности

Кроме стандартных символов строки могут включать управляющие эскейп-последовательности, которые интерпретируются особым образом. Например, последовательность \n представляет перевод строки. Поэтому следующее выражение:

print("Время пришло в гости отправится\nЖдет меня старинный друг")

На консоль выведет две строки:

Время пришло в гости отправится

Ждет меня старинный друг

Тоже самое касается и последовательности \t, которая добавляет табляцию.

Кроме того, существуют символы, которые вроде бы сложно использовать в строке. Например, кавычки. И чтобы отобразить кавычки (как двойные, так и одинарные) внутри строки, перед ними ставится слеш:

print("Кафе \"Central Perk\"")

Сравнение строк

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

str1 = "1a" str2 = "aa" str3 = "Aa" print(str1 > str2) # False, так как первый символ в str1 - цифра print(str2 > str3) # True, так как первый символ в str2 - в нижнем регистре

Поэтому строка "1a" условно меньше, чем строка "aa". Вначале сравнение идет по первому символу. Если начальные символы обоих строк представляют цифры, то меньшей считается меньшая цифра, например, "1a" меньше, чем "2a".

Если начальные символы представляют алфавитные символы в одном и том же регистре, то смотрят по алфавиту. Так, "aa" меньше, чем "ba", а "ba" меньше, чем "ca".

Если первые символы одинаковые, в расчет берутся вторые символы при их наличии.

Зависимость от регистра не всегда желательна, так как по сути мы имеем дело с одинаковыми строками. В этом случае перед сравнением мы можем привести обе строки к одному из регистров.

Функция lower() приводит строку к нижнему регистру, а функция upper() - к верхнему.

str1 = "Tom" str2 = "tom" print(str1 == str2) # False - строки не равны print(str1.lower() == str2.lower()) # True

Условная конструкция if

Условные конструкции используют условные выражения и в зависимости от их значения направляют выполнение программы по одному из путей. Одна из таких конструкций - это конструкция if. Она имеет следующее формальное определение:

if логическое_выражение: инструкции [elif логическое выражение: инструкции] [else: инструкции]

В самом простом виде после ключевого слова if идет логическое выражение. И если это логическое выражение возвращает True, то выполняется последующий блок инструкций, каждая из которых должна начинаться с новой стоки и должна иметь отступы от начала строки:

age = 22 if age > 21: print("Доступ разрешен") print("Завершение работы")

Поскольку в данном случае значение переменной age больше 21, то будет выполняться блок if, а консоль выведет следующие строки:

Доступ разрешен

Завершение работы

Отступ желательно делать в 4 пробела или то количество пробелов, которое кратно 4.

Обратите внимание в коде на последнюю стоку, которая выводит сообщение "Завершение работы". Она не имеет отступов от начала строки, поэтому она не принадлежит к блоку if и будет выполняться в любом случае, даже если выражение в конструкции if возвратит False.

Но если бы мы поставили бы отступы, то она также принадлежала бы к конструкции if:

age = 22 if age > 21: print("Доступ разрешен") print("Завершение работы")

Если вдруг нам надо определить альтернативное решение на тот случай, если условное выражение возвратит False, то мы можем использовать блок else:

age = 18 if age > 21: print("Доступ разрешен") else: print("Доступ запрещен")

Если выражение age > 21 возвращает True, то выполняется блок if, иначе выполняется блок else.

Если необходимо ввести несколько альтернативных условий, то можно использовать дополнительные блоки elif, после которого идет блок инструкций.

age = 18 if age >= 21: print("Доступ разрешен") elif age >= 18: print("Доступ частично разрешен") else: print("Доступ запрещен")

Вложенные конструкции if

Конструкция if в свою очередь сама может иметь вложенные конструкции if:

age = 18 if age >= 18: print("Больше 17") if age > 21: print("Больше 21") else: print("От 18 до 21")

Стоит учитывать, что вложенные выражения if также должны начинаться с отступов, а инструкции во вложенных конструкциях также должны иметь отступы. Отступы, расставленные не должным образом, могут изменить логику программы. Так, предыдущий пример НЕ аналогичен следующему:

age = 18 if age >= 18: print("Больше 17") if age > 21: print("Больше 21") else: print("От 18 до 21")

Теперь напишем небольшую программку, которая использует условные конструкции. Данная программка будет представлять собой своего рода обменный пункт:

# Программа Обменный пункт usd = 57 euro = 60 money = int(input("Введите сумму, которую вы хотите обменять: ")) currency = int(input("Укажите код валюты (доллары - 400, евро - 401): ")) if currency == 400: cash = round(money / usd, 2) print("Валюта: доллары США") elif currency == 401: cash = round(money / euro, 2) print("Валюта: евро") else: cash = 0 print("Неизвестная валюта") print("К получению:", cash)

С помощью функции input() получаем вводимые пользователем данные на консоль. Причем данная функция возвращает данные в виде строки, поэтому нам надо ее еще привести к целому числу с помощью функции int(), чтобы введенные данные можно было использовать в арифметических операциях.

Программа подразумевает, что пользователь вводит количество средств, которые надо обменять, и код валюты, на которую надо произвести обмен. Коды валюты достаточно условны: 400 для долларов и 401 для евро.

С помощью конструкции if проверяем код валюты и делим на соответствующий валютный курс. Так как в процессе деления образуется довольно длинное число с плавающей точкой, которое может содержать множество знаков после запятой, то оно округляется до двух чисел после запятой с помощью функции round().

В завершении на консоль выводится полученное значение. Например, запустим программу и введем какие-нибудь данные:

Введите сумму, которую вы хотите обменять: 20000

Укажите код валюты (доллары - 400, евро - 401): 401

Валюта: евро

К получению: 333.33

Циклы

Циклы позволяют повторять некоторое действие в зависимости от соблюдения некоторого условия.

Цикл while

Первый цикл, который мы рассмотрим, это цикл while. Он имеет следующее формальное определение:

while условное_выражение: инструкции

После ключевого слова while указывается условное выражение, и пока это выражение возвращает значение True, будет выполняться блок инструкций, который идет далее.

Все инструкции, которые относятся к циклу while, располагаются на последующих строках и должны иметь отступ от начала строки.

choice = "y" while choice.lower() == "y": print("Привет") choice = input("Для продолжения нажмите Y, а для выхода любую другую клавишу: ") print("Работа программы завешена")

В данном случае цикл while будет продолжаться, пока переменная choice содержит латинскую букву "Y" или "y".

Сам блок цикла состоит из двух инструкций. Сначала выводится сообщение "Привет", а потом вводится новое значение для переменной choice. И если пользователь нажмет какую-то другую клавишу, отличную от Y, произойдет выход из цикла, так как условие choice.lower() == "y" вернет значение False. Каждый такой проход цикла называется итерацией.

Также обратите внимание, что последняя инструкция print("Работа программы завешена") не имеет отступов от начала строки, поэтому она не входит в цикл while.

Дугой пример - вычисление факториала:

#! Программа по вычислению факториала number = int(input("Введите число: ")) i = 1 factorial = 1 while i <= number: factorial *= i i += 1 print("Факториал числа", number, "равен", factorial)

Здесь вводит с консоли некоторое число, и пока число-счетчик i не будет больше введенного числа, будет выполняться цикл, в котором происходит умножения числа factorial.

Консольный вывод:

Введите число: 6

Факториал числа 6 равен 720

Цикл "for"

Другой тип циклов представляет конструкция for. Цикл for вызывается для каждого числа в некоторой коллекции чисел. Коллекция чисел создается с помощью функции range(). Формальное определение цикла for:

for int_var in функция_range: инструкции

После ключевого слова for идет переменная int_var, которая хранит целые числа (название переменной может быть любое), затем ключевое слово in, вызов функции range() и двоеточие.

А со следующей строки располагается блок инструкций цикла, которые также должны иметь отступы от начала строки.

При выполнении цикла Python последовательно получает все числа из коллекции, которая создается функцией range, и сохраняет эти числа в переменной int_var. При первом проходе цикл получает первое число из коллекции, при втором - второе число и так далее, пока не переберет все числа. Когда все числа в коллекции будут перебраны, цикл завершает свою работу.

Рассмотрим на примере вычисления факториала:

#! Программа по вычислению факториала number = int(input("Введите число: ")) factorial = 1 for i in range(1, number+1): factorial *= i print("Факториал числа", number, "равен", factorial)

Вначале вводим с консоли число. В цикле определяем переменную i, в которую сохраняются числа из коллекции, создаваемой функцией range.

Функция range здесь принимает два аргумента - начальное число коллекции (здесь число 1) и число, до которого надо добавлять числа (то есть number +1).

Допустим, с консоли вводится число 6, то вызов функции range приобретает следующую форму:

range(1, 6+1):

Эта функция будет создавать коллекцию, которая будет начинаться с 1 и будет последовательно наполняться целыми числами вплоть до 7. То есть это будет коллекция [1, 2, 3, 4, 5, 6].

При выполнении цикла из этой коллекции последовательно будут передаваться числа в переменную i, а в самом цикле будет происходить умножение переменной i на переменную factorial. В итоге мы получим факториал числа.

Консольный вывод программы:

Введите число: 6

Факториал числа 6 равен 720

Функция "range"

Функция range имеет следующие формы:

  • range(stop): возвращает все целые числа от 0 до stop

  • range(start, stop): возвращает все целые числа в промежутке от start (включая) до stop (не включая). Выше в программе факториала использована именно эта форма.
  • range(start, stop, step): возвращает целые числа в промежутке от start (включая) до stop (не включая), которые увеличиваются на значение step


Примеры вызовов функции range:

range(5) # 0, 1, 2, 3, 4 range(1, 5) # 1, 2, 3, 4 range(2, 10, 2) # 2, 4, 6, 8 range(5, 0, -1) # 5, 4, 3, 2, 1

Например, выведем последовательно все числа от 0 до 4:

for i in range(5): print(i, end=" ")

Вложенные циклы

Одни циклы внутри себя могут содержать другие циклы. Рассмотрим на примере вывода таблицы умножения:

for i in range(1, 10): for j in range(1, 10): print(i * j, end="\t") print("\n")

Внешний цикл for i in range(1, 10) срабатывает 9 раз, так как в коллекции, возвращаемой функцией range, 9 чисел. Внутренний цикл for j in range(1, 10) срабатывает 9 раз для одной итерации внешнего цикла, и соответственно 81 раз для всех итераций внешнего цикла.

В каждой итерации внутреннего цикла на консоль будет выводится произведение чисел i и j. В итоге мы получим следующий консольный вывод:

1 2 3 4 5 6 7 8 9


2 4 6 8 10 12 14 16 18


3 6 9 12 15 18 21 24 27


4 8 12 16 20 24 28 32 36


5 10 15 20 25 30 35 40 45


6 12 18 24 30 36 42 48 54


7 14 21 28 35 42 49 56 63


8 16 24 32 40 48 56 64 72


9 18 27 36 45 54 63 72 81

Выход из цикла. break и continue

Для управления циклом мы можем использовать специальные операторы break и continue. Оператор break осуществляет выход из цикла. А оператор continue выполняет переход к следующей итерации цикла.

Оператор break может использоваться, если в цикле образуются условия, которые несовместимы с его дальнейшим выполнением. Рассмотрим следующий пример:

#! Программа Обменный пункт print("Для выхода нажмите Y") while True: data = input("Введите сумму для обмена: ") if data.lower() == "y": break # выход из цикла money = int(data) cache = round(money / 56, 2) print("К выдаче", cache, "долларов") print("Работа обменного пункта завершена")

Здесь мы имеем дело с бесконечным циклом, так как условие while True всегда истинно и всегда будет выполняться. Это популярный прием для создания программ, которые должны выполняться неопределенно долго.

В самом цикле получаем ввод с консоли. Мы предполагаем, что пользователь будет вводить число - условную сумму денег для обмена. Если пользователь вводит букву "Y" или "y", то с помощью оператора break выходим из цикла и прекращаем работу программы. Иначе делим введенную сумму на обменный курс, с помощью функции round округляем результат и выводим его на консоль. И так до бесконечности, пока пользователь не захочет выйти из программы, нажав на клавишу Y.

Консольный вывод программы:

Для выхода нажмите Y

Введите сумму для обмена: 20000

К выдаче 357.14 долларов

Введите сумму для обмена: Y

Работа обменного пункта завершена

Но что, если пользователь введет отрицательное число? В этом случае программа также выдаст отрицательный результат, что не является корректным поведением. И в этом случае перед вычислением мы можем проверить значение, меньше ли оно нуля, и если меньше, с помощью оператора continue выполнить переход к следующей итерации цикла без его завершения:

#! Программа Обменный пункт print("Для выхода нажмите Y") while True: data = input("Введите сумму для обмена: ") if data.lower() == "y": break # выход из цикла money = int(data) if money < 0: print("Сумма должна быть положительной!") continue cache = round(money / 56, 2) print("К выдаче", cache, "долларов") print("Работа обменного пункта завершена")

Также обращаю внимание, что для определения, относится ли инструкция к блоку while или к вложенной конструкции if, опять же используются отступы.

И в этом случае мы уже не сможем получить результат для отрицательной суммы:

Для выхода нажмите Y

Введите сумму для обмена: -20000

Сумма должна быть положительной!

Введите сумму для обмена: 20000

К выдаче 357.14 долларов

Введите сумму для обмена: y

Работа обменного пункта завершена

Функции

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

def имя_функции ([параметры]): инструкции

Определение функции начинается с выражения def, которое состоит из имени функции, набора скобок с параметрами и двоеточия. Параметры в скобках необязательны. А со следующей строки идет блок инструкций, которые выполняет функция. Все инструкции функции имеют отступы от начала строки.

Например, определение простейшей функции:

def say_hello(): print("Hello")

Функция называется say_hello. Она не имеет параметров и содержит одну единственную инструкцию, которая выводит на консоль строку "Hello".

Для вызова функции указывается имя функции, после которого в скобках идет передача значений для всех ее параметров. Например:

def say_hello(): print("Hello") say_hello() say_hello() say_hello()

Здесь три раза подряд вызывается функция say_hello. В итоге мы получим следующий консольный вывод:

Hello

Hello

Hello

Теперь определим и используем функцию с параметрами:

def say_hello(name): print("Hello,",name) say_hello("Tom") say_hello("Bob") say_hello("Alice")

Функция принимает параметр name, и при вызове функции мы можем передать вместо параметра какой-либо значение:

Hello, Tom

Hello, Bob

Hello, Alice

Значения по умолчанию

Некоторые параметры функции мы можем сделать необязательными, указав для них значения по умолчанию при определении функции. Например:

def say_hello(name="Tom"): print("Hello,", name) say_hello() say_hello("Bob")

Здесь параметр name является необязательным. И если мы не передаем при вызове функции для него значение, то применяется значение по умолчанию, то есть строка "Tom".

Именованные параметры

При передаче значений функция сопоставляет их с параметрами в том порядке, в котором они передаются. Например, пусть есть следующая функция:

def display_info(name, age): print("Name:", name, "\t", "Age:", age) display_info("Tom", 22)

При вызове функции первое значение "Tom" передается первому параметру - параметру name, второе значение - число 22 передается второму параметру - age. И так далее по порядку. Использование именованных параметров позволяет переопределить порядок передачи:

def display_info(name, age): print("Name:", name, "\t", "Age:", age) display_info(age=22, name="Tom")

Именованные параметры предполагают указание имени параметра с присвоением ему значения при вызове функции.

Неопределенное количество параметров

С помощью символа звездочки можно определить неопределенное количество параметров:

def sum(*params): result = 0 for n in params: result += n return result sumOfNumbers1 = sum(1, 2, 3, 4, 5) # 15 sumOfNumbers2 = sum(3, 4, 5, 6) # 18 print(sumOfNumbers1) print(sumOfNumbers2)

В данном случае функция sum принимает один параметр - *params, но звездочка перед названием параметра указывает, что фактически на место этого параметра мы можем передать неопределенное количество значений или набор значений. В самой функции с помощью цикла for можно пройтись по этому набору и произвести с переданными значениями различные действия. Например, в данном случае возвращается сумма чисел.

Возвращение результата

Функция может возвращать результат. Для этого в функции используется оператор return, после которого указывается возвращаемое значение:

def exchange(usd_rate, money): result = round(money/usd_rate, 2) return result result1 = exchange(60, 30000) print(result1) result2 = exchange(56, 30000) print(result2) result3 = exchange(65, 30000) print(result3)

Поскольку функция возвращает значение, то мы можем присвоить это значение какой-либо переменной и затем использовать ее: result2 = exchange(56, 30000).

В Python функция может возвращать сразу несколько значений:

def create_default_user(): name = "Tom" age = 33 return name, age user_name, user_age = create_default_user() print("Name:", user_name, "\t Age:", user_age)

Здесь функция create_default_user возвращает два значения: name и age. При вызове функции эти значения по порядку присваиваются переменным user_name и user_age, и мы их можем использовать.

Функция "main"

В программе может быть определено множество функций. И чтобы всех их упорядочить, хорошей практикой считается добавление специальной функции main, в которой потом уже вызываются другие функции:

def main(): say_hello("Tom") usd_rate = 56 money = 30000 result = exchange(usd_rate, money) print("К выдаче", result, "долларов") def say_hello(name): print("Hello,", name) def exchange(usd_rate, money): result = round(money/usd_rate, 2) return result # Вызов функции main main()

Область видимости переменных

Область видимости или scope определяет контекст переменной, в рамках которого ее можно использовать. В Python есть два типа контекста: глобальный и локальный.

Глобальный контекст подразумевает, что переменная является глобальной, она определена вне любой из функций и доступна любой функции в программе. Например:

name = "Tom" def say_hi(): print("Hello", name) def say_bye(): print("Good bye", name) say_hi() say_bye()

Здесь переменная name является глобальной и имеет глобальную область видимости. И обе определенные здесь функции могут свободно ее использовать.

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

def say_hi(): name = "Sam" surname = "Johnson" print("Hello", name, surname) def say_bye(): name = "Tom" print("Good bye", name) say_hi() say_bye()

В данном случае в каждой из двух функций определяется локальная переменная name. И хотя эти переменные называются одинаково, но тем не менее это дву разных переменных, каждая из которых доступна только в рамках своей функции. Также в функции say_hi определена переменная surname, которая также является локальной, поэтому в функции say_bye мы ее использовать не сможем.

Есть еще один вариант определения переменной, когда локальная переменная скрывают глобальную с тем же именем:

name = "Tom" def say_hi(): print("Hello", name) def say_bye(): name = "Bob" print("Good bye", name) say_hi() # Hello Tom say_bye() # Good bye Bob

Здесь определена глобальная переменная name. Однако в функции say_bye определена локальная переменная с тем же именем name. И если функция say_hi использует глобальную переменную, то функция say_bye использует локальную переменную, которая скрывает глобальную.

Если же мы хотим изменить в локальной функции глобальную переменную, а не определить локальную, то необходимо использовать ключевое слово global:

def say_bye(): global name name = "Bob" print("Good bye", name)

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

PI = 3.14 # вычисление площади круга def get_circle_square(radius): print("Площадь круга с радиусом", radius, "равна", PI * radius * radius) get_circle_square(50)

В данном случае число 3.14 представлено константой PI. Понятно, что это значение в принципе не изменится, поэтому его можно вынести из функций и определить в виде константы. Как правило, имя константы определяется заглавными буквами.

Модули

Модуль в языке Python представляет отдельный файл с кодом, который можно повторно использовать в других программах.

Для создания модуля необходимо создать собственно файл с расширением *.py, который будет представлять модуль. Название файла будет представлять название модуля. Затем в этом файле надо определить одну или несколько функций.

Пусть основной файл программы будет называться hello.py. И мы хотим подключить к нему внешние модули.

Для этого сначала определим новый модуль: создадим новый файл, который назовем account.py, в той же папке, где находится hello.py. Если используется PyCharm или другая IDE, то оба файла просто помещаются в один проект.

Основы Python

Соответственно модуль будет называться account. И определим в нем следующий код:

def calculate_income(rate, money, month): if money <= 0: return 0 for i in range(1, month+1): money = round(money + money * rate / 100 / 12, 2) return money

Здесь определена функция calculate_income, которая в качестве параметров получает процентную ставку вклада, сумму вклада и период, на который делается вклад, и высчитывает сумму, которая получится в конце данного периода.

В файле hello.py используем данный модуль:

#! Программа Банковский счет import account rate = int(input("Введите процентную ставку: ")) money = int(input("Введите сумму: ")) period = int(input("Введите период ведения счета в месяцах: ")) result = account.calculate_income(rate, money, period) print("Параметры счета:\n", "Сумма: ", money, "\n", "Ставка: ", rate, "\n", "Период: ", period, "\n", "Сумма на счете в конце периода: ", result)

Для использования модуля его надо импортировать с помощью оператора import, после которого указывается имя модуля: import account.

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

Получив пространство имен модуля, мы сможем обратиться к его функциям по схеме пространство_имен.функция:

account.calculate_income(rate, money, period)

И после этого мы можем запустить главный скрипт hello.py, и он задействует модуль account.py. В частности, консольный вывод мог бы быть следующим:

Введите процентную ставку: 10Введите сумму: 300000Введите период ведения счета в месяцах: 6Параметры счета: Сумма: 300000 Ставка: 10 Период: 6 Сумма на счете в конце периода: 315315.99

Настройка пространства имен

По умолчанию при импорте модуля он доступен через одноименное пространство имен. Однако мы можем переопределить это поведение. Так, ключевое слово as позволяет сопоставить модуль с другим пространством имен. Например:

import account as acc #............... result = acc.calculate_income(rate, money, period)

В данном случае пространство имен будет называться acc.

Другой вариант настройки предполагает импорт функциональности модуля в глобальное пространство имен текущего модуля с помощью ключевого слова from:

from account import calculate_income #............... result = calculate_income(rate, money, period)

В данном случае мы импортируем из модуля account в глобальное пространство имен функцию calculate_income. Поэтому мы сможем ее использовать без указания пространства имен модуля как если бы она была определена в этом же файле.

Если бы в модуле account было бы несколько функций, то могли бы их импортировать в глобальное пространство имен одним выражением:

from account import * #............... result = calculate_income(rate, money, period)

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

Имя модуля

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

При выполнении модуля среда определяет его имя и присваивает его глобальной переменной __name__ (с обеих сторон два подчеркивания). Если модуль является запускаемым, то его имя равно __main__ (также по два подчеркивания с каждой стороны). Если модуль используется в другом модуле, то в момент выполнения его имя аналогично названию файла без расширения py. И мы можем это использовать. Так, изменим содержимое файла account.py:

def calculate_income(rate, money, month): if money <= 0: return 0 for i in range(1, month+1): money = round(money + money * rate / 100 / 12, 2) return money def main(): rate = 10 money = 100000 period = 12 result = calculate_income(rate, money, period) print("Параметры счета:\n", "Сумма: ", money, "\n", "Ставка: ", rate, "\n", "Период: ", period, "\n", "Сумма на счете в конце периода: ", result) if __name__=="__main__": main()

Кроме того, для тестирования функции определена главная функция main. И мы можем сразу запустить файл account.py отдельно от всех и протестировать код.

Следует обратить внимание на вызов функции main:

if __name__=="__main__": main()

Переменная __name__ указывает на имя модуля. Для главного модуля, который непосредственно запускается, эта переменная всегда будет иметь значение __main__ вне зависимости от имени файла.

Поэтому, если мы будем запускать скрипт account.py отдельно, сам по себе, то Python присвоит переменной __name__ значение __main__, далее в выражении if вызовет функцию main из этого же файла.

Однако если мы будем запускать другой скрипт, а этот - account.py - будем подключать в качестве вспомогательного, для account.py переменная __name__ будет иметь значение account. И соответственно метод main в файле account.py не будет работать.

Данный подход с проверкой имени модуля является более рекомендуемым подходом, чем просто вызов метода main.

В файле hello.py также можно сделать проверку на то, является ли модуль главным (хотя в прицнипе это необязательно):

#! Программа Банковский счет import account def main(): rate = int(input("Введите процентную ставку: ")) money = int(input("Введите сумму: ")) period = int(input("Введите период ведения счета в месяцах: ")) result = account.calculate_income(rate, money, period) print("Параметры счета:\n", "Сумма: ", money, "\n", "Ставка: ", rate, "\n", "Период: ", period, "\n", "Сумма на счете в конце периода: ", result) if __name__ == "__main__": main()

Обработка исключений

При программировании на Python мы можем столкнуться с двумя типами ошибок. Первый тип представляют синтаксические ошибки (syntax error). Они появляются в результате нарушения синтаксиса языка программирования при написании исходного кода. При наличии таких ошибок программа не может быть скомпилирована. При работе в какой-либо среде разработки, например, в PyCharm, IDE сама может отслеживать синтаксические ошибки и каким-либо образом их выделять.

Второй тип ошибок представляют ошибки выполнения (runtime error). Они появляются в уже скомпилированной программе в процессе ее выполнения. Подобные ошибки еще называются исключениями. Например, в прошлых темах мы рассматривали преобразование числа в строку:

string = "5" number = int(string) print(number)

Данный скрипт успешно скомпилируется и выполнится, так как строка "5" вполне может быть конвертирована в число. Однако возьмем другой пример:

string = "hello" number = int(string) print(number)

При выполнении этого скрипта будет выброшено исключение ValueError, так как строку "hello" нельзя преобразовать в число. С одной стороны, здесь очевидно, сто строка не представляет число, но мы можем иметь дело с вводом пользователя, который также может ввести не совсем то, что мы ожидаем:

string = input("Введите число: ") number = int(string) print(number)

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

try:

инструкции

except [Тип_исключения]:

инструкции

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

После ключевого слова except опционально можно указать, какое исключение будет обрабатываться (например, ValueError или KeyError). После слова except на следующей стоке идут инструкции блока except, выполняемые при возникновении исключения.

Рассмотрим обработку исключения на примере преобразовании строки в число:

try: number = int(input("Введите число: ")) print("Введенное число:", number) except: print("Преобразование прошло неудачно") print("Завершение программы")

Вводим строку:

Введите число: hello

Преобразование прошло неудачно

Завершение программы

Как видно из консольного вывода, при вводе строки вывод числа на консоль не происходит, а выполнение программы переходит к блоку except.

Вводим правильное число:

Введите число: 22

Введенное число: 22

Завершение программы

Теперь все выполняется нормально, исключение не возникает, и соответственно блок except не выполняется.

В примере выше обрабатывались сразу все исключения, которые могут возникнуть в коде. Однако мы можем конкретизировать тип обрабатываемого исключения, указав его после слова except:

try: number = int(input("Введите число: ")) print("Введенное число:", number) except ValueError: print("Преобразование прошло неудачно") print("Завершение программы")

Если ситуация такова, что в программе могут быть сгенерированы различные типы исключений, то мы можем их обработать по отдельности, используя дополнительные выражения except:

try: number1 = int(input("Введите первое число: ")) number2 = int(input("Введите второе число: ")) print("Результат деления:", number1/number2) except ValueError: print("Преобразование прошло неудачно") except ZeroDivisionError: print("Попытка деления числа на ноль") except Exception: print("Общее исключение") print("Завершение программы")

Если возникнет исключение в результате преобразования строки в число, то оно будет обработано блоком except ValueError. Если же второе число будет равно нулю, то есть будет деление на ноль, тогда возникнет исключение ZeroDivisionError, и оно будет обработано блоком except ZeroDivisionError.

Тип Exception представляет общее исключение, под которое попадают все исключительные ситуации. Поэтому в данном случае любое исключение, которое не представляет тип ValueError или ZeroDivisionError, будет обработано в блоке except Exception:.

Блок finally

При обработке исключений также можно использовать необязательный блок finally. Отличительной особенностью этого блока является то, что он выполняется вне зависимости, было ли сгенерировано исключение:

try: number = int(input("Введите число: ")) print("Введенное число:", number) except ValueError: print("Не удалось преобразовать число") finally: print("Блок try завершил выполнение") print("Завершение программы")

Как правило, блок finally применяется для освобождения используемых ресурсов, например, для закрытия файлов.

Получение информации об исключении

С помощью оператора as мы можем передать всю информацию об исключении в переменную, которую затем можно использовать в блоке except:

try: number = int(input("Введите число: ")) print("Введенное число:", number) except ValueError as e: print("Сведения об исключении", e) print("Завершение программы")

Пример некорректного ввода:

Введите число: fdsf

Сведения об исключении invalid literal for int() with base 10: 'fdsf'

Завершение программы

Генерация исключений

Иногда возникает необходимость вручную сгенерировать то или иное исключение. Для этого применяется оператор raise.

try: number1 = int(input("Введите первое число: ")) number2 = int(input("Введите второе число: ")) if number2 == 0: raise Exception("Второе число не должно быть равно 0") print("Результат деления двух чисел:", number1/number2) except ValueError: print("Введены некорректные данные") except Exception as e: print(e) print("Завершение программы")

При вызове исключения мы можем ему передать сообщение, которое затем можно вывести пользователю:

Введите первое число: 1

Введите второе число: 0

Второе число не должно быть равно 0

Завершение программы

Начать дискуссию