Como Lidar com Argumentos de Função Ausentes ou Inválidos em Python

PythonBeginner
Pratique Agora

Introdução

Os argumentos de função em Python são um aspecto fundamental da programação, mas lidar com argumentos ausentes ou inválidos pode ser desafiador. Este tutorial irá guiá-lo através do tratamento de argumentos de função em Python, desde a compreensão dos conceitos básicos até a implementação de estratégias robustas de validação e tratamento de erros. Ao final, você será capaz de escrever código Python que gerencia elegantemente os argumentos de função, levando a aplicações mais confiáveis e sustentáveis.

Compreendendo os Argumentos Básicos de Função e Valores Padrão

Em Python, as funções são blocos de código reutilizáveis que executam tarefas específicas. Ao definir uma função, você pode especificar parâmetros que a função espera receber. Vamos aprender como configurar funções com diferentes tipos de argumentos e explorar como fornecer valores padrão.

Criando Nossa Primeira Função

Vamos começar criando um arquivo Python simples para trabalhar. No WebIDE, navegue até o diretório do projeto e crie um novo arquivo chamado function_args.py:

  1. Clique no menu "File" no WebIDE
  2. Selecione "New File"
  3. Insira function_args.py como o nome do arquivo
  4. Clique em "OK"

Agora, vamos adicionar uma função básica a este arquivo:

def greet(name):
    """A simple function that greets a person by name."""
    return f"Hello, {name}!"

## Call the function and print the result
result = greet("Alice")
print(result)

Salve o arquivo (Ctrl+S ou File > Save) e execute-o no terminal:

python3 function_args.py

Você deve ver a saída:

Hello, Alice!

Compreendendo os Argumentos Obrigatórios

No exemplo acima, name é um argumento obrigatório. Se você tentar chamar a função sem fornecer este argumento, o Python irá levantar um erro.

Vamos modificar nosso arquivo para demonstrar isso:

def greet(name):
    """A simple function that greets a person by name."""
    return f"Hello, {name}!"

## This will work
result = greet("Alice")
print(result)

## This will raise an error
try:
    result = greet()
    print(result)
except TypeError as e:
    print(f"Error: {e}")

Salve o arquivo e execute-o:

python3 function_args.py

Saída:

Hello, Alice!
Error: greet() missing 1 required positional argument: 'name'

Como você pode ver, o Python levanta um TypeError quando não fornecemos o argumento obrigatório.

Adicionando Valores Padrão

Para tornar os argumentos opcionais, podemos fornecer valores padrão. Vamos atualizar nossa função:

def greet(name="Guest"):
    """A function that greets a person by name, with a default value."""
    return f"Hello, {name}!"

## With an argument
result1 = greet("Alice")
print(result1)

## Without an argument - uses the default value
result2 = greet()
print(result2)

Salve e execute:

python3 function_args.py

Saída:

Hello, Alice!
Hello, Guest!

Agora a função funciona com e sem um argumento.

Múltiplos Argumentos com Padrões

Vamos expandir nossa função para lidar com múltiplos argumentos, alguns com valores padrão:

def greet(name="Guest", message="Hello", punctuation="!"):
    """A function with multiple arguments and default values."""
    return f"{message}, {name}{punctuation}"

## Using all default values
print(greet())

## Providing only the name
print(greet("Alice"))

## Providing name and message
print(greet("Bob", "Hi"))

## Providing all arguments
print(greet("Charlie", "Welcome", "!!!"))

Salve e execute:

python3 function_args.py

Saída:

Hello, Guest!
Hello, Alice!
Hi, Bob!
Welcome, Charlie!!!

Usando Argumentos de Palavra-chave (Keyword Arguments)

Você também pode especificar argumentos por nome, independentemente de sua ordem:

def greet(name="Guest", message="Hello", punctuation="!"):
    """A function with multiple arguments and default values."""
    return f"{message}, {name}{punctuation}"

## Using keyword arguments
print(greet(message="Hey", name="David"))
print(greet(punctuation="...", message="Welcome back", name="Emma"))

Salve e execute:

python3 function_args.py

Saída:

Hey, David!
Welcome back, Emma...

Isso é particularmente útil quando uma função tem muitos argumentos e você só quer especificar alguns deles.

Agora você entende como criar funções com argumentos padrão e como usar argumentos de palavra-chave. No próximo passo, exploraremos maneiras mais avançadas de lidar com argumentos de função ausentes ou inválidos.

Lidando com Argumentos Ausentes com *args e **kwargs

Em Python, às vezes precisamos criar funções flexíveis que podem aceitar um número variável de argumentos. Para lidar com esses casos, o Python fornece dois elementos de sintaxe especiais: *args e **kwargs.

Criando um Novo Arquivo Python

Vamos criar um novo arquivo para trabalhar com esses conceitos:

  1. Clique no menu "File" no WebIDE
  2. Selecione "New File"
  3. Insira flexible_args.py como o nome do arquivo
  4. Clique em "OK"

Compreendendo *args

A sintaxe *args permite que uma função aceite qualquer número de argumentos posicionais, que são coletados em uma tupla.

Adicione o seguinte código a flexible_args.py:

def sum_numbers(*args):
    """A function that sums up any number of arguments."""
    result = 0
    for num in args:
        result += num
    return result

## Test the function with different numbers of arguments
print(f"Sum of 1, 2: {sum_numbers(1, 2)}")
print(f"Sum of 1, 2, 3, 4, 5: {sum_numbers(1, 2, 3, 4, 5)}")
print(f"No arguments: {sum_numbers()}")

Salve o arquivo e execute-o:

python3 flexible_args.py

Saída:

Sum of 1, 2: 3
Sum of 1, 2, 3, 4, 5: 15
No arguments: 0

Isso demonstra como *args pode lidar com qualquer número de argumentos, incluindo nenhum. Dentro da função, args é uma tupla contendo todos os argumentos fornecidos.

Compreendendo **kwargs

A sintaxe **kwargs permite que uma função aceite qualquer número de argumentos de palavra-chave (keyword arguments), que são coletados em um dicionário.

Vamos adicionar outra função ao nosso arquivo:

def build_profile(**kwargs):
    """A function that builds a user profile from keyword arguments."""
    profile = {}

    ## Add required fields with defaults
    profile["name"] = kwargs.get("name", "Anonymous")
    profile["age"] = kwargs.get("age", "Not specified")

    ## Add any additional fields
    for key, value in kwargs.items():
        if key not in ["name", "age"]:
            profile[key] = value

    return profile

## Test the function with different keyword arguments
print("Basic profile:", build_profile())
print("Full profile:", build_profile(name="Alice", age=30, occupation="Developer", location="New York"))
print("Custom fields:", build_profile(hobby="Reading", favorite_color="Blue"))

Salve e execute:

python3 flexible_args.py

Saída:

Basic profile: {'name': 'Anonymous', 'age': 'Not specified'}
Full profile: {'name': 'Alice', 'age': 30, 'occupation': 'Developer', 'location': 'New York'}
Custom fields: {'name': 'Anonymous', 'age': 'Not specified', 'hobby': 'Reading', 'favorite_color': 'Blue'}

Observe como kwargs.get("key", default_value) nos permite recuperar valores com padrões se eles não existirem.

Combinando Required, Default, *args e **kwargs

Vamos criar uma função mais complexa que combina todos esses tipos de argumentos:

def format_message(recipient, message="Hello", *args, **kwargs):
    """
    A function that formats a message with various customization options.
    - recipient: Required - who the message is for
    - message: Default greeting
    - *args: Additional message parts
    - **kwargs: Formatting options
    """
    ## Start with the basic message
    full_message = f"{message}, {recipient}!"

    ## Add any additional message parts
    if args:
        full_message += " " + " ".join(args)

    ## Apply formatting options
    if kwargs.get("upper", False):
        full_message = full_message.upper()

    if kwargs.get("wrap", False):
        full_message = f"[{full_message}]"

    return full_message

## Test with different combinations
print(format_message("Alice"))
print(format_message("Bob", "Hi"))
print(format_message("Charlie", "Welcome", "Hope", "you", "are", "well"))
print(format_message("David", "Greetings", upper=True))
print(format_message("Emma", wrap=True))
print(format_message("Frank", "Hey", "How's it going?", upper=True, wrap=True))

Salve e execute:

python3 flexible_args.py

Saída:

Hello, Alice!
Hi, Bob!
Welcome, Charlie! Hope you are well
GREETINGS, DAVID!
[Hello, Emma!]
[HEY, FRANK! HOW'S IT GOING?]

Este exemplo demonstra como usar todos os tipos de argumentos de função juntos:

  1. recipient é um argumento posicional obrigatório
  2. message tem um valor padrão, tornando-o opcional
  3. *args captura quaisquer argumentos posicionais adicionais
  4. **kwargs captura quaisquer argumentos de palavra-chave

Ao combinar essas abordagens, você pode criar funções altamente flexíveis que lidam com argumentos ausentes ou opcionais de forma elegante.

Validando Argumentos de Função

Ao criar funções em Python, é importante verificar se os argumentos passados para suas funções são válidos antes de prosseguir com a lógica principal da função. Nesta etapa, aprenderemos várias técnicas para validar argumentos de função.

Criando um Novo Arquivo Python

Vamos criar um novo arquivo para trabalhar com conceitos de validação:

  1. Clique no menu "File" no WebIDE
  2. Selecione "New File"
  3. Insira validate_args.py como o nome do arquivo
  4. Clique em "OK"

Validação Básica com Condicionais

A maneira mais simples de validar argumentos é usar instruções condicionais. Vamos começar com algumas validações básicas:

def calculate_rectangle_area(length, width):
    """Calculate the area of a rectangle, validating inputs."""
    ## Validate that inputs are numbers
    if not isinstance(length, (int, float)):
        raise TypeError("Length must be a number")
    if not isinstance(width, (int, float)):
        raise TypeError("Width must be a number")

    ## Validate that inputs are positive
    if length <= 0:
        raise ValueError("Length must be positive")
    if width <= 0:
        raise ValueError("Width must be positive")

    ## Calculate the area
    return length * width

## Test with valid inputs
try:
    area = calculate_rectangle_area(5, 3)
    print(f"Area of rectangle: {area}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with invalid types
try:
    area = calculate_rectangle_area("5", 3)
    print(f"Area of rectangle: {area}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with invalid values
try:
    area = calculate_rectangle_area(5, -3)
    print(f"Area of rectangle: {area}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Salve e execute:

python3 validate_args.py

Saída:

Area of rectangle: 15
Error: Length must be a number
Error: Width must be positive

Esta função valida os tipos e os valores de seus argumentos antes de realizar quaisquer cálculos. Quando argumentos inválidos são detectados, mensagens de erro apropriadas são levantadas.

Usando Asserções para Validação

Outra maneira de validar argumentos é usar asserções. Asserções são declarações que levantam um AssertionError se uma condição não for atendida:

def calculate_discount(price, discount_percent):
    """Calculate the discounted price."""
    ## Assert that inputs are valid
    assert isinstance(price, (int, float)), "Price must be a number"
    assert isinstance(discount_percent, (int, float)), "Discount must be a number"
    assert price >= 0, "Price cannot be negative"
    assert 0 <= discount_percent <= 100, "Discount must be between 0 and 100"

    ## Calculate the discount
    discount_amount = price * (discount_percent / 100)
    return price - discount_amount

## Test with valid inputs
try:
    discounted_price = calculate_discount(100, 20)
    print(f"Discounted price: ${discounted_price}")
except AssertionError as e:
    print(f"Error: {e}")

## Test with invalid discount percentage
try:
    discounted_price = calculate_discount(100, 120)
    print(f"Discounted price: ${discounted_price}")
except AssertionError as e:
    print(f"Error: {e}")

Salve e execute:

python3 validate_args.py

Saída:

Discounted price: $80.0
Error: Discount must be between 0 and 100

As asserções são úteis para desenvolvimento e depuração, mas podem ser desativadas no código de produção, portanto, nem sempre são a melhor escolha para validação em aplicações do mundo real.

Usando Dicas de Tipo para Documentação

Python 3.5+ suporta dicas de tipo (type hints), que podem ajudar a documentar os tipos esperados de argumentos de função e valores de retorno. Embora as dicas de tipo não realizem validação em tempo de execução por si só, elas fornecem documentação útil e podem ser verificadas por ferramentas externas como mypy:

def calculate_average(numbers: list[float]) -> float:
    """Calculate the average of a list of numbers."""
    if not numbers:
        raise ValueError("Cannot calculate average of empty list")

    if not all(isinstance(n, (int, float)) for n in numbers):
        raise TypeError("All elements must be numbers")

    return sum(numbers) / len(numbers)

## Test with valid input
try:
    avg = calculate_average([1, 2, 3, 4, 5])
    print(f"Average: {avg}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with empty list
try:
    avg = calculate_average([])
    print(f"Average: {avg}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with non-numeric elements
try:
    avg = calculate_average([1, 2, "3", 4, 5])
    print(f"Average: {avg}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Salve e execute:

python3 validate_args.py

Saída:

Average: 3.0
Error: Cannot calculate average of empty list
Error: All elements must be numbers

Observe que as dicas de tipo (list[float] e -> float) não realizam nenhuma validação por si só - ainda precisamos escrever nosso próprio código de validação. Elas servem como documentação e podem ser verificadas por ferramentas externas.

Criando uma Função Robusta com Validação

Agora, vamos aplicar todas essas técnicas para construir uma função robusta que calcula o custo total de itens com um desconto:

def calculate_total_cost(items=None, tax_rate=0, discount=0):
    """
    Calculate the total cost of items with tax and discount.

    Args:
        items: List of (item_name, price) tuples
        tax_rate: Tax rate percentage (0-100)
        discount: Discount percentage (0-100)

    Returns:
        A dictionary with the total, subtotal, tax amount, and discount amount
    """
    ## Validate items
    if items is None:
        items = []

    if not isinstance(items, list):
        raise TypeError("Items must be a list")

    ## Validate each item in the list
    for i, item in enumerate(items):
        if not isinstance(item, tuple) or len(item) != 2:
            raise ValueError(f"Item {i} must be a tuple of (name, price)")

        name, price = item
        if not isinstance(name, str):
            raise TypeError(f"Name of item {i} must be a string")
        if not isinstance(price, (int, float)):
            raise TypeError(f"Price of item {i} must be a number")
        if price < 0:
            raise ValueError(f"Price of item {i} cannot be negative")

    ## Validate tax_rate and discount
    if not isinstance(tax_rate, (int, float)):
        raise TypeError("Tax rate must be a number")
    if not isinstance(discount, (int, float)):
        raise TypeError("Discount must be a number")

    if not (0 <= tax_rate <= 100):
        raise ValueError("Tax rate must be between 0 and 100")
    if not (0 <= discount <= 100):
        raise ValueError("Discount must be between 0 and 100")

    ## Calculate the total
    subtotal = sum(price for _, price in items)
    discount_amount = subtotal * (discount / 100)
    tax_amount = (subtotal - discount_amount) * (tax_rate / 100)
    total = subtotal - discount_amount + tax_amount

    return {
        "subtotal": subtotal,
        "discount_amount": discount_amount,
        "tax_amount": tax_amount,
        "total": total
    }

## Test with valid inputs
shopping_cart = [
    ("Laptop", 1000),
    ("Mouse", 25),
    ("Keyboard", 45)
]

try:
    result = calculate_total_cost(shopping_cart, tax_rate=8.5, discount=10)
    print("Shopping Cart Total:")
    for key, value in result.items():
        print(f"  {key.replace('_', ' ').title()}: ${value:.2f}")
except (TypeError, ValueError) as e:
    print(f"Error: {e}")

## Test with invalid item
try:
    invalid_cart = [
        ("Laptop", 1000),
        ("Mouse", "twenty-five"),  ## Invalid price
        ("Keyboard", 45)
    ]
    result = calculate_total_cost(invalid_cart)
    print(result)
except (TypeError, ValueError) as e:
    print(f"Error with invalid item: {e}")

Salve e execute:

python3 validate_args.py

Saída:

Shopping Cart Total:
  Subtotal: $1070.00
  Discount Amount: $107.00
  Tax Amount: $81.86
  Total: $1044.86
Error with invalid item: Price of item 1 must be a number

Esta função demonstra uma validação robusta por:

  1. Verificando os tipos de todas as entradas
  2. Validando a faixa de valores numéricos
  3. Fornecendo mensagens de erro detalhadas
  4. Definindo padrões razoáveis para parâmetros opcionais
  5. Usando docstrings para documentar as entradas e valores de retorno esperados

Ao implementar uma validação completa em suas funções, você pode evitar erros, fornecer um feedback melhor aos usuários e tornar seu código mais robusto e sustentável.

Construindo uma Aplicação Completa

Agora que aprendemos várias técnicas para lidar e validar argumentos de função, vamos aplicar essas habilidades para construir uma aplicação simples, mas completa. Criaremos um sistema básico de rastreamento de despesas que demonstra boas práticas para o tratamento de argumentos de função.

Criando o Arquivo da Aplicação

Vamos criar um novo arquivo Python para nosso rastreador de despesas:

  1. Clique no menu "File" no WebIDE
  2. Selecione "New File"
  3. Insira expense_tracker.py como o nome do arquivo
  4. Clique em "OK"

Projetando as Funções do Rastreamento de Despesas

Nosso rastreador de despesas terá várias funções que lidam com diferentes aspectos do gerenciamento de despesas:

def create_expense(description, amount, category=None, date=None):
    """
    Create a new expense entry.

    Args:
        description (str): Description of the expense
        amount (float): The amount spent
        category (str, optional): Category of the expense
        date (str, optional): The date in YYYY-MM-DD format

    Returns:
        dict: An expense entry
    """
    ## Validate description
    if not isinstance(description, str):
        raise TypeError("Description must be a string")
    if not description:
        raise ValueError("Description cannot be empty")

    ## Validate amount
    if not isinstance(amount, (int, float)):
        raise TypeError("Amount must be a number")
    if amount <= 0:
        raise ValueError("Amount must be positive")

    ## Create the expense dictionary
    expense = {
        "description": description,
        "amount": float(amount),
        "category": category or "Uncategorized",
        "date": date or "Not specified"
    }

    return expense


def add_expense_to_list(expenses, **kwargs):
    """
    Add a new expense to the expenses list.

    Args:
        expenses (list): The list of expenses
        **kwargs: The expense details to be passed to create_expense

    Returns:
        list: The updated list of expenses
    """
    ## Validate the expenses list
    if not isinstance(expenses, list):
        raise TypeError("Expenses must be a list")

    ## Extract required arguments
    if "description" not in kwargs:
        raise ValueError("Expense description is required")
    if "amount" not in kwargs:
        raise ValueError("Expense amount is required")

    ## Create the expense and add it to the list
    expense = create_expense(
        kwargs["description"],
        kwargs["amount"],
        kwargs.get("category"),
        kwargs.get("date")
    )

    expenses.append(expense)
    return expenses


def get_total_expenses(expenses, category=None):
    """
    Calculate the total amount of expenses, optionally filtered by category.

    Args:
        expenses (list): The list of expenses
        category (str, optional): Filter by this category if provided

    Returns:
        float: The total amount
    """
    ## Validate the expenses list
    if not isinstance(expenses, list):
        raise TypeError("Expenses must be a list")

    ## Calculate the total
    if category:
        return sum(e["amount"] for e in expenses if e["category"] == category)
    else:
        return sum(e["amount"] for e in expenses)


def get_expense_summary(expenses):
    """
    Get a summary of expenses by category.

    Args:
        expenses (list): The list of expenses

    Returns:
        dict: A dictionary with categories as keys and total amounts as values
    """
    ## Validate the expenses list
    if not isinstance(expenses, list):
        raise TypeError("Expenses must be a list")

    ## Create the summary
    summary = {}
    for expense in expenses:
        category = expense["category"]
        if category in summary:
            summary[category] += expense["amount"]
        else:
            summary[category] = expense["amount"]

    return summary

Usando Nosso Rastreamento de Despesas

Agora, vamos usar nossas funções para rastrear algumas despesas:

def print_expense_summary(summary):
    """Print a formatted summary of expenses by category."""
    print("\nExpense Summary by Category:")
    print("-" * 30)
    for category, amount in summary.items():
        print(f"{category}: ${amount:.2f}")
    print("-" * 30)
    print(f"Total: ${sum(summary.values()):.2f}")

## Initialize an empty expenses list
expenses = []

## Add some expenses
try:
    ## Add with required arguments only
    expenses = add_expense_to_list(
        expenses,
        description="Groceries",
        amount=45.75
    )

    ## Add with all arguments
    expenses = add_expense_to_list(
        expenses,
        description="Movie tickets",
        amount=25.00,
        category="Entertainment",
        date="2023-11-15"
    )

    ## Add another expense
    expenses = add_expense_to_list(
        expenses,
        description="Dinner",
        amount=65.40,
        category="Food",
        date="2023-11-14"
    )

    ## Add with default category
    expenses = add_expense_to_list(
        expenses,
        description="Gas",
        amount=35.80,
        date="2023-11-16"
    )

    ## Display all expenses
    print("All Expenses:")
    for i, expense in enumerate(expenses, 1):
        print(f"{i}. {expense['description']}: ${expense['amount']:.2f} " +
              f"({expense['category']}, {expense['date']})")

    ## Get and display the total
    total = get_total_expenses(expenses)
    print(f"\nTotal expenses: ${total:.2f}")

    ## Get and display expenses for a specific category
    food_total = get_total_expenses(expenses, "Food")
    print(f"Food expenses: ${food_total:.2f}")

    ## Get and display the summary
    summary = get_expense_summary(expenses)
    print_expense_summary(summary)

except (TypeError, ValueError) as e:
    print(f"Error: {e}")

Vamos também adicionar algum código para demonstrar o tratamento de erros:

## Try some invalid inputs
print("\nTesting error handling:")

try:
    ## Invalid expense description
    expenses = add_expense_to_list(expenses, description="", amount=10)
except ValueError as e:
    print(f"Caught error: {e}")

try:
    ## Invalid expense amount
    expenses = add_expense_to_list(expenses, description="Coffee", amount=-5)
except ValueError as e:
    print(f"Caught error: {e}")

try:
    ## Missing required argument
    expenses = add_expense_to_list(expenses, description="Coffee")
except ValueError as e:
    print(f"Caught error: {e}")

Salve o arquivo e execute:

python3 expense_tracker.py

Saída esperada:

All Expenses:
1. Groceries: $45.75 (Uncategorized, Not specified)
2. Movie tickets: $25.00 (Entertainment, 2023-11-15)
3. Dinner: $65.40 (Food, 2023-11-14)
4. Gas: $35.80 (Uncategorized, 2023-11-16)

Total expenses: $171.95
Food expenses: $65.40

Expense Summary by Category:
------------------------------
Uncategorized: $81.55
Entertainment: $25.00
Food: $65.40
------------------------------
Total: $171.95

Testing error handling:
Caught error: Description cannot be empty
Caught error: Amount must be positive
Caught error: Expense amount is required

Revisão da Aplicação

Nosso rastreador de despesas demonstra vários conceitos importantes:

  1. Validação de argumentos: Cada função valida seus argumentos para garantir que eles atendam aos tipos e restrições esperados.

  2. Valores padrão: Usamos valores padrão para tornar certos argumentos opcionais, como category e date.

  3. Argumentos obrigatórios: Para informações essenciais como description e amount, garantimos que elas sejam fornecidas e válidas.

  4. Argumentos de palavra-chave (keyword arguments): A função add_expense_to_list usa **kwargs para aceitar detalhes de despesas de forma flexível.

  5. Tratamento de erros: Usamos exceções apropriadas com mensagens de erro significativas para facilitar a depuração.

  6. Docstrings: Cada função inclui uma docstring que explica sua finalidade, argumentos e valores de retorno.

Ao aplicar essas técnicas, criamos uma aplicação robusta que lida com argumentos de função de maneira confiável e amigável ao usuário. Essa abordagem ajuda a prevenir erros, melhora a capacidade de manutenção do código e fornece feedback claro quando algo dá errado.

Resumo

Neste tutorial, você aprendeu técnicas essenciais para lidar com argumentos de função ausentes ou inválidos em Python:

  1. Entendendo argumentos de função básicos e padrões: Você explorou diferentes tipos de argumentos de função, incluindo argumentos obrigatórios, argumentos opcionais com valores padrão e argumentos de palavra-chave (keyword arguments). Essa base o ajuda a projetar funções que são flexíveis e fáceis de usar.

  2. Lidando com números variáveis de argumentos: Você aprendeu a usar *args e **kwargs para criar funções que podem aceitar qualquer número de argumentos, tornando suas funções mais adaptáveis a diferentes casos de uso.

  3. Validando argumentos de função: Você implementou várias técnicas de validação para garantir que os argumentos atendam aos tipos e restrições esperados, ajudando a prevenir erros e fornecer mensagens de erro claras.

  4. Construindo uma aplicação completa: Você aplicou esses conceitos para construir uma aplicação prática de rastreamento de despesas, demonstrando como o tratamento adequado de argumentos leva a um código robusto e sustentável.

Essas habilidades são fundamentais para escrever código Python confiável. Ao lidar adequadamente com argumentos de função, você pode criar funções que são mais flexíveis, fáceis de usar e menos propensas a erros. À medida que você continua sua jornada em Python, essas técnicas o ajudarão a construir aplicações mais sofisticadas que podem lidar com entradas inesperadas e casos extremos com elegância.