Skip to content

TeachKait20/-7-Functions-in-Python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 

Repository files navigation

-7-Functions-in-Python

Функции в Python

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

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

Синтаксис:

def имя_функции(параметры):
    """Документация (опционально)"""
    # Тело функции
    # Инструкции
    return результат

Компоненты определения функции:

  • def- Ключевое слово, используемое для объявления новой функции.
  • имя_функции- Имя функции, которое используется для ее вызова. Должно следовать правилам именования переменных.
  • параметры или аргументы- Переменные, которые функция принимает в качестве входных данных. Указываются в скобках. Если параметров нет, скобки остаются пустыми.
  • Документация (опционально)- Строка, заключенная в тройные кавычки, описывающая, что делает функция. Она может отстутствовать.
  • Тело функции- Блок кода, который выполняется при вызове функции. Он должен быть сдвинут вправо (используя отступы).
  • return- Оператор, используемый для возврата значения из функции. Если return не указан, функция вернет None. return - сохраняет результат функции, его можно заменить на print, но тогда функция будет только выводить результат на экран без сохранения.

Примеры функций

Пример 1

Программа, которая выводит сумму двух чисел:

def add(a, b):
    """Возвращает сумму двух чисел."""
    result  = a + b
    return result 

# Вызов функции (несколько вариантов)
print(add.__doc__) # Вызов документации функции
var_summ = add(3, 5) # Передаём значения другой переменной
print(var_summ)  # Выведет: 8
print(add(10, 5)) # Напрямую вызываем функцию. Выведет: 15

Обратите внимание, что вызов функции происходит по её имени и без ключевого слова def

Пример 2

Рассмотрим ситуацию: есть компьютерная игра с различными персонажами и диалогами.

Персонаж Фраза
Mage: I use my best spell for protection.
Archer: My people are ready! What's next?
Enemy: AAAAaaarrrrrggghhhhh

Таких диалогов (строк) может быть огромное количество. Наша задача: проверить у всех ли строк в конце есть знак препинания и не является ли строка пустой.
Для начала представим всё в виде кода:

Mage = "I use my best spell for protection."
Archer = "My people are ready! What's next?"
Enemy = "AAAAaaarrrrrggghhhhh"

Данное задание можно сделать с помощью простейших условий и применить их к каждой строке:

if len(Mage) == 0:
    print("Строка пуста!")
else:
    if Mage[-1] in "!.?":
        print(True)
    else:
        print(False)

if len(Archer) == 0:
    print("Строка пуста!")
else:
    if Archer[-1] in "!.?":
        print(True)
    else:
        print(False)

if len(Enemy) == 0:
    print("Строка пуста!")
else:
    if Enemy[-1] in "!.?":
        print(True)
    else:
        print(False)

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

# Функция для проверки строки
def exam_string(string):
    # Проверка, пуста ли строка
    if len(string) == 0:
        print("Строка пуста!")
        return None  # Возвращаем None, так как строка пуста
    else:
        # Проверка, оканчивается ли строка на любой из символов '!', '.', '?'
        if string[-1] in "!.?":
            return True
        else:
            return False

# Вызов функции для каждой строки и вывод результатов
print(exam_string(Mage))   # Ожидается: True
print(exam_string(Archer)) # Ожидается: True
print(exam_string(Enemy))  # Ожидается: False

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

Пример 3

Можно быстро присваивать переменным большие/длинные значения:

Объект Описание
объект: космический корабль
класс корабля: штурмовой
работает: да
скорость: 32000
количество пушек: 4
объект: космический корабль
класс корабля: разведывательный
работает: да
скорость: 48000
количество пушек: 0

Представим в виде функции:

def create_spaceship(object, ship_class, works, speed, guns):
    if works == True:
        return f"[{object}] class: {ship_class} speed: {speed} number of guns: {guns}"
    else:
        return f"[{object}] class: {ship_class} speed: {speed} number of guns: {guns} ERROR: the ship is broken!"

spaceship_1 = create_spaceship("spaceship", "assault", True, 32000, 4)
spaceship_2 = create_spaceship("spaceship", "reconnaissance", True, 48000, 0)
spaceship_3 = create_spaceship("spaceship", "cargo ", False, 13000, 0)

print(spaceship_1)
print(spaceship_2)
print(spaceship_3)

Пример 4

Функции можно вызывать в потоке. Есть план для текстовой игры:

image

def start():
    print("Игра началась")

def rules():
    print("Правила игры ...")

def menu():
    while True:
        print("[1] - Начать игру\n[2] - Правила игры\n[3] - Выход")
        answer = input("> ")
        if answer == "1":
            start()
            break
        elif answer == "2":
            rules()
        elif answer == "3":
            print("Выход...")
            break
        else:
            print("Такого варианта нет. Повторите выбор.")


menu()

Аргументы функций

Аргументов (параметров) для функции бывает несколько. Различные типы аргументов в функции с реальным кодом.

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

def user_verification(name_user, age_user):
    print(f"Hello {name_user}! You are {age_user} years old.")
    
    if age_user < 16:
        print("Sorry, you are denied access.")
    else:
        print("Access granted!")

1. Позиционные аргументы

Передаются в функцию в определенном порядке.

user_verification("Ruby", 28)
user_verification("Melissa", 15)

2. Именованные аргументы

Позволяют явно указывать имена параметров при вызове функции.

user_verification(age_user=14, name_user="Ruby")
user_verification(name_user="Melissa", age_user=36)

3. Аргументы со значениями по умолчанию

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

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

def user_verification(name_user, age_user, gender_user=None):
    if gender_user == None:
        print(f"Hello, {name_user}! You are {age_user} years old.")
    else:
        print(f"Hello, {name_user}! You are {age_user} years old. Gender: {gender_user}")
    
    if age_user < 16:
        approved = True
        print("Sorry, you are denied access.")
    else:
        print("Access granted!")

user_verification("Judy", 26, "female")
user_verification("Tom", 11, "male")
user_verification("Henry", 22)

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

4. Неопределенное количество позиционных аргументов (*args)

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

def add_numbers(*args):
    total = 0
    for number in args:
        total += number
    return total

# Вызов функции с разным количеством аргументов
print(add_numbers(1, 2, 3))        # Выведет: 6
print(add_numbers(5, 10, 15, 20))  # Выведет: 50

Или:

def summ(*args):
    res = sum(args)
    print(f"Сумма: {res}")

# Вызов функции с несколькими аргументами
summ(1, 2, 3, 4)

5. Неопределенное количество именованных аргументов (**kwargs)

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

def user_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

# Вызов функции с разными именованными аргументами
user_info(name="Alice", age=30, gender="female")
# Выведет:
# name: Alice
# age: 30
# gender: female

user_info(name="Bob", occupation="Engineer", country="USA")
# Выведет:
# name: Bob
# occupation: Engineer
# country: USA

6. Комбинация различных типов аргументов

Можно комбинировать позиционные, *args, аргументы со значениями по умолчанию, **kwargs.

def complex_function(a, b=2, *args, **kwargs):
    print(f"a: {a}, b: {b}")
    print(f"Дополнительные позиционные аргументы: {args}")
    print(f"f"Именованные аргументы: {kwargs}")

# Вызов функции с приведенными аргументами
complex_function(1, 3, 4, 5, x=10, y=20)

Глобальные и локальные переменные

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

var = 15

def summ(a, b):
    var = a + b
    return var

print(var)
print(summ(2, 3))

Конечно, так лучше вообще не делать, но код работает. Такое происходит, потому что var на первой строке — глобальная переменная, а var внутри функции — локальная переменная.

В Python переменные могут быть локальными или глобальными, и их область видимости (scope) определяет, где они могут быть использованы в коде.

Глобальные переменные

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

Они доступны для чтения и изменения (если использовать global) внутри функций.

Пример использования:

count = 0  # Глобальная переменная

def increment():
    global count  # Используем глобальную переменную
    count += 1

increment()
print(count)  # Выведет: 1

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

Локальные переменные

Определение: Переменные, объявленные внутри функции и доступны только в пределах этой функции.

Они существуют только во время выполнения функции и недоступны за ее пределами.

Пример использования:

def my_function():
    local_var = 10  # Локальная переменная
    print(local_var)

my_function()  # Выведет: 10
print(local_var)  # Ошибка: 'local_var' не доступна вне функции

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

Ещё о локальных переменных

Бывает такое, что функции вложены. Чтобы изменить переменную из одной функции в другой, используют ключевое слово nonlocal. Оно позволяет обращаться к переменной из объемлющей функции и изменять ее значение внутри вложенной функции. Пример с использованием:

def outer_function():
    x = 10  # Переменная в объемлющей функции

    def inner_function():
        nonlocal x  # Указываем, что x - переменная из объемлющей области
        x += 5
        print(f"Внутри inner_function: {x}")  # Выведет: 15

    inner_function()
    print(f"Внутри outer_function: {x}")  # Выведет: 15

outer_function()

Пояснение:

  • В функции outer_function создается переменная x со значением 10.
  • Внутри outer_function определена inner_function, которая использует nonlocal для изменения переменной x из объемлющей области.
  • При вызове inner_function переменная x увеличивается на 5.
  • После этого изменения видны и в inner_function, и в outer_function.

Аннотации

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

Как работают аннотации для переменных

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

int_number: int = 9  # int_number имеет тип int и значение 9
float_number: float = 7.3  # float_number имеет тип float и значение 7.3
string: str = "My name is ..."  # string имеет тип str и значение "My name is ..."
array: list = [1, 2, 3]  # array имеет тип list и содержит [1, 2, 3]

Польза аннотаций для переменных:

- Явная типизация. Аннотации показывают, какого типа данных ожидается в переменной, что снижает вероятность ошибок.

- Лучшая поддержка кода. Когда переменные имеют явные типы, легче поддерживать и модифицировать код. Это особенно полезно в больших проектах.

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

- Совместимость с внешними инструментами. Инструменты, такие как mypy, могут проверять типы во всём коде, помогая автоматически находить ошибки в типизации.

array: List[int] = [1, 2, 3]  # array — это список целых чисел

Аннотации в функциях

Пример 1

def summ_nums(a: int, b: int) -> int:
    return a + b

print(summ_nums(5, 7))

Разбор:

Аннотации параметров функции:
Параметры a и b аннотированы как целые числа (int). Это означает, что при вызове функции ожидается, что аргументы должны быть целыми числами.

Аннотация возвращаемого значения:
После оператора -> указано, что функция должна возвращать целое число (int).

Работа функции:
Функция принимает два числа a и b, складывает их и возвращает результат. В данном случае вызов summ_nums(5, 7) возвращает 12, так как оба аргумента — целые числа.

Пример 2

def len_exam(string: str) -> int:
    return len(string)

print(len_exam("random!! @STRing 123 ((abc)"))

Разбор:

Аннотации параметров функции:
Параметр string аннотирован как строка (str). Это означает, что функция ожидает строковый аргумент.

Аннотация возвращаемого значения:
После оператора -> указано, что функция должна возвращать целое число (int).

Работа функции:
Функция принимает строку string, вычисляет её длину с помощью функции len() и возвращает результат. В данном случае вызов len_exam("random!! @STRing 123 ((abc)") возвращает длину строки — 27.

Частые ошибки

🏡 Список ошибок
1. Передача недостаточного или избыточного количества аргументов при вызове функции.
2. Изменение глобальных переменных внутри функции.
3. Забыта инструкция return, или она не используется, когда нужно вернуть значение. В результате функция возвращает None.
4. Неправильное управление изменяемыми объектами, такими как списки или словари, может привести к неожиданным результатам, так как они передаются по ссылке.
5. Использование одинаковых имен для параметров функции и глобальных переменных может привести к путанице и ошибкам.
6. Неправильное позиционирование или использование *args и **kwargs в определении функции может вызвать ошибки.
7. Использование изменяемых объектов в качестве значений по умолчанию может привести к неожиданным результатам, поскольку они создаются только один раз при определении функции.
8. Отсутствие документации в функциях затрудняет понимание их назначения и использования.

Задания для самостоятельного выполнения

В каких-то задания функция должна возвращать значение, а каких-то просто выводить. Будьте внимательны.

Задание 1

Создайте функцию create_car, которая принимает три аргумента: brand (строка, марка автомобиля), color (строка, цвет автомобиля), max_speed (целое число, максимальная скорость автомобиля).

Функция должна возвращать строку в формате:

"Марка: {brand} Цвет: {color} Максимальная скорость: {max_speed} км/ч"

Пример входных данных:
image

Пример выходных данных:
image

Задание 2

Напишите функцию switch_check, которая принимает один аргумент switch и выполняет проверку состояния переключателя.

Если switch равен True, выведите сообщение: "True работает". Если switch равен False, выведите сообщение: "False не работает". Если switch имеет любое другое значение (например, None), выведите сообщение: "{значение} сломан.". После этого создайте три переменные:

switch_1 = True (работающий переключатель), switch_2 = False (неработающий переключатель), switch_3 = None (переключатель сломан).

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

Пример входных данных:
image

Пример выходных данных:
image

Задание 3

Задание разбито на части. Не переходите к другой части, пока не выполнена предыдущая.

Часть 1

  • Создайте функцию, принимающую на вход три аргумента как три стороны треугольника. В зависимости от переданных сторон выведите сообщение пользователю: "Равносторонний треугольник", "Равнобедренный треугольник" или "Разносторонний треугольник". Если по переданным сторонам треугольник построить невозможно, выведете: "Некорректные стороны. Невозможно построить треугольник." Чтобы определить, можно ли построить треугольник с заданными сторонами, нужно проверить, что сумма любых двух сторон больше третьей.

    image

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

Пример входных данных:
image

Пример выходных данных:
image

Часть 2

  • Дополним информацию о треугольнике, выведем его периметр и площадь.
  • После всех проверок, добавьте расчёт для вычисления периметра и площади. Периметром треугольника называют сумму длин трёх его сторон, а половину этой величины называют полупериметром. В данном случае, лучше всего подойдёт формула Герона:

image

  • Найдите способ оставить только 2 знака после точки.

Описание:

  • В коде найдите периметр: p = a + b + c
  • Далее полупериметр: s = p / 2
  • И наконец площадь: area = (s * (s - a) * (s - b) * (s - c)) ** 0.5

В Python нет прямого обозначения корня, поэтому воспользуемся ** 0.5

Пример входных данных:
image

Пример выходных данных:
image

Задание 4

Создайте функцию number_change, которая принимает два аргумента:

  • input_number — исходное число,
  • output_number — конечное число, к которому нужно привести первое.

Функция должна считать количество шагов, необходимых для того, чтобы превратить input_number в output_number. На каждом шаге можно:

  • либо увеличить число на 1, если input_number меньше output_number,
  • либо уменьшить число на 1, если input_number больше output_number.

Функция возвращает кортеж из трёх значений:

  • Количество шагов (целое число),
  • Финальное значение input_number (оно должно совпадать с output_number),
  • Значение output_number

Пример входных данных:
image

Пример выходных данных:
image

Подсказка: Используйте цикл while и операторы if для сравнения чисел и выполнения нужных операций. А для подсчёта локальный счётчик.

Задание 5

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

1. Есть глобальная переменная player, которая изначально равна 0 и хранит информацию о том, сколько километров пробежал игрок.

2. Напишите функцию info_player(), которая выводит на экран сообщение в формате:
"Игрок пробежал {player} км.", где player — глобальная переменная, отражающая общее количество километров.

3. Напишите функцию run_player(km), которая:

  • принимает параметр km (количество километров),
  • делит значение km на 2 (половина расстояния),
  • добавляет это значение к глобальной переменной player.
  • Для изменения глобальной переменной используйте ключевое слово global.

4. Проверьте работу программы:

  • Вызовите info_player() для отображения начального значения.
  • Вызовите run_player(30) — игрок пробежал 30 км, но учитывается только половина (15 км).
  • Вызовите run_player(12.5) — снова половина пути (6.25 км) добавляется к пробегу.
  • Вызовите info_player() ещё раз для проверки итогового значения пробега.

Пример входных данных:
image

Пример выходных данных:
image

Задание 6

Напишите свою функцию для работы с числами, которая содержит документацию, описывающую её работу. Она необязательно должна быть большой и выполнять много действий (2-3 достаточно), но документация, должна быть расписана подробно. Добавьте аннотации. Пример функции:

def info_number(number: int) -> str:
    """
    Выводит информацию о целых положительных числах.

    Функция определяет:
    - Является ли число чётным или нечётным.
    - Наименьший делитель числа (кроме 1).

    Параметры:
    number (int): Целое положительное число.

    Возвращает:
    str: Строка с информацией о числе, его чётности и наименьшем делителе.
    Если число меньше или равно нулю, возвращает сообщение об ошибке.

    Пример:
     >> info_number(28)
    Число: 28
    Чётное: True
    Наименьшее кратное: 2
     >> info_number(-2)
    Ошибка. Число меньше или равно нулю.
    """
    min_divider = 2
    even = None

    # Проверка, является ли число положительным
    if number <= 0:
        return "Ошибка. Число меньше или равно нулю."

    # Проверка, является ли число чётным
    if number % 2 == 0:
        even = True
    else:
        even = False

    # Поиск наименьшего делителя
    while number % min_divider != 0:
        min_divider += 1

    return f"Число: {number}\nЧётное: {even}\nНаименьшее кратное: {min_divider}"


# Пример использования:
print(info_number.__doc__)  # Документация функции
print(info_number(28))  # Вывод информации о положительном числе
print(info_number(-2))  # Вывод сообщения об ошибке

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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages