Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo,...

36
Programação II Exercícios Universidade de Lisboa Faculdade de Ciências Departamento de Informática Licenciatura em Tecnologias da Informação 2014/2015 1 Exceções e Tratamento de Ficheiros Nota prévia. O tratamento de ficheiros é uma área onde frequentemente ocorrem exceções. Todos os exercícios nesta secção devem estar preparados com o tratamento adequado das exceções derivadas da abertura de ficheiros, nomeadamente através da utilização da instrução try: except: finally: ou da instrução with. 1. Escreva uma função média que dada uma lista de strings, cada uma representando um número, devolva a sua média, um número em vírgula flutuante. 2. Dados referentes a observações são frequentemente guardados em ficheiros de texto. Por exemplo, as temperaturas lidas a várias horas do dia, ao longo de vários dias, podem ser guardadas num ficheiro de números em vírgula flutuante, onde cada linha contém os valores das várias temperaturas medidas num dia. 5.6 7.8 11.7 12.6 9.3 7.3 6.7 8.5 11.6 11.6 9.4 7.0 5.4 7.2 10.5 11.1 10.0 8.3 Utilizando a função media, escreva uma função médias que, dado o nome de um ficheiro de texto como o acima, imprima as temperaturas médias diárias. Deverá imprimir um valor por linha e tantos valores quantas as linhas do ficheiro. Sugestão: utilize o método string.split(s) para obter a lista de palavras existentes numa string. A função media deve apanhar a exceções referentes à utilização do ficheiro. Para isso utilize um try: finally: ou um with, para se assegurar

Transcript of Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo,...

Page 1: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

Programação II

Exercícios

Universidade de LisboaFaculdade de Ciências

Departamento de InformáticaLicenciatura em Tecnologias da Informação

2014/2015

1 Exceções e Tratamento de Ficheiros

Nota prévia. O tratamento de ficheiros é uma área onde frequentementeocorrem exceções. Todos os exercícios nesta secção devem estar preparadoscom o tratamento adequado das exceções derivadas da abertura de ficheiros,nomeadamente através da utilização da instrução try: except: finally: ou dainstrução with.

1. Escreva uma função média que dada uma lista de strings, cada umarepresentando um número, devolva a sua média, um número emvírgula flutuante.

2. Dados referentes a observações são frequentemente guardados emficheiros de texto. Por exemplo, as temperaturas lidas a várias horas dodia, ao longo de vários dias, podem ser guardadas num ficheiro denúmeros em vírgula flutuante, onde cada linha contém os valores dasvárias temperaturas medidas num dia.

5.6 7.8 11.7 12.6 9.3 7.36.7 8.5 11.6 11.6 9.4 7.05.4 7.2 10.5 11.1 10.0 8.3

Utilizando a função media, escreva uma função médias que, dado o nomede um ficheiro de texto como o acima, imprima as temperaturas médiasdiárias. Deverá imprimir um valor por linha e tantos valores quantas aslinhas do ficheiro. Sugestão: utilize o método string.split(s) para obter alista de palavras existentes numa string.

A função media deve apanhar a exceções referentes à utilização doficheiro. Para isso utilize um try: finally: ou um with, para se assegurar

Page 2: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

que fecha o ficheiro. Exceções sobre a abertura do ficheiro deverão sertratadas pelo chamador (ver exercício seguinte).

3. Escreva uma função principal sem parâmetros que pede ao utilizador onome dum ficheiro de temperaturas, e chama a função medias passandoo nome do ficheiro. Caso ocorra algum problema de acesso ao ficheiro, afunção principal deve escrever Erro de I/O ao ler o ficheiro<nome do ficheiro>.

4. Por vezes os ficheiros de observações trazem um cabeçalho cominformação sobre os dados. Para este exercício vamos supor que cadalinha no cabeçalho começa com o carater cardinal, #. O cabeçalho écomposto por um número indeterminado de linhas, possivelmente zero.Eis um exemplo:

# Localização: Observatório de Muge# Datas: 1 a 3 de fevereiro de 20155.6 7.8 11.7 12.6 9.3 7.36.7 8.5 11.6 11.6 9.4 7.05.4 7.2 10.5 11.1 10.0 8.3

Escreva uma função salta_cabeçalho que, dado um ficheiro aberto paraleitura, devolva a primeira linha que não é cabeçalho.

5. Usando a função salta_cabeçalho, altere a função do exercício 9, de modoa utilizar um ficheiro com cabeçalhos. Apelide-a demedias_salta_cabecalho.

6. Escreva uma função lista_para_ficheiro que, dada uma lista e o nome deum ficheiro, escreve os vários elementos da lista, um por linha, noficheiro.

7. Usando a função lista_para_ficheiro, altere a função do exercício 9, demodo a escrever as médias num dado ficheiro. A função médias devereceber duas strings com os nomes dos dois ficheiros envolvidos.

8. Informação referente a símbolos químicos pode ser guardada emficheiros de texto. Neste caso estamos interessados apenas no nome,número atómico e densidade (em g/dm3). Eis um exemplo:

Hélio 2 0.1786Néon 10 0.9002Argon 18 1.7818Cripton 36 3.708Xenon 54 5.851Radônio 86 9.97

2

Page 3: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

Escreva uma função linha_para_elemento que dada uma linha de umficheiro de elementos (uma string), produz um dicionário com chaves'nome', 'atomico' e 'densidade'. O nome é do tipo string, o número atómicodo tipo int e a densidade do tipo float.

9. Utilizando a função linha_para_elemento, escreva uma outra função quedada uma string representando o nome de um ficheiro, produz umalista de dicionários com chaves 'nome', 'atomico' e 'densidade'. Chame-lheler_elementos.

10. Escreva a função inversa de linha_para_elemento, isto é, uma função quedado um dicionário representando um elemento, devolve uma stringcom o nome, número atómico e densidade, separados por espaços. Astring termina com uma mudança de linha. Apelide a função deelemento_para_string.

11. Utilizando a função elemento_para_string, escreva uma funçãoescrever_elementos que, dada uma lista de dicionários representandoelementos químicos e o nome de um ficheiro, escreve o conteúdo da listano ficheiro.

12. O arranjo de átomos em moléculas pode ser descrito em formato textual,e portanto guardado em ficheiros. Cada molécula é descrita por umnúmero variável de linhas: a primeira contém o nome da molécula, assubsequentes contêm informação sobre o átomo. A última linha, END,fecha a molécula. Cada átomo é composto pelo seu identificador,símbolo químico, e as coordenadas tri-dimensionais. Eis o exemplo deum ficheiro contendo duas moléculas.1

COMPND AMMONIAATOM 1 N 0.257 -0.363 0.000ATOM 2 H 0.257 0.727 0.000ATOM 3 H 0.771 -0.727 0.890ATOM 4 H 0.771 -0.727 -0.890ENDCOMPND METHANOLATOM 1 C -0.748 -0.015 0.024ATOM 2 O 0.558 0.420 -0.278ATOM 3 H -1.293 -0.202 -0.901ATOM 4 H -1.263 0.754 0.600ATOM 5 H -0.699 -0.934 0.609ATOM 6 H 0.716 1.404 0.137END

1Exercício retirado de “Practical Programming: An Introduction to Computer Science UsingPython 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013.

3

Page 4: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

Escreva uma função linha_para_atomo que, dada uma string contendouma linha ATOM, devolve um dicionário com chaves 'símbolo', 'id', 'x', 'y', e'z'.

13. Escreva uma função ler_atomos que, dado um leitor (isto é um ficheiroaberto para leitura), devolve uma lista de átomos. Assuma que o leitorestá posicionado numa linha que começa com ATOM. A função deverádeixar o leitor posicionado na primeira linha que não começa com ATOM,o que, no caso do ficheiro acima deverá ocorrer numa linha END. Não sepretende ler o ficheiro até ao fim, mas apenas até ao fim da molécula.

14. Utilizando a função ler_atomos, escreva uma função ler_molecula que,dado um leitor, devolve ou uma molécula ou None. Assuma que o leitorestá no fim do ficheiro (caso em devolve None) ou está posicionadonuma linha que começa com COMPND (caso em devolve a molécula).Cada molécula é representada por um dicionário com duaschaves—'molécula', e 'átomos'—representando o nome da molécula e alista de átomos que a compõem, respetivamente.

15. Utilizando a função ler_molecula, escreva uma função ler_moleculas que,dado um leitor, devolve uma lista de moléculas.

16. Finalmente, utilizando a função ler_moleculas escreva uma funçãoler_ficheiro que dado uma string representando o nome de um ficheiro,devolve uma lista de moléculas. Não se esqueça de fechar o ficheiro eapanhar as exceções.

2 Testes Unitários Baseados em Especificação

Notas prévias. Os alunos devem também fazer, em regime de trabalhoautónomo, os exercícios da folha 9 da disciplina Programação I, 2014–2015.Para testar os nossos programas vamos utilizar o módulo doctest. Consulte adocumentaçãoù.

Testes baseados em especificação Utilizando o método de geração de testesbaseado na especificação, para cada função vamos escrever os seguintes testes.

• Para cada parâmetro numérico x, escolhemos um teste com x igual azero, um teste com x negativo e um teste com x positivo.

• Se a especificação falar de algum valor n em especial, então escolhemosum teste com x = n, outro com x < n e outro com x > n.

• Se a especificação atribuir limites para x, então escolhemos um teste comx junto ao limite superior, outro junto ao limite inferior, e outro alguresno “meio”.

4

Page 5: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

• Para cada lista l procedemos de modo semelhante: um teste para a listavazia, outro para uma lista não vazia.

• Para cada dicionário d fazemos como para as listas.

• Para cada resultado possível da função, procedemos como se de umparâmetro se tratasse.

• Tomamos em consideração o nosso conhecimento do domínio.

• Tomamos também em consideração outras condições constantes naespecificação.

• Para uma função com um parâmetro, fazemos o “produto” dos testes(testes cruzados) para o parâmetro e para o resultado. Para funções comdois ou mais parâmetros, fazemos o “produto” dos testes dos váriosparâmetros e do resultado.

• Finalmente, da lista de testes acima retiramos os testes inviáveis (porexemplo: x ocorre na lista e a lista é vazia).

1. Considere as duas funções abaixo.2

def encontraUltimo (v, x):"""O índice do último elemento numa lista que é igual a um dado elemento.

Requires: v é uma listaEnsures: devolve o índice do último elemento em v que é igual a x.Se x não ocorrer em v, devolve None.

>>> encontraUltimo (['b', 'c', 'e'], 'b')0"""for i in range(len(v)−1, 0, −1):

if v[i] == x:return i

return None

def contaPositivos (v):"""O número de elementos positivos em v

Requires: v é uma lista de númerosEnsures: Devolve o número de valores positivos em v>>> contaPositivos ([−4, 2, 0, 2])2"""

2Exercício adaptado de “Introduction to Software Testing”, Paul Ammann and Jeff Offutt, Cam-bridge University Press, 2008.

5

Page 6: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

conta = 0for x in v:

if x >= 0:conta = conta + 1

return conta

Para cada um dos programas:

(a) Encontre a falha (o defeito).

(b) Se possível encontre um teste que não execute a falha.

(c) Repare a falha.

2. Para a função encontraUltimo, e utilizando a técnica baseada naespecificação, escreva testes para os seguintes casos. Utilize diferentestipos de dados (por exemplo, números inteiros, valores lógicos e cadeiasde carateres).

(a) A lista é vazia;

(b) A lista não é vazia e o elemento não se encontra na lista;

(c) O elemento encontra-se na primeira posição da lista;

(d) O elemento encontra-se na última posição da lista;

(e) O elemento encontra-se numa posição não extrema (nem primeira,nem última) da lista;

(f) O elemento encontra-se mais do que uma vez na lista.

(g) Outros que achar relevantes.

3. Para a função contaPositivos, e utilizando a técnica baseada na especificação,escreva os testes que achar convenientes. Explique a razão de ser decada um dos testes.

4. Considere a seguinte especificação da função unicos.

A função recebe uma lista e devolve uma outra contendoexactamente uma cópia de cada elemento da lista original. Alista original está ordenada; a lista resultado deverá estartambém ordenada. A lista original não deve ser alterada.

Utilizando a técnica baseada na especificação, escreva testes para osseguintes casos. Em todos os casos verifique que a lista original não éalterada.

(a) Lista vazia

(b) Lista com um elemento

(c) Lista com dois ou mais elementos não repetidos

(d) Lista com dois elementos repetidos contíguos

6

Page 7: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

(e) Lista com três ou mais elementos repetidos

(f) Lista com elementos repetidos na cabeça (início) da lista

(g) Lista com elementos repetidos na cauda (fim) da lista

5. Para a seguinte função, escreva testes baseados na especificação.

def diferenca(l1, l2):"""Requires: l1 é uma listaRequires: l2 é uma listaEnsures: devolve uma lista que contem os elementos de l1 que nãoestão em l2. As listas l1 e l2 não são alteradas."""

O que é que os testes, quando executados, permitem concluir sobre acorreção da função?

6. Escreva testes baseados na especificação para a seguinte função.

def produto_matrizes (a, b, c):"""Coloca em a o produto de duas matrizes b e cRequires: linhas de a == linhas b; colunas de a = colunas de c;colunas de b = linhas cRequires: a não é a matriz b nem a matriz c(isto é 'not a is b and not a is c')"""

3 Testes Unitários Baseados no Fluxo de Controle

Notas prévias. Os alunos devem também fazer, em regime de trabalhoautónomo, os exercícios da folha 9 da disciplina Programação I, 2014–2015.Para testar os nossos programas vamos utilizar o módulo doctest. Consulte adocumentaçãoù.

Grafo de controlo de fluxo Para utilizar o método de geração de testesbaseado no fluxo de controle, temos de primeiro desenhar o grafo de controlo defluxo do programa.3 Um grafo de controlo de fluxo associa um arco a cadaramo de um programa, e um nó a uma sequência de instruções. Um blocobásico é a maior sequência de instruções tal que, se uma das instruções dobloco for executada, então todas as instruções no bloco são executadas. Umbloco básico tem um único ponto de entrada e um único ponto de saída. Acada bloco básico corresponde um único nó no grafo. Caso de um condicional:

3Texto e diagramas adaptados de “Introduction to Software Testing”, Paul Ammann and JeffOffutt, Cambridge University Press, 2008.

7

Page 8: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

if x < y:y = 0x = x +1

else:x = y

introtest CUUS047-Ammann ISBN 9780521880381 November 8, 2007 17:13 Char Count= 0

52 Coverage Criteria

if (x < y){ y = 0; x = x + 1;}else{ x = y;}

n0

n1 n2

n3

y = 0x = x+1

x < y x > y

x = y

Figure 2.16. CFG fragment for the if-elsestructure.

(Direct tours only.) Use the given test paths.(f) List a minimal test set that satisfies all-du-paths coverage with respect to

x. (Direct tours only.) Use the given test paths.

2.3 GRAPH COVERAGE FOR SOURCE CODE

Most of the graph coverage criteria were developed for source code, and these def-initions match the definitions in Section 2.2 very closely. As in Section 2.2, we firstconsider structural coverage criteria and then data flow criteria.

2.3.1 Structural Graph Coverage for Source Code

The most widely used graph coverage criteria are defined on source code. Althoughprecise details vary from one programming language to another, the basic pattern isthe same for most common languages. To apply one of the graph criteria, the firststep is to define the graph, and for source code, the most common graph is called acontrol flow graph (CFG). Control flow graphs associate an edge with each possiblebranch in the program, and a node with sequences of statements. Formally, a basicblock is a maximum sequence of program statements such that if any one statementof the block is executed, all statements in the block are executed. A basic block hasonly one entry point and one exit point. Our first example language structure is anif statement with an else clause, shown as Java code followed by the correspondingCFG in Figure 2.16. The if-else structure results in two basic blocks.

Note that the two statements in the then part of the if statement both appearin the same node. Node n0, which represents the conditional test x < y has morethan one out-edge, and is called a decision node. Node n3, which has more than onein-edge, is called a junction node.

Next we turn to the degenerate case of an if statement without an else clause,shown in Figure 2.17. This is the same graph previously seen in Figure 2.6, but thistime based on actual program statements.

Note that the control flow graph for this structure has only three nodes. Thereader should note that a test with x < y traverses all of the nodes in this controlflow graph, but not all of the edges.

Representing loops is a little tricky because we have to include nodes that arenot directly derived from program statements. The simplest kind of loop is a whileloop with an initializing statement, as shown in Figure 2.18. (Assume that y has a

Uma estrutura condicional resulta em dois blocos básicos. O grafo inclui doisnós para os blocos básicos: um para o ramo “então” outro para o ramo“senão”. Além disso, contém um nó para a decisão e outro para o fim deprograma. De notar que:

• As duas instruções do ramo then aparecem no mesmo nó (um só blocobásico);

• Do nó do teste x<y saiem dois arcos. Este nó, chamado de decisão, nãocorresponde a nenhuma instrução no programa;

• O último nó, chamado de junção, também não corresponde a nenhumainstrução do programa.

Caso degenerado de um condicional sem ramo else:

if x < y:y = 0x = x +1

introtest CUUS047-Ammann ISBN 9780521880381 November 8, 2007 17:13 Char Count= 0

Graph Coverage 53

if ( x < y ){ y = 0; x = x + 1;}

n0

n1

n2

y = 0x = x+1

x < y

x > y

Figure 2.17. CFG fragment for the ifstructure without an else.

value defined at this point in the program.)The graph for the while structure has a decision node, which is needed for the

conditional test, and a single node for the body of the while loop. Node n1 is some-times called a “dummy node,” because it does not represent any statements, butgives the iteration edge (n2, n1) somewhere to go. Node n1 can also be thought of asrepresenting a decision. A common mistake for beginners is to try to have the edgego to n0; this is not correct because that would mean the initialization step is doneeach iteration of the loop. Note that the method call f(x,y) is not expanded in thisparticular graph; we return to this issue later.

Now, consider a for loop that is equivalent to the prior while loop. The graphbecomes a little more complicated, as shown in Figure 2.19, essentially because thefor structure is at a very high level of abstraction.

Although the initialization, test, and increment of the loop control variable x areall on the same line in the program, they need to be associated with different nodesin the graph. The control flow graph for the for loop is slightly different from thatof the while loop. Specifically, we show the increment of x in a different node thanthe method call y = f(x,y). Technically speaking, this violates the definition of a ba-sic block and the two nodes should be combined, but it is often easier to developtemplates for the various possible program structures and then plug the controlflow graph for the relevant code into the correct spot in the template. Commer-cial tools typically do this to make the graph generation simpler. In fact, commercialtools often do not follow the strict definition of the basic block and sometimes addseemingly random nodes. This can have trivial effects on the bookkeeping (for ex-

x = 0;while (x < y){ y = f (x, y); x = x+1;}

n1

n3n2

n0

x > y

x = 0

x < y

y = f (x, y)x = x + 1

Figure 2.18. CFG fragment for the while loopstructure.

Caso de um ciclo while:

x = 0while x < y:

y = f(x,y)x = x + 1

introtest CUUS047-Ammann ISBN 9780521880381 November 8, 2007 17:13 Char Count= 0

Graph Coverage 53

if ( x < y ){ y = 0; x = x + 1;}

n0

n1

n2

y = 0x = x+1

x < y

x > y

Figure 2.17. CFG fragment for the ifstructure without an else.

value defined at this point in the program.)The graph for the while structure has a decision node, which is needed for the

conditional test, and a single node for the body of the while loop. Node n1 is some-times called a “dummy node,” because it does not represent any statements, butgives the iteration edge (n2, n1) somewhere to go. Node n1 can also be thought of asrepresenting a decision. A common mistake for beginners is to try to have the edgego to n0; this is not correct because that would mean the initialization step is doneeach iteration of the loop. Note that the method call f(x,y) is not expanded in thisparticular graph; we return to this issue later.

Now, consider a for loop that is equivalent to the prior while loop. The graphbecomes a little more complicated, as shown in Figure 2.19, essentially because thefor structure is at a very high level of abstraction.

Although the initialization, test, and increment of the loop control variable x areall on the same line in the program, they need to be associated with different nodesin the graph. The control flow graph for the for loop is slightly different from thatof the while loop. Specifically, we show the increment of x in a different node thanthe method call y = f(x,y). Technically speaking, this violates the definition of a ba-sic block and the two nodes should be combined, but it is often easier to developtemplates for the various possible program structures and then plug the controlflow graph for the relevant code into the correct spot in the template. Commer-cial tools typically do this to make the graph generation simpler. In fact, commercialtools often do not follow the strict definition of the basic block and sometimes addseemingly random nodes. This can have trivial effects on the bookkeeping (for ex-

x = 0;while (x < y){ y = f (x, y); x = x+1;}

n1

n3n2

n0

x > y

x = 0

x < y

y = f (x, y)x = x + 1

Figure 2.18. CFG fragment for the while loopstructure.

De notar, novamente, que o nó n1 não corresponde a nenhuma instrução doprograma, funcionando apenas como um nó onde é feito o teste e ondetermina cada iteração do ciclo.E se estivermos em presença de um ciclo for? Neste caso procedemos como seem presença de um ciclo while estivéssemos: do nó do teste (sem etiqueta)

8

Page 9: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

saiem dois arcos (um com o teste, o outro com a negação do teste).

x = 0for y in v:

x += y

Testes baseados no fluxo de controle Utilizando o método de geração detestes baseado no fluxo de controle, para cada função vamos escrever osseguintes testes.

• Testes que exercitem ambos os ramos de cada instrução condicional (if);

• Testes que exercitem cada clausula except;

• Para cada ciclo for, testes onde:

– O ciclo não é executado nenhuma vez;

– O corpo do ciclo é executado exatamente uma vez;

– O corpo do ciclo é executado mais do que uma vez;

• Para cada ciclo while, testes que:

– Considerem os três casos descritos para ciclos for;

– Considerem todas as formas possíveis de sair do ciclo. Porexemplo, para um ciclo da forma

while len(l) > 0 and not l[i] == e:

incluir testes em que o ciclo termina pelo facto de len(l) ser menorou igual a 0 ou pelo facto que l[i] ser diferente de e.

1. Para a função encontraUltimo (listada no exercício 1 da semana 2) e baseadono fluxo de controle escreva um teste para cada um dos casos seguintes.

(a) Não entra no ciclo;

(b) Entra no ciclo exactamente uma vez e passa no ramo then (isto é oteste v[i] == x é verdadeiro)

(c) Entra no ciclo exactamente uma vez e passa no ramo else (isto é oteste v[i] == x é falso)

(d) Entra no ciclo mais do que uma vez, passando sempre pelo else;

(e) Entra no ciclo mais do que uma vez, passando umas vezes por thene outras por else;

(f) Consegue escrever um teste que passe mais do que uma vez porthen? Ou estaremos em face de um teste inviável?

9

Page 10: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

2. Considere a função contaPositivos (listada no exercício 1 da semana 2).

(a) Desenhe o diagrama de fluxo da execução da função.

(b) Escreva testes de acordo com as regras do método de análise dofluxo do programa.

3. Para a função abaixo, escreva testes baseados no fluxo de programa.Comece por desenhar o diagrama de fluxo da execução da função.

def diferenca(l1, l2):resultado = l1i=0while i < len(l1):

if l1[i] in l2:resultado.remove(l1[i])

i += 1return resultado

Ao executar os testes, o que pode concluir sobre a correção da função?Consegue escrever algum teste que falhe?

4. Dada a seguinte implementação da função unicos, desenhe o grafo defluxo e seguidamente uma bateria de testes baseados no fluxo de controlodo programa.

def unicos(lista):resultado = []i = 0while i < len(lista):

elemento = lista[i]i = i + 1resultado.append(elemento)while i < len(lista) and elemento == lista[i]:

i = i + 1return resultado

5. Para a seguinte função, escreva testes baseados no fluxo do programa.Comece por desenhar o diagrama de fluxo da execução da função.

def principal (nome_ficheiro):try:

medias (nome_ficheiro)except IOError:

print "Erro de I/O ao ler o ficheiro", nome_ficheiro

6. Escreva testes baseados no fluxo de controlo para a seguinte função.

def busca(lista, elemento):"""Devolve True se o elemento está na lista, e False caso contrário.Requires lista é uma lista"""

10

Page 11: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

encontrado = Falsei=0while i < len(lista) and not encontrado:

encontrado = lista[i] == elementoi += 1

return encontrado

7. Escreva testes baseados no fluxo de controlo para a seguinte função.

def produto_matrizes (a, b, c):"""Coloca em a o produto de duas matrizes b e cRequires: linhas de a == linhas b; colunas de a = colunas de c;colunas de b = linhas c"""for i in range (len(b)):

for j in range (len(c[0])):a[i][j] = 0for k in range (len(c)):

a[i][j] += b[i][k] * c[k][j]

4 Complexidade Algorítmica

1. Apresente uma caracterização O do tempo de execução de cada funçãoabaixo. Indique em cada caso o significado de n.

def par (x):return x % 2 == 0

def absoluto (x):return x if x>0 else 0

def max3 (x, y, z):return max(x, max(y, z))

def max (x, y):return x if x>y else y

2. Apresente uma caracterização O do tempo de execução de cada funçãoabaixo. Indique em cada caso o significado de n.

def a (n):m = 0for i in range(1, 10*n):

for j in range (1, n):m += 1

return m

def b (n):soma = 0for a in range (0, 2004):

11

Page 12: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

soma += a*nreturn soma

def c (n):b = n * nwhile b > n:

if b % 2 == 0:b −= 1

else:b −= 2;

return b

def d (n, v):soma = 0for i in range(0, n):

for j in range (1, 4):soma += v[i]

return soma

def e (n):x = n * n * n;while x > 1:

x /= 2;

def f (n):soma = n * nwhile soma % 2 == 0:

soma −= 1return soma

def g (a, b, c):for i in range (len(b)):

for j in range (len(c[0])):a[i][j] = 0for k in range (len(c)):

a[i][j] += b[i][k] * c[k][j]

def h (n):c = 0for i in range (0, n):

for j in range (i, n):c += 1

return c

3. Analise a complexidade computacional da função diferenca, exercício 3da semana 3.

4. Analise o O-grande da função unicos, exercício 4 da semana 3.

5. Analise o tempo de execução da função busca, exercício 6 da semana 3.

12

Page 13: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

6. Considere o seguinte algoritmo para o cálculo das médias dos prefixosde um vector. Verifique que o algoritmo dado tem um tempo deexecução quadrático e apresente uma solução com tempo linear.

def mediaPrefixos (l):""""Requires: uma lista de númerosEnsures: devolve uma lista m onde m[i] é a média

dos elementos l[0] ,... ,l[i−1]"""m = []for i in range(0, len(l)):

soma = 0.0for j in range(0, i+1):

soma += l[j]m.append(soma/(i +1))

return m

7. As funções semRepetidos e semRepetidos2 verificam se uma lista não temrepetidos.

def semRepetidos1 (l):for i in range (len(l)):

if l[i] in l[(i+1):]:return False

return True

def semRepetidos2 (l):copia = list(l)copia.sort()for i in range (len(l) − 1):

if copia[i] == copia[i+1]:return False

return True

(a) Analise a complexidade assintótica de cada uma das soluções.

(b) Proponha uma solução linear. Sugestão: converta a lista numconjunto.

5 Algoritmos de Pesquisa e de Ordenação

1. Escreva uma versão iterativa da seguinte função. Analise a suacomplexidade computacional.

def buscaBinaria (l,e):"""Requires: l é uma lista e está ordenada por ordem crescenteEnsures: Devolve True se e ocorre em l, e False caso contrário"""

13

Page 14: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

def buscaBin (l, e, baixo, alto):"""Requires: l é uma lista e está ordenada por ordem crescenteEnsures: Devolve True se e ocorre em l entre os índices baixo e alto,e False caso contrário"""

if alto < baixo:return False

meio = (baixo + alto) // 2if l[meio] > e:

return buscaBin (l, e, baixo, meio − 1)elif l[meio] < e:

return buscaBin (l, e, meio + 1, alto)else:

return Truereturn buscaBin (l, e, 0 , len(l) − 1)

2. Analise a complexidade computacional das seguintes funções:

• No pior caso;

• No melhor caso.

Identifique cada um dos casos.

(a) Ordenação por inserção (insertion sort).

def ordenacaoPorInsercao(lista):"""Ordena a lista por ordem ascendente.Requires: lista é uma lista de elementos comparáveis entre si"""for i in range(1, len(lista)):

valorCorrente = lista[i]posicao = iwhile posicao > 0 and lista[posicao − 1] > valorCorrente:

lista[posicao] = lista[posicao − 1]posicao = posicao − 1

lista[posicao] = valorCorrente

(b) Ordenação por flutuação (bubble sort). Barack Obama - ComputerScience Questionù

def ordenacaoPorFlutuacao(lista):"""Ordena a lista por ordem ascendente.Requires: lista é uma lista de elementos comparáveis entre si"""for comeco in range(len(lista) −1 , 0 ,−1):

for i in range(comeco):if lista[i] > lista[i+1]:

lista[i+1], lista[i] = lista[i], lista[i+1]

14

Page 15: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

(c) Ordenacao por seleção (selection sort).

def ordenacaoPorSelecao(lista):"""Ordena a lista por ordem ascendente.Requires: lista é uma lista de elementos comparáveis entre si"""for comeco in range(len(lista)):

for i in range(comeco+1, len(lista)):if lista[i] < lista[comeco]:

lista[comeco], lista[i] = lista[i], lista[comeco]

3. Considere a ordenação por flutuação (exercício 2 acima).

(a) Qual o tempo de execução quando a lista estiver ordenada?

(b) Adapte o algoritmo de modo a torná-lo linear neste caso.

4. Quicksort, desenvolvido por Sir Tony Hoareù, 1960, apoia-se numaestratégia de dividir e conquistar em que uma sequência inicial S édividida em várias sub-sequências às quais o algoritmo é aplicadorecursivamente. O resultado é posteriormente concatenado obtendo-seuma sequência ordenada. Tipicamente o QuickSort pode ser dividido emtrês passos:

Dividir Se S tem pelo menos dois elementos (se tem zero ou um asequência está ordenada), selecionar um elemento de S que passa aser o pivot. Retirar todos os elementos de S construindo asseguintes duas sequências:

B (baixo) contendo todos os elementos inferiores ou iguais ao pivot;A (alto) contendo todos os elementos superiores ao pivot;

Conquistar Aplicar recursivamente o algoritmo às sequências B e A.

Combinar Concatenar B, pivot, A, por esta ordem para obter oresultado.

(a) Discuta a complexidade computational do algoritmo no melhor eno pior caso.

(b) Qual o tempo de execução quando todos os elementos da lista sãoiguais?

(c) Qual o tempo de execução quando a lista estiver ordenada?

(d) Implemente o algoritmo na linguagem Python.

5. Counting sort, ou bucket sort, apoia-se no pressuposto que o número dechaves (elementos) a ordenar é conhecido e pode ser usado como índicede uma sequência de baldes (buckets). Eis o algoritmo:

• Seja S uma sequência de elementos com chaves no intervalo[0, N − 1].

15

Page 16: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

• Seja B uma sequência (lista) de N baldes inicialmente vazios.

• Para cada elemento e de S:

– seja k a chave de e;– retirar e de S;– adicionar S ao balde B[k].

• Para cada i entre 0 e N − 1:

– Para cada elemento e de B[i]:

* remover e de B[i];

* adicionar e no final de S.

• Devolver S.

(a) Implemente o algoritmo na linguagem Python.

(b) Discuta a complexidade computational do algoritmo. Se chegar auma solução sub O(n · log n) explique porque é que esta nãocontradiz o resultado que estabelece O(n · log n) como limiteinferior para qualquer algoritmo de ordenação baseado emcomparação.

6 Funções de Ordem Superior

1. Qual o valor de cada expressão?

(a) map (lambda x:x+1, range(1,4))

(b) map (lambda x:x>0, [3,−5,−2,0])

(c) filter (lambda x:x>5, range(1,7))

(d) filter (lambda x:x%2==0, range(1,11))

(e) filter (lambda x:x>0,map (lambda y:y**2, range(−3,4)))

(f) map (lambda x:x**2, filter (lambda x:x>0, range(−3,4)))

(g) map (lambda x:x+'s', ["A", "arte", "do", "aluno"])

(h) map (lambda x:'s'+x, ["O", "aluno","bem−comportado"])

(i) map (lambda x: map (lambda y:y*y, x), [[1,2],[3,4,5]])

2. Defina uma função produtoInterno que calcule o produto escalar Σn1xi · yi

de dois vetores ~x e ~y. Os vetores são dados por listas de números.Resolva o problema utilizando apenas funções da linguagem Python.Sugestão: utilize a função zip.

3. Determine o valor de cada uma das expressões seguintes.

(a) reduce (lambda y, z: y*3+z, range(1,5))

(b) reduce (lambda x, y: x+y if x>0 else y, [4,−3,2,−1])

16

Page 17: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

(c) reduce (lambda x, y: x**2+y, range(2,6))

(d) reduce (operator.mul, range(−3,0,−1), 1)

(e) reduce(operator.sub, [1,2,3])

(f) reduce(operator.sub, [1,2,3], 10)

4. Escreva um conversor binário para decimal utilizando a função reduce.O número binário é apresentado por uma lista de inteiros. Por exemplo:

>>> binarioParaDecimal([1,1,0,1])13>>> binarioParaDecimal([])0

5. Utilizando a função map, escreva uma função gz que transforme umamatriz (lista de listas) de inteiros numa matriz de valores lógicos, ondecada entrada indica se o valor inicial é ou não maior do que zero. Porexemplo:

>>> gz( [[1,2,3], [2,−1,3,7]])[[True,True,True], [True,False,True,True]]

6. Defina uma função mapaSeletivo que devolve uma lista contendo osresultados de aplicar a função dada no primeiro argumento aoselementos da lista dada no terceiro argumento, que satisfaçam acondição dada no segundo argumento. Exemplo:

>>> mapaSeletivo (lambda x:x*3, lambda y:y>0, range(−4,5))[3, 6, 9, 12]

7. Escreva a função filter recorrendo às funções map e reduce. Sugestão:para o predicado lambda x: x>0 e a lista [2,0,−3,4] comece por calcular alista [[2],[],[],[4]]. Concatene depois as listas todas para obter [2,4].

8. Escreva a função filter recorrendo apenas à função reduce.

9. Escreva a função map recorrendo apenas à função reduce.

10. Dado um par de listas, a função zip devolve uma lista de pares. Oi-ésimo par é composto pelo i-ésimo elemento da primeira lista e peloi-ésimo da segunda lista. A lista resultante contém tantos elementosquantos os da mais curta das duas listas parâmetro. Escreva uma funçãozipWith, variante da função zip, que receba uma função que combine osdois elementos.

def zipWith (f, l1, l2):""">>> zipWith(lambda x, y:x, [], [1,2])[]>>> zipWith(lambda x,y :x, ['a'], [])

17

Page 18: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

[]>>> zipWith(lambda x, y:(x,y), ['a','b'], [2,3,4])[('a', 2), ('b', 3)]>>> zipWith(max, [5,2,0,9], [2,3,4])[5, 3, 4]"""

Escreva a função zip recorrendo à função zipWith.

7 Gráficos de funções com pylab

1. Vamos chamar gráfico a um par de listas de números com o mesmocomprimento. A primeira lista deve estar ordenada por ordem crescentee denota as abcissas, a segunda as ordenadas. Eis o gráfico da funçãoquadrática tomada nos números inteiros entre 0 e 5:

([0, 1, 2, 3, 4, 5], [0, 1, 4, 9, 16, 25])

Procuramos uma função grafico que, dada uma função de números emnúmeros, devolve o seu gráfico. A função grafico recebe quatroparâmetros, três dos quais opcionais. São eles: a função, a primeiraabcissa baixo=0.0, a última abcissa alto=10.0, e o incremento entreabcissas incremento=1.0. Exemplo:

>>> grafico (lambda x: 2*x, alto = 5.0, incremento=1.7)([0, 1.7, 3.4], [0, 3.4, 6.8])

2. Escreva uma função tracarGrafico que trace o gráfico de uma função. Afunção deve receber um gráfico (um par de listas, ver exercício acima) etrês parâmetros opcionais, a saber: etiquetax='x', etiquetay='f(x)',titulo='grafico da funcao f'. Consulte o manual do Pylabù, secção Beginner’sGuide para descobrir as funções apropriadas.

Eis o aspeto da função n · log(n), gerado pelo código abaixo.

>>> import math>>> g = grafico(lambda n: n*math.log(n), baixo=1, alto=10000)>>> tracarGrafico(g, etiquetax='n', etiquetay='n*log(n)', titulo=u'Gráfico da

função log−linear')

Sugestão: Para transformar um par em dois argumentos separados, demodo a passá-los para uma função, utilize o operador de desempacotarargumentos (e.g., *tuplo e *lista), Unpacking Argument Listsù.

18

Page 19: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

3. Escreva uma função tracarGraficos que trace conjuntamente os gráficosde um número variável de funções. A função recebe como únicoparâmetro a lista dos vários gráficos (cada gráfico é um par de listas, verexercício 1). Utilize uma função de ordem superior para iterar sobre osgráficos na lista.

Por exemplo:

>>> baixo = 0.1>>> alto = 100>>> linear = grafico (lambda n: n, baixo=baixo, alto=alto)>>> loglinear = grafico (lambda n: n*math.log(n), baixo=baixo, alto=alto)>>> quadratico = grafico (lambda n: n**2, baixo=baixo, alto=alto)>>> tracarGraficos ([linear, loglinear, quadratico])

deverá produzir um gráfico deste tipo:

19

Page 20: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

4. Escreva uma função potencias que devolva gráficos (pares de listas) paraas várias potências de um número. Dado um número k, a função deverádevolver uma lista com k + 1 gráficos correspondentes às funçõesx0, x1, x2, . . . , xk. Para além deste parâmetro (que é obrigatório), afunção deverá receber três parâmetros opcionais, tal como noexercício 1. Utilize funções de ordem superior sempre que possível.

5. Escreva uma função graficos que devolva gráficos (pares de listas) paravárias funções. A função recebe uma lista de funções e devolve umalista de gráficos, um gráfico por função. Para além deste parâmetro (queé obrigatório), a função deverá receber três parâmetros opcionais, talcomo no exercício 1. Utilize funções de ordem superior sempre quepossível.

6. Podemos traçar um gráfico num par de eixos (caso do exercício 2),vários gráficos no mesmo par de eixos (caso do exercício 3) ou gráficosem diferentes pares de eixos (caso de este exercício). Todos os comandospyplot dizem respeito ao par de eixos (abcissas, ordenadas) corrente. Osvários eixos estão organizados em linhas e colunas. Para escolher umnovo par de eixos usamos a função

pylab.subplot(numero_de_linhas, numero_de_colunas, numero_dos_eixos)

onde o número dos eixos deverá estar entre 1 e o produto das linhaspelas colunas.

Escreva uma função tracarSubGrafico que dado um gráfico (isto é, um parde listas ordenadas-abcissas), o número de linhas e de colunas, e onúmero do gráfico, construa um novo gráfico (pylab.plot) num dado parde eixos.

Depois construa uma função tracarSubGraficos que dado uma lista degráficos e o número de linhas construa uma figura com tantos gráficosquantos os presentes na lista. Por exemplo, o código Pyton abaixo deveimprimir o gráfico na figura também abaixo.

>>> baixo = 0.1>>> alto = 20.0>>> constante = grafico (lambda x: 10.0, baixo=baixo, alto=alto)>>> logaritmico = grafico(lambda x: math.log(x), baixo=baixo, alto=alto)>>> linear = grafico(lambda x: x, baixo=baixo, alto=alto)>>> loglinear = grafico (lambda x: x*math.log(x), baixo=baixo, alto=alto)>>> quadratico = grafico (lambda x: x*x, baixo=baixo, alto=alto)>>> exponencial = grafico (lambda x: 2**x, baixo=baixo, alto=alto)>>> seisGraficos = [constante, logaritmico, linear, loglinear, quadratico,

exponencial]>>> tracarSubGraficos(seisGraficos,2)

20

Page 21: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

7. De modo a distinguir melhor os diferentes gráficos a traçar num par deeixos podemos personalizar a sua visualização. Assim, é possíveladicionar a cada plot uma string de formatação. Por exemplo, podemosfazer:

pylab.plot(abcissas,ordenadas,'go−−')

para que a linha seja desenhada em cor verde ('g' de green), commarcas circulares ('o') e tracejada ('--'). Todas a opções deformatação das linhas podem ser consultadas na documentação dafunção plotù.

Escreva uma função tracarGraficosPersonalizados que recebe doisargumentos: uma lista de gráficos e uma lista de strings de formataçãocom as formatações pretendidas para cada um dos gráficos fornecidos.As duas listas deverão ter o mesmo comprimento. A função deverátraçar os gráficos dados de acordo com as respectivas strings deformatação.

Por exemplo:

>>> baixo = 0.1>>> alto = 10>>> linear = grafico (lambda n: n, baixo=baixo, alto=alto)>>> loglinear = grafico (lambda n: n*math.log(n), baixo=baixo, alto=alto)>>> quadratico = grafico (lambda n: n**2, baixo=baixo, alto=alto)>>> formatacoes = ['r^−','go−−','bs:']>>> tracarGraficosPersonalizados ([linear, loglinear, quadratico],formatacoes)

deverá produzir um gráfico deste tipo:

21

Page 22: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

8. Escreva uma função maximos que, dada uma lista de gráficos, devolveuma lista com os máximos de cada um dos gráficos. A lista a devolverdeverá ser uma lista de pares (abcissa,ordenada) correspondentes aospontos máximos de cada gráfico.

9. Escreva uma função medias que, dada uma lista de gráficos, constrói umnovo gráfico no qual, para cada abcissa, a ordenada é a média dasordenadas dos vários gráficos fornecidos. Assuma que todos os gráficostêm a mesma lista de abcissas.

10. Utilizando a função medias, definida no exercício 9, defina uma funçãotracarComMedias que recebe uma lista de gráficos e traça, num mesmosistema de eixos, todos esse gráficos e ainda o gráfico das médias, sendoque este deverá ser apresentado com marcas circulares.

11. Escreva uma função booleana ehMaxima que, dados dois gráficos,verifica se o primeiro é maior ou igual que o segundo em todos ospontos fornecidos, devolvendo, nesse caso, o valor True. Deverádevolver False caso exista pelo menos uma abcissa para a qual asordenadas não verifiquem a condição indicada.

8 Manipulação de tabelas em memória e valoresseparados por vírgulas (CSV)

1. Comma Separated Values (CSV) é o formato mais comum deimportação/exportação de dados para folhas de cálculo e para bases dedados. A linguagem Python conta com um módulo para o efeito, CSVFile Reading and Writingù. O padrão mais comum de utilização doCSV para leitura é o seguinte:

import csv

22

Page 23: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

with open('ficheiro.csv', 'rU') as ficheiro_csv:leitor = csv.reader(ficheiro_csv, delimiter=';')

No código acima leitor é um iterador, Iteratorù. Pode ser usado numciclo for, como por exemplo:

for linha in leitor:<fazer algo com linha>

Alternativamente, podemos chamar o método leitor.next() para obter ossucessivos elementos no iterador. A exceção StopIteration é levandadaquando tentamos fazer um next() e não há mais elementos no iterador.

A razão para usar 'rU' está relacionado com a função open(), e nãopropriamente com CSV. O parâmetro 'U' (de Universal), aceita linhascom a convenção Unix ('\n') e Windows ('\r\n') .

O delimitador ';' é importante pois o formato CVS para a línguaportuguesa utiliza o ponto-e-vírgula como separador, uma vez que avírgula é utilizada como separador da parte decimal dos números.

Escreva uma função csvLinhaParaGrafico que leia dum ficheiro CSV ográfico de uma função e o devolva (no formato de um par de listas; verexercício 1 da semana 7). A função recebe o nome de um ficheiro.Assuma que o ficheiro é composto por duas linhas, a primeira contendoos valores das abcissas, a segunda os valores das ordenadas. Não seesqueça de converter as strings lidas do ficheiro em números em vírgulaflutuante.

2. No seguimento do exercício anterior, constatamos que é bem maiscomum encontrarmos as funções dispostas em colunas do que emlinhas. Escreva uma função csvParaGrafico que devolva o gráfico de umafunção, assumindo que o ficheiro CSV contém as abcissas na primeiracoluna e as ordenadas na segunda.

Sugestão: comece por escrever uma função lerCSV que lê um ficheiroCSV, linha a linha, para uma lista de listas de strings. Assuma que oficheiro tem um número indeterminado de linhas (e não duas apenas).

Escreva depois uma função transposta que transpõe uma lista de listas,isto é, que troca as linhas pelas colunas.

Escreva ainda uma função converter que, dada uma lista de listas e umafunção de conversão, devolve uma nova lista de listas onde todos oselementos da lista original foram convertidos pela função parâmetro.

Finalmente, para compor a função csvParaGrafico, utilize as funçõeslerCSV, transposta, converter, e tuple, por esta ordem. Poderia alterar aordem das funções transposta e converter? E das funções converter e tuple?

3. Este exercício assume que o ficheiro CSV está organizado da seguinteforma. Coluna 1: abscissas para todas as funções, coluna 2: ordenadas

23

Page 24: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

primeira função, coluna 3: ordenadas segunda função, e por aí emdiante. Escreva uma função csvParaGraficos que devolva uma lista comos gráficos das várias funções constantes no ficheiro. Sugestão: utilize asfunções do exercício anterior.

4. O padrão típico para escrever num ficheiro CSV é o seguinte.

import csvwith open('ficheiro.csv', 'wb') as ficheiro_csv:

escritor = csv.writer(ficheiro_csv, delimiter=';')escritor.writerow([0, 1, 2, 3, 4, 5])escritor.writerow([0, 2, 4, 6, 8, 10])

Escreva uma função graficoParaCsvLinha que receba o nome de umficheiro e um gráfico (um par de listas), e escreva o gráfico no ficheiro doseguinte modo: a primeira linha contém as abcissas, a segunda asordenadas.

5. Escreva uma função graficoParaCsv que escreva o gráfico, desta vezorganizado por colunas.

6. Escreva uma função graficosParaCsv que, dado o nome de um ficheiro euma lista de gráficos (uma lista de listas de números), escreva osgráficos num ficheiro CSV. Organize a informação no ficheiro doseguinte modo: a primeira coluna contém as abcissas, a segunda colunacontém as ordenadas da primeira função, a terceira coluna contém asordenadas da segunda função, e por aí em diante. Assuma que todas asfunções têm listas de abcissas iguais.

7. No exercício 1 vimos como ler cada uma das linhas de um ficheiro CSVpara uma lista. Se pretendermos ler cada linha para um dicionário,usamos a função DictReader. A função recebe um ficheiro CSV e algunsparâmetros opcionais. Entre eles há um de especial interesse:fieldnames=None, representando uma lista com as chaves do dicionário acriar. Imagine que o ficheiro ficheiro.csv contém nomes de pessoas:na primeira coluna o nome próprio e na segunda o nome de família.Eisuma utilização típica:

import csvwith open('ficheiro.csv', 'rU') as ficheiro_csv:

leitor = csv. DictReader (ficheiro_csv, fieldnames=['nome_proprio','apelido'],delimiter=';')

for linha in leitor<linha é um dicionário com chaves 'nome_proprio' e 'apelido'>

Suponha agora ficheiros contendo a seguinte informação sobrejogadores de voleibol, referentes a uma dada época desportiva: naprimeira coluna o nome do jogador, na segunda o clube a que pertence,na terceira o número de pontos que marcou, na quarta o número de ases(número de serviços que resultaram diretamente em ponto), na quinta a

24

Page 25: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

eficiência de ataque (rácio entre o número de passes que recebe e onúmero de pontos que marca), na sexta o número de blocos efetuados, ena sétima o número de cartões amarelos. Escreva uma função lerVoleique, dado o nome de um ficheiro CSV, devolve uma lista de dicionárioscom a informação constante no ficheiro. A uma lista de dicionáriosvamos chamar tabela.

8. Dado uma tabela (uma lista de dicionários) tal como descrito noexercício acima, escreva funções para calcular os seguintes indicadores.Assuma que não há jogadores repetidos na tabela.

(a) O nome do jogador que mais pontos marcou.

(b) O clube a que pertence o jogador que mais amarelos sofreu.Sugestão: Generalize a função da alínea acima, de modo a recebercomo parâmetros a entidade ('clube', por exemplo) e a propriedade('ases', por exemplo). Escreva a função entidadeComMais (tabela,entidade, propriedade). Aplique-a depois ao caso concreto tomando oclube como entidade e os amarelos como propriedade. Aproveitepara escrever expressões para obter o nome do jogador com maisblocos e o clube a que pertence o jogador que mais ases marcou.

(c) O clube que mais pontos marcou. Sugestão: comece por criar umatabela (lista de dicionários) com duas chaves: clube e total depontos. Por exemplo:

[{'clube': 'FC Porto', 'pontos': 50}, {'clube': 'SC Espinho', 'pontos': 115}]

Utilize depois a função entidadeComMais da alínea 8b, para obter oclube com mais pontos.

(d) O clube que obteve o maior número de ases. Sugestão: baseado nafunção da alínea acima, escreva uma função mais geralreduzirClubeSoma(tabela, propriedade) que produza uma tabela comchaves 'clube' e propriedade correspondentes à soma daspropriedades na tabela original. Componha depois com a funçãoentidadeComMais para obter o resultado.

(e) Uma lista ordenada dos clubes por ordem crescente de cartõesamarelos recebidos. Sugestão: utilize a função reduzirClubeSoma()da alínea 8d.

(f) Uma tabela com a percentagem de pontos que foram obtidos porases por clube. A tabela deverá ter como chaves 'clube' e'ases por ponto'. Sugestão: comece por utilizar a funçãoreduzirClubeSoma() da alínea 8d para obter tabelas com os númerosde ases e de pontos. Efectue depois uma “fusão” das duas tabelas.

(g) O clube que obteve a maior percentagem de pontos marcados porases. Baseie-se na alínea anterior.

25

Page 26: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

(h) Uma tabela onde cada dicionário contém um campo com o nomedo clube e outro contendo uma lista com os nomes dos jogadores.Sugestão: generalize a função reduzirClubeSoma() da alínea 8d demodo a receber mais um parâmetro: a função de acumulação.Exemplo:

>>> tabela = lerVolei('volei.csv')>>> reduzirClubeSoma(tabela, 'pontos') == reduzirClube(tabela, 'pontos',

lambda x,y: int(x)+int(y))True

(i) Uma tabela (lista de dicionários) com chaves clube, melhorMarcador.

(j) Uma lista ordenada por ordem decrescente dos jogadores commaior eficiência de ataque. Em caso de empate ganha o jogadorcom maior número de blocos efetuados. Em caso de empateutiliza-se a ordem alfabética do nome do jogador. Assuma que nãohá dois jogadores com o mesmo nome.

9 Programação por contrato; escrita e verificação depré-condições

1. Para os seguintes programas indique, justificando se

• O programa termina com sucesso e, neste caso, se apresenta oresultado esperado;

• Ainda em caso negativo, quem é o culpado, cliente ou fornecedor.

(a) def media (lista):return sum(lista) / float(len(lista))

>>> print media ([])

(b) def media (lista):"""Requires: Uma lista não vaziaEnsures: Devolve um número em vírgula flutuante representando a

média dos elementos na lista"""return sum(lista) / float(len(lista))

>>> print media ([])

(c) def media (lista):"""Requires: Uma lista não vaziaEnsures: Devolve um número em vírgula flutuante representando a

26

Page 27: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

média dos elementos na lista"""return len(lista) / float(sum(lista))

>>> print media ([0])

(d) def media (lista):"""Requires: Uma lista não vaziaEnsures: Devolve um número em vírgula flutuante representando a

média dos elementos na lista"""return len(lista) / float(sum(lista))

>>> print media ([1,2,3])

(e) def maximo (lista):resultado = lista[0]for x in lista:

if x > resultado:resultado = x

return resultado

>>> print maximo ([])

(f) def maximo(lista):"""Requires: Uma lista não vaziaEnsures: Devolve o maior elemento na lista"""resultado = lista[0]for x in lista:

if x > resultado:resultado = x

return resultado

>>> print maximo ([])

2. Para cada uma das expressões regulares, indique quais das alíneascorrespondem a strings reconhecidas:

(a) Expressão regular: [a-z]*\d+.

i. 33ii. 2

iii. carro2iv. carro234v. _25

27

Page 28: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

(b) Expressão regular: [1-4]\d{3}[^a-z]

i. 12345ii. 5392A

iii. 1274aiv. 2461_v. 4a221

(c) Expressão regular: ([a-z0-9]{2}|[A-Z])\d-?

i. 456ii. ab5-

iii. F4iv. 23A5-v. 333-

3. Para cada uma das expressões regulares abaixo, escreva uma funçãoPython que verifique se uma dada string é reconhecida pela expressãoregular.

(a) Os códigos postais portugueses. Exemplo: 1234-567 Lisboa.

(b) As matrículas de veículos registados em Portugal. Exemplos:AA-11-11, ou 11-AA-11, ou ainda 11-11-AA.

(c) Um número escrito na notação científica. Exemplos: 2.3e4,-1.345e-34.

(d) Os endereços de email dos alunos da FCUL. Exemplo:[email protected].

10 Probabilidades, Estatística e Simulação (I)

1. Escreva uma função lancarDado que devolva um número aleatório entre1 e 6. Escreva a função de quatro modos distintos, utilizando as funçõeschoice, randint, randrange e random do módulo random.

2. Escreva uma função lancarNDados(n) que devolva um número com oresultado de n lançamentos de um dado equilibrado de seis faces.Escreva um contrato apropriado para a função.

3. Nem todos os dados são equilibrados. Escreva uma funçãolancarDadoViciado() que simule um dado viciado, com probabilidadeP (1) = 0, 20, P (2) = 0, 10, P (3) = 0, 30, P (4) = 0, 05, P (5) = 0, 27,P (6) = 0, 08. Resolva este exercício sem usar a instruções if e elifencadeadas. Sugestão: comece por escrever uma função mais geral,lancarDadoComProbabilidade, que recebe uma lista de probabilidades.

28

Page 29: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

4. O paradoxo do aniversário diz que a probabilidade de duas pessoasnuma sala terem a mesma data de aniversário é superior a 1/2 mesmopara um número de pessoas relativamente pequeno. Esta propriedadenão é realmente um paradoxo, mas muitas pessoas acham-nasurpreendente. Dado o número de pessoas na sala, n, escreva umafunção simularAniversarios(n) que teste o “paradoxo” através de uma sériede experiências com dias de aniversário gerados aleatoriamente.Determine experimentalmente qual o mais pequeno número de pessoaspara qual o “paradoxo” acontece.

5. A técnica de Monte Carlo pode ser utilizada para estimar o valor de π.Imagine que dispõe de um alvo circular inscrito num quadrado.Suponha que todos os lançamentos de dardos acertam no quadrado,possivelmente no alvo. Se n for o número total de dardos lançados, e hfor o número que acerta no alvo, é fácil mostrar que π = 4h

n . Escrevauma função simPi que calcule o valor de π, dado o número delançamentos de dardos.

Sugestão: utilize a fórmula 2*random.random()−1 para gerar ascoordenadas x e y de um ponto dentro de quadrado 2× 2 centrado em(0, 0). O ponto está no alvo se x2 + y2 ≤ 1.

11 Probabilidades, Estatística e Simulação (II)

1. Suponha uma corrida de quatro cavalos conhecidos: Artimanhas,Bombom, Caramelo e Dilúvio. Estima-se que a probabilidade de venceré 5% para Artimanhas, 20% para Bombom, 25% para Caramelo e 50%Dilúvio. Simule uma corrida no computador em que seja indicado decada vez o nome do vencedor. Determine a percentagem de vitóriasobtidas por cada cavalo nas realização de n corridas.

2. Considere o lançamento de três dados. Faça uma estimativa daprobabilidade da sua soma ser 3, 4, . . . , 18 através de simulaçãocomputacional. Apresente o resultado na forma de um histograma.

3. Suponha uma roleta de um casino com 37 ranhuras e com a numeração

0, 1, 2, . . . , 36. A ranhura 0 é verde, dezoito

29

Page 30: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

das restantes são pretas e as outras dezoito são vermelhas. O banqueirofaz a roda virar e lança uma bola.

(a) Se um jogador apostar na cor preta e a bola parar na cor preta,ganha uma importância igual à que apostou (além de recuperar aimportância que apostou). Caso contrário, perde o dinheiro daaposta. Estime a probabilidade de um jogador ganhar, simulandoeste jogo e supondo que ele aposta um grande número de vezesseguidas a importância de e1.

>>> simulacaoPretas (10000)0.4864

(b) Se um jogador apostar num número específico e a bola parar nessaranhura, ganha 35 vezes o valor da aposta (sempre de e1) além derecuperar a importância que apostou. Caso contrário, perde odinheiro da aposta.Considere a seguinte estratégia: o jogador aposta sempre nomesmo número (por exemplo, 6), fixa o limite da perda diária (porexemplo, e50), e faz por noite um número máximo de apostas (porexemplo, 100). Faça uma simulação do que ganharia um jogadornuma noite. Por exemplo, para um máximo de 100 apostas, umorçamento inicial de e50 e número da sorte 6:

>>> simulacaoNoite (100, 50, 6)−11>>> simulacaoNoite (100, 50, 6)26

(c) A experiência acima tem pouca relevância estatística. Estime olucro obtido, repetindo a experiência um grande número de vezes.Eis um exemplo, onde o primeiro parâmetro é o número deexperiências noites, e os três últimos como na alínea anterior:

>>> simulacaoNNoites (10000, 100, 50, 6)−49.3637

(d) Suponha agora que um jogador de roleta usa a estratégia daduplicação de parada que consiste no seguinte: aposta sempre na corpreta. Se ganhar a aposta, volta a apostar e1 a roda voltar a girar.Se perder, duplica a aposta anterior. Continua a jogar até que tenhaganho ou perdido e10. Simule este jogo um número suficiente devezes para poder concluir que deve evitar este tipo de estratégia.

>>> simulacaoDuplicacaoNParadas(10000, 10)−3.2653

30

Page 31: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

12 Probabilidades, Estatística e Simulação (III)

1. Nas próximas eleições autárquicas há dois candidatos à presidência dacâmara: o Abel e a Beatriz. Sabe-se que x% dos votantes querem votarna Beatriz e (100− x)% no Abel. Um jornal local encomendou umasondagem a uma empresa de marketing, baseada na opinião de nvotantes. O objectivo é prever o vencedor e publicar o resultado dasondagem no dia das eleições. Pretende-se simular esta sondagem eanalisar as possibilidades do jornal se enganar nos seguintes casos:

(a) x = 45% e n = 10, 100, 1000

(b) x = 47% e n = 10, 100, 1000

(c) x = 49% e n = 10, 100, 1000

2. Efectue a simulação de um jogo de voleibol entre duas equipas.

Um jogo de voleibol joga-se à melhor de 5 sets. Cada um dos sets iniciaisjoga-se até aos 25 pontos. O quinto set, chamado a negra, se acontecer,joga-se até aos 15 pontos. Em qualquer caso, um set tem de ser ganhopor uma diferença igual ou superior a 2 pontos.

O lançamento de uma moeda decide a equipa que sai (serve o primeiroponto) no primeiro set.4 Nos sets seguintes, as equipas saem por ordemalternada. Para a negra uma nova moeda é lançada. A equipa ganha umponto mesmo que não tenha sido ela a servir. A equipa que ganha oponto serve o ponto seguinte.

A eficiência do serviço é a percentagem de pontos que uma equipaconsegue quando serve. Uma eficiência de 20% indica que a equipaganha 1 em 5 pontos que serve. Obviamente as equipas com melhoreficiência de serviço terão maior probabilidade de ganhar. Mas quantomais? Este exercício de simulação responde a esta questão. Resolva-o epasme-se!

Os dados da simulação são: a probabilidade da equipa A ganhar oponto quando serve, a probabilidade da equipa B ganhar o pontoquando serve, e o número de jogos a simular.

Para a simulação temos de simularUmSetVolei(), simularUmJogoVolei() esimularNJogosVolei().

3. O jogo de dados (craps) é um jogo jogado em muitos casinos. Umjogador lança um par de dados, convencionais, de seis faces. Se olançamento inicial somar 2, 3, ou 12, o jogador perde.§ Se o dadomostrar 7 ou 11 o jogar vence. Em qualquer outro caso, o número quesaiu torna-se o ponto. A partir daqui só interessam dois números: o 7 e oponto. O jogador continua a lançar o dado até que saia um destes

4Na realidade a face favorável da moeda permite que o capitão da equipa escolha ou o campoou a equipa que serve primeiro.

31

Page 32: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

valores. Se sair o ponto, o jogador ganha; se sair 7 o jogador perde.Escreva uma função simulaNJogoDados que simule múltiplos jogos dedados e que estime a probabilidade do jogador ganhar. Por exemplo:

>>> simulaNJogoDados (100000)0.49108

indica que a probabilidade do jogador ganhar é 49,108%, ou que ojogador ganhou 49108 jogos em 100000.

4. Na realidade o jogo dos dados consta de duas apostas principais: aaposta da linha de passagem e a aposta da linha de não passagem. Oexercício acima desenvolve a aposta na linha de passagem. Na aposta nalinha de não passagem aplica-se o oposto, mas aparece a noção deempate: se o lançamento inicial somar 7 ou 11 o jogador perde, se sair 2ou 3 o jogador ganha, e se sair 12 dá-se um empate. O jogo prosseguecom o número ponto, tal como em linha de passagem.

Prepare uma funçãosimDadosNaoPassagem(lancamentosPorJogo, numeroDeJogos) que calcule oretorno sobre investimento (ROI em inglês, “Return On Investment”), naforma de média e desvio padrão.

Que consegue concluir sobre a “melhor estratégia”?

5. Vinte e Um (Blackjack) é um jogo de casino jogado com cartas. O objetivodo jogo é retirar cartas de um baralho que somem um número tãopróximo quanto possível de 21, sem nunca ultrapassar este valor.

O valor da mão (conjunto de cartas) é determinado pela soma do valorde cada uma das cartas na mão. Cartas numeradas de 2 a 10 valem o seuvalor facial; figuras (valetes, damas ou reis) valem 10 pontos cada; asesvalem 1 ou 11 pontos, aquele que for mais favorável.

O jogo é jogado de encontro a um banqueiro. O banqueiro dá duascartas abertas (com a face virada para cima) para cada jogador. Obanqueiro tira duas cartas para si, mas apenas uma aberta. Com base nacarta do banqueiro virada para cima e na sua mão, o jogador decide sebate (pede carta adicional) ou passa (mantem sua mão como está).

Uma vez os jogadores satisfeitos com as suas mãos, o banqueiro mostraa face da sua segunda carta e procede de acordo com as regras dobanqueiro. As regras do banqueiro são as seguintes:

• O banqueiro deve tirar cartas adicionais até que a sua mão valha 17pontos ou mais;

• Se a mão do banqueiro somar 17 ou mais, então ele deve “passar”.

Ganham os jogadores que somarem mais pontos do que o banqueiro.

32

Page 33: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

(a) Escreva uma função probabilidadeBanqueiroRebentar que simulemúltiplos jogos de Vinte e Um e que estime a probabilidade dobanqueiro rebentar. Verifique o resultado obtido de encontro aoproposto por BlackJack Ageù.

(b) Se estiver indeciso sobre se há-de pedir nova carta ou passar, sabera probabilidade do banqueiro rebentar dada a carta virada paraconstitui uma grande ajuda. Escreva uma funçãoprobabilidadeBanqueiroRebentarDadaUmaCarta que apresente umatabela com três colunas: valor da carta virada para cima,probabilidade de rebentar, e desvio padrão. Analise os váriosvalores da carta virada para cima: 2 a 10, e ás. Novamente,verifique o resultado obtido de encontro ao proposto por BlackJackAgeù.

6. Ainda assim, como decidir entre bater ou passar, baseado na esperançado banqueiro vir a rebentar? A melhor aposta é conhecer as suaspróprias probabilidades de rebentar. Deverá passar apenas quando suashipótestes de rebentar são maiores do que as do banqueiro. É que nãoqueremos correr o risco de rebentar quando a probabilidade dobanqueiro rebentar é maior do que a nossa. Construa uma tabela deprobabilidades do jogador rebentar, dado o valor da mão. Considere osseguintes valores 12, 13, . . . , 20.

13 Ferramentas de sistema (I)

1. Escreva um script paramin que imprima no ecrã o conteúdo do ficheirocom todas as letras convertidas para minúsculas. Exemplo:

$ cat mensagem.txtA Europa jaz, posta nos cotovellos:De Oriente a Occidente jaz, fitando,$ python paramin.py mensagem.txta europa jaz, posta nos cotovellos:de oriente a occidente jaz, fitando,

Sugestão: proceda em três passos:

(a) Escreva uma funcão scanner(nomeDeFicheiro,funcao) que aplica amesma funcao a todas as linhas do ficheiro.

(b) Escreva uma função paraMinuscula(linha) que imprima no ecrã a linhacom todas as letras convertidas para minúsculas.

(c) Baseado nas duas funções anteriores, escreva agora o script paraminque imprime no ecrã o conteúdo do ficheiro com todas as letrasconvertidas para minúsculas.

33

Page 34: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

2. More é um filtro para visualizar o conteúdo de um ficheiro, uma páginade cada vez. Na mais simples utilização, more é lançado da linha decomandos deste modo:

$ python more.py o_meu_ficheiro

Neste caso a primeira página do ficheiro aparece no ecrã. Depois,sempre que o utilizador carregar em Enter aparecerá uma nova página.Qualquer outra tecla seguida de Enter termina o programa.

Um exemplo de interação mais complexo especifica o número daprimeira linha a exibir (-l) e o tamanho de cada página (-p):

$ python more.py -l 15 -p 20 more.py

O valor por omissão para a primeira linha é 1 e o do comprimento dapágina é 10. Deverá ser possível executar o script com as seguintesopções:

• -h, --help

mostra como utilizar o programa;

• -c N, --comprimento N

o comprimento da página em número de linhas;

• -l M, --linha M

o número da primeira linha a mostrar.

Escreva o script more.py. Utilize o módulo argparse.

3. Escreva um script para imprimir os ficheiros numa directoria esubdirectorias em forma de “árvore deitada”. Para cada ficheiro,imprimos o seu nome; o nome de cada directoria é precedido por +.Cada nova directoria começa uma nova coluna dois espaços para adireita.

$ python deitada.py disciplinas/prog2+docs

exercicios.tex+trabalho

enunciado.texgrafico.png

+srcmore.pydeitados.py

4. Escreva um script que imprima o caminho absoluto de todos os ficheirosPython que se encontram numa dada directoria, incluindo as suassubdirectorias.

34

Page 35: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

$ python todospy.py exemplosC:\temp\exemplos\simulacao\roleta.pyC:\temp\exemplos\scripts\more.pyC:\temp\exemplos\scripts\deitada.pyC:\temp\exemplos\todospy.py

Escreva duas versões:

(a) Versão iterativa, utilizando os.walk();

(b) Versão recursiva, utilizando os.listdir().

Sugestão: para imprimir o caminho absoluto utilize a funçãoos.path.abspath().

14 Ferramentas de sistema (II)

1. Escreva um script que imprima o maior ficheiro numa dada diretoria,incluindo as suas subdiretorias.

$ python maior_ficheiro.py .(18254877, 'atrasos.csv')

2. Escreva um script que imprima o nome de todos os ficheiros Pythonnum certo diretório (e seus subdiretórios se for dada a opção -r ou--recursivo) que tenham alguma linha que emparelhe com uma certaexpressão regular. Utilize desta vez o caminho relativo. Por exemplo, oseguinte comando lista todos os ficheiros Python no diretório atual quetenham alguma linha iniciada pela palavra "import":

$ python todosexpr.py . '^import'./atrasos.py./cat.py./coop.py./csv_test.py./frequentes.py

Sugestão: utilize a biblioteca re para expressões regulares, e adapte oexercício 4 da secção 13.

3. Escreva um script que, à semelhança do comando wc (word count) doUnix, conte o número de palavras em vários ficheiros de entrada.Adicionalmente, o script deverá aceitar as seguintes opções:

• -h, --help

mostra como utilizar o programa;

35

Page 36: Programação II Exercícios · Python 3”, Paul Gries, Jennifer Campbell, e Jason Montojo, Pragmatic Programmers, 2013. 3. Escreva uma função linha_para_atomo que, dada uma string

• -c

mostra o número de bytes do ficheiro;

• -l

mostra o número de linhas.

Por exemplo:

$ python conta_palavras.py lab1.py lab2.py146 634 4404 lab1.py154 469 3781 lab2.py300 1103 8185 total

$ python conta_palavras.py -l lab1.py lab2.py146 lab1.py154 lab2.py300 total

$ python conta_palavras.py -c lab1.py lab2.py4404 lab1.py3781 lab2.py8185 total

$ python conta_palavras.py -l -c lab1.py lab2.py146 4404 lab1.py154 3781 lab2.py300 8185 total

$ python conta_palavras.py lab1.py lab2.py ff146 634 4404 lab1.py154 469 3781 lab2.py

conta_palavras.py: ff: open: No such file or directory300 1103 8185 total

4. Escreva um script que dado um ficheiro comprimido no formato .zipmostre a lista de ficheiros nele contido, o tamanho original de cadaficheiro, e o seu tamanho comprimido.

$ python listazip.py umficheiro.zip

Nome do ficheiro Tamanho Compressãot1-1415.pdf 300074 bytes 251683 bytes (83.9%)t2-1415.pdf 83083 bytes 82260 bytes (99.0%)

Sugestão: importe o módulo zipfileù.

$Date: 2015-05-27 10:50:57 +0100 (Qua, 27 Mai 2015) $

36