
Passo 1 de 8
Enxergar as responsabilidades dentro do bloco
Execute um relatório concentrado em um único bloco, registre seu comportamento e identifique as responsabilidades já presentes no código.
Trilha de aprendizado · Nível 4 · Tutorial 6
Transforme um programa concentrado em um único bloco em pequenas funções que cooperam por meio de entradas e resultados explícitos.
Enxergar as responsabilidades dentro do bloco
Execute um relatório concentrado em um único bloco, registre seu comportamento e identifique as responsabilidades já presentes no código. 2 min
Escolher o que merece virar função
Defina funções a partir de responsabilidades reconhecíveis e planeje entradas e resultados explícitos antes de alterar o programa. 3 min
Extrair o processamento em pequenas mudanças
Extraia a seleção e o resumo de forma incremental, substituindo cada trecho por uma chamada e conferindo o resultado após cada mudança. 4 min
Separar cálculo de interação
Isole a leitura e a apresentação para reutilizar as funções de processamento sem depender do terminal. 3 min
Conectar as funções com uma coordenadora
Organize leitura, seleção, resumo e apresentação em uma função coordenadora que encaminha resultados por variáveis locais. 3 min
Ajustar o tamanho das responsabilidades
Compare organizações sobrecarregadas, coesas e excessivamente fragmentadas para escolher funções pelo propósito, não pela quantidade de linhas. 2 min
Conferir se o comportamento foi preservado
Compare resultados esperados e observados, verifique retornos intermediários e confirme que as funções não alteram as listas recebidas nem acumulam estado. 3 min
Consolidar a decomposição e encerrar
Finalize o relatório, revise as fronteiras entre as funções e registre as evidências de que a reorganização preservou o comportamento. 3 min

Passo 1 de 8
Execute um relatório concentrado em um único bloco, registre seu comportamento e identifique as responsabilidades já presentes no código.
O programa recebe durações inteiras não negativas, separadas por espaços, e um mínimo também não negativo. Ele seleciona as sessões com duração maior ou igual ao mínimo e informa a quantidade e o total de minutos selecionados.
Crie um único arquivo Python no seu computador e copie o código abaixo. Por enquanto, não reorganize nada. Se a primeira entrada ficar em branco, o programa considera uma lista vazia.
Salve e execute este código como um script Python. Ele não usa dependências externas.
entrada_duracoes = input("Durações em minutos: ")
duracoes = [int(valor) for valor in entrada_duracoes.split()]
minimo = int(input("Duração mínima: "))
selecionadas = [
duracao
for duracao in duracoes
if duracao >= minimo
]
quantidade = len(selecionadas)
total = 0
for duracao in selecionadas:
total += duracao
print(f"Sessões selecionadas: {quantidade}")
print(f"Total de minutos: {total}")Uma refatoração muda a organização interna sem mudar as regras nem o comportamento observável. Antes de reorganizar o programa, execute-o com as entradas abaixo e registre o resultado. Essa referência permitirá comparar a versão atual com as próximas versões.
Exemplo
Entrada de durações: 25 40 60 15
Duração mínima: 40
Resultado esperado:
Sessões selecionadas: 2
Total de minutos: 100
Faça também uma execução deixando a entrada de durações em branco e informando mínimo 30. O resultado deve ser quantidade 0 e total 0.
Embora o código ainda esteja concentrado, suas operações têm propósitos diferentes: leitura recebe e converte os dados; seleção aplica o critério mínimo; resumo calcula quantidade e total; apresentação mostra o relatório.
Reconhecer essas fronteiras vem antes de criar funções. Nas próximas etapas, a organização mudará, mas o critério duracao >= minimo, os cálculos e as mensagens deverão continuar produzindo o mesmo comportamento.

Leitura → seleção → resumo → apresentação. Cada área tem um propósito, mesmo enquanto todas permanecem no mesmo bloco.
Associe cada trecho ou compromisso à sua função no programa.
Toque em um item e depois no par correspondente.

Passo 2 de 8
Defina funções a partir de responsabilidades reconhecíveis e planeje entradas e resultados explícitos antes de alterar o programa.
Um trecho merece virar função quando contém uma regra repetida ou uma operação com significado próprio. A operação não precisa aparecer várias vezes: selecionar sessões ou produzir um resumo já são responsabilidades reconhecíveis, mesmo com uma única chamada.
Prefira nomes que expressem a finalidade, como selecionar_sessoes e resumir_sessoes. Nomes como fazer_parte_1 ou processar_dados descrevem pouco sobre o trabalho realizado.
Exemplo
A seleção aplica uma regra do domínio: manter cada duração maior ou igual ao mínimo. O resumo responde a duas perguntas relacionadas: quantas sessões foram selecionadas e quantos minutos elas totalizam. Cada operação tem um propósito que pode ser explicado sem mencionar sua posição no arquivo.
Antes de implementar, defina quais dados atravessam a fronteira de cada função. Tudo de que a operação precisa deve chegar por parâmetros; tudo o que o restante do programa precisa deve sair pelo retorno. Assim, a função não depende de variáveis externas ocultas.
A seleção recebe a lista de durações e o mínimo. A lista resultante alimenta o resumo, que produz quantidade e total.

Cada bloco conhece somente suas entradas e entrega resultados explícitos ao próximo uso.
Exemplo
selecionar_sessoes(duracoes, minimo)
Docstring planejada: “Retorna as durações maiores ou iguais ao mínimo.”
Exemplo: com durações [25, 40, 15, 40] e mínimo 30, o retorno esperado é [40, 40].
resumir_sessoes(sessoes_selecionadas)
Docstring planejada: “Retorna a quantidade e o total de minutos selecionados.”
Exemplo: com [40, 40], o retorno esperado é (2, 80). Esses são contratos de entrada e saída; a implementação será feita depois.
O programa precisa obter a quantidade e o total de minutos das sessões já selecionadas. Embora essa operação apareça apenas uma vez, ela tem significado próprio. Qual é o melhor contrato?

Passo 3 de 8
Extraia a seleção e o resumo de forma incremental, substituindo cada trecho por uma chamada e conferindo o resultado após cada mudança.
Para extrair um trecho com segurança: delimite a operação, identifique os dados de que ela depende, crie a função, substitua o trecho original por uma chamada e confira o resultado. A regra deve existir em um único lugar: depois da substituição, não deixe uma cópia ativa do trecho original.
O percurso vai do trecho original à função e termina com uma conferência antes da próxima mudança.

Delimitar → explicitar dependências → criar a função → substituir pela chamada → conferir.
Substitua todo o conteúdo do seu arquivo pela versão abaixo. A compreensão que aplica duracao >= minimo agora está somente em selecionar_sessoes. No ponto em que o trecho existia, fica a chamada que fornece duracoes e minimo e recebe a nova lista.
Execute com durações 25 40 60 15 e mínimo 40. O resultado de referência deve continuar sendo 2 sessões e 100 minutos.
def selecionar_sessoes(duracoes, minimo):
"""Retorna as durações que atingem o mínimo."""
return [
duracao
for duracao in duracoes
if duracao >= minimo
]
entrada_duracoes = input("Durações em minutos: ")
duracoes = [int(valor) for valor in entrada_duracoes.split()]
minimo = int(input("Duração mínima: "))
selecionadas = selecionar_sessoes(duracoes, minimo)
quantidade = len(selecionadas)
total = 0
for duracao in selecionadas:
total += duracao
print(f"Sessões selecionadas: {quantidade}")
print(f"Total de minutos: {total}")Agora substitua todo o arquivo pela versão abaixo. Quantidade e total permanecem juntos porque respondem ao mesmo propósito: resumir as sessões selecionadas. O bloco principal apenas chama a função e desempacota seus dois resultados.
Repita somente o caso de referência: durações 25 40 60 15 e mínimo 40. O resultado deve permanecer igual após esta segunda mudança.
def selecionar_sessoes(duracoes, minimo):
"""Retorna as durações que atingem o mínimo."""
return [
duracao
for duracao in duracoes
if duracao >= minimo
]
def resumir_sessoes(sessoes):
"""Retorna a quantidade de sessões e o total de minutos."""
quantidade = len(sessoes)
total = 0
for duracao in sessoes:
total += duracao
return quantidade, total
entrada_duracoes = input("Durações em minutos: ")
duracoes = [int(valor) for valor in entrada_duracoes.split()]
minimo = int(input("Duração mínima: "))
selecionadas = selecionar_sessoes(duracoes, minimo)
quantidade, total = resumir_sessoes(selecionadas)
print(f"Sessões selecionadas: {quantidade}")
print(f"Total de minutos: {total}")Dica
Os input e os print continuam no bloco principal por enquanto. Nesta etapa, a mudança está limitada à extração do processamento: o critério, o cálculo e as mensagens permanecem iguais.
Coloque as ações na ordem adequada para extrair uma responsabilidade sem manter duas cópias ativas da regra.
Com o caso de referência, registre o resultado observado após extrair selecionar_sessoes e após extrair resumir_sessoes. Informe também se cada trecho original foi removido e substituído pela chamada correspondente.
Escreva pelo menos 60 caracteres (0/60).

Passo 4 de 8
Isole a leitura e a apresentação para reutilizar as funções de processamento sem depender do terminal.
Na etapa anterior, seleção e resumo viraram funções, mas as duas chamadas de input e os dois print ainda ficaram no bloco principal. Agora, concentre a leitura e a conversão em ler_sessoes, que retorna duracoes e minimo. Concentre a apresentação em exibir_relatorio, que recebe quantidade e total já calculados. Assim, selecionar_sessoes e resumir_sessoes continuam dedicadas ao processamento: recebem dados por parâmetros e devolvem resultados, sem solicitar entradas nem mostrar mensagens.

A interação fica nas extremidades. No centro, as funções de processamento trabalham apenas com argumentos e retornos.
Substitua todo o conteúdo do arquivo usado nas etapas anteriores pela versão abaixo. ler_sessoes preserva os mesmos prompts e faz as mesmas conversões do programa-base. exibir_relatorio preserva as mensagens e não recalcula o resumo. O encadeamento ao final ainda é temporário; a próxima etapa organizará essa sequência.
Execute com durações 25 40 60 15 e mínimo 40. O resultado deve continuar sendo 2 sessões e 100 minutos.
def ler_sessoes():
"""Lê as durações e o mínimo e retorna os valores convertidos."""
entrada_duracoes = input("Durações em minutos: ")
duracoes = [int(valor) for valor in entrada_duracoes.split()]
minimo = int(input("Duração mínima: "))
return duracoes, minimo
def selecionar_sessoes(duracoes, minimo):
"""Retorna as durações que atingem o mínimo."""
return [
duracao
for duracao in duracoes
if duracao >= minimo
]
def resumir_sessoes(sessoes):
"""Retorna a quantidade de sessões e o total de minutos."""
quantidade = len(sessoes)
total = 0
for duracao in sessoes:
total += duracao
return quantidade, total
def exibir_relatorio(quantidade, total):
"""Apresenta a quantidade e o total de minutos."""
print(f"Sessões selecionadas: {quantidade}")
print(f"Total de minutos: {total}")
duracoes, minimo = ler_sessoes()
selecionadas = selecionar_sessoes(duracoes, minimo)
quantidade, total = resumir_sessoes(selecionadas)
exibir_relatorio(quantidade, total)Como as funções de processamento não chamam input, você pode reutilizar as regras com uma lista escrita diretamente no código. No arquivo desta etapa, substitua temporariamente apenas o bloco abaixo das definições — começando em duracoes, minimo = ler_sessoes() — pelo bloco a seguir. A execução não solicitará nenhuma entrada.
O resultado esperado é a seleção [45, 60], seguida do resumo (2, 105).
selecionadas = selecionar_sessoes([20, 45, 60], 40)
quantidade, total = resumir_sessoes(selecionadas)
print("Seleção:", selecionadas)
print("Resumo:", (quantidade, total))
# Resultado esperado:
# Seleção: [45, 60]
# Resumo: (2, 105)Dica
Os print deste bloco servem apenas para observar os retornos. Eles estão fora das funções de processamento. Para usar o relatório interativo novamente, restaure o bloco que começa com duracoes, minimo = ler_sessoes().
Qual organização permite reutilizar a seleção e o resumo sem interação com o terminal?

Passo 5 de 8
Organize leitura, seleção, resumo e apresentação em uma função coordenadora que encaminha resultados por variáveis locais.
As quatro funções já têm responsabilidades próprias. Agora, executar_relatorio organiza a ordem das chamadas: recebe os resultados da leitura, encaminha esses dados à seleção, envia a lista selecionada ao resumo e entrega quantidade e total à apresentação.
A coordenadora não contém o critério duracao >= minimo, não calcula o total e não imprime diretamente. Ela apenas conecta as funções por meio de resultados intermediários locais com nomes significativos.
Cada resultado produzido em uma etapa alimenta explicitamente os parâmetros da próxima chamada.

Os dados atravessam a coordenadora por retornos, atribuições locais e argumentos, sem depender de estado global compartilhado.
Coloque as instruções na ordem correta para formar o corpo de executar_relatorio. A coordenadora deve encaminhar todos os resultados sem usar variáveis globais e sem repetir regras de processamento.
Substitua todo o conteúdo do seu arquivo local pelo script abaixo. As funções auxiliares permanecem com as responsabilidades já definidas. A novidade é executar_relatorio, que reúne a sequência ordenada no exercício.
Após todas as definições, a chamada direta executar_relatorio() inicia o programa.
Execute com durações 25 40 60 15 e mínimo 40. O resultado deve continuar sendo 2 sessões e 100 minutos.
def ler_sessoes():
"""Lê as durações e o mínimo e retorna os valores convertidos."""
entrada_duracoes = input("Durações em minutos: ")
duracoes = [int(valor) for valor in entrada_duracoes.split()]
minimo = int(input("Duração mínima: "))
return duracoes, minimo
def selecionar_sessoes(duracoes, minimo):
"""Retorna as durações que atingem o mínimo."""
return [
duracao
for duracao in duracoes
if duracao >= minimo
]
def resumir_sessoes(sessoes):
"""Retorna a quantidade de sessões e o total de minutos."""
quantidade = len(sessoes)
total = 0
for duracao in sessoes:
total += duracao
return quantidade, total
def exibir_relatorio(quantidade, total):
"""Apresenta a quantidade e o total de minutos."""
print(f"Sessões selecionadas: {quantidade}")
print(f"Total de minutos: {total}")
def executar_relatorio():
"""Coordena a leitura, o processamento e a apresentação."""
duracoes, minimo = ler_sessoes()
selecionadas = selecionar_sessoes(duracoes, minimo)
quantidade, total = resumir_sessoes(selecionadas)
exibir_relatorio(quantidade, total)
executar_relatorio()Dica
Os nomes duracoes, minimo, selecionadas, quantidade e total tornam o percurso legível dentro de executar_relatorio. Nenhum deles precisa ser global: cada valor é produzido, armazenado localmente e encaminhado à próxima função.

Passo 6 de 8
Compare organizações sobrecarregadas, coesas e excessivamente fragmentadas para escolher funções pelo propósito, não pela quantidade de linhas.
A qualidade da decomposição não depende de produzir o maior número de funções. Uma função fica sobrecarregada quando reúne propósitos distintos, como ler entradas, selecionar sessões, calcular o resumo e imprimir. No outro extremo, dividir cada instrução em uma função obriga o leitor a saltar entre definições sem tornar a regra mais clara. A organização coesa fica entre esses extremos: cada função reúne operações que contribuem para um propósito identificável.
À esquerda, uma única função concentra responsabilidades diferentes. No centro, funções coesas formam um percurso legível. À direita, funções minúsculas criam etapas e saltos sem acrescentar significado.

A granularidade útil torna as responsabilidades visíveis sem transformar cada instrução em uma nova fronteira.
resumir_sessoes responde a duas perguntas relacionadas sobre a mesma lista: quantas sessões existem e quantos minutos elas totalizam. Manter esses cálculos juntos é coeso porque ambos contribuem para o propósito declarado de resumir. Não é necessário criar uma função para cada atribuição, chamada ou linha do acumulador.
Esta versão preserva o acumulador do programa-base e mantém os dois resultados relacionados na mesma função.
def resumir_sessoes(sessoes):
"""Retorna a quantidade de sessões e o total de minutos."""
quantidade = len(sessoes)
total = 0
for duracao in sessoes:
total += duracao
return quantidade, totalEsta alternativa produz o mesmo resumo, mas introduz nomes vagos e repasses que dificultam acompanhar uma operação simples.
def etapa_1(sessoes):
return len(sessoes)
def etapa_2(total, duracao):
return total + duracao
def etapa_3(sessoes):
total = 0
for duracao in sessoes:
total = etapa_2(total, duracao)
return total
def resumir_sessoes(sessoes):
quantidade = etapa_1(sessoes)
total = etapa_3(sessoes)
return quantidade, totalDica
Desconfie de divisões que geram nomes vagos, apenas repassam dados ou exigem vários saltos para entender uma regra curta. Não existe uma quantidade fixa de linhas que determine quando criar uma função: prefira a organização que deixa cada responsabilidade mais fácil de reconhecer e acompanhar.
Qual organização é mais adequada para o relatório de sessões?

Passo 7 de 8
Compare resultados esperados e observados, verifique retornos intermediários e confirme que as funções não alteram as listas recebidas nem acumulam estado.
Monte a conferência com três informações: entrada, resultado esperado do programa-base e resultado observado na versão refatorada. Use casos que exercitem sessões abaixo, acima e exatamente no mínimo, além de nenhuma sessão selecionada e lista vazia. Compare primeiro o retorno de selecionar_sessoes e depois o de resumir_sessoes. Se o resultado final divergir, essa ordem ajuda a localizar a primeira responsabilidade que produziu um valor diferente.
A comparação começa pela seleção, passa pelo resumo e termina no relatório completo.

Conferir resultados intermediários permite localizar a primeira divergência, em vez de observar somente a saída final.
No arquivo criado na etapa 5, substitua temporariamente somente a chamada final executar_relatorio() pelo bloco abaixo. Uma única execução cobre os casos representativos, chama as duas funções de processamento sucessivamente e confere se as listas entregues a elas continuam iguais ao conteúdo anterior.
Em cada caso, compare as linhas “esperada” e “observada”. As três verificações finais devem mostrar True.
casos = [
(
"abaixo, exatamente no mínimo e acima",
[20, 40, 60],
40,
[40, 60],
(2, 100),
),
(
"nenhuma sessão selecionada",
[10, 20],
30,
[],
(0, 0),
),
(
"lista vazia",
[],
30,
[],
(0, 0),
),
]
for nome, duracoes, minimo, selecao_esperada, resumo_esperado in casos:
duracoes_antes = duracoes.copy()
selecao_1 = selecionar_sessoes(duracoes, minimo)
selecao_2 = selecionar_sessoes(duracoes, minimo)
sessoes_para_resumo = selecao_1.copy()
sessoes_antes = sessoes_para_resumo.copy()
resumo_1 = resumir_sessoes(sessoes_para_resumo)
resumo_2 = resumir_sessoes(sessoes_para_resumo)
print(f"\nCaso: {nome}")
print("Entrada:", duracoes, "Mínimo:", minimo)
print("Seleção esperada:", selecao_esperada)
print("Seleção observada:", selecao_1)
print("Resumo esperado:", resumo_esperado)
print("Resumo observado:", resumo_1)
print("Durações preservadas:", duracoes == duracoes_antes)
print("Sessões do resumo preservadas:", sessoes_para_resumo == sessoes_antes)
print("Chamadas sucessivas iguais:", selecao_1 == selecao_2 and resumo_1 == resumo_2)Exemplo
No primeiro caso, a seleção esperada e observada é [40, 60], e o resumo é (2, 100). Isso confirma que 40, exatamente igual ao mínimo, foi incluído. Nos outros dois casos, a seleção é [] e o resumo é (0, 0). Em todos os casos, as três verificações booleanas devem exibir True. Se uma seleção divergir, investigue selecionar_sessoes; se a seleção estiver correta e apenas o resumo divergir, investigue resumir_sessoes.
Remova o bloco temporário e restaure a chamada final executar_relatorio(). Execute o programa com durações 25 40 60 15 e mínimo 40. Além dos valores finais — 2 sessões e 100 minutos — compare com o programa-base os prompts, as mensagens e a ordem da interação. A conferência manual encontra regressões nos casos escolhidos, mas não prova que todas as entradas possíveis produzem comportamento equivalente.
Quais resultados você observou no bloco de conferência? Inclua o caso exatamente no mínimo, um caso sem sessões selecionadas, a preservação das duas listas e o resultado das chamadas sucessivas. Depois, informe se a execução completa manteve valores, prompts, mensagens e ordem da interação.
Escreva pelo menos 120 caracteres (0/120).

Passo 8 de 8
Finalize o relatório, revise as fronteiras entre as funções e registre as evidências de que a reorganização preservou o comportamento.
Confira se o arquivo local contém a versão completa abaixo. As fronteiras devem permanecer claras: ler_sessoes cuida da entrada, selecionar_sessoes aplica o critério, resumir_sessoes calcula os resultados, exibir_relatorio apresenta as mensagens e executar_relatorio coordena as chamadas. Não acrescente novas regras ao relatório.
Execute uma última vez com durações 25 40 60 15 e mínimo 40. O resultado deve ser 2 sessões e 100 minutos, com os mesmos prompts e mensagens do programa-base.
def ler_sessoes():
"""Lê as durações e o mínimo e retorna os valores convertidos."""
entrada_duracoes = input("Durações em minutos: ")
duracoes = [int(valor) for valor in entrada_duracoes.split()]
minimo = int(input("Duração mínima: "))
return duracoes, minimo
def selecionar_sessoes(duracoes, minimo):
"""Retorna as durações que atingem o mínimo."""
return [
duracao
for duracao in duracoes
if duracao >= minimo
]
def resumir_sessoes(sessoes):
"""Retorna a quantidade de sessões e o total de minutos."""
quantidade = len(sessoes)
total = 0
for duracao in sessoes:
total += duracao
return quantidade, total
def exibir_relatorio(quantidade, total):
"""Apresenta a quantidade e o total de minutos."""
print(f"Sessões selecionadas: {quantidade}")
print(f"Total de minutos: {total}")
def executar_relatorio():
"""Coordena a leitura, o processamento e a apresentação."""
duracoes, minimo = ler_sessoes()
selecionadas = selecionar_sessoes(duracoes, minimo)
quantidade, total = resumir_sessoes(selecionadas)
exibir_relatorio(quantidade, total)
executar_relatorio()A coordenadora recebe os resultados de uma função e os encaminha à próxima por parâmetros. As funções de processamento não usam input, não imprimem e não dependem de estado global compartilhado. A decomposição também evita fragmentar cada instrução: quantidade e total continuam reunidos na responsabilidade de resumo.
Use o mapa para acompanhar o percurso desde a leitura até a apresentação. A coordenação envolve todo o fluxo, mas não substitui as responsabilidades internas.

Os dados seguem da leitura para a seleção e o resumo; somente depois os resultados chegam à apresentação.
Resumo
Use estes critérios para revisar o programa final.
selecionar_sessoes e resumir_sessoes não chamam input nem print.Escreva um relato curto sobre sua implementação local. Inclua: a responsabilidade, as entradas e os resultados de selecionar_sessoes e resumir_sessoes; como executar_relatorio conecta leitura, seleção, resumo e apresentação; e as evidências observadas para o caso exatamente no mínimo, um caso sem seleção, a preservação das listas, as chamadas sucessivas e a execução completa.
Escreva pelo menos 250 caracteres (0/250).
Resumo
Ao reorganizar outros programas concentrados em um único bloco, repita este percurso.
Parabéns! Você concluiu: Decompor um programa em funções com responsabilidades claras
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks