Содержание
Python
Перенос установленных пакетов pypi в закрытый контур
# Экспорт установленных пакетов на машине, имеющей доступ в интернет $folder = 'C:\temp\twine' mkdir $folder -ErrorAction SilentlyContinue > $null (pip.exe list |select -Skip 2) -replace '\s+','==' |% { pip.exe download -d $folder $_ } Compress-Archive $folder\* -DestinationPath "$folder.zip" # Импорт на машине, где нет доступа к интернету, распаковав архив (здесь: C:\temp\twine). # Запускать раз за разом, пока не исчезнут ошибки. $pip = "$env:localappdata\Programs\Python\Python312\Scripts\pip.exe" (dir "C:\temp\twine" |? name -notmatch '^pip').fullname |% { & $pip install --no-warn-script-location $_ }
code-basics.com
Функции
Параметры функций
def truncate(text, length): t = text[:length] + '...' return t print(truncate('Нашли ошибку? Есть что добавить?', 16))
Необязательные параметры функций. Обязательные параметры должны идти первыми.
def get_hidden_card(num, star=4): return '*' * star + num[-4:] print(get_hidden_card('1425364758697069'))
Именованные аргументы.
Преимущество перед позиционными в том, что он более наглядны и можно указывать только те параметры, которые нужны, а не все необязательные.
Позиционные должны идти первыми.
def trim_and_repeat(string, offset=0, repetitions=1): return string[offset:] * repetitions print(trim_and_repeat('Hello!', offset=3, repetitions=5)) #lo!lo!lo!lo!lo!
Аннотации типов. Указание типов, какие нужно ожидать и какой будет на выходе, повышает удобство и читаемость.
def word_multiply(string: str, repetitions: int) -> str: return string * repetitions print(word_multiply('Hello!',2)) #Hello!Hello!
Логика
Логический тип (true/false). ==
- равно, !=
- не равно.
def is_pensioner (age: int): return age >= 60 print(is_pensioner(79)) # True
Предикаты. Возврат True/False, функции принято обозначать, начиная с is_/has_
def is_mister(mister: str): return mister == 'Mister' print(is_mister('Mister')) # чувствительно к регистру
Комбинирование операций и функций.
Приоритет арифметических операций выше логических.
def is_international_phone(number: str):
return number[0] == '+'
print(is_international_phone('89651234567')) # False </code>
And/Or.
#Решение учителя: def is_leap_year(year): return year % 400 == 0 or (year % 4 == 0 and year % 100 != 0) #Ваше решение: def is_leap_year(year: int): return year % 4 == 0 and (year % 400 == 0 or year % 100 != 0) print(is_leap_year(2000)) # True print(is_leap_year(1900)) # False
Not. Возможно множественное отрицание: not not
.
def is_palindrome(string: str): str = string.lower().replace(' ','') return str == str[::-1] # Через регулярку #def is_palindrome(string: str): # import re # str = re.sub('\s+', '', string.lower()) # return str == str[::-1] def is_not_palindrome(string: str): return not is_palindrome(string) print(is_palindrome('Оголи жопу пожилого')) # True print(is_palindrome('Привет родителям')) # False print(is_not_palindrome('Оголи жопу пожилого')) # False print(is_not_palindrome('Привет родителям')) # True
Результат логических выражений.
Проверка идёт слева направо: OR возвращает первое true, AND - первое false.
None
, 0
, 0.0
- False, остальное - True.
# true and yes = true, true or no = true print(10 % 2 == 0 and 'yes' or 'no') # => 'yes' # false and yes = false, false or no = false print(11 % 2 == 0 and 'yes' or 'no') # => 'no' print(1 and 2 and 3 and 4 or 5) # 4 print(1 or 2 or 3 or 4 and 5) # 1 def string_or_not(string): return isinstance(string, str) and 'yes' or 'no' print(string_or_not('Hexlet')) # 'yes' print(string_or_not(10)) # 'no' print(string_or_not('')) # 'yes' print(string_or_not(False)) # 'no'
Условия
IF
def guess_number(num: int): if num == 42: return 'You win!' return 'Try again!' # Вариант с and/or #def guess_number(num: int): # return num == 42 and 'You win!' or 'Try again!' print(guess_number(42)) # You win!
ELSE
Сделать все URL начинающимися с https://
.
def normalize_url(url): if url[:8] == 'https://': return url else: if url[:7] == 'http://': return 'https://' + url[7:] else: return 'https://' + url print(normalize_url('https://ya.ru')) # https://ya.ru print(normalize_url('google.com')) # https://google.com print(normalize_url('http://ai.fi')) # https://ai.fi
ELIF - альтернативное условие.
def who_is_this_house_to_starks(i): if i == 'Karstark' or i == 'Tully': return 'friend' elif i == 'Lannister' or i == 'Frey': return 'enemy' else: return 'neutral' print(who_is_this_house_to_starks('Karstark')) # => 'friend' print(who_is_this_house_to_starks('Frey')) # => 'enemy' print(who_is_this_house_to_starks('Joar')) # => 'neutral' print(who_is_this_house_to_starks('Ivanov')) # => 'neutral' # Можно обойтись без else (в этом случае): elif i == 'Lannister' or i == 'Frey': return 'enemy' return 'neutral'
Тернарный оператор
if — это инструкция, а не выражение. В Python есть конструкция, которая работает как if-else, но считается выражением.
В целом, тернарный оператор - это более лаконичный вариант if-else.
# Вариант IF def flip_flop(i: str): if i == 'flip': return 'flop' return 'flip' # Тернарный оператор def flip_flop(i: str): return 'flop' if i == 'flip' else 'flip' print(flip_flop('flip')) # flop print(flip_flop('floppy')) # flip
Match (аналог switch в Powershell)
Частный случай if-else, в ряде случаев читается лучше.
def get_number_explanation(i: int): match i: case 666: return 'devil number' case 42: return 'answer for everything' case 7: return 'prime number' case _: return 'just a number' print(get_number_explanation(8)) # just a number print(get_number_explanation(666)) # devil number print(get_number_explanation(42)) # answer for everything print(get_number_explanation(7)) # prime number # Без case_, как и без else, здесь можно обойтись: match i: case 7: return 'prime number' return 'just a number'
Циклы
WHILE
def print_numbers(last_number): i = last_number while i >= 1: print(i) i = i - 1 print('finished!') print_numbers(4) # 4,3,2,1,finished!
Агрегирование данных - добавление к уже имеющимся.
# Перемножение чисел в диапазоне def multiply_numbers_from_range(start, end): result = 1 while start <= end: result = result * start start = start + 1 return result print(multiply_numbers_from_range(1, 15)) # 1307674368000 # Агрегирование строк def join_numbers_from_range(start, end): string = '' while start <= end: string = string + str(start) start = start + 1 return string print(join_numbers_from_range(4, 11)) # 4567891011
Обход строк
def print_reversed_word_by_symbol(word): i = len(word) - 1 while i >= 0: print(word[i]) i = i - 1 print_reversed_word_by_symbol('word') d r o w
Условия внутри тела цикла
def count_chars(string, char): string = string.lower() char = char.lower() index = 0 count = 0 while index < len(string): if string[index] == char: # Считаем только подходящие символы count = count + 1 # Счетчик увеличивается в любом случае index = index + 1 return count # или делать каждую итерацию: if string[index].lower() == char.lower():
Подстрока (substring) с помощью цикла
def my_substr(string, num): index = 0 result = '' while index < num: result = result + string[index] index = index + 1 return result print(my_substr('Привет, как поживаешь?', 9)) Привет, к # Проверка правильности аргументов # Функция возвращает False, если хотя бы одно из условий истинно: # Отрицательная длина извлекаемой подстроки. # Отрицательный заданный индекс. # Заданный индекс выходит за границу всей строки. # Длина подстроки в сумме с заданным индексом выходит за границу всей строки. # В ином случае функция возвращает True. def is_arguments_for_substr_correct(string, index, subst): if subst < 0 or index < 0 or index >= len(string) or (subst + index) > len(string): return False return True string = 'Sansa Stark' end = len(string) - 1 print(is_arguments_for_substr_correct(string, 2, -3)) # False print(is_arguments_for_substr_correct(string, -1, 3)) # False print(is_arguments_for_substr_correct(string, 0, 5)) # True print(is_arguments_for_substr_correct(string, end + 1, 0)) # False
Синтаксический сахар
Вместо index = index + 1
пишется index += 1
.
Исходная форма | Сокращённая форма |
---|---|
a = a + 1 | a += 1 |
a = a - 1 | a -= 1 |
a = a * 2 | a *= 2 |
a = a / 1 | a /= 1 |
# Удаление символа из строки без replace() def filter_string(text, letter): length = len(text) index = 0 word = '' while index < length: if text[index] != letter: word += text[index] index += 1 return word print(filter_string("Привет, как поживаешь?", 'а')) Привет, кк поживешь?
Возврат из цикла
# Решение по теме def is_contains_char(string, char): index = 0 while index < len(string): if string[index] == char: return True index += 1 return False # Моё решение (не вчитался в условие, сделал по-другому) def is_contains_char(str, char): if (char in str): return True return False
Цикл For
Как foreach в powershell. Для while нужно задавать условие остановки и вводить счетчик.
Цикл For предназначен для коллекций, где понятно, где останавливаться, в результате он лаконичнее while.
# Функция filter_string(), реализованная ранее с помощью while def filter_string(str, char): res = '' for c in str: if (c.lower() != char.lower()): res += c return res # range() - диапазон #range(stop) создает последовательность от 0 до stop - 1 #range(start, stop) создает последовательность от start до stop - 1 #range(start, stop, step) создает последовательность из чисел от start до stop - 1, с шагом step for i in range(3, 0, -1): print(i) 3 2 1 def print_table_of_squares(start, end): for i in range(start, end+1): print(f'square of {i} is {i ** 2}') print(print_table_of_squares(1, 4)) square of 1 is 1 square of 2 is 4 square of 3 is 9 square of 4 is 16 None
Тони Гэддис - Начинаем программировать на Python, 5 изд.
Ввод, обработка, вывод
>>> name = 'world' >>> print('name') # в кавычках - буквальное значение name >>> print(name) # без кавычек - чтение переменной world print('One', 'two') # Разделитель - пробел One two >>> print('One', 'two', sep='---') # Задать разделитель One---two >>> print('One', end='-') # Задать символ окончания строки (по умолчанию - перенос строки) >>> print('two', end='!') One-two! name = input('Enter your name: ') # Ввод пользователя hours = int(input('How many hours you\'ve worked: ')) # Вложенная функция - строку (при вводе всегда строка) в целое число. \ - экранирование # f-строки - форматирование вывода >>> print(f'Hello, {name}!') # {name} - местозаполнитель Hello, world! >>> num = 10 >>> print(f'Значение равно {num + 2}.') # В местозаполнителе можно использовать выражения Значение равно 12. orig_price = float(input("Введите исходную цену: ")) # Цена со скидкой 20% print(f'Конечная цена: {orig_price - orig_price * 0.2}') # {местозаполнитель:спецификатор формата}, например, :.2f для округления до 2-го знака после запятой print(f'Конечная цена: {orig_price - orig_price * 0.2:.2f}') # Если перед округлением поставить запятую, то целочисленная часть будет поделена запятыми по три разряда num = 1234567890.12345 print(f'{num:,.2f}') 1,234,567,890.12 # Для целых чисел тип d num = 1234567890 print(f'{num:d}') 1,234,567,890 # Вывод десятичной дроби в процентах (в научной нотации - :e) discount = 0.256 print(f'{discount:%}') 25.600000% print(f'{discount:.0%}') 26% # Ширина поля. 10 знаков у поля с числом (включая само число). Если число больше поля, поле будет увеличено. num = 123 print(f'Число равно {num:10}') Число равно 123 # Совмещение округления и ширины поля discount = 2.256 print(f'Число {discount:20.2f}') Число 2.26 # Выравнивание. Числа по умолчанию вправо, строки - влево. # < - влево, > - вправо, ^ - по центру f'num:<10d' # f'num:>20,2 f' # вправо с округлением до 2 знаков name1 = 'Василий' name2 = 'Константин' name3 = 'Мария' name4 = 'Ольга' print(f'***{name1:^20}***') print(f'***{name2:^20}***') print(f'***{name3:^20}***') print(f'***{name4:^20}***') *** Василий *** *** Константин *** *** Мария *** *** Ольга *** # Порядок следования условных обозначений: # [выравнивание][ширина][,][.точность][тип] print(f'{num:^10,.2f}') # Конкатенация f-строк print(f'Имя: {name}, ' + f'Отдел: {dep}, ' + f'Должность: {pos}') Имя: Вася, Отдел: ИТ, Должность: сисадмин # Неявная конкатенация (без плюсов), результат тот же. print(f'Имя: {name}, ' f'Отдел: {dep}, ' f'Должность: {pos}') # Следует избегать "магических чисел" в коде, например, amount = balance * 0.069 # Что за 0.069, непонятно # Рекомендуется использовать именованные константы # Сразу понятно, что это, меньше вероятность опечаток, легче изменить значение, если оно повторяется в коде interest_rate = 0.069 amount = balance * interest_rate
"Черепашья" графика
import turtle # Импорт модуля turtle.showturtle() # Показать окно turtle.forward(200) # Двинуть черепаху вперёд на 200 пикселей turtle.left(45) # Развернуться влево на 45° (относительно текущего положения) turtle.setheading(180) # Развернуться влево (абсолютно). 90° - вверх, 270° - вниз, 0° - вправо. turtle.heading() # выяснить текущую ориентацию turtle.penup() # поднять перо (линия рисоваться не будет) turtle.pendown() # опустить перо turtle.circle(100) # Нарисовать круг радиусом 100 пкс turtle.dot() # Нарисовать точку turtle.bgcolor('gray') # Цвет холста, здесь: серый turtle.pencolor('red') # Цвет пера, здесь: красный # Сброс turtle.reset() # Стирает все рисунки, задаёт чёрный цвет пера, черепаха в исходном положении. Фон не сбрасывается. turtle.clear() # Стирает все рисунки, остальное остаётся на месте. turtle.clearscreen() # Полный сброс turtle.setup(640, 480) # размер холста (ширина, высота) turtle.goto(-100, 0) # Переместить на координаты, здесь: x: -100, y: 0 turtle.pos() # Выяснить координаты turtle.xcor() # Вывести положение по оси x turtle.ycor() # Вывести положение по оси y turtle.speed(0) # Скорость перемещения черепахи от 1 (по умолчанию, медленно) до 10 (быстро). 0 - анимация отключена, рисуется мгновенно. Без цифры - вывести текущую скорость. turtle.hideturtle() # скрыть значок черепахи turtle.showturtle() # показать значок черепахи turtle.write('Привет') # Написать текст # Заполнение фигуры цветом turtle.fillcolor('green') # Выбор цвета. Если не задать, то будет чёрный по умолчанию. turtle.begin_fill() # Перед началом рисования фигуры turtle.circle(-200) turtle.end_fill() # После окончания рисования фигуры # Если фигура не замкнута, то заполнение будет как если бы фигура была замкнутой # Интерактивный запрос данных, здесь: число, по умолчанию - 100, допустимый минимум 20, максимум 500 radius = turtle.numinput('Требуются данные', 'Введите радиус окружности', default=100, minval=20, maxval=500) turtle.circle(radius) # Строка name = turtle.textinput('Требуются данные', 'Введите имя') turtle.done() # Предотвращение закрытия холста после выполнения программы (для IDLE не нужно). Добавляется последней строкой. # Созвездие Ориона betelgeuse_x = -70 betelgeuse_y = 200 bellatrix_x = 80 bellatrix_y = 180 alnitak_x = -40 alnitak_y = -20 alnilam_x = 0 alnilam_y = 0 mintaka_x = 40 mintaka_y = 20 saif_x = -90 saif_y = -180 rigel_x = 120 rigel_y = -140 import turtle turtle.clearscreen() turtle.reset() turtle.hideturtle() turtle.penup() turtle.goto(betelgeuse_x, betelgeuse_y) turtle.write('Бетельгейзе') turtle.pendown() turtle.dot() turtle.goto(alnitak_x, alnitak_y) turtle.write('Альнитак') turtle.dot() turtle.goto(saif_x, saif_y) turtle.write('Саиф') turtle.dot() turtle.goto(alnitak_x, alnitak_y) turtle.goto(alnilam_x, alnilam_y) turtle.write('Альнилам') turtle.dot() turtle.goto(mintaka_x, mintaka_y) turtle.write('Минтака') turtle.dot() turtle.goto(bellatrix_x, bellatrix_y) turtle.write('Беллатрикс') turtle.dot() turtle.goto(mintaka_x, mintaka_y) turtle.goto(rigel_x, rigel_y) turtle.write('Ригель') turtle.dot() turtle.done()
Практические задания
# Цельсий -> Фаренгейт celsius = int(input('Градусы по Цельсию: ')) print(f'Градусы по Фаренгейту: {1.8 * celsius + 32}') # Ингредиенты для булочек (норматив известен на 48 булочек) buns = int(input('Кол-во булочек: ')) buns_standard = 48 print(f'Стаканов сахара: {buns * 1.5 / buns_standard:.1f}') print(f'Стаканов масла: {buns * 1 / buns_standard:.1f}') print(f'Стаканов муки: {buns * 2.75 / buns_standard:.1f}') # Расчёт кол-ва лоз в гряде length = int(input('Длина гряды: ')) length_pillar = int(input('Длина опоры: ')) gap = int(input('Расстояние между лозами: ')) quantity = int((length - length_pillar * 2) / gap) # Не округление, а отбрасывание десятичных знаков, иначе может не влезть print(f'Кол-во лоз: {int((length - length_pillar * 2) / gap)}') # Сложный процент initial_sum = float(input('Сумма, внесённая на счёт: ')) percent = float(input('Процентная ставка: ')) / 100 quant_per_year = int(input('Сколько раз в год начисляется процент: ')) years = int(input('Кол-во лет: ')) print(f'Итоговая сумма: {initial_sum * (1 + percent / quant_per_year) ** (quant_per_year * years):.2f}')
Структуры принятия решения и булева логика
if/elif/else
i = 10 reference = 50 if i > reference: print('Больше') elif i == reference: print('Равно') else: print ('Меньше') # Строки тоже можно сравнивать password = input('Пароль: ') reference = 'На горшке сидел король' if password == reference: print('Проходи') else: print('Пошёл вон') # При сравнении строк сравниваются их ASCII-коды, поэтому здесь будет "aa меньше ab". # Более длинная строка будет больше более короткой. if 'aa' < 'ab': print('aa меньше ab') else: print('ab меньше aa') # При вложенных условиях нужно делать соответствующие отступы if условие: if условие: действия elif условие: действия else: действия else: действия
Логические операторы
# and - true, если оба выражения истинны if temperature > 40 and minutes > 5: print(f'Температура больше 40 уже больше {minutes} мин!') # or - true, если хотя бы одно из выражений истинно if temperature > 40 or temperature < 0: print('Температура вне пределов нормы!') # not - инвертирует булево выражение if not(temperature > 0): print('Вода замерзает!') # Переменная с типом bool (значения True и False пишутся с большой буквы) if sales >= 50000: sales_quota_met = True else: sales_quota_met = False if sales_quota_met: print('Квота продаж выполнена') # Движение по условию позиции "черепахи" if turtle.xcor() > 249 or turtle.ycor() > 349: turtle.goto(0, 0) # Если "черепаха" направлена под углом от 90 до 270 градусов, установить её в 180 if turtle.heading() >= 90 and turtle.heading() <= 270: turtle.setheading(180) # Если перо опущено, поднять if turtle.isdown(): turtle.penup() # Если перо не опущено, опустить if not(turtle.isdown()): turtle.pendown() # Если "черепаха" видна, скрыть if turtle.isvisible(): turtle.hideturtle() # Если перо красное, установить синее if turtle.pencolor() == 'red': turtle.pencolor('blue')
Практические задания
# Калькулятор ингредиентов для хот-догов visitors = int(input('Кол-во гостей: ')) hotdogs = int(input('Кол-во хот-догов на одного гостя: ')) sausage_pack = 10 buns_pack = 8 total = visitors * hotdogs if total % sausage_pack == 0 and total % buns_pack == 0: print(f'Необходимо {total // sausage_pack} упаковок с сосисками и {total // buns_pack} упаковок с булочками.') print('Лишнего не осталось.') elif total % sausage_pack != 0 and total % buns_pack == 0: print(f'Необходимо {total // sausage_pack + 1} упаковок с сосисками и {total // buns_pack} упаковок с булочками.') print(f'Осталось {sausage_pack - total % sausage_pack} сосисок.') elif total % sausage_pack == 0 and total % buns_pack != 0: print(f'Необходимо {total // sausage_pack} упаковок с сосисками и {total // buns_pack + 1} упаковок с булочками.') print(f'Осталось {buns_pack - total % buns_pack} булочек.') else: print(f'Необходимо {total // sausage_pack + 1} упаковок с сосисками и {total // buns_pack + 1} упаковок с булочками.') print(f'Осталось {sausage_pack - total % sausage_pack} сосисок и {buns_pack - total % buns_pack} булочек.') # Цвета колеса рулетки # RANGE даёт диапазон на единицу меньше в конце! Т. е., range(19, 29) реально будет 19-28! pocket = int(input('Номер кармана (0-36): ')) if pocket == 0: print('Зелёный') elif pocket in range(1, 10) or pocket in range(19, 29): if pocket % 2 == 0: print('Чёрный') else: print('Красный') elif pocket in range(11, 18) or pocket in range(29, 37): if pocket % 2 == 0: print('Красный') else: print('Чёрный') else: print('Число вне диапазона!') # Продажа ПО со скидкой pkgs = int(input('Кол-во купленных пакетов ПО: ')) price = 99 discount = 0 if pkgs in range(10, 20): discount = 10 elif pkgs in range(20, 50): discount = 20 elif pkgs in range(50, 100): discount = 30 elif pkgs >= 100: discount = 40 print(f'Итого: {(price - discount / 100) * pkgs:.2f} (скидка {discount}%)') # Тариф на доставку weight = int(input('Масса посылки в граммах: ')) if weight <= 200: fee = 150 elif weight in range(201, 601): fee = 300 elif weight in range(601, 1001): fee = 400 elif weight >= 1001: fee = 475 print(f'Тариф: {weight / 100 * fee:.2f} ({weight} г., тариф {fee})') # Индекс массы тела height = int(input('Ваш рост (см): ')) weight = int(input('Ваш вес (кг): ')) index = round(weight / (height / 100) ** 2, 1) if index <= 18.5: print ('Худой') elif index >= 18.5 and index <= 25: print ('Туда-сюда') elif index > 25: print ('Толстый') # Секунды в дни-часы-минуты-секунды sec = int(input('Секунд: ')) if sec in range(60, 3600): print (f'{sec // 60} мин {sec % 60} сек') elif sec in range(3600, 86400): print (f'{sec // 3600} ч {sec % 3600 // 60} мин {sec % 3600 % 60} сек') elif sec >= 86400: print (f'{sec // 86400} д {sec % 86400 // 3600} ч {sec % 86400 % 3600 // 60} мин {sec % 86400 % 3600 % 60} сек') else: print (f'{sec} сек') # Високосный ли год year = int(input('Год: ')) if (year % 100 == 0 and year % 400 == 0) or (year % 100 != 0 and year % 4 == 0): print(f'Год {year} високосный') else: print(f'Год {year} не високосный')
Циклы
while: цикл с условием повторения
Цикл повторяется, пока условие истинно. Если условие ложно изначально, цикл выполняться не будет.
number = 5 while number <= 10: print (number) number = number + 1
for: цикл со счётчиком
for number in [1, 2, 3, 4, 5, 10]: print (number) for word in ['Бегать', 'Прыгать', 'Ползти', 'Стоять']: print (word) for word in range(3): print ('3 повтора') 3 повтора 3 повтора 3 повтора # range (начало, конец, ширина шага) for num in range(1, 10, 2): print (num) 1 3 5 7 9 # Часы - хорошая иллюстрация вложенных циклов for for hours in range(24): for minutes in range(60): for seconds in range(60): print(f'{hours}:{minutes}:{seconds}') # Ёлочка из звёздочек (range [0, 1, 2, 3, 4]) for row in range(5): for col in range(row+1): print('*', end='') print() * ** *** **** ***** # С пробелами for row in range(5): for col in range(row): print(' ', end='') print('*') * * * * *
Функции
2 варианта: функция без возврата значения (void function) и функция с возвратом. Имена функций подчиняются тем же правилам, что и имена переменных.
Хорошим вариантом имени будет глагол_существительное, например, get_hours или calculate_tax.
def main(): startup_message() input('Press Enter to see Step 1.') step1() def startup_message(): weight = '5 кг' # Локальная переменная. Действует только в рамках функции print('Приветствую!') print('{weight} картошки') def step(): weight = '10 кг' # Локальная переменная. Действует только в рамках функции print('Шаг 1') print('{weight} сахара') # Вызов основной функции для старта программы main() # pass - заглушка, ничего не делает. Используется, когда функция планируется, но деталей ещё нет. # pass можно использовать и в других случаях, например, в циклах if/else, while и т. д. def step1(): pass def step2(): pass
Передача аргументов в функцию
# Позиционные аргументы def main(): print('Сумма двух чисел') show_sum(75, 15) def show_sum(num1, num2): result = num1 + num2 print(result) main() # Именованные аргументы def main(): print('Сумма процентного дохода') show_interest(rate=0.01, periods=10, principal=10000.0) def show_interest(principal, rate, periods): interest = principal * rate * periods print(f'Доход составит {interest:,.2f}') main()
Можно использовать одновременно и позиционные, и именованные аргументы, но в этом случае позиционные должны стоять первыми, иначе будет ошибка.
Глобальные переменные и константы
Глобальную переменную, которая действует на все функции, можно задать и внутри функции с помощью слова global
.
def main(): global number number = int(input('Введите число: '))
Глобальные переменные нужно использовать очень ограниченно, т. к. они затрудняют отладку и понимание программы. Лучше максимально использовать локальные переменные и аргументы функций.
Глобальные константы в Питоне отсутствуют, но имитируются с помощью глобальных переменных, которые не меняются внутри функций с использованием слова global
.
Общепринятой практикой является написание их названий прописными буквами.
# CONTRIBUTION_RATE здесь - это процентная ставка, значение которой легко поменять, чтобы обновить весь расчёт. CONTRIBUTION_RATE = 0.05 def show_pay_contrib(gross): contrib = gross * CONTRIBUTION_RATE print(f'Взнос: {contrib :,.2f}')
Функции с возвратом значения
При завершении возвращает значение в ту часть программы, которая её вызвала. Пишется так же, как и функция без возврата значения, но в конце имеет инструкцию return
.
def sum(num1, num2): return num1 + num2
Библиотечные функции - print()
, input()
, range()
. Многие функции хранятся в файлах-модулях, их нужно импортировать перед использованием.
import random number = random.randint(1, 100) # Вызов функции из f-строки print(f'{random.randint(1, 1000):^10d}') # Случайное число в диапазоне 0-9 number = random.randrange(10) # Случайное число в диапазоне 5-9 number = random.randrange(5,10) # Случайное число среди 0, 10, 20 ... 100 number = random.randrange(0,101,10) # Случайное число в диапазоне 0.0 - 1.0 (исключая 1.0) number = random.random() # Случайное число в диапазоне 1.0 - 10.0 number = random.uniform(1.0, 10.0) # Каждый раз генерировать одну и ту же последовательность псевдослучайных чисел (random.seed) random.seed(10) print(f'{random.randint(1, 100)}') print(f'{random.randint(1, 100)}') print(f'{random.randint(1, 100)}')
Для документирования функций удобно использовать таблицу «ввод-обработка-вывод», где описаны соответствующие действия функций.
Функция | Ввод | Обработка | Вывод |
---|---|---|---|
get_price() | Розничная цена | Запрос розничной цены товара | Розничная цена товара |
Возврат булева значения
# Допустимы только значения 100, 200 и 300 def is_invalid(mod_num): if mod_num not in [100,200,300]: status = True else: status = False return status model = int(input('Enter model number: ')) if is_invalid(model): print('Enter anotner number!') else: print('OK')
Возврат нескольких значений
def get_info(): n = input('Ваше имя: ') a = int(input('Ваш возраст: ')) return n, a # Присвоение значений переменным по порядку. Кол-во должно совпадать, иначе ошибка. my_name, my_age = get_info()
Значение None
def main(): n1 = int(input('Введите делимое: ')) n2 = int(input('Введите делитель: ')) res = divide(n1, n2) if res is None: print('Деление на 0 невозможно!') else: print(f'{n1} : {n2} = {res}') def divide(n1, n2): if n2 == 0: res = None else: res = n1 / n2 return res main()
Хранение функций в модулях
Когда накапливается много функций, их можно систематизировать, поместив в модули - файлы с набором функций определённого направления, например, rectangle.py - функции, связанные с треугольниками, round.py - с кругами и т. д.
Имя модуля должно иметь расширение .py
и не должно совпадать с командами Питона (например, for
). В коде загрузить модуль можно командой import, например, import rectangle
. Поиск подходящего модуля идёт сначала в каталоге в программой, потом в других местах (module search path).
После импорта модуля можно вызывать его функции.
import circle # Площадь круга my_area = circle.area(radius)
Исполнение функции main по условию в модуле
Иногда может потребоваться импортировать как модуль саму программу или скрипт, т. е., получить её функции, не исполняя главной main()
. Это можно сделать, написав условие в потенциально импортируемой программе.
if __name__ == '__main__': main()
Суть в том, что переменная __name__ == '__main__'
только в случае самостоятельного запуска программы. Если программа была импортирована как модуль, то __name__
будет равна имени модуля.
Практические задания
### Оценочная стоимость и налог с недвижимости def main(): my_sum = float(input('Введите стоимость недвижимости: ')) ocenochnaya_stoimost, nalog = tax(my_sum) print(f'Оценочная стоимость: {ocenochnaya_stoimost:.2f}') print(f'Налог: {nalog:.2f}') def tax(s): # Оценочная стоимость - 60% от указанной ocenochnaya_stoimost = s * 0.6 # 72 коп на каждые 100 руб от оценочной стоимости nalog = ocenochnaya_stoimost / 100 * 0.72 return ocenochnaya_stoimost, nalog if __name__ == '__main__': main() Стоимость недвижимости: 5000000 Оценочная стоимость: 3000000.00 Налог: 21600.00 ### Выручка от продажи мест на стадионе (стоимость: А - 20, B - 15, C - 10) def main(): sold_a = int(input('Продано мест А: ')) sold_b = int(input('Продано мест B: ')) sold_c = int(input('Продано мест C: ')) print(f'Выручено: {income(sold_a,sold_b,sold_c)}') def income(a,b,c): return a*20 + b*15 + c*10 if __name__ == '__main__': main() Продано мест А: 1000 Продано мест B: 2000 Продано мест C: 4000 Выручено: 90000
стр 302 (pdf 327)
Проблемы и их решение
pip: Fatal error in launcher: Unable to create process
После установки новой версии питона и удаления старой. Помогло удаление каталогов старых версий в %LocalAppData%\Programs\Python