PDS e Metodologias Ágeis
Exercícios comentados

1️⃣ Exercício: Gerenciamento de Mudanças em Requisitos

Enunciado

Uma clínica médica está implementando um sistema de prontuário eletrônico. Durante o desenvolvimento, um novo requisito surge: permitir que os pacientes consultem seus exames online.

Tarefas:

  1. Elaborar um plano de gerenciamento de mudanças.
  2. Criar um fluxo UML para análise/aprovação da mudança.
  3. Explicar como métodos ágeis poderiam ajudar.

Resolução

Plano de Gerenciamento de Mudanças:

  • Identificação da Mudança: Inclusão do módulo de consulta de exames online.
  • Justificativa: Aumentar a autonomia dos pacientes e reduzir demanda no atendimento.
  • Avaliação de Impacto:
    • Custo: Necessidade de servidor seguro e integração com o laboratório.
    • Prazo: Estimativa de +3 sprints no Scrum.
    • Segurança: Implementação de autenticação multifator.
    • Usabilidade: Interface simplificada para acesso via celular.
  • Prioridade: Alta (impacto direto no valor para o cliente).
  • Controle de Versão: Atualização do documento de requisitos (IEEE 830).

Fluxo UML (atividade simplificada):

[Solicitação de Mudança] → [Análise de Impacto] → [Aprovação do Comitê] → 
[Planejamento no Backlog] → [Implementação e Testes] → [Deploy e Feedback]

Métodos Ágeis:

  • Scrum permite ajustes rápidos via backlog.
  • Cada sprint incorpora incrementos pequenos (entrega contínua).
  • Feedback dos usuários nas revisões ajuda a validar rapidamente.

2️⃣ Exercício: Herança e Encapsulamento

Enunciado

Crie uma classe Pessoa com atributos comuns (nome, idade e CPF), e duas subclasses: Aluno e Professor, que herdam atributos e adicionam informações específicas.


Resolução em Python

class Pessoa:
def __init__(self, nome, idade, cpf):
self._nome = nome
self._idade = idade
self._cpf = cpf

def get_nome(self):
return self._nome

def set_nome(self, nome):
self._nome = nome

def get_idade(self):
return self._idade

def set_idade(self, idade):
self._idade = idade

def get_cpf(self):
return self._cpf

def set_cpf(self, cpf):
self._cpf = cpf


class Aluno(Pessoa):
def __init__(self, nome, idade, cpf, serie):
super().__init__(nome, idade, cpf)
self.serie = serie

def exibir_informacoes(self):
return f"Aluno: {self.get_nome()}, Idade: {self.get_idade()}, Série: {self.serie}"


class Professor(Pessoa):
def __init__(self, nome, idade, cpf, disciplina):
super().__init__(nome, idade, cpf)
self.disciplina = disciplina

def exibir_informacoes(self):
return f"Professor: {self.get_nome()}, Idade: {self.get_idade()}, Disciplina: {self.disciplina}"


# Teste
aluno1 = Aluno("Carlos", 15, "123.456.789-00", "9º Ano")
prof1 = Professor("Ana", 35, "987.654.321-00", "Matemática")

print(aluno1.exibir_informacoes())
print(prof1.exibir_informacoes())

Saída esperada:

yamlCopiarEditarAluno: Carlos, Idade: 15, Série: 9º Ano
Professor: Ana, Idade: 35, Disciplina: Matemática

3️⃣ Exercício: Polimorfismo em um Sistema de Entregas

Enunciado

Implemente classes de transporte (Moto, Caminhao, Drone) que calculam o tempo de entrega de forma distinta, utilizando polimorfismo.


Resolução em Python

from abc import ABC, abstractmethod

class Transporte(ABC):
@abstractmethod
def calcular_tempo(self, distancia):
pass


class Moto(Transporte):
def calcular_tempo(self, distancia):
velocidade = 60 # km/h
return distancia / velocidade


class Caminhao(Transporte):
def calcular_tempo(self, distancia):
velocidade = 40 # km/h
return distancia / velocidade


class Drone(Transporte):
def calcular_tempo(self, distancia):
velocidade = 80 # km/h
return distancia / velocidade


# Teste com polimorfismo
transportes = [Moto(), Caminhao(), Drone()]
distancia = 120 # km

for t in transportes:
print(f"{t.__class__.__name__}: Tempo estimado = {t.calcular_tempo(distancia):.2f} horas")

Saída esperada:

Moto: Tempo estimado = 2.00 horas
Caminhao: Tempo estimado = 3.00 horas
Drone: Tempo estimado = 1.50 horas
PDS e Metodologias Ágeis
Programação – 3 Bimestre

Validação e Verificação de Requisitos

  • Verificação de requisitos: Processo que assegura clareza, completude, consistência, rastreabilidade e testabilidade antes do desenvolvimento.
    • Técnicas: revisões por pares, análise de gap, checklists, matriz de rastreabilidade e critérios de aceitação.
    • Ferramentas: IBM Rational DOORS, JIRA e Enterprise Architect.
  • Validação de requisitos: Garante que o sistema atenda às necessidades dos stakeholders, evitando mal-entendidos e retrabalho.
    • Ferramentas: planilhas de validação, reuniões com clientes, critérios claros de aceitação e feedback contínuo.
    • Exemplo: uso em sistemas de e-commerce, finanças pessoais e reservas de voos.

Pilares da Programação Orientada a Objetos (POO) – Encapsulamento

  • Conceito: Protege atributos e métodos de uma classe, permitindo acesso controlado através de getters e setters.
  • Benefícios:
    • Segurança: impede alterações indevidas nos dados.
    • Manutenibilidade: facilita ajustes e ampliações no código.
    • Modularidade: separa responsabilidades, tornando o sistema mais organizado.
  • Exemplos práticos em Python:
    • Controle de curtidas em e-commerce.
    • Sistema de gestão de carros com atributos encapsulados.
    • Sistema de biblioteca com implementação de métodos de acesso.

Principais Aprendizados

  1. Requisitos bem validados e verificados reduzem falhas e retrabalho no desenvolvimento.
  2. POO com encapsulamento reforça boas práticas de segurança e organização no código.
  3. Ferramentas de apoio (planilhas, checklists, IDEs) otimizam processos técnicos e colaborativos.
  4. Exemplos reais facilitam a compreensão e aplicação dos conceitos de engenharia de software.

Encapsulamento em Projetos Práticos (POO)

  • Reforço do encapsulamento: Controle de atributos e métodos com segurança e acesso controlado, melhorando integridade e confiabilidade do código.
  • Exemplo prático: Sistema de controle de estoque de carros, com classes Carro e Estoque, aplicação de getters e setters, e métodos como adicionar_carro.
  • Benefícios: Segurança, manutenção facilitada, modularidade e prevenção de bugs.
  • Questões éticas: Proteção de dados, segurança cibernética e transparência no uso de informações.

Testes Não Funcionais

  • Desenvolvimento e execução: Identificação de requisitos não funcionais (desempenho, segurança, usabilidade, confiabilidade), definição de critérios e uso de ferramentas apropriadas.
  • Ferramentas e práticas:
    • Pentest: Exploração de vulnerabilidades usando Kali Linux e ferramentas como SQLMap e PortSwigger.
    • Burp Suite: Interceptação e modificação de requisições HTTP para identificar falhas de controle de acesso.
  • Testes de desempenho e segurança: Avaliação de escalabilidade, estabilidade, vulnerabilidades e usabilidade.
  • OWASP Top 10: Referência essencial para práticas de segurança web.

Diagramas UML – Diagrama de Estados

  • Definição: Representa mudanças de estados de um objeto ou sistema em resposta a eventos.
  • Elementos principais:
    • Estados (inicial, intermediários e final).
    • Transições acionadas por eventos.
    • Ações associadas às mudanças de estado.
  • Exemplos práticos:
    • Controle de acesso eletrônico (porta: fechada, abrindo, aberta, fechando, trancada).
    • Processo de matrícula em instituições educacionais.
  • Benefícios: Visualização do comportamento do sistema, identificação de falhas e melhor comunicação entre stakeholders.

Diagramas UML – Atividades

  • Definição: Ferramenta visual que modela o fluxo de atividades, ações e decisões em sistemas e processos.
  • Aplicações:
    • Modelagem de processos de negócios (reservas de passagens aéreas).
    • Desenvolvimento de software (fluxos de tela, módulos específicos).
    • Engenharia de sistemas complexos (controle de tráfego aéreo).
  • Benefícios:
    • Facilita comunicação entre stakeholders.
    • Identifica gargalos e otimiza processos.
    • Documenta sistemas e facilita manutenção.
  • Ferramentas: Lucidchart, Draw.io, Microsoft Visio.

Herança em POO

  • Conceito: Permite que classes herdem atributos e métodos de outras, criando hierarquias reutilizáveis.
  • Exemplo prático:
    • ContaBancaria (superclasse): métodos comuns (depositar, sacar, consultar_saldo).
    • ContaCorrente, ContaPoupanca e ContaInvestimento (subclasses) com funcionalidades específicas.
  • Reutilização de código:
    • Implementação de cálculos de tarifas com métodos estáticos e classes utilitárias.
    • Inclusão de novas funcionalidades (ex: conta universitária gratuita) sem duplicação de código.
  • Método de transferência: Transferência entre contas com verificação de saldo.
  • Aspectos éticos:
    • Privacidade dos dados, segurança de transações e transparência nas práticas bancárias.

Principais Aprendizados

  1. Diagramas de atividades ajudam na visualização, comunicação e melhoria de sistemas.
  2. Herança simplifica manutenção e amplia escalabilidade, evitando duplicação de código.
  3. Práticas éticas e segurança devem ser consideradas na implementação de sistemas financeiros.
  4. Ferramentas de modelagem e POO combinadas fornecem base sólida para projetos de software.

Gerenciamento de Mudanças em Requisitos

  • Definição: Processo contínuo que ocorre durante todo o ciclo de vida do projeto, envolvendo identificação, análise, documentação, priorização e controle de requisitos.
  • Importância:
    • Permite adaptação às mudanças de mercado e necessidades do cliente.
    • Minimiza riscos e falhas decorrentes de requisitos mal gerenciados.
  • Boas práticas:
    • Documentação clara e enxuta.
    • Avaliação de impacto (prazo, custo e qualidade).
    • Controle rigoroso de versões e rastreabilidade.
  • Exemplos práticos: Aplicação em sistemas de saúde (SUS), lojas e softwares corporativos, com foco em segurança e ética (proteção de dados).

Herança em Projetos Práticos (POO)

  • Exemplo aplicado: Sistema de gestão de loja de eletrônicos.
    • Classe base: ProdutoEletronico (atributos e métodos comuns).
    • Subclasses: Smartphone, Laptop, Televisor, cada uma com características próprias.
  • Benefícios da herança:
    • Reutilização de código.
    • Estrutura hierárquica clara e extensível.
    • Facilidade de manutenção e escalabilidade.
  • Prática de implementação:
    • Testes práticos para validar métodos.
    • Flexibilidade para novos tipos de produtos.

Principais Aprendizados

  1. Gerenciamento eficaz de requisitos é essencial para evitar falhas e alinhar o projeto às expectativas do cliente.
  2. Documentação ágil e enxuta facilita comunicação e evita burocracia excessiva.
  3. Herança em POO permite criar sistemas organizados, reutilizáveis e preparados para expansão.
  4. Aspectos éticos e segurança devem ser considerados tanto no gerenciamento de mudanças quanto na implementação de software.

Herança em Projetos Práticos

  • Exemplo aplicado: Sistema de gerenciamento escolar com classes Pessoa, Funcionario e Aluno, mostrando a criação de estruturas hierárquicas e reutilização de código.
  • Conceitos aplicados:
    • Encapsulamento de atributos e métodos.
    • Uso de composição (objetos como atributos de outras classes).
    • Estrutura hierárquica clara e extensível para novos tipos de entidades.

Polimorfismo (POO)

  • Definição: Permite que objetos de diferentes classes respondam de forma distinta a uma mesma interface, aumentando flexibilidade e reutilização.
  • Tipos abordados:
    • Sobreposição (override): Subclasses redefinem métodos herdados da classe pai.
    • Exemplo prático: Sistema de entregas com veículos (carro, caminhão, bicicleta), cada um com cálculo específico de tempo de entrega.
  • Aplicações adicionais:
    • Loja virtual com diferentes tipos de produtos (livros, eletrônicos e alimentos).
    • Sistema de rastreamento de encomendas com classes Encomenda, Pacote, Carta e RemessaGrande, utilizando herança e sobreposição para especializações.

Benefícios Chave

  1. Reutilização de código: Com herança e polimorfismo, métodos comuns são centralizados e especializados conforme necessário.
  2. Flexibilidade e extensibilidade: Fácil adição de novos tipos de classes sem alterar estruturas existentes.
  3. Modelagem próxima ao mundo real: Representação clara de entidades e suas relações hierárquicas.
  4. Manutenção simplificada: Alterações localizadas reduzem riscos de falhas globais no sistema.
PDS e Metodologias Ágeis
Resultado do Projeto

A partir dessa conversa, o aluno consegue extrair:

Banco de Dados Simplificado

  • Tabela produtos
    • id (PK)
    • nome
    • preco
    • tamanho
    • foto
    • ativo (booleano)
  • Tabela adicionais
    • id (PK)
    • nome
    • preco
  • Tabela pedidos
    • id (PK)
    • nome_cliente
    • telefone_cliente
    • bairro
    • data_hora
  • Tabela itens_pedido
    • id (PK)
    • pedido_id (FK)
    • produto_id (FK)
    • tamanho
    • adicionais (lista simplificada, se quiser)

Casos de Uso

  • Cliente:
    • Visualizar produtos
    • Adicionar produtos ao carrinho
    • Escolher adicionais
    • Finalizar pedido
  • Dono da loja:
    • Cadastrar produto
    • Editar produto
    • Cadastrar adicionais
    • Desativar produto
    • Ver pedidos

Objetivo Final

🎯 Criar um site com:

  • Página inicial listando os produtos
  • Tela de escolha de adicionais
  • Carrinho de compras
  • Formulário simples (Nome, Telefone, Bairro)
  • Botão “Enviar pedido” integrando com WhatsApp
  • Painel administrativo bem simples

Vou seguir essa ordem para ficar fácil para seus alunos:

  1. 🎯 Casos de Uso
  2. 📦 Diagrama de Classes
  3. 🛢️ Tabelas (Banco de Dados)
  4. 🖥️ Programa em Python (bem simples, tipo console) para atender o cliente

Vou fazer tudo bem simples e didático para quem está começando! Vamos lá:


🎯 1. Casos de Uso

Ator 1: Cliente

  • Visualizar lista de produtos
  • Escolher produto e adicionais
  • Preencher nome, telefone e bairro
  • Confirmar pedido

Ator 2: Dono da loja

  • Cadastrar novo produto
  • Editar produto
  • Desativar produto
  • Cadastrar adicionais
  • Visualizar pedidos recebidos

📦 2. Diagrama de Classes (Simplificado)

+----------------+        +----------------+        +----------------+
|    Produto     |        |    Adicional    |        |     Pedido      |
+----------------+        +----------------+        +----------------+
| - id: int      |        | - id: int       |        | - id: int       |
| - nome: str    |        | - nome: str     |        | - nome_cliente  |
| - preco: float |        | - preco: float  |        | - telefone      |
| - tamanho: str |        +----------------+        | - bairro        |
| - ativo: bool  |                                 | - data_hora     |
+----------------+                                 +----------------+
          |                                               |
          |                                               |
          |                      +------------------------+
          |                      |
          |                 +-----------------+
          |                 |  ItensPedido     |
          |                 +-----------------+
          |                 | - id: int        |
          +---------------->| - pedido_id: int |
                            | - produto_id: int|
                            | - adicionais: str|
                            +-----------------+

🛢️ Tabelas no SQLite

Aqui está o script para criar o banco SQLite:

-- Criação das tabelas no SQLite

CREATE TABLE produtos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nome TEXT NOT NULL,
    preco REAL NOT NULL,
    tamanho TEXT NOT NULL,
    ativo INTEGER DEFAULT 1 -- 1 = ativo, 0 = inativo
);

CREATE TABLE adicionais (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nome TEXT NOT NULL,
    preco REAL NOT NULL
);

CREATE TABLE pedidos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nome_cliente TEXT NOT NULL,
    telefone_cliente TEXT NOT NULL,
    bairro TEXT,
    data_hora TEXT DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE itens_pedido (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    pedido_id INTEGER,
    produto_id INTEGER,
    adicionais TEXT,
    FOREIGN KEY (pedido_id) REFERENCES pedidos(id),
    FOREIGN KEY (produto_id) REFERENCES produtos(id)
);

🐍 Código Python usando SQLite (bem fácil)

Aqui está o programa completo agora com banco SQLite:

import sqlite3
from datetime import datetime

# Conexão com o banco SQLite
conn = sqlite3.connect('acai.db')
cursor = conn.cursor()

# Cria tabelas se não existirem
cursor.execute('''
CREATE TABLE IF NOT EXISTS produtos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nome TEXT NOT NULL,
    preco REAL NOT NULL,
    tamanho TEXT NOT NULL,
    ativo INTEGER DEFAULT 1
)
''')

cursor.execute('''
CREATE TABLE IF NOT EXISTS adicionais (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nome TEXT NOT NULL,
    preco REAL NOT NULL
)
''')

cursor.execute('''
CREATE TABLE IF NOT EXISTS pedidos (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nome_cliente TEXT NOT NULL,
    telefone_cliente TEXT NOT NULL,
    bairro TEXT,
    data_hora TEXT DEFAULT CURRENT_TIMESTAMP
)
''')

cursor.execute('''
CREATE TABLE IF NOT EXISTS itens_pedido (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    pedido_id INTEGER,
    produto_id INTEGER,
    adicionais TEXT,
    FOREIGN KEY (pedido_id) REFERENCES pedidos(id),
    FOREIGN KEY (produto_id) REFERENCES produtos(id)
)
''')

conn.commit()

def cadastrar_produto():
    nome = input("Nome do produto: ")
    preco = float(input("Preço: "))
    tamanho = input("Tamanho (ex: 300ml, 500ml): ")
    cursor.execute("INSERT INTO produtos (nome, preco, tamanho) VALUES (?, ?, ?)", (nome, preco, tamanho))
    conn.commit()
    print("Produto cadastrado!\n")

def cadastrar_adicional():
    nome = input("Nome do adicional: ")
    preco = float(input("Preço do adicional: "))
    cursor.execute("INSERT INTO adicionais (nome, preco) VALUES (?, ?)", (nome, preco))
    conn.commit()
    print("Adicional cadastrado!\n")

def listar_produtos():
    cursor.execute("SELECT id, nome, preco, tamanho FROM produtos WHERE ativo = 1")
    produtos = cursor.fetchall()
    print("\nProdutos disponíveis:")
    for prod in produtos:
        print(f"{prod[0]}. {prod[1]} - {prod[3]} - R$ {prod[2]:.2f}")
    print()

def listar_adicionais():
    cursor.execute("SELECT id, nome, preco FROM adicionais")
    adicionais = cursor.fetchall()
    print("\nAdicionais disponíveis:")
    for ad in adicionais:
        print(f"{ad[0]}. {ad[1]} - R$ {ad[2]:.2f}")
    print()

def fazer_pedido():
    listar_produtos()
    produto_id = input("Escolha o número do produto: ")
    cursor.execute("SELECT nome, tamanho FROM produtos WHERE id = ? AND ativo = 1", (produto_id,))
    produto = cursor.fetchone()
    if not produto:
        print("Produto inválido!")
        return

    adicionais_selecionados = []
    while True:
        listar_adicionais()
        add = input("Escolha o número do adicional (ou ENTER para finalizar): ")
        if add == "":
            break
        cursor.execute("SELECT nome FROM adicionais WHERE id = ?", (add,))
        adicional = cursor.fetchone()
        if adicional:
            adicionais_selecionados.append(adicional[0])

    nome_cliente = input("Nome do cliente: ")
    telefone = input("Telefone do cliente: ")
    bairro = input("Bairro do cliente: ")

    cursor.execute("INSERT INTO pedidos (nome_cliente, telefone_cliente, bairro) VALUES (?, ?, ?)", 
                   (nome_cliente, telefone, bairro))
    pedido_id = cursor.lastrowid

    adicionais_texto = ', '.join(adicionais_selecionados)
    cursor.execute("INSERT INTO itens_pedido (pedido_id, produto_id, adicionais) VALUES (?, ?, ?)", 
                   (pedido_id, produto_id, adicionais_texto))
    
    conn.commit()
    print("Pedido registrado com sucesso!\n")

def listar_pedidos():
    cursor.execute('''
    SELECT pedidos.nome_cliente, pedidos.telefone_cliente, pedidos.bairro, pedidos.data_hora,
           produtos.nome, produtos.tamanho, itens_pedido.adicionais
    FROM pedidos
    JOIN itens_pedido ON pedidos.id = itens_pedido.pedido_id
    JOIN produtos ON produtos.id = itens_pedido.produto_id
    ''')
    pedidos = cursor.fetchall()
    print("\nPedidos recebidos:")
    for ped in pedidos:
        print(f"- {ped[0]} ({ped[1]}) pediu {ped[4]} {ped[5]} com {ped[6]} [{ped[3]}] - Bairro: {ped[2]}")
    print()

def menu_admin():
    while True:
        print("\n=== Menu Admin ===")
        print("1. Cadastrar Produto")
        print("2. Cadastrar Adicional")
        print("3. Listar Pedidos")
        print("4. Sair")
        op = input("Escolha: ")
        if op == "1":
            cadastrar_produto()
        elif op == "2":
            cadastrar_adicional()
        elif op == "3":
            listar_pedidos()
        elif op == "4":
            break
        else:
            print("Opção inválida.")

def menu_cliente():
    while True:
        print("\n=== Menu Cliente ===")
        print("1. Fazer Pedido")
        print("2. Sair")
        op = input("Escolha: ")
        if op == "1":
            fazer_pedido()
        elif op == "2":
            break
        else:
            print("Opção inválida.")

def main():
    while True:
        print("\n=== Sistema Açaí ===")
        print("1. Cliente")
        print("2. Admin")
        print("3. Sair")
        op = input("Escolha: ")
        if op == "1":
            menu_cliente()
        elif op == "2":
            menu_admin()
        elif op == "3":
            print("Até mais!")
            break
        else:
            print("Opção inválida.")

if __name__ == "__main__":
    main()

🧡 O que você tem agora:

  • Casos de uso ✅
  • Diagrama de classes ✅
  • Estrutura de tabelas SQL ✅
  • Programa Python inicial ✅

Vou montar agora um exemplo usando Streamlit, que é perfeito para criar interfaces web simples em Python — ideal pra mostrar pra turma!

💡 O que vamos fazer:

  • Listar produtos
  • Cliente escolher o produto
  • Selecionar adicionais
  • Preencher nome, telefone e bairro
  • Confirmar o pedido
  • Mostrar o pedido feito na tela (como simulação)

Tudo direto pelo navegador, usando o acai.db (SQLite)!


🖥️ Código Streamlit (arquivo app.py)

import streamlit as st
import sqlite3
from datetime import datetime

# Conexão com o banco SQLite
conn = sqlite3.connect('acai.db', check_same_thread=False)
cursor = conn.cursor()

# Funções auxiliares
def listar_produtos():
    cursor.execute("SELECT id, nome, preco, tamanho FROM produtos WHERE ativo = 1")
    return cursor.fetchall()

def listar_adicionais():
    cursor.execute("SELECT id, nome, preco FROM adicionais")
    return cursor.fetchall()

def registrar_pedido(nome_cliente, telefone, bairro, produto_id, adicionais_lista):
    cursor.execute("INSERT INTO pedidos (nome_cliente, telefone_cliente, bairro) VALUES (?, ?, ?)", 
                   (nome_cliente, telefone, bairro))
    pedido_id = cursor.lastrowid
    adicionais_texto = ', '.join(adicionais_lista)
    cursor.execute("INSERT INTO itens_pedido (pedido_id, produto_id, adicionais) VALUES (?, ?, ?)", 
                   (pedido_id, produto_id, adicionais_texto))
    conn.commit()

# Layout da página
st.title("🍧 Loja de Açaí")

st.header("Escolha seu Açaí")

produtos = listar_produtos()
produtos_dict = {f"{nome} - {tamanho} - R$ {preco:.2f}": id for id, nome, preco, tamanho in produtos}

produto_escolhido = st.selectbox("Selecione um produto", list(produtos_dict.keys()))

adicionais = listar_adicionais()
adicionais_selecionados = st.multiselect(
    "Escolha adicionais (opcional)",
    [f"{nome} - R$ {preco:.2f}" for id, nome, preco in adicionais]
)

st.header("Seus Dados")

nome_cliente = st.text_input("Nome completo")
telefone = st.text_input("Telefone")
bairro = st.text_input("Bairro")

if st.button("Confirmar Pedido"):
    if nome_cliente and telefone and produto_escolhido:
        # Captura IDs dos adicionais selecionados
        adicionais_nomes = [a.split(' - ')[0] for a in adicionais_selecionados]
        
        produto_id = produtos_dict[produto_escolhido]
        registrar_pedido(nome_cliente, telefone, bairro, produto_id, adicionais_nomes)

        st.success("Pedido enviado com sucesso!")
        st.balloons()
    else:
        st.error("Preencha seu nome, telefone e selecione um produto!")

st.divider()

st.subheader("📋 Últimos Pedidos")

cursor.execute('''
    SELECT pedidos.nome_cliente, produtos.nome, produtos.tamanho, itens_pedido.adicionais, pedidos.data_hora
    FROM pedidos
    JOIN itens_pedido ON pedidos.id = itens_pedido.pedido_id
    JOIN produtos ON produtos.id = itens_pedido.produto_id
    ORDER BY pedidos.data_hora DESC
    LIMIT 5
''')
ultimos_pedidos = cursor.fetchall()

for ped in ultimos_pedidos:
    st.write(f"**{ped[0]}** pediu **{ped[1]} {ped[2]}** com _{ped[3]}_ em {ped[4]}")


🚀 Como Rodar:

  1. Instalar o Streamlit:
bashCopiarEditarpip install streamlit
  1. Criar o arquivo app.py com o código acima.
  2. Rodar o aplicativo:
bashCopiarEditarstreamlit run app.py
  1. Vai abrir o navegador automaticamente!
    (Você verá a lojinha de Açaí funcionando 💜)

📋 O que esse exemplo ensina:

  • Conexão SQLite
  • Interface web amigável
  • Escolha de produtos e adicionais
  • Registro de pedidos
  • Feedback visual para o usuário
  • Listagem dos últimos pedidos feitos
PDS e Metodologias Ágeis
Levantamento de Requisitos

Este trabalho simula o dialogo entre um vendedor e um programador.

🟣 Entrevista 1 — Primeira Reunião (Levantamento Inicial)

CLIENTE:
Oi, tudo bem? Então… eu queria fazer um site pra minha loja de açaí, sabe? Um site bonito, que apareça as fotos dos potes bem cheios, com aquelas coberturas caindo assim…

Programador:
Oi, tudo ótimo! Ah, entendi, você quer um site que destaque bem as imagens dos seus produtos, certo?

CLIENTE:
Isso! E queria também que desse pra pessoa montar o açaí dela… tipo, ela escolhe o tamanho, os adicionais, põe leite condensado, paçoca… essas coisas.

Programador:
Entendi. Então seriam dois tipos de venda: produtos prontos (como um açaí tradicional 500ml) e o cliente montando o seu próprio açaí.

CLIENTE:
Exatamente! E sabe o que seria legal? Se tivesse música tocando no site!

Programador:
(risos) Música? Podemos pensar em colocar, mas talvez isso atrapalhe um pouco a navegação, sabe?
Você quer focar em vender ou fazer algo mais descontraído?

CLIENTE:
Ah, é… melhor vender né? Então esquece a música!

Programador:
Certo! Sobre os pedidos: como você quer receber? O cliente paga no site ou paga na hora?

CLIENTE:
Olha, ainda tô começando… queria que ele só mandasse o pedido. Daí eu confirmo no WhatsApp e combino o pagamento.

Programador:
Ok, pedido sem pagamento online. E você quer controlar o estoque também?

CLIENTE:
Estoque? Ah… seria bom saber quando tá acabando leite condensado, paçoca… Mas não precisa ser complicado, não. Se não der, deixa pra depois.

Programador:
Tudo bem, vou anotar como “controle simples de estoque” pra uma segunda fase.

CLIENTE:
Isso!


🟣 Entrevista 2 — Definindo o Básico (com mais detalhes)

Programador:
Oi, voltei! Organizei algumas ideias pra gente confirmar.

CLIENTE:
Ótimo! Vamos ver!

Programador:
Sobre os produtos: você quer cadastrar o nome do açaí, o preço, o tamanho (ex: 300ml, 500ml) e colocar uma foto. Correto?

CLIENTE:
Certo. Mas às vezes eu quero fazer promoções! Tipo, “Compre um de 500ml e ganhe uma granola grátis.”

Programador:
Entendi. Promoções podem ser configuradas também, mas talvez num segundo momento, combinado?

CLIENTE:
Tá bom! Primeiro vamos focar no básico.

Programador:
Sobre os adicionais: vamos ter uma listinha? Tipo: Banana, Paçoca, Leite condensado… cada um com um preço.

CLIENTE:
Sim! E às vezes eu queria dar adicionais grátis em dias especiais, tipo “sexta-feira da banana grátis”.

Programador:
Ok, posso deixar espaço para adicionar promoções depois. No momento, vamos focar no cliente escolher os adicionais e adicionar ao pedido.

CLIENTE:
Perfeito.

Programador:
Agora: o pedido.
O cliente seleciona o produto, escolhe os adicionais e informa o nome e telefone para contato, certo?

CLIENTE:
Isso! E o bairro também, né? Vai que eu começo a entregar…

Programador:
Boa ideia. Vamos incluir campo para Bairro também.

CLIENTE:
Ah, e se a pessoa quiser pedir dois açaís diferentes no mesmo pedido?

Programador:
Ótimo ponto. Então vamos deixar o carrinho com possibilidade de adicionar mais de um produto.


🟣 Entrevista 3 — Confirmando Tudo (com cliente viajando um pouco)

Programador:
Oi, tudo certo? Vim só pra validar antes de começar!

CLIENTE:
Opa! Tô animado!

Programador:
Então vamos lá:
No site, o cliente vai poder:

  • Ver a lista de produtos
  • Ver os adicionais
  • Escolher o produto e o tamanho
  • Escolher adicionais
  • Adicionar ao carrinho
  • Informar nome, telefone e bairro
  • Confirmar pedido
  • E o pedido vai pro seu WhatsApp.

CLIENTE:
Show! E se der, eu queria que o site piscasse alguma coisa, tipo uma estrela, quando a pessoa confirmasse o pedido!

Programador:
(risos) Vamos fazer uma mensagem de “Pedido enviado com sucesso”, pode ser?

CLIENTE:
Tá ótimo! Estrela piscando era bobagem minha, esquece!

Programador:
Beleza. Sobre o controle dos produtos: você vai conseguir acessar um painel pra:

  • Cadastrar novo açaí
  • Alterar preço
  • Cadastrar novos adicionais
  • Alterar fotos

CLIENTE:
Ahhh, legal! Quero também poder desativar um produto, tipo “acabou”, sem apagar tudo.

Programador:
Perfeito, vou colocar a opção de deixar um produto inativo.

CLIENTE:
E se eu mudar de ideia e quiser cobrar o pedido online?

Programador:
A gente consegue adicionar depois. Por enquanto vamos deixar como “pedido via WhatsApp” mesmo.

CLIENTE:
Combinado!

PDS e Metodologias Ágeis
PDS e Metodologias Ágeis

Resumo: Programação, Testes e Modelagem de Sistemas

1. Programação Orientada a Objetos com Python

Conceitos-chave:

  • Classes e Objetos:
    Uma classe é um molde; o objeto é o produto. Classes definem atributos (características) e métodos (ações).
  • Encapsulamento:
    Técnica que protege os dados dentro de uma classe, permitindo acesso controlado através de getters (leitura) e setters (modificação).

Aplicações práticas:

  • Criação de softwares modulares e organizados.
  • Utilização de boas práticas como separação de responsabilidades, reutilização de código e manutenção mais fácil.

Exemplos:

  • Criar uma classe Carro com atributos como cor e métodos como acelerar().

Boas práticas destacadas:

  • Utilizar convenções de encapsulamento (_atributo).
  • Planejar o código com esboços no papel antes da implementação.

2. Testes Não Funcionais: Desempenho, Segurança e Usabilidade

Desempenho

  • Testes de carga e stress:
    Avaliam se o sistema suporta alta demanda (ex.: Black Friday).
  • Otimização de recursos:
    Melhor uso de memória, CPU e armazenamento, como fazem Netflix e Spotify.
  • Monitoramento contínuo:
    Ferramentas como Google Analytics analisam o desempenho em tempo real.

Segurança

  • Testes de invasão (PenTest) e vulnerabilidade:
    Simulam ataques para descobrir falhas.
  • Autenticação e Autorização:
    Como o uso de 2FA (Autenticação de dois fatores).
  • Compliance:
    Seguir normas como GDPR para proteger dados dos usuários.

Exemplo real:
O ataque à Sony Pictures (2014) mostrou falhas como falta de 2FA e servidores desatualizados.

Usabilidade

  • Avaliação heurística:
    Avaliar a facilidade de uso seguindo princípios como os de Nielsen.
  • Testes com usuários reais:
    Observar o uso prático para melhorar a experiência.
  • Acessibilidade:
    Tornar sistemas usáveis para todos, como faz a Apple com seus recursos para deficientes.

3. Diagramas de Casos de Uso (UML)

Exemplo de diagrama de caso de uso: Referencia: https://medium.com/operacionalti/uml-diagrama-de-casos-de-uso-29f4358ce4d5

Use o site site https://www.draw.io/ para gerar o modelo da loja de açaí

O que são:

  • Diagramas que mostram como os usuários (atores) interagem com o sistema.
  • Representam funcionalidades e ajudam no entendimento, planejamento e comunicação do sistema.

Componentes principais:

  • Atores: quem usa (pessoas ou outros sistemas).
  • Casos de uso: o que o sistema faz para atender o ator.
  • Relacionamentos: associação, inclusão e extensão.

Exemplos:

  • E-commerce: Cliente compra produtos; administrador gerencia estoque.
  • Sistema bancário: Cliente faz saques e consultas.
  • Educação: Aluno assiste aula, professor publica material.

Importância prática:

  • Clarificam requisitos e interações antes da programação.
  • Ajudam a prever problemas e definir prioridades de desenvolvimento.

Resumo Final para Aula

TemaPontos PrincipaisExemplos Reais
Programação O.O.Classes, Objetos, EncapsulamentoPython (classe Carro)
Testes Não FuncionaisCarga, Segurança, UsabilidadeNetflix, Sony Pictures
Diagramas de Casos de UsoVisualizar ações do sistemaE-commerce, Saúde, Educação

💬 Sugestão de abordagem com os alunos:

“Hoje vamos aprender como construir softwares organizados, seguros e fáceis de usar, entendendo como desenhar, testar e programar melhor!”

Resumo Elaborado: Programação, Modelagem de Dados e Requisitos de Software


1. Diagramas UML: Casos de Uso, Classes e Sequências

Diagramas de Casos de Uso ​​

  • Representam as funcionalidades que o sistema oferece e como os usuários (atores) interagem com ele.
  • Principais elementos:
    • Atores: Pessoas ou sistemas externos que usam o sistema.
    • Casos de uso: Ações realizadas pelo sistema.
    • Relacionamentos: Mostram como atores e casos de uso se conectam.
  • Aplicações práticas: e-commerce, bancos, sistemas de ensino.
  • Objetivo: Melhorar a comunicação entre desenvolvedores, clientes e usuários.

Diagramas de Classes

referencia: https://slideplayer.com.br/slide/13956163/

  • Representam a estrutura estática do sistema.
  • Cada classe mostra seus atributos (informações) e métodos (ações que podem ser realizadas).
  • Exemplo: Classe “Usuário” com atributos como nome, email e métodos como logar().

Use o site site https://www.draw.io/ para gerar o modelo da loja de açaí

Diagramas de Sequência

Referencia: https://medium.com/documenta%C3%A7ao-uml/introdu%C3%A7%C3%A3o-ao-diagrama-de-sequ%C3%AAncia-1ea5e9563594

Use o site site https://www.draw.io/ para gerar o modelo da loja de açaí

  • Mostram como os objetos interagem no tempo para realizar funções.
  • Utilizados para representar o fluxo de mensagens entre usuários, sistemas e bases de dados.
  • Exemplo: Usuário adiciona produto ao carrinho → Sistema processa → Estoque é atualizado.


2. Modelagem de Dados Relacional ​​

Use o site site https://www.draw.io/ para gerar o modelo da loja de açaí

Fundamentos:

  • Entidades: Representam objetos reais, como Clientes, Produtos, Pedidos.
  • Relacionamentos: Como esses objetos se conectam (ex.: Cliente faz Pedido).

Normalização dos dados:

  • 1ª Forma Normal (1NF): Cada campo com um único valor.
  • 2ª Forma Normal (2NF): Eliminar dependências parciais em chaves compostas.
  • 3ª Forma Normal (3NF): Eliminar dependências transitivas.

Melhores práticas:

  • Chaves primárias e chaves estrangeiras para manter integridade dos dados.
  • Indexação para melhorar a performance de consultas.
  • Monitoramento contínuo do banco para otimizar consultas grandes.

Exemplo de aplicação:

  • Em sistemas de vendas, é necessário dividir dados em tabelas como Clientes, Pedidos, Produtos para evitar repetição de informações.

3. Modelagem de Requisitos de Software ​​

Requisitos de Software:

  • Requisitos Funcionais:
    Descrevem o que o sistema faz (ex.: “Usuário pode se cadastrar”).
  • Requisitos Não Funcionais:
    Definem qualidades do sistema (ex.: “O sistema deve carregar em 2 segundos”).
  • Requisitos de Domínio:
    Específicos de uma área (ex.: um sistema médico que precisa seguir normas de saúde).

Levantamento de requisitos:

  • Técnicas: entrevistas, questionários, observação direta, workshops.
  • Ferramentas: UML, JIRA, Trello.

Documentação:

  • Especificação de Requisitos de Software (SRS): documento técnico detalhado.
  • User Stories (Histórias de Usuário):
    Exemplo: “Como cliente, quero adicionar produtos ao carrinho para finalizar minha compra.”

Requisitos em Metodologias Ágeis:

  • Flexibilidade:
    Permitem mudanças rápidas durante o desenvolvimento.
  • Priorização:
    Entregam primeiro o que é mais importante.
  • User Stories e Critérios de Aceitação:
    Validam se a funcionalidade foi entregue corretamente.

Quadro Resumo para Aula

TemaPontos PrincipaisExemplos
Diagramas de Casos de UsoComo o usuário interage com o sistemaLoja online, Banco, Escola
Diagramas de ClassesEstrutura de dados do sistemaCadastro de clientes
Diagramas de SequênciaOrdem de interação entre objetosCompra online
Modelagem de DadosOrganização eficiente de informaçõesBanco de dados de vendas
Modelagem de RequisitosO que o sistema faz e como deve se comportarCadastro rápido e seguro

Sugestão para Apresentação Oral

Você pode dizer algo assim:

“Hoje vamos conhecer ferramentas essenciais para criar sistemas modernos: vamos entender como desenhar os requisitos de um sistema, organizar seus dados, planejar suas funções e testar se tudo está funcionando corretamente.”

Tabela de Jargões e Significados

JargãoSignificado
UML (Unified Modeling Language)Linguagem usada para desenhar diagramas que explicam como um sistema funciona.
Diagrama de Casos de UsoDesenho que mostra o que o sistema faz e como os usuários (atores) interagem com ele.
AtorQuem interage com o sistema (pessoa, sistema ou dispositivo).
Caso de UsoAção ou funcionalidade que o sistema deve realizar.
Relacionamento (UML)Ligação entre atores e casos de uso ou entre casos de uso diferentes.
Diagrama de ClassesRepresentação das partes de um sistema: suas informações (atributos) e ações (métodos).
Diagrama de SequênciaMostra a ordem em que as ações acontecem entre os objetos de um sistema.
Linha de VidaRepresenta o tempo de vida de um objeto enquanto ele interage no sistema.
Mensagem SíncronaComunicação onde quem envia espera uma resposta antes de continuar.
Mensagem AssíncronaComunicação onde quem envia não precisa esperar resposta para continuar.
Modelagem de Dados RelacionalTécnica para organizar as informações em bancos de dados, evitando erros e repetição.
EntidadeRepresentação de um objeto ou conceito real (ex: cliente, produto).
Relacionamento (Dados)Conexão entre duas entidades no banco de dados.
NormalizaçãoProcesso para organizar os dados em tabelas de forma correta, evitando repetições.
Chave PrimáriaIdentificador único de cada registro numa tabela (ex: CPF de uma pessoa).
Chave EstrangeiraLigação entre duas tabelas diferentes.
User StoryPequena história escrita do ponto de vista do usuário dizendo o que ele precisa fazer.
Critério de AceitaçãoCondições que mostram que uma funcionalidade foi feita corretamente.
MoSCoWTécnica para priorizar tarefas: Must (deve ter), Should (deveria ter), Could (poderia ter), Won’t (não terá agora).
Levantamento de RequisitosProcesso de descobrir tudo o que o sistema precisa fazer.
SRS (Software Requirements Specification)Documento formal que descreve todos os requisitos do sistema.
Framework ÁgilModelo de trabalho que permite fazer entregas rápidas e adaptáveis no desenvolvimento de software.
CI/CD (Integração Contínua/Entrega Contínua)Técnicas para automatizar testes e entregas de novos códigos em sistemas de forma rápida e segura.
WorkshopReunião prática e interativa para resolver problemas ou levantar informações.
ProtótipoModelo simples de um sistema feito para testar ideias antes de fazer a versão final.
Elicitação de RequisitosColeta de informações necessárias para definir o que o sistema precisa fazer.

Resumo Geral para Apresentação — Sistemas, Modelagem e Testes


1. Modelagem de Dados Relacionais

  • Conceitos-chave:
    Entidades (como “Cliente” ou “Produto”), Relacionamentos e Normalização (1ª, 2ª e 3ª Formas Normais)​.
  • Objetivo:
    Garantir organização dos dados, evitando redundância e melhorando a integridade.
  • Exemplos:
    Cadastro de clientes, pedidos em lojas virtuais.

2. Modelagem de Dados Não Relacionais

  • Tipos de bancos:
    • Documentos: Estruturam informações como JSON (ex: MongoDB).
    • Grafos: Representam conexões complexas (ex: Redes Sociais)​.
    • Chave-Valor: Para acesso ultra rápido de informações, como sessões de usuários​.
  • Importância:
    Usados onde precisamos de alta escalabilidade, consultas rápidas ou análise de redes.

3. Diagramas UML: Casos de Uso, Classes e Sequências

  • Casos de Uso:
    Mostram como usuários interagem com o sistema​.
  • Classes:
    Estruturam informações e métodos em sistemas​​.
  • Sequência:
    Representam o fluxo temporal de interações entre objetos​​.
  • Exemplos práticos:
    E-commerce (Cliente → Carrinho → Pagamento → Estoque).

4. Requisitos de Software

  • Funcionais:
    Definem o que o sistema faz (ex: “Cadastrar usuário”).
  • Não Funcionais:
    Definem qualidades do sistema (ex: “Tempo de resposta menor que 2 segundos”).
  • User Stories:
    Pequenas histórias que ajudam a entender melhor o que o usuário precisa.

5. Testes de Software

Testes Funcionais

  • O que são:
    Verificam se o sistema cumpre seus requisitos.
  • Técnicas:
    • Caixa Preta (testar sem saber o código).
    • Testes de equivalência, valor-limite.
    • Automação de testes (ex: usando pytest).
  • Importância:
    Garante que o sistema faça exatamente o que foi prometido.

Testes Não Funcionais ​

  • Tipos:
    • Desempenho:
      Avalia velocidade, escalabilidade e estabilidade.
    • Segurança:
      Testa vulnerabilidades e proteção de dados.
    • Usabilidade:
      Garante facilidade de uso e compatibilidade com vários dispositivos.
  • Exemplos reais:
    • Black Friday: Testes de carga para aguentar milhões de acessos​.
    • Aplicativos bancários: Testes de segurança e compatibilidade em vários celulares​.

6. Planejamento e Gestão de Testes

  • Planejamento de Testes:
    Definição de escopo, cronograma e recursos necessários​.
  • Gestão de Defeitos:
    • Identificar.
    • Registrar (documentar claramente).
    • Monitorar (corrigir e validar).
  • Testes Ágeis:
    Testar continuamente usando integração contínua (CI/CD).

Resumo Final para Aula

TemaFocoExemplos
Modelagem RelacionalOrganização e estruturação de dadosBanco de dados de vendas
Modelagem Não RelacionalEficiência e escalabilidadeMongoDB, Redis, Neo4j
Diagramas UMLEntender funcionamento e interaçõesSistema de Compras Online
RequisitosDefinir o que fazer e como se comportarCadastrar usuário rapidamente
Testes FuncionaisVerificar se tudo funciona como planejadoCadastro de clientes
Testes Não FuncionaisGarantir qualidade, segurança e desempenhoTeste de carga em Black Friday

💬 Sugestão de Introdução para Apresentação:

“Hoje vamos explorar como projetar sistemas, organizar dados, definir funções e testar tudo para garantir que a tecnologia funcione de maneira rápida, segura e fácil de usar no nosso dia a dia.”

en_USEnglish