Capítulo 3 — Programação I
Mapa da aula
Aula 03 publicada. Mapa, exemplo, EX005.
flowchart TD
N0["3.1 Por que um estudante de segurança programa"]
N1["3.2 As construções básicas"]
N2["3.3 Caso resolvido e Laboratório 2: triagem do inven"]
N3["3.4 Atividade prática"]
N4["Síntese do capítulo"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX005"]
Desenho lógico
flowchart LR
N0["3.1 Por que um estudante de segurança programa"]
N1["3.2 As construções básicas"]
N2["3.3 Caso resolvido e Laboratório 2: triagem do inven"]
N3["3.4 Atividade prática"]
N4["Síntese do capítulo"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX005"]
[3.1 Por que um estudante de segurança programa]
|
v
[3.2 As construções básicas]
|
v
[3.3 Caso resolvido e Laboratório 2: triagem do inven]
|
v
[3.4 Atividade prática]
|
v
[Síntese do capítulo]
|
v
[Exemplo resolvido] --> [Exercício EX005]
Objetivos de aprendizagem e conexão
Depois deste capítulo, você consegue (1) escrever programas curtos em Python usando variáveis, condições, laços, funções, listas e dicionários; (2) ler texto estruturado (CSV) com a biblioteca padrão; (3) transformar uma pergunta sobre um sistema ("quais dispositivos passaram do fim do suporte?") num filtro, numa contagem e num relatório; e (4) testar um programa contra um caso pequeno cuja resposta você já conhece. O capítulo se apoia no ciclo de vida de dispositivos do Capítulo 2 e prepara o Capítulo 8, em que os programas se tornam robustos contra entradas ruins.
3.1 Por que um estudante de segurança programa
O trabalho de segurança nos serviços críticos trata, sobretudo, de saber o que você tem e de perceber o que mudou. As duas coisas exigem processamento de dados: inventários com milhares de linhas, logs com milhões de linhas, alertas publicados todos os dias. Uma planilha funciona para cinquenta linhas; um programa curto funciona para cinquenta mil e pode ser executado de novo amanhã. O Python é usado aqui porque a sua biblioteca padrão lê CSV, JSON, datas e bancos de dados sem instalar nada, e porque um código legível é mais fácil de revisar — uma propriedade que importa quando o seu resultado informa uma decisão sobre a segurança de pacientes.
3.2 As construções básicas
Uma variável dá nome a um valor (year = 2026). Uma condição escolhe entre caminhos (if eos < year:). Um laço repete o trabalho para cada item (for row in rows:). Uma função empacota uma etapa com um nome e entradas, para que possa ser testada sozinha. Uma lista guarda itens em ordem; um dicionário associa chaves a valores (row["os"]). O módulo csv transforma cada linha de um arquivo CSV num dicionário indexado pelo cabeçalho. A classe collections.Counter conta quantas vezes cada valor aparece. Com isso, você consegue responder à maioria das perguntas sobre inventários.
Duas disciplinas importam desde o início. Primeiro, teste contra uma resposta conhecida: antes de rodar no arquivo real, rode em cinco linhas que você conferiu à mão. Segundo, imprima o que você excluiu, e não só o que encontrou: um filtro que descarta silenciosamente as linhas com data em branco vai reportar "nenhum dispositivo sem suporte" justamente para os dispositivos que ninguém documentou.
3.3 Caso resolvido e Laboratório 2: triagem do inventário do CVH (sintético)
Este caso é sintético. A equipe de engenharia clínica do CVH exporta uma amostra de oito linhas do seu inventário de dispositivos. A pergunta: quais dispositivos rodam software que passou do fim do suporte, onde eles estão, e há algum dispositivo não clínico na rede clínica?
# Lab 2 - triage a synthetic hospital device inventory with the standard library (offline)
import csv, io
from collections import Counter
DATA = """asset,type,os,os_end_of_support,network,clinical
INF-01,infusion pump,RTOS-x 2.1,2030,clinical-vlan,yes
INF-02,infusion pump,RTOS-x 1.4,2021,clinical-vlan,yes
IMG-01,imaging workstation,Windows 7,2020,clinical-vlan,yes
IMG-02,imaging workstation,Windows 10,2025,clinical-vlan,yes
LAB-01,lab analyser,Linux 3.10,2019,lab-vlan,yes
ADM-01,office pc,Windows 11,2031,corporate,no
ADM-02,office pc,Windows 10,2025,clinical-vlan,no
BMS-01,building controller,vendor fw 4,2027,bms-vlan,no
"""
YEAR = 2026
rows = list(csv.DictReader(io.StringIO(DATA)))
unsupported = [r for r in rows if int(r["os_end_of_support"]) < YEAR]
print("assets:", len(rows), "| unsupported:", len(unsupported))
for r in unsupported:
print(f" {r['asset']:7} {r['type']:20} {r['os']:12} EoS {r['os_end_of_support']} clinical={r['clinical']}")
print("by network:", dict(Counter(r["network"] for r in unsupported)))
misplaced = [r["asset"] for r in rows if r["clinical"] == "no" and r["network"] == "clinical-vlan"]
print("non-clinical devices on clinical VLAN:", misplaced)
Saída esperada:
assets: 8 | unsupported: 5
INF-02 infusion pump RTOS-x 1.4 EoS 2021 clinical=yes
IMG-01 imaging workstation Windows 7 EoS 2020 clinical=yes
IMG-02 imaging workstation Windows 10 EoS 2025 clinical=yes
LAB-01 lab analyser Linux 3.10 EoS 2019 clinical=yes
ADM-02 office pc Windows 10 EoS 2025 clinical=no
by network: {'clinical-vlan': 4, 'lab-vlan': 1}
non-clinical devices on clinical VLAN: ['ADM-02']
Interpretação: quatro dispositivos clínicos estão sem suporte, o que é um problema de planejamento de substituição com controles compensatórios (Capítulo 2). O ADM-02 é diferente: um PC de escritório sem suporte na rede clínica é a constatação mais barata de corrigir — atualizá-lo e movê-lo. As linhas são dados didáticos: os rótulos dos dispositivos são inventados e, embora alguns nomes de sistemas operacionais sejam conhecidos, trate cada ano de fim de suporte aqui como entrada de exemplo e confira qualquer produto real na página de ciclo de vida publicada pelo seu fornecedor.
3.4 Atividade prática
Estenda o Laboratório 2: (1) acrescente uma linha com os_end_of_support vazio e observe o erro; (2) mude o programa para que essas linhas sejam reportadas como "desconhecido — precisa de dono", em vez de travar ou serem puladas; (3) escreva um assert que confira que a contagem de dispositivos sem suporte nas oito linhas originais é 5.
A etapa (2) é a importante. Uma linha reportada como "desconhecido — precisa de dono" põe um nome numa lacuna; uma linha pulada a esconde, e uma trava interrompe o relatório para todos. O assert da etapa (3) é um teste com resposta conhecida: se uma mudança posterior no filtro o fizer imprimir 4 ou 6, o teste falha antes que alguém leia um relatório errado.
3.5 Erros comuns e limites
- Comparar números guardados como texto (
"2025" < "2026"por acaso funciona;"9" < "10"não). - Pular silenciosamente as linhas malformadas.
- Fixar o ano atual no código, de modo que o relatório envelheça; leia-o do relógio, mas mantenha-o fixo nos testes.
- Tratar uma exportação de inventário como a verdade: ela só é tão boa quanto a última pessoa que a atualizou (Capítulo 22).
No Laboratório 2, o segundo erro teria escondido o VEN-01 do EX005, o terceiro teria feito os dispositivos de 2025 parecerem com suporte de novo se o ano tivesse ficado em 2025, e o quarto se aplica à exportação inteira: o ADM-02 aparece na VLAN clínica apenas porque alguém registrou corretamente a sua rede.
Exercícios — capítulo 3
EX005 — Desconhecidos são constatações. Objetivo: tornar visíveis os dados ausentes. Entradas: o Laboratório 2 mais uma nona linha VEN-01,ventilator,,,clinical-vlan,yes. Etapas: modifique o programa para imprimir uma seção de "desconhecidos"; explique por que uma data de suporte desconhecida num ventilador deve ser escalada. Evidência esperada: mudança no código, saída e duas frases. Rubrica: 3 = sem trava, VEN-01 reportado como desconhecido, motivo de escalonamento ligado à consequência clínica; 2 = funciona sem raciocínio; 1 = trava evitada pulando a linha; 0 = nada.
EX006 — Uma função que você consegue testar. Objetivo: separar a lógica dos dados. Entradas: Laboratório 2. Etapas: escreva def is_unsupported(row, year) -> bool, teste-a com três linhas feitas à mão (com suporte, sem suporte, ano-limite igual a year) e declare a sua regra para o limite. Evidência esperada: função, testes e a regra. Rubrica: 3 = função correta, os três testes, regra do limite declarada e justificada; 2 = limite não discutido; 1 = só a função; 0 = nada.
Síntese do capítulo
Programas curtos e legíveis transformam inventários em decisões. Filtre, conte e reporte — e reporte sempre o que você não conseguiu classificar. Teste contra casos que você conhece, mantenha a lógica em funções e lembre-se de que o programa só é tão verdadeiro quanto os seus dados.
Continue estudando — capítulo 03 de 40
← Capítulo 02 · Índice de capítulos do curso · Capítulo 04 →
Siga para a próxima lição escrita.