Buscar

AED_2020_2021_01_requisitos

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 38 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 38 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 38 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Algoritmos e Estruturas de Dados
Python e Objetos
Universidade Autónoma de Lisboa
UAL © 2021 AED: Requisitos 1 / 38
Requisitos
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git UAL © 2021 AED: Requisitos 2 / 38
Requisitos
UAL © 2021 AED: Requisitos 3 / 38
Python
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 4 / 38
Python
Python
Python é uma linguagem imperativa, orientada a objetos. Vai ser a linguagem utilizada durante
em Algoritmos e Estruturas de Dados.
É necessário dominar as seguintes construções da linguagem:
• Variáveis
• Estruturas de controlo (if, for, while)
• Funções
• Módulos e pacotes
• Exceções
• Classes e objetos
UAL © 2021 AED: Requisitos 5 / 38
Python
Método
As aplicações devem ser escritas com um editor de texto, e.g., Visual Studio Code.
Se o programa for simples, pode fazer sentido escrever todo o código num só ficheiro.
Geralmente, os programas terão vários ficheiros.
O código escrito num ficheiro (ou vários) deve ser executado com o interpretador python. Este
está disponível na linha de comandos.
Se a distribuição Python for a Anaconda, a linha de comandos deve ser a disponibilizada pela
Anaconda.
UAL © 2021 AED: Requisitos 6 / 38
Python
Método (2)
A execução de código deve ser feita com recurso ao contexto main.
if __name__ == "__main__":
# Executar neste contexto
É necessário sistematizar o processo de desenvolvimento, identificando a funcionalidade a
implementar, e garantir que ficou a funcionar depois de implementada.
Vamos recorrer a testes unitários para garantir que os artefactos que produzidos têm o
comportamento pretendido.
UAL © 2021 AED: Requisitos 7 / 38
Python
Metodologia
Qualquer programa pode dividir a sua implementação em três tipos de módulo:
Módulos de modelos de informação: Contêm as estruturas de dados, e métodos que operam
sobre elas diretamente.
Módulos de controlo: Contém as regras de negócio, que relacionam os vários modelos de
informação. Permitem criar as condições para dar resposta aos pedidos do utilizador.
Módulos de interação: Leem as instruções do utilizador, e entregam as respostas.
Existem mais abordagens para organizar um programa.
Em AED, vamos construir bibliotecas de estruturas e dados e programas. Quando for
necessário implementar um programa, vamos funcionar com esta metodologia.
UAL © 2021 AED: Requisitos 8 / 38
Python
Advertência
Todas as funções, módulos, e classes devem ser experimentadas. Não faz sentido entregar
código que nunca foi executado com sucesso.
É necessário ficar confortável com o editor de texto, e com o processo de escrita de código e
execução. Esse conforto exige tempo e repetição.
Não é suficiente observar terceiros a desenvolver aplicações sem passar pelo processo de
resolução de problemas. Vai gerar uma falsa sensação de competência.
Os problemas têm que ser resolvidos. O código tem que ser escrito. É sempre útil procurar
ajuda, mas não existe substituto, ou alternativa, para o esforço individual.
UAL © 2021 AED: Requisitos 9 / 38
Orientação a objetos
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 10 / 38
Orientação a objetos
Classes e objetos
Existem dois conceitos fundamentais em Programação Orientada a Objetos: Classe e Objeto.
Uma classe define um novo tipo de dados. É o artefacto de código que contém a descrição dos
dados e algoritmos disponíveis para cada objeto.
Um objeto é uma instância de uma classe, i.e., é um elemento do tipo definido pela classe, e
pode estar atribuído a uma variável, ou fazer parte de uma coleção (e.g., lista).
As classes definem métodos que operam sobre a informação contida nos objetos.
Em Python, o primeiro atributo de cada método é uma referência para o objeto através o qual o
método é executado. Por convenção, esse atributo chama-se self.
Da relação entre o conceito de classe e objeto é importante reter que para um determinado tipo
de dados, existe uma classe que o define, e, eventualmente, vários objetos criados de acordo
com essa definição.
UAL © 2021 AED: Requisitos 11 / 38
Orientação a objetos
Construção de classes
Uma classe é definida com recurso ao operador class. Cada classe tem um nome e,
eventualmente, um método construtor de objetos, __init__.
class Pessoa:
def __init__(self, nome, data_de_nascimento, nacionalidade):
self.nome = nome
self.data_de_nascimento = data_de_nascimento
self.nacionalidade = nacionalidade
Quando um objeto é criado, a classe executa o método __init__.
UAL © 2021 AED: Requisitos 12 / 38
Orientação a objetos
Atributos e métodos
Cada objeto vai ter um conjunto de atributos, i.e., variáveis com dados. Os métodos da classe
permitem manipular atributos dos objetos.
Todos os métodos podem criar e alterar atributos. Geralmente, no método __init__, existe uma
declaração inicial do valor dos atributos.
class Pessoa:
def __init__(self, nome, data_de_nascimento, nacionalidade):
self.nome = nome
self.data_de_nascimento = data_de_nascimento
self.nacionalidade = nacionalidade
def idade(self):
hoje = date.today()
return int((hoje - self.data_de_nascimento).days / 365)
UAL © 2021 AED: Requisitos 13 / 38
Orientação a objetos
Utilização de objetos
Para construir um objeto do tipo de uma classe, é necessário invocar o método construtor.
pessoa = Pessoa('Alice', Date(1990, 1, 1), 'PT')
O objeto criado, do tipo Pessoa, encontra-se numa determinada localização de memória. Esssa
localização é retornada pelo método construtor, e pode ficar guardada numa variável (no
exemplo, pessoa). Diz-se que variável guarda um apontador para o objeto.
Para executar um método de um objeto utiliza-se um ponto entre o nome da variável que
guarda o apontador para o objeto, e o nome do método.
idade = pessoa.idade()
UAL © 2021 AED: Requisitos 14 / 38
Orientação a objetos
Herança
É possível definir heranças entre classes. Uma herança representa uma extensão de um tipo de
dados, permitindo expressar construções complexas com facilidade.
A herança é definida com recurso à indicação da classe base entre parêntesis, após o nome da
classe.
class Autor(Pessoa):
def __init__(self, nome, data_de_nascimento, nacionalidade):
Pessoa.__init__(self, nome, data_de_nascimento, nacionalidade)
self.obras = []
def registar_obra(self, obra):
self.obras.append(obra)
UAL © 2021 AED: Requisitos 15 / 38
Orientação a objetos
Herança (2)
class Autor(Pessoa):
def __init__(self, nome, data_de_nascimento, nacionalidade):
Pessoa.__init__(self, nome, data_de_nascimento, nacionalidade)
self.obras = []
def registar_obra(self, obra):
self.obras.append(obra)
Um autor é um objeto do tipo Autor que, por sua vez, é um sub-tipo de Pessoa.
autor = Autor('Tokien', date(1892, 1, 3), 'UK')
autor.registar_obra("LOTR")
Responde a métodos do tipo Autor.
print(autor.obras)
Também responde a métodos do tipo Pessoa.
print(autor.idade())
UAL © 2021 AED: Requisitos 16 / 38
Orientação a objetos
Exceções
Em Python, uma exceção é um tipo de dados definido por uma classe que estende Exception.
class SomeException(Exception):
pass
A exceção pode ser utilizada onde o tipo de dados estiver disponível.
def m():
...
raise SomeException()
Para tratar a exceção:
try:
m()
except SomeException as error:
print('Ocorreu um erro.')
UAL © 2021 AED: Requisitos 17 / 38
Testes unitários
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 18 / 38
Testes unitários
Problema
O código deve ser experimentado. Após a interpretação do problema, planeamento, e
implementação, é sempre necessário assegurar que o programa executa de acordo com a
expectativa.
Com um programa concluído, dependemos da instrumentação de entrada e saída de dados (i.e.,
I/O) para avaliar se este se comporta corretamente.
Faz sentido efetuar testes durante a construçãodo programa mas é importante considerar
que alterações futuras no código podem estragar funcionalidades que já estão corretas, i.e., é
frequente ser necessário alterar código estável para suportar novidades.
É importante aplicar uma estratégia de teste que assegure que uma funcionalidade corretamente
implementada continua correta.
UAL © 2021 AED: Requisitos 19 / 38
Testes unitários
Intuição
Intuitivamente, experimentamos os programa através cenários de teste que demonstrem a
funcionalidade esperada.
Por exemplo:
• Podemos executar o programa, e utilizar a interface disponível;
• Podemos escrever um módulo com o um ponto de entrada (__main__), onde funções e
métodos são executados.
Seja qual for a estratégia, é importante assegurar que o programa continua correto no
que respeita a todos os aspetos testados.
UAL © 2021 AED: Requisitos 20 / 38
Testes unitários
Sistematização
A sistematização dos testes passa por:
• Ser possível descrever um teste de uma funcionalidade;
• O teste deve ser determinístico, i.e., o input do cenário deve produzir sempre o mesmo output
• O teste deve ser o mais simples possível, isolando pequenos incrementos no projeto
• Não conseguimos isolar nada que não esteja numa função ou método
• O teste mais simples possível será, necessariamente, focado numa única função ou método
• As funções ou métodos são as unidades fundamentais de um programa.
• Assegurar que, quando efetuamos um teste a uma nova funcionalidade, efetuamos todos os
testes anteriores também.
Desta forma asseguramos que a nova funcionalidade não interfere com a correção das anteriores.
Procuramos um instrumento que suporte testes unitários.
UAL © 2021 AED: Requisitos 21 / 38
unittest
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 22 / 38
unittest
Plataforma unittest
A plataforma (i.e., biblioteca e executáveis) para testes unitários incluída na distribuição Python
de referência é a unittest.
Foi inspirada pela JUnit em Java, e oferece os mecanismos comuns à maioria das soluções
disponíveis para construir estes testes.
O princípio geral da unittest dita que os testes são métodos de uma classe que estende a
classe TestCase, distribuída pela plataforma.
Os testes devem ser independentes, e cristalizam cenários de utilização das funções e métodos
do projeto.
UAL © 2021 AED: Requisitos 23 / 38
https://docs.python.org/3/library/unittest.html
https://junit.org/junit5/
unittest
Classe unittest.TestCase
A classe TestCase, do módulo unittest representa um contexto de testes. Foi desenhada para ser
estendida, recorrendo ao mecanismo de herança de Python.
Um programa simples tem apenas um contexto de texto, mas com o aumento de complexidade
pode fazer sentido separar os testes em vários contextos. Com orientação a objetos, faz sentido
ter um contexto por cada classe.
A TestCase disponibiliza quatro métodos para configuração (facultativa) dos testes, e um
conjunto de métodos para determinar se o teste foi bem ou mal sucedido.
Para configuração existe setUp(), tearDown(), setUpClass(), e tearDownClass(). Estes métodos
permitem definir código que executa antes ou depois de cada testes, ou do conjunto de testes.
Para determinar o resultado do teste existem vários métodos com o prefixo assert.
UAL © 2021 AED: Requisitos 24 / 38
unittest
Métodos de teste
Um teste corresponde a um método da classe que estende TestCase.
Para o teste ser interpretado corretamente, o nome do método deve começar com a palavra test.
# example.py
import unittest
class Example(unittest.TestCase):
def test_stuff(self):
pass
A classe pode ter vários métodos que começam com test, e podem ser todos executados
automaticamente pela plataforma de testes.
Para executar:
python -m unittest example.py
UAL © 2021 AED: Requisitos 25 / 38
unittest
Ponto de início unittest.main()
Os testes também podem ser executados diretamente, sendo necessário definir o ponto de início
com a invocação de uma função main() do módulo unittest.
# example.py
import unittest
class Example(unittest.TestCase):
def test_stuff(self):
pass
if __name__ == "__main__":
unittest.main()
Para executar:
>python example.py
UAL © 2021 AED: Requisitos 26 / 38
unittest
Métodos assert
Existem vários métodos disponíveis para avaliar testes em TestCase, que passam a estar
disponíveis na nossa classe de testes.
Método Descrição
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) isFalse
assertIs(a, b) a is b
assertIsNone(x) x is None
assertIn(a, b) a in b
assertIsInstance(a, b) isinstance(a, b)
UAL © 2021 AED: Requisitos 27 / 38
Exemplo unittest
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 28 / 38
Exemplo unittest
Problema
Consideramos um programa que calcula a raiz quadrada de um número.
# util.py
def square_root(n):
x = 100000
s = n/x
while x-s >= 0.05:
x = (x+s)/2
s = n/x
return x
if __name__ == "__main__":
print(f"Raiz quadrada de 10: {square_root(10)}")
> python util.py
Raiz quadrada de 10: 3.1638660565937267
Pretendemos construir testes unitários para a função square_root.
UAL © 2021 AED: Requisitos 29 / 38
Exemplo unittest
Testes
# test_util.py
import unittest
from util import square_root
class TestUtil(unittest.TestCase):
def test_square_root(self):
self.assertEqual(round(square_root(10), 2), 3.16)
if __name__ == '__main__':
unittest.main()
> python test_util.py
.
---------------------------------------------------------------------
Ran 1 test in 0.000s
OK
UAL © 2021 AED: Requisitos 30 / 38
Exemplo unittest
Mais funcionalidade ⇒ Mais testes
Pretendemos agora suportar mais uma operação matemática: o maior divisor comum.
Idealmente, começamos por descrever o teste.
# test_util.py
import unittest
from util import square_root
class TestUtil(unittest.TestCase):
...
def test_mdc(self):
a = 12
b = 9
self.assertEqual(mdc(a, b), 3)
UAL © 2021 AED: Requisitos 31 / 38
Exemplo unittest
Falhar o teste em primeiro lugar
> python test_util.py
E.
======================================================================
ERROR: test_mdc (__main__.TestUtil)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_util.py", line 12, in test_mdc
self.assertEqual(mdc(a, b), 3)
NameError: name 'mdc' is not defined
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (errors=1)
Falta importar implementar a função mdc de util, e importar nos testes.
UAL © 2021 AED: Requisitos 32 / 38
Exemplo unittest
Passar o teste depois de falhar
# util.py
...
def mdc(x, y):
c = x - y
while c > 0:
if c > y:
x = c
else:
x = y
y = c
c = x - y
return x
...
> python test_util.py
..
-------------------------
Ran 2 tests in 0.000s
OK
UAL © 2021 AED: Requisitos 33 / 38
Cobertura de testes
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 34 / 38
Cobertura de testes
Problema
Com alguns testes construidos, como determinamos que estes representam realmente todas as
funcionalidades implementadas?
Independentemente da qualidade dos testes escritos, é possível quantificar a porção de código
que está a ser testado pelos vários métodos de teste: basta registar todas as linhas de códigos
ativadas durante a execução do teste.
Essa medida tem o nome de cobertura de código, e é facilmente calculada com recurso ao
módulo coverage.
UAL © 2021 AED: Requisitos 35 / 38
Cobertura de testes
coverage
Este módulo tem que ser instalado no sistema. Para instalar um módulo é necessário recorrer a
ferramentas disponíveis no sistema operativo.
Com Anaconda:
> conda install coverage
Sem Anaconda:
> pip install coverage
Para executar os testes com medição de cobertura:
> coverage run --source=. -m unittest discover
> coveragereport -m
Name Stmts Miss Cover Missing
--------------------------------------------
test_util.py 11 1 91% 15
util.py 19 2 89% 22-23
--------------------------------------------
TOTAL 30 3 90%
> coverage html
UAL © 2021 AED: Requisitos 36 / 38
git
Python
Orientação a objetos
Testes unitários
unittest
Exemplo unittest
Cobertura de testes
git
UAL © 2021 AED: Requisitos 37 / 38
git
git
O sistema de controlo de versões git será outra ferramenta fundamental para a realização dos
laboratórios e projeto.
Os enunciados serão distribuídos através do GitHub Classroom, pelo que será necessário registar
uma conta no GitHub.
Estará disponível, no e-learning, um registo de contas GitHub, necessário para associar cada
número de aluno ao utilizador GitHub respetivo.
UAL © 2021 AED: Requisitos 38 / 38
https://github.com/
	Python
	Orientação a objetos
	Testes unitários
	unittest
	Exemplo unittest
	Cobertura de testes
	git

Continue navegando