Aula 04 - Estruturas de Repetição, Laços Determinados e Indeterminados
Navegação Rápida
📍 Disciplina: 01 Lógica de Programação | 🗺️ Área: 06 Computação e Telecomunicações | 🏠 Hub Principal
Metadados da Aula
- Área: 06 Computação e Telecomunicações
- Carga Horária Equivalente: 4 horas-aula teóricas e práticas
- Pré-requisitos: Aula 03 - Estruturas Condicionais
- Palavras-chave: Laço Determinado (for), Laço Indeterminado (while), Protocolo de Iteração, Invariante de Laço, Newton-Raphson, Convergência Quadrática, True RMS, Cláusula else em Laços
📌 Sumário da Aula
- 🧭 1. Contextualização e Objetivos de Aprendizagem
- 📋 2. Sumário Executivo dos Tópicos
- ⚡ 3. Fundamentação Teórica e Modelagem Matemática
- 🖼️ 4. Diagrama Técnico Integrado
- 💻 5. Implementação Prática em Engenharia Elétrica
- 📝 6. Banco de Questões de Fixação e Concursos Auditados
- 📚 7. Referências Bibliográficas e Normas Técnicas
🧭 1. Contextualização e Objetivos de Aprendizagem
O poder transformador da computação em engenharia manifesta-se plenamente quando a máquina executa tarefas matemáticas repetitivas com velocidade e exatidão imunes à fadiga humana. Seja na integração numérica de equações diferenciais de transitórios eletromagnéticos, no processamento discreto de sinais amostrados por conversores A/D a dezenas de milhares de vezes por segundo, ou na convergência de sistemas de equações algébricas não-lineares em redes elétricas de grande porte, as estruturas de repetição constituem o motor primário dos algoritmos de simulação e controle.
Esta aula aprofunda a teoria e a prática dos laços de repetição (laços determinados for e laços indeterminados while). Analisa o formalismo lógico de prova de programas através da técnica de Invariantes de Laço, disseca a dedução analítica e a taxa de convergência quadrática do método de Newton-Raphson, e demonstra a implementação computacional do cálculo do valor eficaz verdadeiro (True RMS) em sinais distorcidos por harmônicas.
Ao término desta aula, o engenheiro será capaz de:
- Selecionar e implementar a estrutura de repetição ótima (
forcom geradoresrange()ouwhilecom sentinelas de segurança), dominando as instruções de controlebreak,continuee a cláusulaelse. - Formular e demonstrar formalmente a corretude de um laço de repetição através das três etapas da prova de Invariante de Laço (Inicialização, Manutenção e Terminação).
- Desenvolver solvers iterativos de raízes e sistemas de equações não-lineares baseados em Newton-Raphson com proteção rigorosa contra singularidades derivadas e limites de iteração máxima.
- Projetar algoritmos discretos de integração numérica temporal para medição digital de grandezas elétricas True RMS e potências segundo as normas IEEE 1459.
📋 2. Sumário Executivo dos Tópicos
- Protocolo de Iteração em Python: Mecanismo subjacente aos laços
for. Objetos iteráveis implementam o método__iter__(), retornando um iterador que avança sequencialmente via__next__()até emitir a exceçãoStopIteration. - Gerador
range(start, stop, step): Estrutura imutável de progressão aritmética com consumo de memória estritamente constante , independente da quantidade de elementos gerados. - Laço Indeterminado
while: Executa iterativamente enquanto a proposição de controle permanecer verdadeira. Exige obrigatoriamente mecanismos de garantia de término (critério de convergência e sentinela de iterações máximas). - Invariante de Laço: Propriedade lógica invariável no tempo comprovada por indução matemática: verdadeira na Inicialização (pré-iteração), conservada na Manutenção (iteração ) e garantidora da corretude na Terminação.
- Método de Newton-Raphson: Algoritmo numérico de aproximação tangencial derivado da expansão em Série de Taylor de 1ª ordem: . Apresenta convergência de ordem quadrática ().
- Cálculo Numérico True RMS: Quadratura média temporal discreta: , computando com exatidão componentes fundamentais e todo o espectro harmônico.
⚡ 3. Fundamentação Teórica e Modelagem Matemática
3.1 Mecanismo de Iteração em Python: for, while e o Protocolo de Iteração
Em Python, a instrução for não é meramente um contador numérico incrementado em registrador como em C ou Assembly (for(int i=0; i<N; i++)). Trata-se de um construto de alto nível governado pelo Protocolo de Iteração (Iterator Protocol).
3.1.1 O Tipo range e Eficiência de Memória
A função range(início, fim, passo) retorna um objeto de sequência aritmética imutável:
Diferente de construir uma lista de 10 milhões de inteiros (list(range(10_000_000))), que consumiria cerca de de memória RAM no Heap, o objeto range armazena exclusivamente três inteiros de 64 bits (start, stop, step), computando cada valor sob demanda em tempo e consumo de memória invariante de .
3.1.2 Instruções de Salto e a Cláusula else em Laços
break: Interrompe prematuramente a execução do laço mais interno, saltando para a primeira instrução externa.continue: Aborta a iteração corrente e avança imediatamente para o teste condicional do próximo ciclo.- Cláusula
elseacoplada ao laço: Recurso sintático exclusivo do Python. O blocoelseassociado a umforouwhileexecuta se e somente se o laço terminar naturalmente (esgotamento do iterável ou condição tornada falsa). Se o laço for interrompido por umbreak, o blocoelseé ignorado.
3.2 Prova Formal de Corretude: A Teoria da Invariante de Laço
Para validar que um algoritmo iterativo produz resultados matematicamente corretos em sistemas de alta criticidade (como telecomando de subestações e cálculos de proteção), utiliza-se o método axiomático formulado por C. A. R. Hoare: a Invariante de Laço (Loop Invariant).
Uma invariante de laço é uma asserção lógica sobre as variáveis do programa que deve ser verdadeira em cada iteração do ciclo. A prova formal exige três etapas rigorosas por indução matemática:
Aplicação: Demonstração da Acumulação de Perdas Joule
Considere o algoritmo que calcula a perda Joule total em ramos de um alimentador elétrico:
Código Python sob análise:
3.3.2 Dedução da Ordem de Convergência Quadrática
Seja a raiz exata da função () e o erro absoluto na iteração . Expandindo em torno de :
Reescrevendo a equação de recorrência multiplicada por :
Substituindo :
Consequência Prática da Convergência Quadrática
A relação significa que o erro na iteração subsequente é proporcional ao quadrado do erro anterior. Se em uma determinada iteração o erro for , na iteração seguinte será , e na subsequente . O número de dígitos significativos corretos dobra a cada iteração do laço. Em contrapartida, se a derivada , o quociente explode e o algoritmo diverge, exigindo guardas de proteção de software.
3.4 Discretização Numérica e Cálculo de Valor Eficaz True RMS
Em instrumentação eletrônica e sistemas digitais de proteção, o cálculo do valor eficaz (Root Mean Square - RMS) de uma forma de onda de tensão ou corrente periódica contínua de período é formalmente definido por:
Quando o sinal é digitalizado por um conversor analógico-digital (ADC) que captura amostras discretas uniformemente espaçadas por no intervalo temporal :
A integral contínua é aproximada numericamente pela quadratura discreta de Riemann (Regra do Ponto Médio / Retangular):
Como , a formulação computacional direta do True RMS Discreto resulta em:
Analogamente, a Potência Ativa Média () absorvida pela carga ao longo de um ciclo é a média temporal do produto das amostras instantâneas de tensão e corrente:
🖼️ 4. Diagrama Técnico Integrado
O diagrama técnico a seguir sintetiza os fundamentos das estruturas de repetição: à esquerda, os paradigmas operacionais dos laços for e while com o formalismo de prova da invariante de laço; à direita, a dinâmica de convergência quadrática do método numérico de Newton-Raphson aplicado à engenharia de potência:
💻 5. Implementação Prática em Engenharia Elétrica
5.1 Solver Não-Linear de Newton-Raphson com Salvaguardas de Divergência
O código a seguir implementa um solver numérico de raízes em Python 3 utilizando o método de Newton-Raphson. A rotina integra verificação de singularidade de derivada (), tolerância absoluta e relativa no resíduo, e limite máximo de iterações com cláusula else no laço while:
"""
Solver Numerico de Newton-Raphson para Sistemas Nao-Lineares.
Equipado com protecao de singularidade de derivada e convergencia estrita.
"""
import math
from typing import Callable, Tuple
def resolver_newton_raphson(
funcao_f: Callable[[float], float],
funcao_df: Callable[[float], float],
estimativa_inicial_x0: float,
tolerancia: float = 1e-9,
max_iteracoes: int = 100,
) -> Tuple[float, int, bool]:
"""
Localiza a raiz de f(x) = 0 utilizando o algoritmo de Newton-Raphson.
Retorna:
Tuple contendo: (raiz_calculada, total_iteracoes, convergiu_flag).
"""
xk = estimativa_inicial_x0
iteracao = 0
print(f"{'Iteracao':<10} | {'x_k':<18} | {'f(x_k)':<18} | {'Passo Delta_x':<18}")
print("-" * 72)
while iteracao < max_iteracoes:
fx = funcao_f(xk)
dfx = funcao_df(xk)
# 1. Salvaguarda contra derivada nula ou excessivamente proxima de zero
if abs(dfx) < 1e-14:
print(f"[ALERTA CRITICO] Derivada nula (f'(x) = {dfx:.2e}) na iteracao {iteracao}! Abortando.")
return xk, iteracao, False
# 2. Calculo do passo de correcao de Newton: Delta_x = f(x) / f'(x)
delta_x = fx / dfx
xk_proximo = xk - delta_x
print(f"{iteracao:<10} | {xk:<18.10f} | {fx:<18.10e} | {delta_x:<18.10e}")
# 3. Criterio de parada conjugado: variacao do passo e residuo da funcao
if abs(delta_x) < tolerancia and abs(fx) < tolerancia:
print("-" * 72)
print(f"[CONVERGENCIA ATINGIDA] Raiz localizada em {iteracao + 1} iteracoes.")
return xk_proximo, iteracao + 1, True
xk = xk_proximo
iteracao += 1
else:
# Clausula else do while: executada se o laco atingir max_iteracoes sem convergir
print("-" * 72)
print(f"[FALHA DE CONVERGENCIA] Limite maximo de {max_iteracoes} iteracoes excedido.")
return xk, iteracao, False
def main():
# Exemplo em Engenharia Eletrica: Calculo da Tensao de Barra em PU
# Equacao de fluxo de carga simplificada: f(V) = V^3 - 0.2*V - 1.05 = 0
# Derivada analitica: f'(V) = 3*V^2 - 0.2
f_tensao = lambda v: (v ** 3) - 0.2 * v - 1.05
df_tensao = lambda v: 3.0 * (v ** 2) - 0.2
print("========================================================================")
print(" CALCULO DE TENSAO DE BARRA DE CARGA VIA NEWTON-RAPHSON ")
print("========================================================================")
v_raiz, passos, sucesso = resolver_newton_raphson(
funcao_f=f_tensao,
funcao_df=df_tensao,
estimativa_inicial_x0=1.0, # Estimativa tipica inicial "Flat Start" (1.0 pu)
tolerancia=1e-8,
max_iteracoes=20
)
if sucesso:
print(f"Tensao Final de Operacao da Barra: V = {v_raiz:.8f} pu")
print("========================================================================\n")
if __name__ == "__main__":
main()5.2 Analisador Numérico Discreto de Grandezas True RMS com Harmônicas
A rotina a seguir simula a aquisição em tempo real de uma onda de corrente industrial distorcida por retificadores a tiristor (contendo fundamental de , de 3ª harmônica e de 5ª harmônica), calculando as grandezas True RMS e a Distorção Harmônica Total ():
"""
Analisador Digital True RMS e Distorcao Harmonica Total (THD).
Implementacao orientada a processamento discreto de sinais amostrados.
"""
import math
def analisar_sinal_digitalizado(
frequencia_rede_hz: float,
num_amostras_por_ciclo: int,
i_fundamental_pico: float,
i_h3_pico: float,
i_h5_pico: float,
defasagem_graus: float = 30.0,
):
periodo_s = 1.0 / frequencia_rede_hz
dt = periodo_s / num_amostras_por_ciclo
omega = 2.0 * math.pi * frequencia_rede_hz
phi_rad = math.radians(defasagem_graus)
# Acumuladores numericos para os lacos de integracao
soma_v2 = 0.0
soma_i2 = 0.0
soma_potencia_inst = 0.0
tensao_pico = 311.127 # Equivalente a 220 V eficazes
for k in range(num_amostras_por_ciclo):
t = k * dt
# Sinal senoidal puro de tensao de alimentacao da rede
v_k = tensao_pico * math.sin(omega * t)
# Corrente distorcida com harmonicas impares tipicas de eletronica de potencia
i_k = (
i_fundamental_pico * math.sin(omega * t - phi_rad)
+ i_h3_pico * math.sin(3.0 * omega * t - (3.0 * phi_rad))
+ i_h5_pico * math.sin(5.0 * omega * t - (5.0 * phi_rad))
)
# Quadratura e produto instantaneo
soma_v2 += v_k ** 2
soma_i2 += i_k ** 2
soma_potencia_inst += v_k * i_k
# Calculo das medias discretas de True RMS
v_rms_true = math.sqrt(soma_v2 / num_amostras_por_ciclo)
i_rms_true = math.sqrt(soma_i2 / num_amostras_por_ciclo)
potencia_ativa_p = soma_potencia_inst / num_amostras_por_ciclo
potencia_aparente_s = v_rms_true * i_rms_true
fator_potencia_real = potencia_ativa_p / potencia_aparente_s
# Calculo analitico de THD da corrente
i1_rms = i_fundamental_pico / math.sqrt(2.0)
i_harmonicas_rms = math.sqrt((i_h3_pico / math.sqrt(2.0))**2 + (i_h5_pico / math.sqrt(2.0))**2)
thd_corrente_percent = (i_harmonicas_rms / i1_rms) * 100.0
return {
"amostras_totais": num_amostras_por_ciclo,
"v_rms_true": v_rms_true,
"i_rms_true": i_rms_true,
"potencia_ativa_w": potencia_ativa_p,
"potencia_aparente_va": potencia_aparente_s,
"fator_potencia_real": fator_potencia_real,
"thd_corrente_percent": thd_corrente_percent,
}
def main():
# Ensaio com 512 amostras por ciclo (taxa de 30.72 kHz para 60 Hz)
laudo = analisar_sinal_digitalizado(
frequencia_rede_hz=60.0,
num_amostras_por_ciclo=512,
i_fundamental_pico=100.0, # 70.71 A rms fundamental
i_h3_pico=25.0, # 25% de 3a harmonica
i_h5_pico=15.0, # 15% de 5a harmonica
defasagem_graus=25.84 # cos(25.84°) ~= 0.90
)
print("=================================================================")
print(" ANALISADOR DISCRETO DE QUALIDADE DE ENERGIA (TRUE RMS) ")
print("=================================================================")
print(f"Total de Amostras por Ciclo : {laudo['amostras_totais']}")
print(f"Tensao Eficaz True RMS : {laudo['v_rms_true']:>10.2f} V")
print(f"Corrente Eficaz True RMS : {laudo['i_rms_true']:>10.2f} A")
print(f"Distorcao Harmonica Total THD: {laudo['thd_corrente_percent']:>10.2f} %")
print("-----------------------------------------------------------------")
print(f"Potencia Ativa Media (P) : {laudo['potencia_ativa_w']:>10.2f} W")
print(f"Potencia Aparente Total (S) : {laudo['potencia_aparente_va']:>10.2f} VA")
print(f"Fator de Potencia Real (FP) : {laudo['fator_potencia_real']:>10.4f}")
print("=================================================================")
if __name__ == "__main__":
main()📝 6. Banco de Questões de Fixação e Concursos Auditados
Questão 01 — Análise de Convergência Quadrática de Newton-Raphson em Fluxo de Potência
(Petrobras — Engenharia de Sistemas de Potência — Adaptada)
Em um estudo de planejamento elétrico, a equação não-linear escalar que determina a tensão da barra é:
Um algoritmo computacional baseado no método de Newton-Raphson é inicializado com uma estimativa plana (flat start) de .
a) Calcule os valores numéricos de e exibidos nas duas primeiras iterações do laço.
b) Calcule os erros absolutos , e sabendo que a raiz exata é .
c) Demonstre que a taxa de redução de erro obedece estritamente à constante de convergência quadrática .
💡 Resolução Analítica Passo a Passo:
a) Cálculo das Iterações de Recorrência: A derivada da função é: A fórmula de recorrência é:
-
Iteração 0 1 ():
-
Iteração 1 2 ():
b) Cálculo dos Erros Absolutos: Com a raiz exata :
c) Comprovação da Constante de Convergência Quadrática: Calculando a constante teórica de erro assintótico: Aplicando a equação teórica :
- Para :
- Para : A demonstração comprova que os erros calculados satisfazem rigorosamente a relação quadrática assintótica de Newton-Raphson.
Questão 02 — Prova Formal de Invariante de Laço em Algoritmo de Busca MPPT
(Marinha do Brasil — Corpo de Engenheiros / Eletrônica)
Em sistemas fotovoltaicos, algoritmos de rastreamento do ponto de máxima potência (Maximum Power Point Tracking - MPPT) varrem amostras de tensão e corrente de painéis solares para identificar o ponto ótimo operacional. Considere o algoritmo a seguir que identifica a potência máxima em um vetor amostrado:
def buscar_potencia_maxima(vetor_potencias):
p_max = vetor_potencias[0]
for i in range(1, len(vetor_potencias)):
# Assercao da Invariante: p_max == max(vetor_potencias[0 : i])
if vetor_potencias[i] > p_max:
p_max = vetor_potencias[i]
return p_maxFormule e prove formalmente a invariante de laço nas três etapas clássicas de Hoare (Inicialização, Manutenção e Terminação).
💡 Resolução Analítica Passo a Passo:
Definição da Invariante de Laço ():
No início de cada iteração do laço for indexada por , a variável local p_max contém o valor máximo estrito dentre todos os elementos contidos no subarray anterior:
-
1. Inicialização:
Antes da primeira iteração do laço, temos . O subarray considerado é formado exclusivamente pelo elemento de índice 0: .
Como a linha imediatamente anterior inicializoup_max = vetor_potencias[0], temos trivialmente . Logo, a invariante é verdadeira na inicialização. -
2. Manutenção:
Assuma por hipótese indutiva que a invariante é verdadeira antes da iteração com índice . Ou seja, .
Durante a iteração , o corpo do laço avalia o elemento :- Se ,
p_maxé atualizado para , tornando-se o maior elemento do conjunto ampliado ; - Se ,
p_maxpermanece inalterado, conservando a condição de ser o maior elemento do conjunto ampliado .
Portanto, ao final da iteração (e antes da iteração ), temos rigorosamente . A invariante é preservada na manutenção.
- Se ,
-
3. Terminação:
O laço encerra quando o índice atinge , onde . Substituindo na invariante: Como o intervalo compreende todos os elementos do vetor amostrado, a instruçãoreturn p_maxentrega o valor máximo absoluto global da potência com garantia matemática de corretude.
Questão 03 — Semântica da Cláusula else em Laços de Varredura de Faltas Elétricas
(ENADE — Engenharia de Computação / Controle)
Considere o seguinte trecho de código projetado para diagnosticar sobrecorrente em um alimentador trifásico com 10 sensores de monitoramento:
def diagnosticar_alimentador(sensores_corrente, limite_i):
for sensor in sensores_corrente:
if sensor.leitura_amperes > limite_i:
print(f"FALTA DETECTADA no sensor {sensor.id}! Disparo acionado.")
break
else:
print("ALIMENTADOR SEGURO: Nenhuma sobrecorrente detectada em nenhum sensor.")a) Explique a função semântica da cláusula else após o bloco for em Python e descreva em que circunstâncias ela é executada.
b) Se a cláusula else for removida e a mensagem print("ALIMENTADOR SEGURO...") for simplesmente tabulada fora do laço for, qual erro de lógica grave ocorrerá quando houver uma falta elétrica real?
💡 Resolução Analítica Passo a Passo:
a) Semântica da Cláusula else em Laços:
No modelo de execução da linguagem Python, a cláusula else vinculada a um laço (for ou while) atua como uma cláusula de sucesso da varredura completa sem interrupção.
Ela é executada se e somente se o laço esgotar todos os itens da sequência iterável sem ter executado nenhuma instrução break. Se qualquer sensor reportar corrente superior a limite_i, a linha break é acionada: o laço é abortado imediatamente e o bloco else associado é ignorado. Portanto, a mensagem "ALIMENTADOR SEGURO" só será emitida se todos os 10 sensores tiverem sido avaliados e nenhum tiver apresentado sobrecorrente.
b) Erro Lógico por Remoção Incorreta:
Se a palavra-chave else: for suprimida e a instrução print("ALIMENTADOR SEGURO...") for posicionada diretamente após o término do bloco for:
# CODIGO COM ERRO GRAVE DE ENGENHARIA:
for sensor in sensores_corrente:
if sensor.leitura_amperes > limite_i:
print(f"FALTA DETECTADA no sensor {sensor.id}!")
break
print("ALIMENTADOR SEGURO: Nenhuma sobrecorrente detectada.") # Executa SEMPRE!Quando ocorrer uma sobrecorrente real no sensor 3, a instrução break interromperá o laço. O interpretador prosseguirá para a próxima linha do script, imprimindo a mensagem de que o sistema está seguro logo após emitir o alarme de falta! O operador do supervisório receberá informações contraditórias simultâneas no log de eventos, gerando confusão operacional em momento crítico de manobra. A cláusula else elimina a necessidade de criar variáveis sentinela do tipo booleano (falta_encontrada = False).
📚 7. Referências Bibliográficas e Normas Técnicas
- HOARE, C. A. R. An Axiomatic Basis for Computer Programming. Communications of the ACM, v. 12, n. 10, p. 576-580, 1969.
- BURDEN, Richard L.; FAIRES, J. Douglas. Numerical Analysis. 9. ed. Boston: Cengage Learning, 2011.
- CHAPRA, Steven C.; CANALE, Raymond P. Métodos Numéricos para Engenharia. 7. ed. Porto Alegre: AMGH, 2016.
- IEEE Std 1459-2010: IEEE Standard Definitions for the Measurement of Electric Power Quantities Under Sinusoidal, Nonsinusoidal, Balanced, or Unbalanced Conditions. New York: IEEE, 2010.
- KNUTH, Donald E. The Art of Computer Programming, Volume 1: Fundamental Algorithms. 3. ed. Boston: Addison-Wesley, 1997.
- PYTHON SOFTWARE FOUNDATION. The Python Language Reference: Compound Statements (The while and for statements). Python 3.12 Documentation, 2024.