Обработка математики: 0%
 

printЯзык Python

printУправляющие конструкции

Python основан на принципах структурного программирования.

  1. Следует отказаться от использования оператора безусловного перехода goto.
  2. Любая программа строится из трёх базовых управляющих конструкций: последовательность, ветвление, цикл.
  3. В программе базовые управляющие конструкции могут быть вложены друг в друга произвольным образом.
  4. Повторяющиеся фрагменты программы можно оформить в виде подпрограмм.
  5. Каждую логически законченную группу инструкций следует оформить как блок.
  6. Все конструкции должны иметь один вход (в начале) и один выход (в конце).
  7. Разработка программы ведётся пошагово, методом «сверху вниз».

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

Пустой блок записывается как pass (пропуск), так как блок должен содержать хотя бы один оператор. Чаще всего оператор pass используется в случае, когда код этой части программы ещё не написан.

Обязательность отступов в Python повышает наглядность программы и позволяет обходиться без схем алгоритмов при разработке.

Рекомендуется писать один оператор в строке, но можно написать несколько операторов через ; (считается, что остальные операторы в строке имеют тот же отступ, что и первый оператор), а слишком длинный оператор можно разбить на несколько строк, указав в конце строки \:

import math
a=float(input()); b=float(input()); c=float(input()) # ввод 3 чисел как строк и преобразование во float
# площадь треугольника по 3 сторонам
S=(a+b+c)*(a+b-c)* \
  (b+c-a)*(a-b+c)
print(math.sqrt(S/16))
Ввод:

Выполнить
Вывод:

Ветвление

Разветвляющийся алгоритм — алгоритм, в котором действия выполняются по одной возможных ветвей решения задачи в зависимости от некоторого условия.

Оператор if выполняет указанный блок, если условие истинно.

if  

import math
# Найти угол по значению cos
a=float(input())
if -1<=a<=1:
   print(math.acos(a))
Ввод:

Выполнить
Вывод:

Оператор if-else выполняет "блок"_1, если условие истинно, иначе выполняет "блок"_2

tt"if" quad "условие" tt":" quad "блок"_1
tt"else:" quad "блок"_2

import math
# Найти угол по значению cos
a=float(input())
if -1<=a<=1:
   print(math.acos(a))
else:
   print(f"Значение {a} не входит в диапазон [-1;1]")
Ввод:

Выполнить
Вывод:

Вместо вложенных if-else нужно использовать дополнительные ветки elif:

# Соответствие российских размеров одежды и международных
s=int(input())
if s<=40:
  if s<=38: print("X", end='') # вывод без перехода на новую строку
  print("XS")
elif s<=44:
  print("S")
elif s<=48:
  print("M")
elif s<=52:
  print("L")
elif s<=58:
  print("XL")
else:
  print("XXL")
Ввод:

Выполнить
Вывод:

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

tt"match" quad "выражение" tt":"
quad quad tt"case" quad "образец"_1 tt":" quad "блок"_1
quad quad tt"case" quad "образец"_2 quad tt"if" quad "условие" tt":" quad "блок"_2
...
quad quad tt"case" quad "_" tt":" quad "блок"_n

Выражение проверяется по порядку, сверху-вниз на соответствие образцу и дополнительному ограничению в tt"if" quad "условие", если оно указано. Когда подходящая ветка будет найдена, выполняется блок в этой ветке и выполнение конструкции заканчивается. Образец _ соответствует любому значению и может быть указан только в последней ветке в конструкции.

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

  • константы – соответствующая часть выражения будет проверена на соответствие типа и равенство значений;
  • набор констант через | – проверка на равенство одному из вариантов, можно дополнительно указать tt"as" quad "имя" для сохранения этой части выражения в переменной;
  • "имя" – переменной "имя" будет присвоено значение, если эта часть не нужна, то вместо имени можно указать _;
  • "тип"("имя") – выражение быть проверено на соответствие типу перед присваиванием переменной.
# Соответствие российских размеров одежды и международных
s=int(input())
match s:
  case 38: print("XXS")
  case 40: print("XS")
  case 42|44: print("S")
  case 46|48: print("M")
  case 50|52: print("L")
  case 54|56|58: print("XL")
  case _: print("XXL")
Ввод:

Выполнить
Вывод:

Можно выделить начальную часть кортежа или списка, часть словаря (но не множества), а оставшуюся часть поместить в переменную с помощью bb"*" "имя" для кортежа или списка и bb"**" "имя" для словаря.

x=[1,7,"a","b"]
match x:
  case int(n) if n in range(10): print("маленькое число")
  case int(_): print("целое число")
  case str(s): 
     print(f"строка длиной {len(s)}")
  case _,_: print("кортеж из 2")
  case (float(_),float(_),float(_)): print("кортеж из 3 вещественных чисел")
  case [1|2|3 as a,int(b),*ost] if len(ost)<=2: print(f"хороший список начинается с {a},{b}")
  case list(_): print("плохой список")
Ввод:

Выполнить
Вывод:

Циклы

Циклический алгоритм — алгоритм, в котором некоторая часть действий (тело цикла) выполняется многократно.

Оператор while повторяет указанное действие, пока условие истинно. while используется, когда количество итераций неизвестно заранее.

tt"while" quad "условие" tt":" quad "блок"

# Найти НОД(a,b)
a=int(input())
b=int(input())
while b!=0:
  a,b=b,a%b
print(a)
Ввод:

Выполнить
Вывод:

Более сложный пример с вложенными циклами:

# Разложение числа N на простые множители
n=int(input())
i=2
while i*i<=n:
  while n%i==0:
    print(i, end=' ')
    n/=i;
  i+=1
if n>1: print(n, end=' ')
print("")
Ввод:

Выполнить
Вывод:

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

tt"for" quad "имя"_1,..., "имя"_n quad tt"in" quad "набор" tt":" quad "блок"

for i in range(10): # 10 итераций, от 0 до 9
  print(i)
for i in [10,25,4,7,11]: # по значениям из списка
  print(i)
d={'a':100,7:25, 'name': 'abc'}
for k in d: # по ключам словаря
  print(k, d[k])
s="string"
for i,c in enumerate(s): # добавляем индекс к значениям последовательности
  print(i, c)
Ввод:

Выполнить
Вывод:

После оператора цикла можно написать
tt"else:" quad "блок"
Операторы блока выполнятся при успешном завершении цикла (условие while станет ложным или будет достигнут конец последовательности).

Внутри блока цикла можно написать операторы:

  • continue – перейти к следующей итерации цикла;
  • break – завершить цикл досрочно, при этом операторы в блоке else не выполняются.
a = [1, 3, 5, 7, 9, 11]
val = 7
for i,v in enumerate(a):
  if v == val:
    print(f"Найден в позиции {i}")
    break
else:
  print("Не найден")
Ввод:

Выполнить
Вывод:

Цикл по точкам с целыми координатами внутри круга радиусом r:

import math
r=4
# с помощью генератора
for p in ((x,y) for x in range(-r,r+1) for y in range(-math.isqrt(r*r-x*x),math.isqrt(r*r-x*x)+1)):
  print(p)
# вложенным for
for x in range(-r,r+1):
  for y in range(-math.isqrt(r*r-x*x),math.isqrt(r*r-x*x)+1):
    print((x,y))
Ввод:

Выполнить
Вывод:

Обработка ошибок

Программа на Python сначала компилируется и могут быть выявлены синтаксические ошибки (пропущена скобка, неправильный отступ и т.д.), а затем выполняется и может быть обнаружена ошибка времени исполнения (деление на ноль, неправильный тип аргумента функции и т.д.). Выполнение программы при этом завершается и выводится сообщение. Если ошибка произошла из-за неправильной информации, введенной пользователем, то должна быть возможность изменить ввод без завершения программы.

n=int(input())
print(n**2)
Ввод:

Выполнить
Вывод:

Для обработки ошибок времени исполнения используется оператор try:

tt"try:" quad "блок"_t
tt"except" quad "тип"_1 quad tt"as" quad "переменная"_1 tt":"quad "блок"_1
tt"except" quad "тип"_2 tt":"quad "блок"_2
...
tt"else:"quad "блок"_e
tt"finally:"quad "блок"_f

Части except, else, finally являются опциональными. "блок"_i выполняется тогда, когда происходит ошибка "типа"_i, информация об ошибке помещается в переменную, указанную после as. "блок"_e выполняется только тогда, когда "блок"_t выполнился до конца без ошибок, return или break/continue. "блок"_f выполняется всегда, даже при завершении "блок"_t по ошибке, return или break/continue.

while True:
  try:
    n=int(input())
  except EOFError: exit() # завершение программы, если конец ввода
  except ValueError as err: print(f"Ошибка {err}, повторите ввод")
  else: break # успешный ввод, завершение цикла
print(n**2)
Ввод:

Выполнить
Вывод:

Оператор raise используется для порождения ошибок (исключительных ситуаций, исключений):
tt"raise" quad "выражение"

n=int(input())
if n<0: raise ValueError('Отрицательное значение')
print(n)
Ввод:

Выполнить
Вывод:

raise без выражения используется в блоках except для повторного порождения ошибки после частичной обработки.

Оператор try не позволяет корректно обработать случаи, требующие парных действий (открытие-закрытие, блокировка-разблокировка):

try:
  f=open('input.txt','r')
  n=int(f.readline())
  ...
finally:
  f.close()

Если ошибка произойдет в строке 2, то переменной f не будет присвоено значение и выполнение f.close() будет ошибкой. Для таких ситуаций рекомендуется использовать оператор with:
tt"with" quad "выражение" quad tt"as" quad "переменная" tt":" quad "блок"
или
tt"with" quad "выражение" tt":" quad "блок"

Для результата выражения вызывается метод __enter__ и результат метода присваивается указанной переменной, если она указана в назначении as. После завершения блока, независимо от успешности, вызывается метод __exit__ для результата выражения. Можно указать несколько выражений или назначений as через запятую.

with open('input.txt','r') as f:
  n=int(f.readline())
  ...
# для файла метод __exit__ выполняет закрытие
loading