Projeto Integrador: Sistema Completo de Gestão em Lógica de Programação
Parabéns! Você chegou ao fim da primeira etapa da sua formação. Nesta aula, vamos unir todas as peças do quebra-cabeça que construímos ao longo das 29 aulas anteriores para edificar um sistema corporativo completo de gestão clínica. Do menu iterativo às rotinas de ordenação por structs e relatórios executivos, veja a lógica de programação em seu estado mais poderoso.
1. A Grande Síntese: O Significado de Chegar à Aula 30
Quando iniciamos este curso na Aula 01, o nosso universo computacional resumia-se a uma linha solitária que imprimia "Olá, Mundo!" no console preto. Você aprendeu que a CPU precisa de instruções unívocas, que números reais não cabem em variáveis inteiras sem truncamento e que um se decide o rumo de um destino lógico.
Depois vieram os laços de repetição (Trilha 3), que transformaram instruções manuais em varreduras automáticas de milhares de passos. Vieram as funções e procedimentos (Trilha 4), que quebraram monolitos opacos em pequenas peças reutilizáveis de lego. Vieram os vetores e matrizes (Trilha 5), que organizaram dados em fileiras e grades espaciais. E, por fim, vieram as boas práticas de Clean Code, o teste de mesa e as estruturas de registros (Trilha 6).
Agora, você não é mais um iniciante que digita comandos sem rumo torcendo para compilar. Você é alguém que compreende a mecânica da memória RAM, avalia a complexidade assintótica de seus laços e projeta a arquitetura do seu código antes de tocar no teclado.
É hora de coroar essa jornada construindo o nosso Projeto Integrador Final.
2. Especificação de Requisitos: O Sistema ClinicaTech
Nosso objetivo é desenvolver o núcleo lógico de um sistema de recepção e faturamento para um centro médico ambulatorial chamado ClinicaTech.
Requisitos Funcionais do Sistema:
-
Menu Interativo em Loop Contínuo: A aplicação deve rodar indefinidamente até que o operador selecione explicitamente a opção
0 (Sair). - Cadastro de Consultas Médicas: Permitir registrar novos atendimentos informando código identificador único (ID), nome do paciente, idade, especialidade médica, valor da consulta e status (ativa/cancelada).
- Validação Estrita com Cláusulas Guarda: O sistema deve impedir cadastros com valores negativos, idades irreais ou duplicidade de código de atendimento.
- Listagem Tabular Formatada: Exibir todos os registros ativos em uma grade limpa com cabeçalho alinhado e formatação monetária.
- Localização Rápida por Código (Busca): Permitir que o operador digite um ID e localize instantaneamente a ficha cadastral do atendimento, informando caso não exista.
- Ordenação de Prioridade (Bubble Sort de Structs): Permitir reordenar todo o rol de pacientes por valor da consulta ou por idade de forma 100% atômica e segura.
-
Dashboard Executivo de Métricas: Consolidar os dados da memória RAM para exibir em tempo real:
- Faturamento bruto total arrecadado;
- Média de valor por consulta realizada;
- Identificação do paciente mais idoso atendido na clínica;
- Total de atendimentos cadastrados versus capacidade máxima da memória.
3. Modelagem de Dados: A Entidade de Domínio Atendimento
Rejeitando totalmente a prática ultrapassada dos vetores paralelos, modelamos nosso domínio através de uma Estrutura de Objeto (Registro Composto) nativa da plataforma logicabr.dev:
// Entidade de negócio fundamental representada como objeto estruturado
registro pacienteExemplo = { id: 101, pacienteNome: "Helena Martins", idade: 34, especialidade: "Cardiologia", valorConsulta: 350.00, ativo: verdadeiro };
Dessa forma, cada paciente atendido tem sua identidade, biometria e transação financeira encapsuladas em uma única unidade atômica com propriedades nomeadas e acesso direto via notação de ponto.
4. Ciclo de Vida do Sistema: Loop e Máquina de Estados
O sistema opera segundo o padrão de Máquina de Estados Finita (State Machine) com ciclo contínuo:
O esqueleto do fluxo principal no logicabr.dev apoia-se em um laço enquanto (opcao != 0) associado a uma estrutura de seleção múltipla escolha / caso com fechamento em chaves { } e interrupção com pare;:
numero opcao = -1;
enquanto (opcao != 0) {
exibirMenu();
opcao = entrada("Digite a opção desejada: ");
escolha (opcao) {
caso 1:
cadastrarAtendimento();
pare;
caso 2:
listarAtendimentos();
pare;
caso 3:
buscarPorId();
pare;
caso 4:
ordenarPorValor();
pare;
caso 5:
exibirDashboardMetricas();
pare;
caso 0:
saida("Encerrando o sistema ClinicaTech. Até logo!");
pare;
padrao:
saida("Opção inválida! Tente novamente.");
}
}
5. Código-Fonte Completo e Comentado do Sistema Integrador
Abaixo disponibilizamos a implementação integral e executável do sistema ClinicaTech. Observe a aplicação rigorosa de:
- Clean Code: Constantes semânticas em
UPPER_SNAKE_CASE, variáveis autoexplicativas e ausência de números mágicos; - Cláusulas Guarda: Validações precoces que abortam cadastros inválidos antes de alocar dados;
- Princípio SRP: Cada rotina faz exatamente o que seu nome declara sem efeitos colaterais ocultos;
- Vetor de Structs: Troca atômica de posições inteiras durante o algoritmo Bubble Sort;
- Tratamento de Borda: Proteção explícita contra divisões por zero ao calcular médias em listas vazias.
// =========================================================================
// CONSTANTES GLOBAIS DE SISTEMA
// =========================================================================
numero CAPACIDADE_MAXIMA = 20;
numero IDADE_MINIMA = 0;
numero IDADE_MAXIMA = 130;
moeda VALOR_MINIMO_CONSULTA = 10.00;
// =========================================================================
// BASE DE DADOS EM MEMÓRIA RAM (VETOR DE OBJETOS ESTRUTURADOS)
// =========================================================================
vetor agenda = [];
agenda[0] = { id: 101, pacienteNome: "Helena Martins", idade: 34, especialidade: "Cardiologia", valorConsulta: 350.00, ativo: verdadeiro };
agenda[1] = { id: 102, pacienteNome: "Antonio Fagundes", idade: 72, especialidade: "Ortopedia", valorConsulta: 280.00, ativo: verdadeiro };
agenda[2] = { id: 103, pacienteNome: "Beatriz Alencar", idade: 19, especialidade: "Dermatologia", valorConsulta: 420.00, ativo: verdadeiro };
agenda[3] = { id: 104, pacienteNome: "Carlos Drummond", idade: 58, especialidade: "Oftalmologia", valorConsulta: 210.00, ativo: verdadeiro };
// =========================================================================
// MÓDULO 1: CADASTRO COM CLÁUSULAS GUARDA E VALIDAÇÕES
// =========================================================================
funcao cadastrarAtendimento(numero novoId, texto nome, numero idade, texto espec, moeda valor) {
// Guarda 1: Capacidade da clínica
se (tamanho(agenda) >= CAPACIDADE_MAXIMA) {
saida("[ERRO]: Limite máximo de capacidade atingido (" + CAPACIDADE_MAXIMA + " pacientes).");
retorno falso;
}
// Guarda 2: Validação biológica da idade
se (idade < IDADE_MINIMA ou idade > IDADE_MAXIMA) {
saida("[ERRO]: Idade inválida (" + idade + " anos). Permitido apenas de 0 a 130.");
retorno falso;
}
// Guarda 3: Piso tarifário da consulta
se (valor < VALOR_MINIMO_CONSULTA) {
saida("[ERRO]: O valor mínimo da consulta é de R$ " + VALOR_MINIMO_CONSULTA);
retorno falso;
}
// Guarda 4: Unicidade do ID (chave primária)
para (numero i = 0; i < tamanho(agenda); i++) {
se (agenda[i].id == novoId) {
saida("[ERRO]: Já existe um atendimento registrado com o ID [" + novoId + "].");
retorno falso;
}
}
// Inserção atômica no final do vetor
agenda[tamanho(agenda)] = { id: novoId, pacienteNome: nome, idade: idade, especialidade: espec, valorConsulta: valor, ativo: verdadeiro };
saida("[SUCESSO]: Atendimento [" + novoId + " - " + nome + "] agendado com êxito!");
retorno verdadeiro;
}
// =========================================================================
// MÓDULO 2: LISTAGEM TABULAR DE ATENDIMENTOS
// =========================================================================
funcao listarAtendimentos() {
se (tamanho(agenda) == 0) {
saida("[AVISO] Nenhum atendimento agendado no momento.");
retorno;
}
saida("");
saida("==================== LISTAGEM GERAL DE CONSULTAS ====================");
saida("ID | PACIENTE | IDADE | ESPECIALIDADE | VALOR (R$)");
saida("---------------------------------------------------------------------");
para (numero i = 0; i < tamanho(agenda); i++) {
saida(agenda[i].id + " | " + agenda[i].pacienteNome + " | " + agenda[i].idade + " anos | " + agenda[i].especialidade + " | R$ " + agenda[i].valorConsulta);
}
saida("=====================================================================");
saida("Total de consultas ativas na lista: " + tamanho(agenda));
}
// =========================================================================
// MÓDULO 3: BUSCA SEQUENCIAL POR ID
// =========================================================================
funcao buscarAtendimentoPorId(numero idProcurado) {
numero indiceAchado = -1;
para (numero i = 0; i < tamanho(agenda); i++) {
se (agenda[i].id == idProcurado) {
indiceAchado = i;
pare; // Encontrou o registro: interrompe imediatamente a busca
}
}
se (indiceAchado != -1) {
saida("");
saida("[BUSCA] FICHA LOCALIZADA:");
saida(" Código ID: " + agenda[indiceAchado].id);
saida(" Nome Paciente: " + agenda[indiceAchado].pacienteNome);
saida(" Idade: " + agenda[indiceAchado].idade + " anos");
saida(" Especialidade: " + agenda[indiceAchado].especialidade);
saida(" Valor Cobrado: R$ " + agenda[indiceAchado].valorConsulta);
retorno indiceAchado;
} senao {
saida("[ERRO] Atendimento com ID [" + idProcurado + "] não consta nos registros.");
retorno -1;
}
}
// =========================================================================
// MÓDULO 4: ORDENAÇÃO BUBBLE SORT POR VALOR (DECRESCENTE)
// =========================================================================
funcao ordenarPorValorDecrescente() {
numero n = tamanho(agenda);
se (n < 2) {
saida("[AVISO] Lista contém menos de dois itens; ordenação dispensada.");
retorno;
}
para (numero i = 0; i < n - 1; i++) {
para (numero j = 0; j < n - i - 1; j++) {
// Critério: Valor maior fica no início (ordem decrescente)
se (agenda[j].valorConsulta < agenda[j + 1].valorConsulta) {
// Troca Atômica do registro (objeto completo)
registro temporario = agenda[j];
agenda[j] = agenda[j + 1];
agenda[j + 1] = temporario;
}
}
}
saida("[ORDENACAO] Base reordenada por valor da consulta (maior para o menor)!");
}
// =========================================================================
// MÓDULO 5: DASHBOARD ANALÍTICO DE MÉTRICAS
// =========================================================================
funcao exibirDashboardMetricas() {
numero total = tamanho(agenda);
se (total == 0) {
saida("[AVISO] Sem dados cadastrados para gerar métricas.");
retorno;
}
moeda faturamentoTotal = 0.0;
numero maiorIdade = agenda[0].idade;
numero indiceMaisVelho = 0;
para (numero i = 0; i < total; i++) {
faturamentoTotal = faturamentoTotal + agenda[i].valorConsulta;
se (agenda[i].idade > maiorIdade) {
maiorIdade = agenda[i].idade;
indiceMaisVelho = i;
}
}
numero mediaValor = faturamentoTotal / total;
saida("");
saida("[RELATORIO] ================= PAINEL EXECUTIVO CLINICATECH =================");
saida("• TOTAL DE ATENDIMENTOS: " + total + " pacientes");
saida("• FATURAMENTO BRUTO TOTAL: R$ " + faturamentoTotal);
saida("• TICKET MÉDIO / CONSULTA: R$ " + mediaValor);
saida("• PACIENTE MAIS IDOSO: " + agenda[indiceMaisVelho].pacienteNome + " (" + maiorIdade + " anos)");
saida("• OCUPAÇÃO DA MEMÓRIA: " + ((total * 100) / CAPACIDADE_MAXIMA) + "% (" + total + "/" + CAPACIDADE_MAXIMA + ")");
saida("=====================================================================");
}
// =========================================================================
// FLUXO PRINCIPAL DO PROGRAMA E DEMONSTRAÇÃO
// =========================================================================
saida("Sistema ClinicaTech inicializado com sucesso na memória.");
// 1. Demonstração dos relatórios iniciais
listarAtendimentos();
buscarAtendimentoPorId(103);
buscarAtendimentoPorId(999); // Caso de borda: ID inexistente
saida("");
saida("Cadastrando novo paciente no sistema...");
cadastrarAtendimento(105, "Drauzio Varella", 80, "Oncologia", 500.00);
saida("");
saida("Reordenando por valor...");
ordenarPorValorDecrescente();
listarAtendimentos();
// 2. Exibição final do dashboard executivo
exibirDashboardMetricas();
saida("");
saida("[CONCLUSAO] EXECUÇÃO DO PROJETO INTEGRADOR CONCLUÍDA COM ÊXITO!");
Detalhamento Arquitetural dos 5 Módulos no logicabr.dev
O sistema ClinicaTech foi concebido para espelhar as melhores práticas empregadas na indústria contemporânea de software, adaptadas com elegância para a sintaxe nativa da plataforma logicabr.dev. Compreender por que cada instrução foi posicionada é o que diferencia o mero digitador de código do verdadeiro arquiteto de software:
-
Módulo 1 (Cadastro Defensivo): Em vez de aninhar múltiplos blocos
se / senaoem escadinha (gerando a famigerada "Arrow Anti-Pattern"), utilizamos cláusulas guarda isoladas no topo da função. Cada validação testa uma condição de erro e retornafalsoimediatamente. A inserção no vetor só ocorre quando todos os requisitos de integridade de dados forem estritamente satisfeitos. -
Módulo 2 (Exibição Tabular Formatada): Utiliza o comando
saida()com concatenação de strings para tabular dados no terminal. A presença do cabeçalho fixo e do rodapé comtamanho(agenda)garante transparência e rastreabilidade visual imediata para o operador do sistema. -
Módulo 3 (Busca com Short-Circuit): Ao encontrar o ID procurado na lista, a instrução
pare;aborta o laçoparainstantaneamente. Se o registro for o primeiro de uma base com 10.000 pacientes, o algoritmo consome apenas 1 iteração em vez de percorrer os 9.999 restantes à toa. -
Módulo 4 (Bubble Sort com Swap de Objetos): Em linguagens legadas que dependiam de vetores paralelos, ordenar dados exigiria permutar manualmente 5 ou 6 vetores separados. No logicabr.dev, como cada atendimento é um objeto unificado dentro do vetor
agenda, uma única variável auxiliar temporária permuta o registro completo com todas as suas propriedades (ID, nome, idade, valor e status) em uma única operação atômica de troca. -
Módulo 5 (Dashboard Analítico com Guarda de Borda): O cálculo de médias estatísticas (como o ticket médio das consultas) possui um perigo fatal: se a clínica não tiver nenhum atendimento cadastrado, a divisão de faturamento por zero resultaria em um erro crítico no sistema. A verificação precoce
se (total == 0)resguarda a estabilidade matemática do sistema antes de qualquer operação aritmética.
6. Como Executar e Estender o Projeto na IDE Online
O código acima foi escrito especificamente para ser 100% compatível com a IDE online do logicabr.dev. Você pode copiar o bloco de código acima, colá-lo diretamente no editor no topo da página e clicar no botão Executar (F5).
Desafios de Extensão para Exercitar Sua Lógica:
Para fixar seu aprendizado, recomendamos que você tente implementar por conta própria as seguintes melhorias:
- Desafio 1 (Exclusão Lógica): Crie uma função
cancelarAtendimento(id)que não apaga o registro da memória, mas altera o campo booleanoativo = falso, e ajuste a listagem para exibir apenas consultas ativas. - Desafio 2 (Filtro por Especialidade): Crie um procedimento que receba o nome de uma especialidade (ex:
"Cardiologia") e liste apenas os pacientes que pertencem àquela área médica. - Desafio 3 (Substituição por Busca Binária): Após ordenar o vetor por ID, substitua a busca sequencial pela busca binária \(O(\log N)\) que aprendemos na Aula 28.
7. Os Próximos Passos: Da Lógica para a Engenharia de Software
Concluir as 30 aulas da primeira etapa coloca você em um patamar diferenciado. A esmagadora maioria das pessoas que desistem de programar não desiste por falta de ferramentas, mas por tentar aprender frameworks modernos (como React, Node.js, Spring Boot ou Django) antes de dominar o pensamento algorítmico básico.
Com essa fundação sólida e inabalável construída no logicabr.dev, você agora está plenamente capacitado para:
-
Migrar com Facilidade para Qualquer Linguagem:
A sintaxe de JavaScript, Python, C#, Java ou C++ não será mais uma barreira misteriosa. Você entenderá imediatamente que variáveis, laçosfore chamadas de métodos são apenas manifestações sintáticas dos conceitos que já domina. -
Aprender Programação Orientada a Objetos (POO):
Com os Registros (Aula 29) bem sedimentados, o salto para Classes, Objetos, Herança e Polimorfismo será natural e intuitivo. -
Construir seu Portfólio no GitHub:
Pegue projetos como o Jogo da Velha (Aula 24), a Folha de Pagamento (Aula 26) e o Sistema ClinicaTech (Aula 30), transcreva-os para Python ou JavaScript e suba-os para o seu perfil no GitHub. Isso comprovará publicamente sua evolução técnica para recrutadores e empresas.
8. Perguntas Frequentes sobre a Formatura (FAQ)
A lógica de programação muda de uma linguagem para outra?
Não! A lógica de programação é universal e independente de linguagem. O raciocínio de dividir um problema em passos, controlar repetições e tomar decisões booleanas é rigorosamente o mesmo em Portugol, C, Rust ou Python. Apenas as palavras-chave e símbolos gramaticais (sintaxe) mudam.
Devo continuar praticando depois das 30 primeiras aulas?
Sem dúvida! A habilidade de programar é como tocar um instrumento musical ou praticar um esporte: depende de memória muscular e consistência. Resolva desafios semanais em plataformas de algoritmos, crie pequenos utilitários para automatizar seu dia a dia e continue explorando a IDE do logicabr.dev.
Onde estão todas as aulas do curso?
O índice completo com as 50 aulas (as 30 da primeira etapa e as 20 da segunda), links, ilustrações vetoriais e exercícios interativos está permanentemente acessível no portal logicabr.dev/aprenda.
Primeira etapa concluída!
Você concluiu as 30 aulas da primeira etapa do logicabr.dev. Rode o projeto ClinicaTech na IDE online e siga para a segunda etapa, que começa na Aula 31: Busca Binária.
Abrir IDE Online e Executar o Projeto Final →