Sebenta · Desenvolver projeto de software (UC03814)
- Introdução
- 1. Programar não é desenvolver software
- 2. Pensamento computacional
- 3. Ciclo de vida do software
- 4. Metodologias de desenvolvimento
- 5. Fase 1 — Identificar o problema (requisitos)
- 6. Fase 2 — Algoritmia e pseudocódigo
- 7. Fluxogramas
- 8. Modelação de dados
- 9. Wireframing e protótipo
- 10. Fase 3 — Ambiente e codificação
- 11. Fase 4 — Debug e testes
- 12. Otimização e documentação
- Exemplo integrador — mini "gestor de tarefas"
- Erros comuns
- Glossário
- Síntese
- Exercícios resolvidos
Introdução
Esta sebenta ensina a desenvolver um projeto de software com método — não apenas a escrever código, mas a percorrer todas as fases que separam uma ideia de um programa que funciona e se mantém. É a diferença entre "saber programar umas linhas" e "conseguir levar um projeto do princípio ao fim".
Vais aprender a pensar como um programador (pensamento computacional), a desenhar a solução antes de a construir (algoritmos, fluxogramas, modelação de dados e wireframes), a codificar num ambiente profissional com controlo de versões, e a testar, corrigir e documentar. Os exemplos usam Python — uma linguagem simples e muito usada — mas o método aplica-se a qualquer linguagem.
Objetivos (referencial): planear as etapas de desenvolvimento de um projeto de software; estruturar dados, desenhar fluxogramas e protótipos; executar o software; e executar testes de funcionamento — cumprindo as fases e as orientações metodológicas, e detetando e corrigindo erros.
1. Programar não é desenvolver software
Escrever código é uma das fases do desenvolvimento — talvez a mais visível, mas não a mais importante. Desenvolver um projeto de software é um processo:
- Perceber o problema e o que o software tem de fazer.
- Desenhar a solução (algoritmos, dados, ecrãs) antes de codificar.
- Construir, testar e corrigir.
- Documentar e entregar.
Um erro descoberto na fase de análise custa cêntimos; o mesmo erro descoberto depois de entregue custa uma fortuna. Por isso os profissionais investem em pensar antes de teclar. Esta competência aplica-se em empresas de informática, consultoras de TI, lojas e serviços de apoio técnico, e na administração pública.
2. Pensamento computacional
Antes de qualquer linguagem, é preciso saber resolver problemas de forma estruturada. O pensamento computacional tem quatro pilares:
- Decomposição — partir um problema grande em partes pequenas e tratáveis.
- Reconhecimento de padrões — identificar o que se repete para reaproveitar.
- Abstração — ignorar os detalhes irrelevantes e focar no essencial.
- Algoritmo — definir a sequência de passos que resolve o problema.
Exemplo — média de uma turma
- Decomposição: ler as notas → somá-las → dividir pelo número de notas → mostrar.
- Padrão: "para cada nota, acrescentar à soma" repete-se.
- Abstração: o nome do aluno não interessa para a média; só a nota.
- Algoritmo: soma = 0; para cada nota, soma += nota; média = soma / número de notas.
Repara que resolvemos o problema sem escrever código — só depois se traduz para uma linguagem.
3. Ciclo de vida do software
Todo o projeto passa por fases (o Software Development Life Cycle, SDLC):
| Fase | O que se faz |
|---|---|
| Análise | perceber o problema, levantar requisitos |
| Desenho | algoritmos, modelo de dados, ecrãs |
| Codificação | escrever o programa |
| Testes | verificar e corrigir |
| Manutenção | evoluir e corrigir após a entrega |
Dentro da construção, a sequência prática de desenvolvimento de um programa é: identificação do problema → elaboração do algoritmo → codificação → debug → testes de funcionamento → otimização. Esta ordem é o fio condutor desta UC.
4. Metodologias de desenvolvimento
Há duas grandes formas de organizar o processo.
O modelo em cascata faz as fases em sequência rígida: analisa-se tudo, desenha-se tudo, codifica-se tudo, testa-se tudo. É previsível, mas descobre os erros tarde e não gosta de mudanças.
As metodologias ágeis (a mais conhecida é o Scrum) trabalham em ciclos curtos e entregam valor cedo:
- Product backlog — lista priorizada de tudo o que há a fazer.
- Sprint — ciclo de 1 a 2 semanas com um objetivo concreto.
- Daily — reunião curta diária (o que fiz, o que vou fazer, bloqueios).
- Review e Retrospetiva — mostrar o incremento e melhorar o processo.
Papéis: Product Owner (decide o quê), Scrum Master (facilita), Equipa (constrói). Hoje o ágil domina, porque permite receber feedback e corrigir o rumo cedo.
5. Fase 1 — Identificar o problema (requisitos)
Tudo começa por responder: o que tem o software de fazer? Distinguem-se:
- Requisitos funcionais — o que o sistema faz ("registar um cliente", "listar as vendas").
- Requisitos não-funcionais — como se comporta (rápido, seguro, acessível, fácil).
- Regras de negócio — restrições ("um NIF não se pode repetir").
Uma técnica muito usada são as user stories, no formato Como [perfil], quero [ação], para [valor]:
Como gestor, quero exportar as vendas do mês em CSV, para as analisar no Excel.
Cada story deve ser pequena, clara e testável, com critérios de aceitação. Levantar bem os requisitos evita construir o software errado.
6. Fase 2 — Algoritmia e pseudocódigo
Um algoritmo é uma sequência finita e ordenada de passos que resolve um problema. Escreve-se primeiro em pseudocódigo — português estruturado, independente da linguagem:
INÍCIO
ler nota
SE nota >= 10 ENTÃO
escrever "Aprovado"
SENÃO
escrever "Reprovado"
FIM SE
FIM
Existem apenas três estruturas de controlo, e com elas se constrói qualquer programa:
- Sequência — um passo a seguir ao outro.
- Decisão —
SE condição ENTÃO … SENÃO …. - Repetição —
PARA i DE 1 ATÉ 10(contada) ouENQUANTO condição(condicional).
Dominar estas três estruturas é dominar a lógica de programação.
7. Fluxogramas
O fluxograma representa o algoritmo em desenho, com símbolos normalizados:
| Símbolo | Significado |
|---|---|
| Oval | Início / Fim |
| Retângulo | Ação / processo |
| Losango | Decisão (sim/não) |
| Paralelogramo | Entrada / Saída |
| Seta | Sentido do fluxo |
Exemplo — decidir se alguém é maior de idade:
(Início) → [ler idade] → < idade >= 18 ? >
│ sim → [escrever "Maior"] → (Fim)
│ não → [escrever "Menor"] → (Fim)
Desenhar o fluxograma antes de codificar revela erros de lógica quando ainda são baratos de corrigir. Ferramentas: diagrams.net, Lucidchart ou papel.
8. Modelação de dados
Definir que dados o programa guarda e como se organizam é decisivo. Identificam-se entidades (Cliente, Produto, Venda), os seus atributos (nome, preço, stock) e as relações (uma venda pertence a um cliente).
Em código, esses dados vivem em estruturas:
produto = {"nome": "Café", "preco": 3.5, "stock": 20} # dicionário
carrinho = [produto, outro_produto] # lista
Modelar bem os dados no início torna todo o código seguinte mais simples e coerente.
9. Wireframing e protótipo
Se o software tem interface, desenha-se antes de o programar:
- Wireframe — esboço de cada ecrã (screen): posição de menus, botões, listas — sem cores nem conteúdo real.
- Protótipo — os wireframes ligados, para simular a navegação e organizar o tipo de conteúdos e as ligações entre ecrãs.
Faz-se em Figma, diagrams.net ou papel. Valida-se a ideia com o cliente antes de escrever uma linha de código.
10. Fase 3 — Ambiente e codificação
Ambiente de desenvolvimento
Trabalha-se num IDE (Ambiente Integrado de Desenvolvimento) — como o VS Code ou o PyCharm — que junta editor, execução e debug. Instala-se a linguagem (ex.: Python) e configura-se o interpretador.
O controlo de versões com Git é obrigatório num projeto sério: guarda o histórico, permite voltar atrás e trabalhar em equipa.
git init
git add .
git commit -m "primeira versão do programa"
Sintaxe e semântica
- Sintaxe — as regras de escrita da linguagem (indentação, dois pontos). Um erro de sintaxe impede o programa de correr.
- Semântica — o significado: o programa corre, mas faz o que se pretendia?
def media(notas):
return sum(notas) / len(notas)
print(media([12, 15, 9])) # 12.0
Código de qualidade tem nomes claros, funções curtas e comentários onde ajudam a perceber o porquê.
11. Fase 4 — Debug e testes
Debug
Debug é encontrar e corrigir defeitos. Há três tipos de erro:
- Sintaxe — o programa nem arranca.
- Execução (runtime) — rebenta a meio (ex.: dividir por zero, aceder a algo inexistente).
- Lógica — o programa corre mas dá o resultado errado. É o mais difícil, porque não avisa.
Técnicas: ler a mensagem de erro com atenção, usar print() para inspecionar valores, colocar breakpoints no debugger do IDE e isolar a parte do código onde está o problema.
Testes de funcionamento
Testar é verificar que o programa faz o esperado, com vários casos:
- Caso normal — dados típicos.
- Casos-limite — vazio, zero, valor máximo, negativos.
- Casos inválidos — texto onde se espera número.
assert media([10, 20]) == 15
assert media([5]) == 5
Corrigem-se os erros e volta-se a testar tudo (teste de regressão), para garantir que a correção não partiu outra coisa.
12. Otimização e documentação
Só depois de funcionar se otimiza: tornar o programa mais simples ou mais rápido (evitar repetições, escolher a estrutura de dados certa). A regra é primeiro correto, depois rápido.
A documentação técnica faz parte da entrega:
- README — o que é o programa, como se instala e como se usa.
- Comentários no código, a explicar as partes menos óbvias.
- Manual do utilizador, se o programa for usado por não-técnicos.
Software sem documentação é software que ninguém consegue manter.
Exemplo integrador — mini "gestor de tarefas"
Percorrendo as fases num pequeno programa:
- Problema: guardar tarefas, marcá-las como feitas e listá-las.
- Algoritmo: menu → escolher (adicionar / listar / concluir / sair) → repetir.
- Dados: cada tarefa =
{"titulo": ..., "feita": False}; lista de tarefas. - Código:
tarefas = []
def adicionar(titulo):
tarefas.append({"titulo": titulo, "feita": False})
def listar():
for i, t in enumerate(tarefas, 1):
estado = "✓" if t["feita"] else " "
print(f"{i}. [{estado}] {t['titulo']}")
def concluir(n):
tarefas[n - 1]["feita"] = True
- Testes: adicionar 2 tarefas, concluir a 1.ª, listar → a 1.ª deve ter "✓".
- Documentar: README com o objetivo e como correr.
Erros comuns
- Ir logo ao código sem perceber o problema nem desenhar o algoritmo.
- Confundir erro de sintaxe (não corre) com erro de lógica (corre mal).
- Testar só o caso normal e esquecer os limites (vazio, zero).
- Não usar controlo de versões — e perder trabalho.
- Otimizar cedo — complicar o código antes de ele sequer funcionar.
- Entregar sem documentação.
Glossário
- SDLC — ciclo de vida do software (fases do projeto).
- Pensamento computacional — decompor, padrões, abstração, algoritmo.
- Algoritmo — sequência finita de passos que resolve um problema.
- Pseudocódigo — algoritmo em português estruturado.
- Fluxograma — representação gráfica de um algoritmo.
- Requisito funcional / não-funcional — o que o sistema faz / como se comporta.
- User story — requisito no formato "Como… quero… para…".
- Wireframe / protótipo — esboço de ecrã / esboços ligados navegáveis.
- IDE — ambiente integrado de desenvolvimento (ex.: VS Code).
- Git — sistema de controlo de versões.
- Sintaxe / semântica — regras de escrita / significado do código.
- Debug — encontrar e corrigir erros.
- Runtime — erro em tempo de execução.
- Regressão — voltar a testar tudo após uma alteração.
- Ágil / Scrum / Sprint — método iterativo / a sua concretização / ciclo curto.
Síntese
Desenvolver software é seguir um processo: analisar (requisitos) → desenhar (algoritmo, fluxograma, dados, wireframe) → codificar (num IDE, com Git) → testar e corrigir (debug) → otimizar e documentar. O pensamento computacional e a algoritmia são a base, independentes da linguagem; as metodologias ágeis organizam o trabalho em ciclos curtos. Quem desenha antes de codificar e testa com rigor entrega software que funciona e se mantém.
Exercícios resolvidos
1. Aplica os 4 pilares do pensamento computacional ao problema "verificar se uma palavra é palíndromo".
Resolução: Decomposição — ler a palavra, invertê-la, comparar. Padrão — comparar caracteres simétricos repete-se. Abstração — ignorar maiúsculas/espaços. Algoritmo — se palavra == palavra invertida → é palíndromo.
2. Que tipo de erro é cada um? (a) esqueceste os dois pontos num if; (b) o programa calcula a média somando mas dividindo por 2 fixo; (c) dividir por len(lista) com a lista vazia.
Resolução: (a) sintaxe (não corre); (b) lógica (corre, resultado errado); (c) execução/runtime (ZeroDivisionError).
3. Escreve o pseudocódigo que lê um número e diz se é par ou ímpar.
Resolução:
ler n SE n MOD 2 == 0 ENTÃO escrever "Par" SENÃO escrever "Ímpar"
4. Um colega quer otimizar o código antes de ele funcionar. Que lhe dizes?
Resolução: primeiro correto, depois rápido — otimizar cedo complica o código e esconde erros. Faz funcionar e testa; só depois otimiza, se for preciso.
5. Que casos de teste usarias para uma função media(notas)?
Resolução: caso normal (
[10,14,16]), um único elemento ([5]), lista vazia (deve tratar o erro em vez de rebentar), e valores nos limites (0 e 20). Testar todos e corrigir o comportamento com lista vazia.