Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 

Repository files navigation

Python_functions

Задание на изучение функций в Python

Задача

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

Даты сдачи оговариваются в канале группы.

Задание 1 (Решить с помощью реккурсии)

Пользователь вводит строку. Нужно проверить, правильно ли в ней расставлены скобки 3 видов (), {}, []. Примеры:

  • пв(ап) - правильно
  • (вав(вып)вввв)ввв - правильно
  • (апвыпыв - неправильно
  • (ывп)) - неправильно
  • авы) выавы( - неправильно (!)
  • выпыв[()] - правильно
  • [(выаыывпыв]) - неправильно

Задание 2 (Решить с помощью реккурсии)

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

Задание 3

С помощью регулярных выражений найдите все аббревиатуры в строке. Аббревиатурой считается слово состоящее из заглавных букв длиной не более 6 символов, не разделённое небуквенным разделителем.

Задание 4

Создайте генератор-функцию factorials(n), которая поочерёдно возвращает факториалы чисел от 1 до n.

Теория

Функции в Python

Функция — именованный блок кода, который может принимать аргументы, выполнять действия и возвращать значение. Функции используются для структурирования кода, повторного использования и сокращения дублирования. Если функция ничего не возвращает, то это уже процедура (Но в действительности, в Python, если нет return, то возвращается None).

Правила использования функций

  • Наименование отображает то, что делает функция.
  • Одна функция - одно назначение.
  • Функция должна быть универсальной.
  • Результат работы функции должен быть стабильным при различных входных данных.

Объявление метода

def <имя_функции>(<параметры>):
    """ Докстринг — описание функции."""
    <тело>

    return <значение>  # опционально

Аргументы и параметры — виды

Позиционные (positional)

Аргументы по порядку:

def add(a, b):

    return a + b


add(2, 3)  # 5

Именованные (keyword)

Можно передать по имени:

add(b=3, a=2)

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

def power(x, n=2):

    return x ** n


power(3)    # 9
power(3, 3) # 27

Предупреждение!

Не используйте изменяемые объекты как значения по умолчанию (list/dict), если вы не понимаете поведение — они будут общими для всех вызовов.

def bad_append(x, lst=[]):
    lst.append(x)

    return lst


bad_append(1)  # [1]
bad_append(2)  # [1, 2]  <- часто неожиданно

Правильный вариант:

def safe_append(x, lst=None):
    if lst is None:
        lst = []

    lst.append(x)

    return lst

*args — произвольный набор позиционных аргументов

def sum_all(*args):
    total = 0

    for v in args:
        total += v

    return total


sum_all(1,2,3)  # 6

Внутри args — кортеж.

**kwargs — произвольные именованные аргументы

def print_info(**kwargs):
    for k, v in kwargs.items():
        print(k, v)


print_info(name="Anna", age=30)

Внутри kwargs — словарь.

Позиционные-only и именованные-only (Python 3.8+ / 3+ синтаксис)

def func(a, b, /, c, *, d):
    """ # a, b — позиционные только
    # c — либо позиционная, либо именованная
    # d — именованный только."""

    return a + b + c + d

Слэши / и * полезны для контроля API функции.

Докстринг (docstring)

Описание функции для пояснения и автодокументации:

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

Доступ: help(add) или add.doc.

Области видимости (scope) и LEGB

LEGB — Local, Enclosing, Global, Builtins.

x = "global"


def outer():
    x = "enclosing"

    def inner():
        x = "local"

        print(x)  # local

    inner()

Чтобы изменить внешнюю переменную в enclosing scope (не глобальную), используйте nonlocal; для глобальной — global.

def counter():
    cnt = 0

    def inc():
        nonlocal cnt
        cnt += 1
    
        return cnt

    return inc


c = counter()
c()  # 1
c()  # 2

Замыкания (closures)

Когда вложенная функция захватывает переменные из внешней области:

def make_power(n):

    def power(x):

        return x ** n

    return power


square = make_power(2)
square(5)  # 25

Это полезно для фабрик функций и функционального стиля.

Лямбда-функции (анонимные)

Короткие функции в одну строку:

f = lambda x, y: x + y


f(2, 3)  # 5

пример: сортировка списка кортежей по второму элементу

pairs = [(1, 'b'), (2, 'a')]
pairs.sort(key=lambda p: p[1])

Лямбды хороши для простых однострочных выражений; не злоупотребляйте — для сложного кода лучше def.

Декораторы

Декоратор — это функция, которая принимает функцию и возвращает новую функцию (обычно обёртку).

def debug(func):

    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with", args, kwargs)

        result = func(*args, **kwargs)

        print(f"{func.__name__} returned", result)

        return result

    return wrapper


@debug
def add(a, b):

    return a + b


add(2, 3)

@debug — синтаксический сахар для add = debug(add). Используйте functools.wraps чтобы сохранить метаданные оригинальной функции:

from functools import wraps

def debug(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
      # ...
    
        return func(*args, **kwargs)
    
    return wrapper

Декораторы применяются для логирования, кеширования (functools.lru_cache), проверки прав, и т.д

Генераторы и yield

Функции с yield возвращают генератор — ленивый итератор.

def count_up_to(n):
    i = 1
  
    while i <= n:

        yield i

        i += 1

for v in count_up_to(3):
    print(v)

Генераторы экономят память, позволяют строить бесконечные последовательности, поддерживают send()/throw() API для продвинутого использования.

Аннотации типов (type hints)

Можно указывать типы параметров и возвращаемого значения (не обязательны):

def greet(name: str) -> str:

    return "Hello " + name

Type hints полезны для статической проверки (mypy), автодополнения в IDE и документации.

Рекурсия

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

Рекурсия = вызов самой себя до тех пор, пока не достигнута простейший (базовый) случай.

Структура рекурсивной функции

Любая корректная рекурсивная функция состоит из двух частей:

  • Базовый случай — условие выхода из рекурсии. Это момент, когда функция больше не вызывает сама себя.
  • Рекурсивный вызов — шаг, в котором функция вызывает себя с изменёнными аргументами, приближая задачу к базовому случаю.

Пример: факториал числа

Факториал n! = n × (n−1)!, при этом 0! = 1.

def factorial(n):
    if n == 0:             # 1 Базовый случай

        return 1
    else:                  # 2 Рекурсивный случай

        return n * factorial(n - 1)


print(factorial(5))  # 120

Как работает:

factorial(5)
→ 5 * factorial(4)
→ 5 * 4 * factorial(3)
→ 5 * 4 * 3 * factorial(2)
→ 5 * 4 * 3 * 2 * factorial(1)
→ 5 * 4 * 3 * 2 * 1
= 120

Визуализация: стек вызовов

Python хранит каждый вызов функции в стеке вызовов.

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

После завершения функции результат возвращается "вверх по стеку".

factorial(3)
 ├─ factorial(2)
 │   ├─ factorial(1)
 │   └─ return 1
 └─ return 2 * 1 = 2
return 3 * 2 = 6

Что будет, если нет базового случая?

Если функция вызывает себя бесконечно, стек переполняется:

def bad_recursion():
    return bad_recursion()

bad_recursion()

Ошибка:

RecursionError: maximum recursion depth exceeded

В Python по умолчанию глубина рекурсии ограничена (обычно ~1000 вызовов). Проверить можно:

import sys


sys.getrecursionlimit()

Когда рекурсия — лучший выбор

Используйте рекурсию, когда:

  • структура данных естественно рекурсивна (деревья, графы, директории);
  • решение задачи естественно описывается через себя (Фибоначчи, факториал);
  • требуется чистый и читаемый код, а не максимальная производительность.

Избегайте рекурсии, когда:

  • глубина может быть очень большой (например, обход длинных списков);
  • время или память критичны — итерация часто быстрее и безопаснее.

About

Задание на использование функций в Python

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Generated from LebGes/java_funcs