1. Crie uma função que “altere” uma string na posição de índice i, substituindo o caracter nessa posição por um novo caracter c. Dica: use concatenação de strings. A assinatura da função pode ser altera (texto, i, c). Faça usando um laço de repetição e depois usando fatiamento de string.

Passo 1

O enunciado pede que eu crie uma função que “altere” uma string na posição de índice i, substituindo o caracter nessa posição por um novo caracter c. Ele sugere a assinatura altera(texto, i, c) e pede duas versões: uma usando um laço de repetição e outra usando fatiamento (slicing). Não foi especificado o comportamento em casos especiais (índice inválido, c com mais de um caracter, índices negativos), então vou escolher comportamentos sensatos e explicá-los nas próximas etapas: validar tipos, exigir que c seja uma string de exatamente um caracter, suportar índices negativos no estilo Python (por exemplo, -1 refere-se ao último caracter) e lançar erro se o índice ficar fora do intervalo da string.
Informações relevantes dadas:
  • Queremos substituir o caracter na posição i por c.
  • Precisamos de duas implementações: uma com laço de repetição e outra com fatiamento.
  • A assinatura sugerida é altera(texto, i, c).

Passo 2

Entendendo os conceitos básicos necessários (muito didático):
  • Strings em Python são imutáveis: não dá para trocar um caracter “no lugar”. Em vez disso, criamos uma nova string com a modificação desejada.
  • Indexação: para acessar o k-ésimo caracter usamos texto[k]. Índices válidos (no estilo positivo) vão de 0 até len(texto)-1. Python também aceita índices negativos: -1 é o último caracter, -2 o penúltimo, etc.
  • Fatiamento (slicing): texto[:i] é a substring de início até o índice i-1; texto[i+1:] é a substring do índice i+1 até o fim. Assim, para substituir o caracter em i podemos combinar três pedaços: prefixo + novo caracter + sufixo.
  • Validações que faremos:
    • i deve ser inteiro.
    • c deve ser str e ter comprimento exatamente 1.
    • Ajustar índices negativos para o equivalente positivo com i = i + len(texto) quando i < 0.
    • Após ajuste, verificar se 0 \le i < \text{len(texto)}; caso contrário, lançar IndexError.

Passo 3

Algoritmo usando um laço de repetição (explicação passo a passo, sem colar ainda a função completa):
  • Primeiro validamos i e c como falei no passo anterior.
  • Obtemos o tamanho L = len(texto).
  • Se i < 0, fazemos i = i + L (assim -1 vira L-1, etc.).
  • Se, depois do ajuste, i estiver fora do intervalo, lançamos IndexError.
  • Para construir a nova string com laço, percorremos cada posição com for idx, ch in enumerate(texto): e vamos acumulando caracteres em uma lista res_chars.
    • Se idx == i, acrescentamos c em vez de ch.
    • Senão, acrescentamos ch.
  • No final retornamos ''.join(res_chars) — usar lista + join é a forma eficiente (evita concatenar strings repetidamente no laço).
Exemplo mental rápido: texto = "abcde", i = 2, c = "X".
  • Percorrendo: idx 0 -> “a”, idx 1 -> “b”, idx 2 -> substitui por “X”, idx 3 -> “d”, idx 4 -> “e”.
  • Resultado: "abXde".

Passo 4

Algoritmo usando fatiamento (slicing):
  • Mesmas validações iniciais de i e c e ajuste de índice negativo.
  • Depois do ajuste garantido, usamos a expressão:
    • prefixo = texto[:i]
    • sufixo = texto[i+1:]
    • resultado = prefixo + c + sufixo
  • Essa forma é muito direta e elegante, e também eficiente (cria apenas as fatias necessárias e concatena três strings).
Observação sobre fatiamento com índices negativos: embora texto[:i] aceite i negativo, para manter comportamento consistente e para poder validar se i está dentro do intervalo, eu preferi transformar i negativo em positivo explicitamente antes de fatiar.

Passo 5

Casos especiais e decisões pedagógicas:
  • Se texto for vazio (len(texto) == 0), qualquer i é inválido — lançar IndexError.
  • Se c não for uma str ou se len\text{(c)} != 1, lançar ValueError (porque a função foi pedida para substituir por um único caracter).
  • Se i não for int, lançar TypeError.
  • Por que lançar erros em vez de “tentar consertar”? Porque em provas/uso prático é melhor comportamento explícito: o chamador recebe um erro e percebe que usou a função de forma incorreta. Explico rapidinho como tratar se quiser comportamento tolerante (por exemplo, truncar c[0] se c tiver comprimento > 1), mas aqui seguirei a política de validação estrita para deixar tudo claro.

Passo 6

Pequena demonstração manual (para fixar):
  • Entrada: texto = "hello", i = -1, c = "!".
  • len(texto) = 5. Ajuste i = -1 + 5 = 4. Substituímos o caractere na posição 4 (o último), resultado "hell!".
  • Entrada: texto = "abc", i = 3, c = "x" -> i está fora do intervalo (após ajuste ainda é 3 e len=3), então IndexError.

Resposta

def altera_loop(texto, i, c):
    """
    Substitui o caracter em índice i por c usando um laço de repetição.
    Validações:
      - i deve ser int
      - c deve ser str de comprimento 1
      - suporta índices negativos no estilo Python
      - lança IndexError se o índice final estiver fora do intervalo
    """
    if not isinstance(i, int):
        raise TypeError("i deve ser um inteiro")
    if not isinstance(c, str) or len\text{(c)} != 1:
        raise ValueError("c deve ser uma string de exatamente 1 caracter")
    L = len(texto)
    if L == 0:
        raise IndexError("string index out of range")
    if i < 0:
        i = i + L
    if i < 0 or i >= L:
        raise IndexError("string index out of range")
    res_chars = []
    for idx, ch in enumerate(texto):
        if idx == i:
            res_chars.append\text{(c)}
        else:
            res_chars.append(ch)
    return ''.join(res_chars)


def altera_slice(texto, i, c):
    """
    Substitui o caracter em índice i por c usando fatiamento (slicing).
    Mesmas validações que a versão com laço.
    """
    if not isinstance(i, int):
        raise TypeError("i deve ser um inteiro")
    if not isinstance(c, str) or len\text{(c)} != 1:
        raise ValueError("c deve ser uma string de exatamente 1 caracter")
    L = len(texto)
    if L == 0:
        raise IndexError("string index out of range")
    if i < 0:
        i = i + L
    if i < 0 or i >= L:
        raise IndexError("string index out of range")
    return texto[:i] + c + texto[i+1:]

Exercícios relacionados