Data da última actualização: 09 de Fevereiro de 2010
Departamento de Ciência de
Computadores,
Faculdade de Ciências da Universidade do
Porto
Armando Matos
- Classificações dos alunos que compareceram ao exame final da primeira época e que constam na pauta do Sigarra. Deve confirmar o seu resultado na página oficial da UP. Se algum aluno pretender ver o seu exame, pode fazê-lo na 4ª feira, dia 3 de Fevereiro entre as 9:00 e as 11:00.
- Alunos sem frequencia à disciplina (não deve ser considerada a exclusão dos alunos com estatuto "TE" ou "DA"):
- A tabela de folhas P e TP contém também enunciados de exames (da
época normal e da época de recurso) com resoluções.
----Avaliação | ----Sumários das aulas teóricas | ----Bibliografia | |
----Folhas P e TP | ----Elementos de estudo | ----Funcionamento das aulas | ----Complementos |
----Provas | ----Classificações | ----Docentes | ---- |
Objectivos
Pretende-se que o aluno
Programa previsto
A valorização do exame é de 15 valores.
Aulas práticas
Em princípio todas as semanas é fornecida uma folha de
exercícios. O aluno deverá tentar resolver os exercícios da folha
antes da aula prática respectiva.
Aulas teórico-práticas
Nas aulas teórico-práticas serão aprofundadas diversas questões
abordadas nas aulas teóricas, propondo-se exercícios complementares;
poderão ainda ser colocadas questões relacionadas com os problemas das
folhas práticas e fornecidas folhas complementares de exercícios.
Aula 01
A disciplina de Introdução à Programação: objectivos, programa, bibliografia, funcionamento das aulas. Evolução dos computadores ao longo da história.
Aula 02
Evolução das linguagens de programação. A linguagem máquina, a linguagem "assembler". Paradigmas de programação. Sobre o python: constantes (int, float, bool...), variáveis expressões. Instruções: atribuição, 'while'; definição de funções: "instruções" 'def' e 'return'.
Aula 03
Análise de um programa específico em linguagem python. Instruções da linguagem python: atribuição, condicionais, de ciclo ('while'). Definição de funções ('def' e 'return') Expressões.
Aula 04
Versão iterativa e recursiva de uma função. ^Ambito ('scope') das variáveis: variáveis locais. Divisibilidade. Exemplos.
Aula 05
Divisibilidade e primalidade. Exemplos e exercícios diversos.
Aula 06
As listas. Funções 'len', 'append', 'range'. A instrução 'for'. Exercícios de aplicação.
Aula 07
Dígitos de um inteiro numa base de numeração. Conversão entre bases Diversos exemplos sobre listas
Aula 08
"Strings". Caracteres e suas codificações. Funções "ord" e "chr". Alguns exercícios sobre "strings".
Aula 09
"Tuplos"; operações com tuplos; comparação com "strings" e listas. Exemplos diversos de implementação de funções que processam "strings".
Aula 10
Introdução às listas em compreensão. Uso em programas simples para contar o número de divisores e testar a primalidade. Introdução aos módulos "rand" e "turtle".
Aula 11
Mais um exemplo de aplicação do módulo "turtle". Forma mais geral da instrução "for". Definição indutiva de listas de inteiros de profundidade arbitrária. Exemplos de programas: soma de todos os inteiros, profundidade máxima de um inteiro.
Aula 12
Entrada de dados com "prompt" Operador de formatação "%". Formatação de dados. Exemplos.
Aula 13
Números pseudo-aleatórios: Lançamento de n dados m vezes: estimativa da média. Cálculo aproximado de um integral definido.
Aula 14
Pesquisa sequêncial. Eficiência em termos do número de comparações.
Aula 15
Pesquisa binária numa lista ordenada. Pesquisa sequêncial e binária: comparação da eficiência.
Aula 16
- Determinação da raíz aproximada de uma equação f(x)=0 pelo método das bissecções sucessivas. - Uso do módulo "turtle" para desenhar o gráfico de uma função arbitrária.
Aula 17
Método de ordenação por selecção do mínimo". Determinação da eficiência do método com base no número de comparações efectuadas. Notas sobre a correcção do algoritmo.
Aula 18
Método de ordenação "quicksort": algoritmo recursivo utilizando listas em compreensão.por selecção do mínimo". Determinação da eficiência do método com base no número de comparações efectuadas no caso médio.
Aula 19
Erros na programação: erros sintácticos, de execução e semanticos; Correcção de erros e técnicas de boa programação. Confirmando predicados no programa: a instrução 'asssert'. Testes. O módulo 'doctest'.
Aula 20
Contagem de frequências ('bit counting') aplicação a uma função para detecção de anagramas. Método de ordenação "bucket-sort". Eficiência, limitações e comparação com outros métodos.
Aula 21
- Criar e inicializar listas. - Representação de pontos a 2 dimensões; função de rotação de um ponto. - Função que determina a tabela de verdade de uma função proposicional dada. - Sufixos de strings.
Aula 22
Representações e operações com conjuntos. Teste de associatividade de uma operação binária
Aula 23
- Várias soluções do problema: determinar o número de ocorrências do máximo numa lista. Comparação das eficiências. - Determinação da raíz quadrada inteira utilizando um método análogo à pesquisa binária. A eficiência é O(log n) - Determinação do determinante de uma matriz quadrada através da sua triangulação.
Aula 24
Fundamentos da utilização do módulo 'Tkinter' Aplicação à construção de um programa de vizualização (a preto e branco e a cores) de imagens bi-dimensionais. Exemplo de processamento de imagens - redução de contraste.
Ir para:
Ir directamente para: 1 5 10 15 20 25 30 35 fim
Incluímos, de uma forma esquemática e não revista, o seguinte:
Pode haver omissões ou repetições...(
x=11 type(x) --> int x=11.1 type(x) --> float y="Ai Ai" type(y) --> str >>> y[1] 'i' >>> y[0] 'A' --------------------------- print x >>> x=5 >>> z=2 >>> x/z 2 >>> x=5.0 >>> z=2 >>> x/5 1.0 >>> x/z 2.5 "overloading" de operadores
O que faz a seguinte função (o que calcula?)? def f(n): prod=1 i=2 while i<n: prod = prod*i return prod O que faz a seguinte função (o que calcula?)? def f(n): prod=1 i=2 while i<n: prod = prod*i i = i+1 return prod >>> sin(1) NameError: name 'sin' is not defined >>> import math >>> math.sin(1) 0.8414709848078965 >>> sin(1) NameError: name 'sin' is not defined >>> from math import sin >>> sin(1) 0.8414709848078965 ----------------------------- precedência (parcial) dos operadores binários primeiro ** depois * / % depois + - depois < <= != == >= > depois and depois or Na dúvida: use parêntesis! ------------------------------- #------------------ Ãútima aula ----------------------------------- def f(n): prod=1 i=2 while i<n: prod=prod*i i=i+1 return prod i=1 while i<=5: print i, f(i) i = i+1 # 1*2*...*(i-1) = (i-1)! excepto se i=0 # -------------------------------------------------------- # atribuição <var> = <expressão> # exemplos sintaticamenre correctos # exemplos sintaticamenre errados # -------------------------------------------------------- # if <condição>: # ..... # ..... # <...continuação...> # # exemplos sintaticamenre correcto # exemplos sintaticamenre errado # -------------------------------------------------------- # if <condição>: # ..... # ..... # else: # ..... # ..... # ..... # <...> # # exemplos sintaticamenre correcto # exemplos sintaticamenre errado # -------------------------------------------------------- # if ... elif ... elif ... else # -------------------------------------------------------- # while <condição>: # ..... # ..... # <...> # # exemplos sintaticamenre correctos # exemplos sintaticamenre errados # -------------------------------------------------------- # while condição>: # ..... # ..... # <...> # # exemplos sintaticamenre correctos # exemplos sintaticamenre errados def jogo(): print "Vamos jogar" n = input("Diz um número ") print n+1, ", ganhei!!!" # if, while, def jogo1(): print "Vamos jogar" n = input("Diz um número ") if n<10: print n+1, ", ganhei!!!" else: print n-1, ", perdi!!!" def jogo2(): print "Vamos jogar" while 2==2: n = input("Diz um número ") print n+1, ", ganhei!!!" print "Vamos jogar outra vez" # Note: tipicamente as funcoes não são assim! # Em princípio as funções devem ser "puras": # - não contém print's nem input's # - fornecem um resultado (com 'return') # - nã têm efeitos laterais (como mudar vars...) # Escreva uma função f: R -> R # x<1 ou x>2 -> 0 # senão -> 1 # Escreva uma função f: R -> R # derivada(f,x) # # com lambda print (lambda x: x**2+1)(2)! def deriv(f): delta = 0.01 return lambda x: (f(x+delta)-f(x-delta))/(2.0*delta) print "derivadas de x^2" x=0 while x<=10: print x, deriv(g)(x) x = x+1
Função que converte segundos -> horas, min, segundos def dhms(segs): s=segs%60 mins=segs/60 m=mins%60 horas=mins/60 h=horas%24 d=horas/24 return [d,h,m,s] Tornando um programa executável
Versão de uma função que calcula r! (factorial de r) com um ciclo def fact(r): p=1 k=2 while k<=r: p=p*k k=k+1 return p Versão de uma função que calcula r! (factorial de r) sem ciclos def fact1(r): if r<=1: return 1 return r*fact1(r-1)
Divisibilidade de a por b, a|b (a divide b) a%b==0 ou então (a/b)*b==a --------------------------------------------- Escreva uma função "div" que testa se a divisível por b div: N*N -> Bool muito simples return a%b==0 mais complicado: if a%b==0 return True else return False # Escreva uma função que determina os inteiros # até n com mais divisores # 1) Função 'maxndiv(n)' que determina o maior número # de divisores de x, com 1 <= x <= n, # 2) (Programa) # Percorre-se x de 1 a n e, sempre que ndiv(x) = maxndiv(n) # imprime-se x # Contagem dos divisoes, melhorias do programa: # Exercício # d*d>x -> pára # d*d==x -> conta 1 divisor # d*d<x -> conta 2 divisores # -------------------------------------------- # Dígitos... # qual o o último dígito de n (inteiro positivo)? # R: n % 10 # E o penútimo, supondo que n>=10? # R: (n/10)# 10 # -------------------------------------------- # Soma dos dígitos # Escreva uma função "sdig(n)" que escreve a soma dos dígitos de um # inteiro positivo n dado. # a) Escrever a função de forma iterativa # (envolverá um ciclo "while") # b) Escrever a função de forma recursiva # (não envolve ciclos, mas uma chamada à própria função). # -------------------------------------------- # Dígitos `ào contrário'' # Escreva uma função "digs_inv(n)" que imprime, por ordem inversa, os # dígitos de um inteiro positivo n dado. # -------------------------------------------- # Escreva uma função "digsb(n,b)" que escreve, <por ordem>, os # dígitos de um inteiro positivo n dado. A base de numeração é # b, 2<=b<=10. # Usar um método recursivo: # se n<b: escrever n # senão: # digsb(???,b) # escrever n# b
Escreva uma função que calcula o número de divisores de a ndiv N -> N c=0 para cada d, 1<=d<=a se a divisível por d: c=c+1 return c
Exercício: Escreva uma função que determina se a é primo primo N -> Bool A função deve ser baseada na condição de primalidade ndiv(a)==2 Melhore a eficiência da função de teste de primalidade, usando a seguinte propriedade que deve demonstrar! se o inteiro positivo a tem um divisor d com 2<= d <a, então tem um divisor d' com 2 <= d' <= sqrt(a)
#-------------------------------------------------------------------- # Soma dos dígitos # Exercício: Escreva uma função "sdíg(n)" que escreve a soma dos # dígitos de um inteiro positivo n dado. # a) Escrever a função de forma iterativa # (envolver so' ciclos "while") def sdig(n): s=0 while n>0: s = s+n%10 n=n/10 return s #for i in range(100,120): # print i, sdig(i) # b) Escrever a função de forma recursiva # (nao envolve ciclos, mas uma chamada à propria função). def sdigr(n): if n<10: return n return n%10 + sdig(n/10) for i in range(100,120): print i, sdigr(i) # -------------------------------------------- # Dígitos `ào contrario'' # Exercício: Escreva uma função "digs_inv(n)" que imprime, # por ordem inversa, os dígitos de um inteiro positivo n dado. # -------------------------------------------- # Exercício: # Escreva uma função "digsb(n,b)" que escreve, <por ordem>, os # dígitos da representação na base 'b' de um inteiro positivo 'n' # dado . A base de numeração é 'b', 2<=b<=10. # Usar um metodo recursivo: # se n<b: escrever n # senão: # digsb(???,b) # escrever n%b def digsb(n,b): if n>=b: digsb(n/b,b) print n%b, for i in range(10): print i, digsb(i,2) print #---------------------------------------------------------------------------- # Uma estrutura de informação "composta": a lista #---------------------------------------------------------- # lista: sequência de 0 ou mais expressões # em particular, uma expressão pode ser uma lista # # indexação li[i]: elemento i da lista (comeca em 0) # comprimento: len(li) # concatenação: lista1 + lista2 # função append: li.append(e): elemento e no fim da lista # multiplicação por inteiro # função range(n) -> [0,1,...,n-1] # range(a,n) -> [a,a+1,...,n-1] # # colocar elemento 'e' no fim da lista 'li': append(li,e) #---------------------------------------------------------- # instrução for: for <var> in <lista>: # # imprimir os inteiros 0, 1,..., 100 e seus quadrados # for i in range(101): print i,i**2 #---------------------------------------------------- # Exercício: # função soma(n) que determina a soma 1+2+...+n def soma(n): s=0 for i in range(1,n+1): s=s+i return s # Melhor solução: retornar a expressão dessa soma! Qual é? #---------------------------------------------------- # Exercício: # função dup(li) que recebe uma lista li e # duplica todos os elementos def dup(li): r=[] for elem in li: r = r + [elem] + [elem] return r #---------------------------------------------------- # Utilizaremos muitas vezes # - instrução for # - listas e indexação # - + (concatenação de listas) # - função range #---------------------------------------------------- # Exercício: # Bem ou mal? # Se 'mal' porquê? # Se 'bem', qual o valor? #--------------------------------------- # [2,[5,4],6][1][1] #--------------------------------------- # li = [2,[5,4],6][1][1] for i in 10: # li[2][1] print i #--------------------------------------- # range(3)+range(3) len(range(3)) # len(3) li.append([]) # li.append(29) #--------------------------------------- # Exercício: Como criar uma lista a com 100 0's: [0,0,...,0]? #--------------------------------------- # Exercício: função quadrado(n) que retorna a lista # [[0, 1,...,...n], (linha 0) # [n+1,n+2,...,2n], (linha 1) # ....... # [..........,n*n-1]] (linha n-1) # a) Usando só a instrução de ciclo 'for' # (uma ou mais vezes!) # a) Usando só a instrução de ciclo 'while' # (uma ou mais vezes!) def quadrado(n): r=[] # lista global a retornar a=0 # número actual a colocar for i in range(n): li=[] # lista linha a formar for j in range(n): li=li+[a] a = a+1 r = r + li return r #--------------------------------------- # Exercício: Mostre que se não existisse a instrução 'for' # o 'python' não perdia potencialidades. # # Nota. Na verdade, nem do 'while' precisamos. basta a # recursividade. # Exercício: função soma(n) que determina a soma 1+2+...+n # sem usar 'for' nem 'while'. # -------------------------------------------- #--- Uma nota sobre a instrução 'for' li=[1,2,3] for i in li: li=[] print i print li
# coding: utf-8 #------------------------------------------------------------ # Escrever uma função soma(n) que calcula a soma 1+2+...+n # a) Usando um ciclo while # b) Usando uma instrução 'for' # c) Sem qualquer instrução de ciclo (nem 'for' nem 'while') #------------------------------------------------------------ # a) def soma1(n): s=0 i=1 while i<=n: s = s + i i = i+1 return s print "soma1(5)", soma1(5) # b) def soma2(n): s=0 for i in range(1,n+1): s = s + i return s print "soma2(5)", soma2(5) # c) def soma3(n): if n<=0: return 0 return n + soma3(n-1) print "soma3(5)", soma3(5) # c) def soma4(n): return n*(n+1)/2 print "soma4(5)", soma4(5) #------------------------------------------------------------ # Escreva uma função arit(a,b) onde 'a' e 'b' são inteiros # que calcula a lista [a,a+1,...,b]. Não pode usar a função # 'range', podendo manipular as listas apenas com 'append' # (e indexação) # Exemplos: arit(5,9) -> [5,6,7,8,9] # arit(5,4) -> #------------------------------------------------------------ def arit(a,b): r=[] # a ser retornada pela função for i in range(a,b+1): r=r+[i] return r print arit(2,5) #------------------------------------------------------------ # Mostre que qualquer instrução 'for' pode ser substituída # por uma instrução 'while' # Relembra-se a forma da instrução 'for' # # for <var> in <lista>: # ... # ... # <continuação> # # Solução # n=len(lista) # nova variável # i=0 # nova variável # while i<n: # ... # ... # i=i+1 # <continuação> #------------------------------------------------------------ #------------------------------------------------------------ # Escrever uma função listas(n) que a partir de n calcula uma # lista [[...[]...]] em que o número de '[' é n. # Exemplo: listas(3)-> [[[]]] #------------------------------------------------------------ # assume-se n>=1 def listas(n): if n==1: return [] return [listas(n-1)] print print listas(3) #------------------------------------------------------------ # Escreva uma função base(n,b) que converte o inteiro n para a # base 'b', ficando os dígitos (inteiros entre 0 e n-1) # no resultado # Exemplos: base(123,10) -> [1,2,3] # base(16,2) -> [1,0,0,0,0 # tipo: int x int -> [int] #------------------------------------------------------------ # assume-se n>0 # Vamos retirando o último dígito a n, n%b # Esse dígito é colocado à cabeca de r def base(n,b): r=[] while n>0: dig = n%b r = [dig]+r n=n/b return r print for (n,b) in [(123,10),(15,2),(29,3)]: print n,b,base(n,b) #------------------------------------------------------------ # Escreva uma função valor(li,b) que a partir de uma lista 'li' # e de uma base 'b', determina o inteiro cuja representação # na base 'b' é a sequência de dígitos contida na lista li # Exemplos: base([1,5,9],10) -> 159 # base([1,1,1,0,1],2) -> 29 # tipo: [int] x int -> int #------------------------------------------------------------ # o valor retornado é obtido olhando para a lista da esquerda # para a direita... # li: [4,5,6], dig s de cada vez: s=s*b+dig # 4 4 # 5 45 # 6 456 def valor(li,b): s=0 for dig in li: s= s*b+dig return s print for (li,b) in [([4,5,6],10), ([1,0,0,1],2), ([2,0,1],3)]: print li,b,valor(li,b) #------------------------------------------------------------ # Strings: "..." ou '...' # Funções: indexação, # len, # + (dá uma nova 'string'), # in # ord, # chr # as strings são imutáveis # Caracteres: strings com comprimento 1 # Códigos dos caracteres, ord e chr #------------------------------------------------------------
#------------------------------------------------------------ # Strings: "..." ou '...' # Funções: indexação, len, + (dá uma nova 'string'), # in ord, chr # São imutáveis # Caracteres: strings com comprimento 1 # Códigos dos caracteres, ord e chr # # Tuplos tu = (1,(2,3),[4,5]) # Iguais às listas, mas imutáveis! # imutáveis em que sentido? # tu[0]=2 # tu[2][1] = "ui" # # Listas, strings, tuplos: # indexação, + (concatenação), len, in # Listas: append, modificação (atribuição a elementos da lista) # Strings: ord, chr #------------------------------------------------------------ #------------------------------------------------------------ # Escreva uma funçao repete(s,n): repete s n vezes # repete("abc",3) -> "abcabcabc" # Escrever função sem usar * #------------------------------------------------------------ def repete(s,n): r="" for i in range(n): r=r+s # r = r+r return r print repete("abc",3) # return s*n #------------------------------------------------------------ # Escreva uma função vogaisu(s) todas as vogais -> u #------------------------------------------------------------ #------------------------------------------------------------ # mima(s) # mima("Batatas!") -> "BATATAS!" # Transforma as minúsculas em maiúsculas # Use minu="abcdefghijklmnoprstuvwxyz" # maiu="ABCDEFGHIJKLMNOPRSTUVWXYZ" # e a função axiliar procura(c,s): (primeiro) índice ou -1 # Não pode importar módulos #------------------------------------------------------------ def mima(s): minu="abcdefghijklmnoprstuvwxyz" maiu="ABCDEFGHIJKLMNOPRSTUVWXYZ" r="" for c in s: if c in minu: ind=localiza(c,minu) a = maiu[ind] else: # tirando o else? a=c r=r+a return r def localiza(a,s): for i in range(len(s)): if a==s[i]: return i return -1 print mima("Batatas!!") #------------------------------------------------------------ # Lista das letras # # #------------------------------------------------------------ from string import * def letras(s): r=[] for x in letters: if x in s: r.append(x) return r print letras("As batatas ") #------------------------------------------------------------ # Substitui cada letra pela letra a seguir # seguir("Aiz!") -> "Bja!" # #------------------------------------------------------------ def seguir(s): r="" minus = "abcdefghijklmnopqrstuvwxyz" maius = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" for c in s: if c in minus: # c é minúscula? ind=ord(c)-ord("a") # posição de c na lista "minus" ind1 = (ind+1)%26 # posiçao seguinte cn = minus[ind1] # a minúscula correspondente elif c in maius: # c é minúscula? ind=ord(c)-ord("A") # ... ind1 = (ind+1)%26 cn = maius[ind1] else: cn = c # fica o mesmo caracter r = r+cn return r s = "Arroz ZIT!" print s, seguir(s) # Exercício: Usar uma função auxiliar # procura(c,str) -> índice de "c" em "str", ou -1 se não existe #------------------------------------------------------------ # Lista ordenada das letras, usa lista de presenças # Converte representação decimal para inteiro # inteiro("1234") -> 1234; deve indicar erro se for caso disso... # #------------------------------------------------------------ def inteiro(s): digitos="0123456789" soma = 0 for c in s: if c in digitos: v = ord(c)-ord("0") soma = soma*10 + v else: print "Formato de string errado" return return soma for s in ["123","99888","12a3"]: print s, inteiro(s) #------------------------------------------------------------ #--- tuplos, troca de valores "for (a,b)..." BD alunos #------------------------------------------------------------ # surpresas... # a = [1,2,3,4,5] # b=a # a[3] = "batatas" # # Como copiar listas? #============================================================ # Módulo turtle # - seth(ang) # - left(ang) # - right(ang) # - forward(comp) # - backward(comp) # - pendown() # - penup() size, color,... # - speed(n) 1 a 10, 0 é o mais rápido #============================================================ # Módulo random # # - rand(1,5): inteiro aleatório uniforme entre 1 e 5 # #------------------------------------------------------------ # Exercício: simule o passeio aleatório de uma pessoa # (movimento browniano) durante n passos; # Em cada passo, escolhe aleatoriamente uma das 4 direcções # (E, N, W, ou S) e move-se nessa direcção o comprimento # "comp". # função a escrever; "def passeio(n,comp)" #------------------------------------------------------------ from turtle import * from random import * from math import * radians() def passeio(n,comp): pendown() speed("fastest") for i in range(n): ang=randint(0,3)*(pi/2.0) seth(ang) forward(comp) passeio (100,10)
#------------------------------------------------------------ # Exercício: desenhe uma estrela de n lados conforme se explica na aula... # estrela(n,comp) #------------------------------------------------------------ def estrela(n,comp): backward(comp/2.0) for i in range(n): forward(comp) right(180-180.0/n) estrela(5,100) #------------------------------------------------------------ # Outras formas da instrução for # for <var> in <lista>: # .... # # for <var> in <string>: # .... # # (ou expressão com valor <lista> / <string>!) # for [a,b] in ([1,2],[3,4],[4,4]): # print (a+b)/2.0 for [a,b] in ([1,2],[3,4],[4,4]): print (a+b)/2.0 # lado esquerdo: lista ou tuplo de variáveis, ex (a,b) # lado direito: lista de elementos da mesma forma, ex (..,..) # #------------------------------------------------------------ #------------------------------------------------------------ # Outro exercício com o turtle # # Exercício: desenhe uma estrela de n lados conforme se explica na aula... # estrela(n,comp) #------------------------------------------------------------ #from turtle import * #from math import * #def estrela(n,comp): # backward(comp/2.0) # for i in range(n): # forward(comp) # right(180-180.0/n) # #estrela(5,100) #================================================================= #================================================================= # teste de tipos # "função" "tipe" - teste com int, float, str, list, # type((2,)) == tuple type((2)) == tuple #--------------------------------------------- # Uma estrutura E pode ser # - um inteiro # - uma lista de 0 ou mais elementos do tipo E # # Exemplos: 0 # [[]] # [[1], 4, [[1,6]], [[[]]] ] # Problema: escrever uma função # soma(e) -> int (onde "e" tem a forma E) # que determina a soma de todos os inteiros na estrutura "e" def soma(e): if type(e)==int: return e s=0 for a in e: s=s+soma(a) return s print print "--------------------------------" li = [[1], 4, [[1,6]], [[[]]] ] print li, soma(li) #----------------------------------------------- # Exercício: # Escreva a função profu(e) onde "e" é uma estrutura # do tipo E, que calcula a profundidade máxima das listas em e # listas em e. # Exemplo: # profu(5) -> 0 # profu([]) -> 1 # profu([5,[[2]],3]) -> 3 def profu(e): # caso base if type(e)==int: return 0 # máxima prof elementos da lista... m=0 for x in e: p=profu(x) if p>m: m=p return m+1 print print "--------------------------------" for x in (5,[],[5,[[2]],3]): print x,profu(x) #----------------------------------------------- # Exercício: # Escreva a função copia(e) onde "e" é uma estrutura # do tipo E, que fornece uma cópia da estrutura e. # Exemplo: # >>> a=[1,2,3] # >>> b=copia(a) # >>> a[1] = "uuu" # >>> a # [1,"uuu",3] # >>> b # [1,2,3]
#================================================================= # Instruções de entrada de dados (input()) def teste(): a = input() print a+1 a = input("Diz um número: ") print a+1 #---------------------------------------------------------- # Saída formatada de dados: # formato % elementos -> string # string opr tuplo -> string # a=10 # s = "a=%4d" % (a+1,) -> "a= 11" # ... tuplos com 1 elemento # por vezes podem-se omitir os "(", ")" dos tuplos... # teste() from math import * def teste1(): s = "ai%3dui" % (4,) print s x=1.1 s = "x=%5.1f log(x)=%10.6f" % (x,log(x)) print s s = "x=%5.1f log(x)=%-10.6f" % (x,log(x)) print s teste1() # Exercício: escreva uma função "logs(n)" que imprime # a tabela dos logaritmos na base 2 dos inteiros 1, 2, ..., n # Formato pretendido # # x log(x) # -------------- # 1 0.0000 # 2 1.0000 # ----********** # 12345678901234 print def logs(n): print " x log(x)" print "--------------" for x in range(1,n+1): log2x = log(x)/log(2) s = "%4d%10.4f" % (x,log2x) print s logs(10) #------------------------------------------- # Exercício: escreva uma função 'codigos(m,n)' que imprime # a tabela dos inteiros m, m+1, ..., n nas bases # decimal, octal e hexadecimal # bem como os caracteres com esses códigos. Tipicamente # é 32 <= m<n <=127. # Formato pretendido # # 1234567890123456789 # -------------------- # 33 41 21 ! # 33 41 21 " # 33 41 21 # # ... ... ... ... print def codigos(m,n): for i in range(m,n+1): print "%4d%6o%5x%4s" % (i,i,i,chr(i)) codigos(33,50)
# Exercício de códigos # teste de minúscula # teste de acentos? # Valores de ("%d" % 3)*5 ("%d" % 3)+"ai" # Formatado: print <string> (só uma <string>) # # Programa com erros # # Random: # dado atirado n vezes: média, variância # área de uma zona # # Ordenação: # importância, slides, 3 métodos (selecção, bs, qs) #------------------------------------------- # Exercício: escreva uma função 'codigos(m,n)' que imprime # a tabela dos inteiros m, m+1, ..., n nas bases # decimal, octal e hexadecimal # bem como os caracteres com esses códigos. Tipicamente # é 32 <= m<n <=127. # Formato pretendido # # 1234567890123456789 # -------------------- # 33 41 21 ! # 33 41 21 " # 33 41 21 # # ... ... ... ... #---------------------------------------------------- # Note que a instrução de impressão formatada é da forma # print <string> # onde <string> é uma expressão cujo valor é uma string #---------------------------------------------------- print def codigos(m,n): for i in range(m,n+1): print "%4d%6o%5x%4s" % (i,i,i,chr(i)) codigos(33,50) #---------------------------------------------------- # Exercício: Letra minúscula? # Escreva uma função minus(a) cujo parâmetro a # é um caracter e que tem o resultado # True se a é uma letra minúscula # False caso contrário. # Deve haver uma só instrução (para além do "def") # da forma # return <expr> # A expressão <expr> deve ser tão curta quanto possível; # pode supor que os códigos de "a", "b",... são # consecutivos. # Não pode usar o módulo string (letters, # lowercase...) #---------------------------------------------------- for a in "aABc23e": print a, ord(a)>=ord("a") and ord(a)<=ord("z") #---------------------------------------------------- # Indique os valores e tipos de: # ("%d" % 3)*5 ________ # ("%2s %3d" % ("ui",3)) + "ai" _______ # len("%1000d" % 1)*1000 # # Atribua a "a" uma expressão curta cujo valor é a lista # [[1,1,...,1], [3,3,...,3],..., [99,99,...,9] ] # tendo cada lista interna 10 elementos # # a = ??? #---------------------------------------------------- a = [[n]*10 for n in range(1,101,2)] #---------------------------------------------------- # Aleatórios # from random import * # randint(a,b) -> aleatório uniforme em {a,a+1,...,b} # random() -> real aleatório em [0,1) #------------------------------------------- #------------------------------------------- # Exercício: escreva expressões aleatórias que correspondam a # lançamento de um dado (resultado 1 ou 2 ou ... ou 6) # lançamento de um par de dados (resultado 1 ou 2 ou ... ou 12) #------------------------------------------- from random import * print randint(1,6) print randint(1,6) + randint(1,6) #------------------------------------------- # Exercício # Escreva uma função # dados(m,n) # que "lança" m dados n vezes e determina a média dos # valores obtidos; por exemplo, para # dados(3,2) # se os resultados foram: 11,4,6, (m=2, n=3) a média é 10.5 #------------------------------------------- def dados(m,n): s=0.0 for i in range(n): r = 0 for d in range(m): r = r + randint(1,6) s = s+r return s/n #------------------------------------------- # Exercício # Determine a área aproximada entre # - a recta vertical x=0 # - a recta vertical x=2 # - a recta horizontal x=0 # - o gráfico da função y=sin(x) (x em radianos) # # Método: # c=0 # Fazer n vezes # 1) gerar um par: # x aleatório em [0,2], # y aleatório em [0,1] # 2) se y<sin(x): # c = c+1 # o resultado é (1*2)*(c/n) (divisão "float") # #------------------------------------------- # Generalize com a função area(f,x1,x2,ymax,n) # onde se admite que # - x=x1, xy=x2: rectas verticais # - f: função não negativa em [x1,x2] # - ymax: majorante de f(x) em [x1,x2] # - n: número de pares (x,y) gerados #------------------------------------------- from math import * def area(f,x1,x2,ymax,n): c=0.0 for i in range(n): x = x1 + (x2-x1)*random() y = ymax*random() if y < sin(x): c=c+1 return ymax*(x2-x1)*(c/n) # http://docs.python.org/index.html
#===================================================================== # Pesquisa e ordenação # Nas folhas P & TP: # método de ordenação por selecção do mínimo # método de ordenação "bubblesort" (bolha") # ------------------------------------------------------------------- # Pesquisa: # Dados: x, lista v # Resultado: determinar i tal que x==v[i] # ou -1 se x não está em v # --------- # Notação: v[a..b]: v[a,a+1,...,b] # (se a>b é a lista vazia) # # Uma implementação da pesquisa (pesquisa sequencial) # - x é comparado com v[0], v[1],... até ser x==v[i] # para algum i<len(v) # - se x não está em v[] é retornado -1 # # Possíveis aplicações...: # v: [("rui",(12,8,16,9)),("ana",(11,20)),("maria",())] # determinar a média das classificações obtidas por "ana" # # print "--- procura sequencial -----" def procura(x,v): """pesquisa sequencial""" for i in range(len(v)): if x==v[i]: return i return -1 a=[2,9,8,11,3,2,4] for x in [2,7,11,9,6]: print x, procura(x,a) def procura2(x,v): """pesquisa sequencial; x colocado no fim (conhecido por `método da sentinela` """ n=len(v) v.append(x) i=0 while x!=v[i]: i=i+1 if i<n: return i return -1 print a=[2,9,8,11,3,2,4] for x in [2,7,11,9,6]: print x, procura2(x,a) #-------------------------- # Pesquisa binária # Se v[] está ordenado (suponhamos por ordem crescente) # podemos procurar x muito mais rapidamente # ----------- # v[a...b] # determina-se m=(a+b)/2 (divisão inteira), é a<=m<=b # se x==v[m]: retorna m # se x<v[m]: retorna o resultado da procura em v[a..m-1] # se x>v[m]: retorna o resultado da procura em v[m+1..b] # ------ # função pesquisab(x,v,a,b): # if a>b: # intervalo vazio # return -1 # m=(a+b)/2 # if x==v[m]: # return m # elif x<v[m]: # return procura(x,v,a,m-1) # return procura(x,v,m+1,b) # ------- # # a m b x=11 # <-- --- --- --- --- --- --- --- --> # 9 # # a m b x=11 # --- --- --- --- --- <-- --- --- --> # 12 # # a=b=m x=11 # --- --- --- --- --- <-> --- --- --- # 10 # # b a x=11 # --- --- --- --- --- --> <-- --- --- # 10 # Intervalo vazio: único local onde x pode estar ==> # x não está ==> retorna -1 # # Mostrar que está correcto: # Por indução em b-a+1 (comprimento do intervalo) # # 1) Termina sempre: b-a reduz-se sempre # (nunca fica igual) e se nunca acontecer x==v[m] # acaba por ser a>b e acaba (também) a execução # 2) Quando é chamada pesquisab(x,v,a,b) # - se x está em v[] (todo), está em v[a..b] # Prova por indução em b-a+1 (tamanho do intervalo) # - caso base: a>b (=b+1) # - caso geral: # ou é calculado um valor correcto de m, # quando x==v[m] - resposta correcta # ou b-a diminui de tamanho e usamos a hipótese indutiva def pesquisab(x,v,a,b): if a>b: # intervalo vazio return -1 m=(a+b)/2 if x==v[m]: return m if x<v[m]: return pesquisab(x,v,a,m-1) return pesquisab(x,v,m+1,b) print a=[2,2,3,4,8,9,11] for x in [2,7,11,9,6]: print x, pesquisab(x,a,0,len(a)-1) def pesquisab2(x,v): """versão iterativa""" a=0 b=len(v)-1 while a<=b: m=(a+b)/2 if x==v[m]: return m if x<v[m]: b=m-1 else: a=m+1 return -1 # teste: print a=[2,2,3,4,8,9,11] for x in [2,7,11,9,6]: print x, pesquisab2(x,a) #================================================== # Ordenação #================================================== #------------------------------------------ # Ordenar uma lista; na saída: # mesmos elementos, # mesma mutiplicidade # por ordem # # Métodos: # muitos: bubble sort, selecção do mínimo, # heap sort, quicksort, merge sort... # # Ver: Knuth, The Art of Computer Programming # Vol III: sorting and searching #------------------------------------------ #------------------------------------------------ # Selecção do mínimo, v[0..n-1] #------------------------------------------------ # - determinar o menor dos v[0..n-1] trocar com v[0] # - determinar o menor dos v[1..n-1] trocar com v[1] # - ... # - determinar o menor dos v[0..n-1] trocar com v[n-1] # # Exemplo: [8,3,2,9,4] -> [2,3,8,9,4] -> [2,3,8,9,4] -> # --------- ------- ----- # -> [2,3,4,9,8] -> -> [2,3,4,8,9] # --- - def sm(v): n=len(v) for i in range(n-1): min=i for j in range(i+1,n): if v[j] < v[min]: # (*) min=j v[i],v[min] = v[min],v[i] return a print "---------- sm" a=[8,3,2,9,4] print a,sm(a) a=[2,1,2,1,2,1,1] print a,sm(a) #------------------------------------------------ # Quicksort #------------------------------------------------ # qs # Fixar um índice, por exemplo v[0] # dividir v em # - l1 = lista dos menores que v[0] # - l1 = lista dos menores que v[0] # - [v[0]] # Resultado: qs(l1)+[v[0]]+l2 #--- funciona se todos distintos... def qs(v): if len(v)<=1: return v return qs([x for x in v if x<v[0]]) + [v[0]] +\ # (*) qs([x for x in v if x>v[0]]) # (*) print "---------- qs" a=[8,3,2,9,4] print a,qs(a) a=[2,1,2,1,2,1,1] print a,qs(a) #--- funciona no caso geral def qs1(v): n=len(v) if len(v)<=1: return v return qs1([v[i] for i in range(1,n) if v[i]<=v[0]]) +\ # (*) [v[0]] +\ qs1([v[i] for i in range(1,n) if v[i]>v[0]]) # (*) print "---------- qs1" a=[8,3,2,9,4] print a,qs1(a) a=[2,1,2,1,2,1,1] print a,qs1(a) #----------------------------------- # Agora um método muito eficiente só aplicável # em casos especiais: # - todos os valores são inteiros distintos # compreendidos entre 0 e m-1 (m não muito grande) def bs(v): m=20 # tipicamente poderia ser m=1000 r=[] c=[0]*m # c[i] vai ser 1 sse i existe em v for x in v: c[x]=1 print c # instrução a retirar! return [i for i in range(m) if c[i]==1] print "---------- bs" a=[8,3,2,9,4] print a,bs(a) a=[2,1,2,1,2,1,1] print a,bs(a) # Exercício: altere a implementação da função 'bs' # por forma a ordenar listas com elementos repetidos. # Sugestão: use c[i] para contar o número de # ocorrências de i em v; # exemplo v=[2,1,2,1,2,1,1], c=[0,4,3,0,0,...] #------------------------------------------------ # Eficiência # Contar o número de comparações envolvendo elementos # do vector a ordenar linha (*) # # Selecção do mínimo: n(n-1)/2 # Quicksort: ~n*log(n) no caso médio # ~n*n no pior caso #------------------------------------------------
Escreva uma função "zero(a,b,erro)" tal que, dado: - um intervalo [a,b] com a<b - um valor erro>0 - uma função f (fixa) contínua em [a,b], com sinais contrários nos extremos do intervalo e com um só zero no intervalo, a função retorna x em [a,b] com f(x) aproximadamente igual a zero, isto é, f(x-erro) e f(x+erro) devem ter sinais contrários. Observações: - Pode assumir que nunca acontece (nunca vai calhar exactamente) f(x)=0. - Pode testar que os sinais de x e y são diferentes com a condição f(x)*f(y)<0. - O intervalo [a,b] deve ser sucessivamente partido a meio, até que b-a<erro. Haverá pois algures uma condição "while b-a >= erro". Quando se verificar b-a<erro, a solução aproximada com um erro (no eixo dos xx) não superior e erro, é a (ou b ou (a+b)/2). ----------------------------------------------------------- Introduzir uma função no argumento de "zero", ficando pois a função "zero(f,a,b,erro)". Método das bissecções sucessivas para calcular (aproximadamente) a raíz f(x)=0: def zero(f,a,b,erro): while b-a>=erro: x=(a+b)/2.0 if f(x)*f(a)>0: # mesmo sinal de x e a -> fica [x,b] a=x else: # mesmo sinal de x e b -> fica [a,x] b=x return (a+b)/2.0 # Nota. também poderia ser "return a" ou "return a" - a condição de erro ficava satisfeita Exercício: ---------- Por hipótese, no início os sinais de a e b são diferentes, mas... se o metodo for aplicado aos casos seguintes o que acontece? a) Função constante igual a 1, a=0, b=10 b) Função com mais que uma raíz Exercício: ---------- Implemente a função "zero" de forma recursiva; a implementação deve ser análoga à anterior, mas - não deve haver qualquer ciclo ("for" ou "while") - devem existir chamadas à própria função que se está a definir (recursividade).
Vamos usar aleatórios para calcular a probabilidade (aproximada) de um acontecimento Atira-se 5 vezes uma moeda ao ar; qual a probabilidade de sairem 4 ou cinco "coroas"? a) Mais geralmente, escreva a função coroas(n,c) que retorna | True se sairam c ou mais coroas | False caso contrario b) Escreva a função probab(n,c,exp) que chama exp vezes "coroas(n,c)" e retorna a probabilidade (aproximada) de sairem c ou mais coroas (aproximadamente) = (Num. de vezes em coroas(n,c)==True) / exp c) Calcule a probabilidade exacta do caso n=5, c=4 e compare com probab(5,4,10000) (6/32)
Pretende-se calcular a área aproximada de uma região... h |................... | /\ | | /--\f(x) | /----\ | | /------\ | |/--------\ ------------------------- a b x At = área a tracejado (entre f(x) e o eixo xx) A = área rectângulo = h(b-a) Gerando um ponto aleatório no rectangulo: x = ... y = ... n = num. pontos total s = num de pontos que satisfaz y < sin(x) At s -- = (aprox.) - A n a) Escreva uma função area(f,a,b,h,n) onde - f(x)>0 para a<=x<=b - h e' um majorante de f(x) para a<=x<=b
# 1) Esquecer de incrementar o i, ciclo infinito # 2) Confundir índices com valores def somapares(li): """ soma os elementos pares da lista de inteiros li""" s=0 i=0 while i<len(li): if i%2==0: # print i,li[i] # assert li[i]%2==0, "Elemento nao e' par!" s=s+li[i] i=i+1 return s lista=[5,6,7,8] print lista, somapares(lista) #-------------- def somapares1(li): """ soma os elementos pares da lista de inteiros li >>> [somapares1(a) for a in [[5,1,3],[2],[1,2,3,6]] ] [0, 2, 8] """ s=0 i=0 while i<len(li): if i%2==0: print i,li[i] assert li[i]%2==0, "Elemento nao e' par!" s=s+li[i] i=i+1 return s def _test(): import doctest doctest.testmod() if __name__ == "__main__": _test() # lista=[5,6,7,8] # print lista, somapares(lista)
# Um anagrama de uma string s á uma string t que # tem exactamente as mesmas letras com as mesmas multiplicidades # Exemplos # s: "banana" t: "anaban" -> True # s: "banana" t: "anabab" -> False # s: "marcelo sousa" t: "salmão escuro" # s: "anibal cavaco" t: "cabala nociva" # Escreva ums função # anagrama(s,t) que testa se t é um anagrama de s # ("ser anagrama de" é uma relação R, S, T) # O resultado é True ou False # Apenas se consideram as letras minúsculas não acentuadas # (ignoram-se espaços, sinais de pontuação, letras maíusculas...) def anagrama(s,t): return contaletras(s)==contaletras(t) def contaletras(s): """ retorna uma lista c[], onde c[0] é o número de a´s de s, c[1] é o número de b´s de s, etc. Exemplo: contaletras("banana") -> [3,1,0,0,...,1,0,...] """ letras="abcdefghijklmnopqrstuvwxyz" c=[0]*26 for x in s: if x in letras: cod = ord(x)-ord("a") c[cod] = c[cod]+1 return c for (s,t) in [("banana","anaban"),\ ("banana","anabab"),\ ("marcelo sousa","salmao escuro"),\ ("anibal cavaco","cabala nociva")]: print s, t, anagrama(s,t) # Outra solução para anagrama(s,t): # "limpar" s # "limpar" t # Ordenar as 2 strings e comparar # return sorted(s1)==sorted(t1) #-------------------------------------------- # Um exercício de ordenação com contagem de frequências # li: [8,5,3,9,1,2,9,3] (elementos entre 0 e m) # c: [0,0,0,0,0,0,0,0,0,0,0,0] (m=11) # c: [0,1,1,2,0,1,0,0,1,2,0,0] # # ordena(li): # constrói c # percorre i:0, 1, ..., m: # repetir c[i] vezes # append de i a r def ordena(li): m=12 c = [0]*(m+1) r=[] for x in li: c[x] = c[x]+1 print c for i in range(1,m): for k in range(c[i]): r.append(i) return r li=[8,5,3,9,1,2,9,3] print li, ordena(li) # Uma nova técnica de ordenação, "bucket sort" # Vantagem: muito rápido, se m não muito grande, # O(m+n) onde n=len(li) # Limitação: valores a ordenar inteiros e não # muito grandes: os valores são índices!
#------------------------------------------------------------ # 1. Criar uma nova lista li com [1,2,3,1,2,3,...] (300 elementos) # a) usando append # b) usando lista*inteiro # c) usando uma lista em compreensão #------------------------------------------------------------ li1=[] for i in range(10): li1.append(1) li1.append(2) li1.append(3) print print "1a" print len(li1),li1 li2=[1,2,3]*10 print print "1b" print len(li2),li2 li3=[i%3+1 for i in range(30)] print "1c" print len(li3),li3 #------------------------------------------------------------ # 2. Como é que uma função retorna 2 valores? # Com um tuplo. # Exemplo: Escreva uma função 'roda(p,a)' onde # - p é um tuplo (x,y) que representa um ponto do plano # - a é um ângulo # que retorna o ponto (x1,y1) que resulta da rotação # do ponto (x,y) de 'a' graus no sentido directo. # # | # | | x1 = x*cos(a) - y*sin(a) # | | y1 = x*sin(a) + y*cos(a) # y| o # ----------------- # x #------------------------------------------------------------ from math import * def roda(p,a): x=p[0] y=p[1] x1 = x*cos(a) - y*sin(a) y1 = x*sin(a) + y*cos(a) return (x1,y1) print print "1b" for (p,a) in [((1,0),pi/4), ((0,1),2*pi),((1,1),0),((-1,-1),pi/2)]: print p,a,roda(p,a) #------------------------------------------------------ # 3. a) Escreva uma função (sem parametros) # # tab_verd() # # que imprima a tabela de verdade de # # a and (b or not c) # # Nota: pode fazer com que "i" tome sucessivamente os valores de uma # lista "lista" com uma instrução do tipo "for i in lista:". # Por exemplo: # # for i in [False,True]: # print i # # Note que a, b, c devem tomar todos as combinações de valores # booleanos. #------------------------------------------------------------ def tab_verd(): logs = [False,True] print print "a and (b or not c)" print print "a b c valor" print "-----------------------" for a in logs: for b in logs: for c in logs: print conv(a),conv(b),conv(c),a and (b or not c) def conv(log): if log: return "True " return "False" tab_verd() #--------------------------------------------- # 4. Considere a função def f(n): if n==1: return 1 if n%2==0: return f(n//2) return f(3*n+1) # a) Determine "com papel e lális" f(3), f(5) e f(7) # b) Confirme # c) Mostre que, qualquer que seja o inteiro n>=1, # a computação de f(n) termina #------------------------------------------------------------ #------------------------------------------------------------ # 5. a) Escreva uma função # sufixo(s,t) # que retorna True se s é sufixo de t e False caso contrário. # Exemplos: # sufixo("","") -> True # sufixo("ab","cab") -> True # sufixo("ab","abc") -> False # sufixo("ab","ab") -> True # # b) Escreva uma função # sufixos(s) # que retorna a lista dos sufixos de s. Pode apenas usar # as funções/métodos ensinados nas aulas. # Exemplos: # sufixos("xbca") -> ["xbca","bca","ca","a",""] #------------------------------------------------------------ # usando slides... suf=s[i:] era mais fácil def sufixo(s,t): # s sufixo de t m=len(s) # s: 0 1 .... m-1 n=len(t) # t: 0 1 ... n-m n-m+1 .... n-1 if m>n: return False for i in range(m): if s[i]!=t[n-m+i]: return False return True print print "5a" for (s,t) in [("",""),("ab","cab"),("ab","abc"),("ab","ab")]: print "s=",s,"t=",t,sufixo(s,t) # usando slides... suf=s[i:] era mais fácil def sufixos(s): n=len(s) suf="" r=[suf] for i in range(n-1,-1,-1): # sufixo s[i]s[i+1]...s[n-1] suf = s[i]+suf r.append(suf) return r print print "5b" s="xbca" print s, sufixos("xbca") # -> ["xbca","bca","ca","a",""] #------------------------------------------------------------ # 6. Uma operação binária definida no conjunto A={0,1,...,n} # é descrita por uma lista de listas, conforme se # exemplica para o caso n=3. # # t: [[0,1,2],\ # [1,2,0],\ # [2,0,1]] # Escreva uma função # associativo(t) # que retorna 'True' se a operação representada por 't' for # associativa e 'False' caso contrário. #------------------------------------------------------------ def associativo(t): n=len(t) # lista de listas... for a in range(n): for b in range(n): for c in range(n): ab = t[a][b] r1 = t[ab][c] bc = t[b][c] r2 = t[a][bc] if r1!=r2: return False return True print print "6" t1= [[0,1,2],\ [1,2,0],\ [2,0,1]] t2= [[0,2,2],\ [1,1,0],\ [2,0,1]] print t1,associativo(t1) print t2,associativo(t2)
#------------------------------------------------------------ # Conjuntos: representações: # - Listas (sem ordem) # - Listas ordenadas # - Vectores de bits (indicativos de presença) # - Usar uma estrutura de dicionário já existente # - usar estruturas conhecidas por árvores.... #------------------------------------------------------------ #------------------------------------------------------------ # 1. Suponha que um conjunto é representado por uma lista # (não necessariamente ordenada) # # {2,3,5,9} <-> [2,9,3,5] (ordem sem importância) # # a) implemente a operação de reunião, uniao(a,b) # Exemplo: uniao([2,4,5],[1,4,9]) -> [1,2,4,5,9] # # b) outras operações: # intersecçao(a,b) # pertence(x,a) # #------------------------------------------------------------ def uniao(a,b): r=[] for x in a: r.append(x) for x in b: if not x in r: r.append(x) return r print print "1" print uniao([2,4,5],[1,4,9]) #------------------------------------------------------------ # 2. Suponha que um conjunto é representado por um # "lista de presenças" (bit array,...) # # {2,3,5,9} <-> [0,0,1,1,0,1,0,0,0,1] (máximo 9) # # a) implemente a operação de reunião, uniao(a,b) # # b) outras operações: # intersecçao(a,b) # pertence(x,a) # # # #------------------------------------------------------------ def uniao2(a,b): m=10 # elementos entre 0 e 9 r=[0]*m for x in range(m): if a[x]==1 or b[x]==1: r[x]=1 return r a=[0,0,1,1,0,1,0,0,0,1] b=[0,1,1,0,0,1,1,0,0,0] print a,b,uniao2(a,b) #------------------------------------------------------------ # 3. Suponha que um conjunto é representado por uma lista # ordenada. # # {2,3,5,9} <-> [2,3,5,9] (ordem sem importância) # # a) Usando o algoritmo de pesquisa binária, implemente # eficientemente a operação # interseccao(a,b) # # Nota: para a 'união' usa-se o algoritmo de 'merge' # # b) Porque é que o resultado fica ordenado (mesma representação)? # # c) Determine a ordem de grandeza da eficiência do algoritmo. # |b| * log(|a|) #------------------------------------------------------------ def pb(x,v): a=0 b=len(v)-1 while a<=b: m=(a+b)/2 if x==v[m]: return True if x<v[m]: b=m-1 else: a=m+1 return False def interseccao(a,b): r=[] for x in a: if pb(x,b): r.append(x) return r print print "3" a=[2,3,5,8,9,11,18] b=[1,3,9,11,33] print a, b, interseccao(a,b) #------------------------------------------------------------ # Escreva uma função converte(li,m) # que converte a lista li para o bit array barray # num universo de m elementos {0,1,...,m-1} # ex: converte([4,2,1],10) -> [0,1,1,0,1,0,0,0,0,0] #------------------------------------------------------------ def converte(li,m): r=[0]*m for x in li: r[x]=1 return r print converte([4,2,1],10) #------------------------------------------------------------ # 6. Uma operação binária definida no conjunto A={0,1,...,n} # é descrita por uma lista de listas, conforme se # exemplica para o caso n=3. # # t: [[0,1,2],\ # [1,2,0],\ # [2,0,1]] # Escreva uma função # associativo(t) # que retorna 'True' se a operação representada por 't' for # associativa e 'False' caso contrário. #------------------------------------------------------------ def associativo(t): n=len(t) # lista de listas... for a in range(n): for b in range(n): for c in range(n): ab = t[a][b] r1 = t[ab][c] bc = t[b][c] r2 = t[a][bc] if r1!=r2: return False return True print print "6" t1= [[0,1,2],\ [1,2,0],\ [2,0,1]] t2= [[0,2,2],\ [1,1,0],\ [2,0,1]] print t1,associativo(t1) print t2,associativo(t2)
#------------------------------------------------------- # Escreva uma funcao nmaximos(li) # onde li é uma lista de inteiros # e que retorna o número de elementos de li # que são iguais ao maior valor na lista. # Exemplo: # nmaximos([2,1,5,9,3,9,4,2]) -> 2 # # 1) Percorrer a lista 1 vez para determinar o máximo # função maximo(li) # 2) Percorrer a lista, e cada vez que li[i]==maximo, # contar mais 1 #------------------------------------------------------- def nmaximos(li): n=len(li) mx=maximo(li) c=0 for i in range(n): if li[i]==mx: c=c+1 return c def maximo(li): mx=li[0] for i in range(2,len(li)): if li[i]>mx: mx=li[i] return mx #------------------------------------------------------- # Escreva uma funcao nmaximos2(li) # efectuando apenas 1 passagem (com 1 ciclo 'for') # pela lista li #------------------------------------------------------- # mx: maior elemento já encontrado # num: número de elementos com valor mx def nmaximos2(li): n=len(li) mx = li[0] num = 0 for x in li: if x>mx: mx=x num=1 elif x==mx: num=num+1 return num for li in ([2,1,5,9,3,9,4,2],[1,1,1],[1,1,2]): print li,nmaximos(li),nmaximos2(li) #------------------------------------------------------- # Escreva uma funcao nmaximos3(li) # com apenas 1 instrução (de 'return') # Nota: pode usar a função 'max' #------------------------------------------------------- def nmaximos3(li): return len([x for x in li if x==max(li)]) for li in ([2,1,5,9,3,9,4,2],[1,1,1],[1,1,2]): print li,nmaximos(li),nmaximos2(li),nmaximos3(li) #-------------------------------------------------------------- # Escreva uma função # perfeito(n) # que retorna True se n é um quadrado perfeito # e False caso contrário # Exemplo: perfeito(16) -> True # # A função deve ser eficiente (tempo proporcional a log(n)) # e basear-se no método da pesquisa binária. # Inicialmente sabe-se que o resultado está entre 0 e n... #-------------------------------------------------------------- def perfeito(n): min=0 max=n # se n tem raiz exacta m (n=m*m), então min <= m <= max while min<=max: m=(min+max)/2 m2=m*m if m2==n: return True # raíz encontrada! elif m2<n: min=m+1 else: max=m-1 return False # não existe raíz for i in range(20): print i, perfeito(i) #-------------------------------------------------------------- # Uma matriz quadrada é representada por uma lista de listas # # [[1,3,4], # [2,1,5], # [4,0,6] # ] # Calcular o determinante # 1. "Triangularizar" a matriz # ------------------------- # determinante = produto dos elementos da diagonal principal # # - Somar uma linha multiplicada por uma constante a outra # não altera o determinante # - Assume-se que nunca vai ser a[i][i]==0 # # i=0, j=1,2 # 1. Somar a 1a linha multiplicada por (-2) à 2a linha # Somar a 1a linha multiplicada por (-4) à 3a linha # [[1, 3, 4], # [0, -5, -3], # [0,-12,-10] # ] # # i=1, j=2 # 1. Somar à 3a linha a 2a linha multiplicada por (-12/5=-2.4) # [[1, 3, 4 ], # [0, -5, -3 ], # [0, 0, -2.8] # ] # # 2. Determinante = produto dos elementos da diagonal principal # Neste caso: 1*(-5)*(-2.8) = 14 #-------------------------------------------------------------- def determinante(mat): n=len(mat) for i in range(n): for j in range(i+1,n): fac=-mat[j][i]/(mat[i][i]+0.0) mult(mat,i,j,fac) display(mat) prod=1 for i in range(n): prod=prod*mat[i][i] return prod def mult(mat,i,j,f): n=len(mat) for k in range(n): mat[j][k] = mat[j][k] + f*mat[i][k] def display(mat): n=len(mat) print print for i in range(n): for j in range(n): print ("%6.2f" % (mat[i][j])), print print mat = [[1,3,4],\ [2,1,5],\ [4,0,6]] display(mat) print determinante(mat)
Nota. O seguinte 'site' contém lições sobre o Tkinter (e sobre aspectos gerais do pyton) que podem ser interessantes... http://wiki.python.org/moin/Intro%20to%20programming%20with%20Python%20and%20Tkinter ------------------------------------------------------------------------ Primeiro exemplo: desenho de um rectângulo e de uma linha num 'canvas' ------------------------------------------------------------------------ from Tkinter import * # objecto Tk... janela: main=Tk() # canvas, chamado 'w': w=Canvas(main,width=200,height=100,bg="#444444") # colocá-lo na janela: w.pack() # rectângulo no canvas 'w' w.create_rectangle(50,50,80,80,fill="#ff0000") # linha (0,20)-(10,90)-(20.90)-(100,10) no canvas 'w' w.create_line(0,20,10,90,20,90,100,10) mainloop() ------------------------------------------------------------------------ Segundo exemplo: texto e botão (carregando nele, destrói-se a janela...) ------------------------------------------------------------------------ from Tkinter import * from Tkconstants import * tk = Tk() frame = Frame(tk, relief=RIDGE, borderwidth=20) frame.pack(fill=BOTH,expand=1) label = Label(frame, text="Que lindo!",background="#a000a0") label.pack(fill=X, expand=1) button = Button(frame,text="Embora!",command=tk.destroy) button.pack(side=BOTTOM) tk.mainloop() ------------------------------------------------------------------------ Desenho de imagens... ------------------------------------------------------------------------ # ===================================================== # Desenho de imagens a preto e branco com o 'Tkinter' -- # Reducao de contraste # ===================================================== # # Possivel representacao de uma imagem # --------------------------------------------------------------- # - Uma "imagem" a preto e branco (PB) e' uma lista de linhas, # cada linha e' uma lista de valores entre 0 (preto) # e 255(branco) # # Uma "imagem" a cores e' um tuplo # (r,g,b) # onde r,g,b sao imagens a preto e branco # ... claro que outras representações (organizações da informação) seriam possíveis... # --------------------------------------------------------------- # Funcoes usadas: # redc: reduz o contraste de uma imagem a preto e branco # pbimagem: mostra uma imagem a preto e branco # cimagem - mostra uma imagem a cores # grey, dig16, color: funcoes auxiliares # --------------------------------------------------------------- # from Tkinter import * # modulo grafico from random import * from copy import * # ----------------------------------------------- # converter inteiro para string - digito hexadecimal # ----------------------------------------------- def dig16(n): "n de 0 a 15 -> digito hexadecimal" return "%x"%(n) # ---------------------------------------------- # gerar uma "imagem" aleatoria # ---------------------------------------------- # #--- -> imagem aleatoria lado * lado def lrand(lado): return [[randint(0,255) for a in range(0,lado)]\ for b in range(0,lado)] # ------------------------------------------------ # reduz o contraste de uma 'imag' quadrada # ------------------------------------------------ def redc(im): n=len(im) c=deepcopy(im) for y in range(1,n-1): # 1 a n-2 for x in range(1,n-1): # 1 a n-2 c[x][y]=(im[x][y]+im[x-1][y]+im[x+1][y]+im[x][y-1]+im[x][y+1])/5 return c # -------------------------------------------------------- # desenha uma imagem a preto e branco # list: [[linha 0],[linha 1],...,[linha n]] # ps: pixel size, cada ponto e' representado por um quadrado # de dimensoes ps*ps # Nota: O valor de y cresce quando se desce na janela # (convenção contrária à usual...) # -------------------------------------------------------- def pbimagem(lista,ps=30): """ desenha o rectangulo composto de quadrados, 'lista'; cada quadrado tem 'ps' de lado """ nx=len(lista[0]) # n. de colunas ny=len(lista) # n. de linhas dx=nx*ps # lado horizontal (total dos quadrados) dy=ny*ps # lado vertical (total dos quadrados) main=Tk() w=Canvas(main,width=dx,height=dy) w.pack() for y in range(ny): # desenhar os quadrados y0=dy-y*ps-ps for x in range(nx): col=grey(lista[y][x]) x0=x*ps w.create_rectangle(x0,y0,x0+ps,y0+ps,fill=col) mainloop() #-- define string de cor cinzenta def grey(x): """ cor cinzenta ex, x=160 -> "#a0a0a0" (cinzento) """ r=dig16(x/16)+dig16(x%16) g=r b=r return "#"+r+g+b # Pequeno teste sem usar o Tkinter: #a=lrand(3) #print a #a=[[6,0,3],[8,0,8],[6,1,5]] #print a #print redc(a) # teste do desenho da imagem a pb e da redução de contraste: #a=lrand(50) #pbimagem(a,20) #pbimagem(redc(a),20) # ===================================================== # Desenho de imagens a cores com o 'Tkinter' # ===================================================== # # Lembrando... # --------------------------------------------------------------- # - Uma "imagem" a cores e' formada por 3 listas de linhas, # 3 imagens, # como nas imagens a preto e branco # --- e' da forma (r,g,b) onde r,g,b sao imagens a preto e branco # --------------------------------------------------------------- # ----------------------------------------------- # converter inteiro para string - digito hexadecimal # <Igual ao programa "preto e branco"> # #---------------------------------------------- # gerar uma "imagem" aleatoria # <Igual ao programa "preto e branco"> # #------------------------------------------------ # --- exercicio das aulas # reduz contraste, imag tem que ser quadrada # <Igual ao programa "preto e branco"> # # ----------------------------------------------- # (r,g,b): R, g b - mesmo formato que a preto e branco # podiamos ter usado uma lista de lista de trios... # ----------------------------------------------- def cimagem((r,g,b),ps): nx=len(r[0]) # n. de colunas ny=len(r) # n. de linhas dx=nx*ps # lado horizontal dy=ny*ps # lado vertical main=Tk() w=Canvas(main,width=dx,height=dy) w.pack() for y in range(ny): y0=dy-y*ps-ps for x in range(nx): col=color(r[y][x],g[y][x],b[y][x]) x0=x*ps w.create_rectangle(x0,y0,x0+ps,y0+ps,fill=col) mainloop() def color(r,g,b): """ r,g,b: entre 0 e 255 retorna string com r, g, b em hexadecimal RRGGBB Exemplo, vermelho escuro: 880000 """ red =dig16(r/16)+dig16(r%16) green=dig16(g/16)+dig16(g%16) blue =dig16(b/16)+dig16(b%16) return "#"+red+green+blue #===================================================== # --- teste a cores #===================================================== # teste do desenho da imagem a cores e da redução de contraste: #lado=32 #r=lrand(lado) # vermelhos: lado*lado aleatório, cada de 0 a 255 #g=lrand(lado) # verdes: lado*lado aleatório, cada de 0 a 255 #b=lrand(lado) # azuis: lado*lado aleatório, cada de 0 a 255 #imag = (r,g,b) # tuplo rgb #cimagem(imag,30) #x=raw_input() #rimag = (redc(r),redc(g),redc(b)) #cimagem(rimag,30) # imagem com o contraste reduzido
# 1) # Descrever por palavras (ou através de uma expressão matemática) # o valor calculado (no caso geral) por cada uma das seguintes funções # Admite-se que os parâmetros a, b são inteiros não negativos. # a) def fx(a,b): x=a for i in range(b): x=x*a return x # b) def fy(a,b): x=a for i in range(b): x=x*x return x # c) def fz(a,b): x=a for i in range(b): x=x*x return x return x # 2) # Escrever uma função equivalente à função 'fz' sem usar qualquer # ciclo (while ou for) #---------------------------------------- # 3) # Reescrever a função 'fy' substituindo o ciclo 'for' por # um ciclo 'while' #---------------------------------------- # 4) # A seguinte função é equivalente a uma das funões 'fx, 'fy' ou 'fz'. # Diga a qual e porquê. def g(a,b): if b==0: return a return g(a,b-1)*a # teste for (a,b) in [(2,3),(3,0),(3,1),(3,4)]: print "a=", a, "b=", b, "fx=", fx(a,b),\ "fy=", fy(a,b), "fz=", fz(a,b), "g=", g(a,b) #---------------------------------------- # 5) # Seja 'a' uma lista de valores 'int' ou 'float'. Escreva uma função # retira(a) # que determina a lista que se obtém de 'a' retirando todos os # valores iguais ao máximo e todos os valores iguais ao mínimo. # Exemplo retira([8,9,1,9,2,7,9]) -> [8,2,7] # Admite-se que 'a' tem pelo menos um elemento. # Notas: # Pode usar as funções 'max' e 'min'. A utilização de listas em # compreensão facilita a solução deste problema, def retira(a): ... # teste li=[8,9,1,9,2,7,9] print li, retira(li) li=[5] print li, retira(li)
Estruturas de dados Básicas: int, float, bool Objectos listas (list) [...,...,...] tuplos (tuple) (...,...,...) strings e caracteres (str) "...." Funções bissexto: int --> bool >: int * int --> bool divisivel: int * int --> bool sort: list --> list divisores: int --> list newton: function * function * float * float --> float -------------------------------------------------------- Exercícios com strings 1) contar vogais cvog(s) str -> int percorrendo os caracteres de uma string teste "c é vogal"? -> incrementa s def cvog(s): n=len(s) nv=0 for i in range(n): if s[i] in "aeiou": nv=nv+1 return nv 2) diminuitivos (o programa nao vai ser perfeito) dim(s) str --> str Formar novo string até ao penútimo caracter (usar +) se o último caracter = a ==> nao o incluir e concatenar ... se o último caracter = o ==> nao o incluir e concatenar ... outros casos ==> juntar ... Melhorar: casario -> casariozinho def dim(s): n=len(s) r="" for i in range(n-1): r=r+s[i] if s[n-1]=="a": return r+"inha" if s[n-1]=="o": return r+"inho" return r+s[n-1]+"inho" 3) Concatenação concat(a,b) str*str --> str Formar novo string para o qual se copia a e depois b (r = r + c) def concat(a,b): na=len(a) nb=len(b) r="" for i in range(na): r=r+a[i] for i in range(nb): r=r+b[i] return r 4) Ordenar: escrever uma função de comparação comp(a,b) que compara palavras que (só) podem ter letras maiúsculas ou minúsculas ou dígitos. - Não há diferenca entre letras maiúsculas ou minúsculas - Os dígitos são ignorados - resultado: -1,0,1 conforme a<b, a=b, a>b Exemplos: compara("Ai50","a9i") -> 0 compara("","a") -> -1
Bibliografia
Muitas outras referências podem ser interessantes...ver por exemplo os slides. Mas não nos esqueçamos que, para aprender programar, mais importante que ler livros é programar.
Ver também os "elementos de estudo"
Prova prática, exames e classifica�'ões
Classifica�'ões
Classifica�'ões da prova prática.
Alunos sem frequência (de entre os alunos que estavam inscritos � s aulas práticas).
Notas importantes sobre a prova e o exame
Pergunta: Qual o valor de [1+3-2 for i in range(1,5)]? Respostas: 2,2,2,2 ......... errada, 0%! [2 2 2 2] ......... errada, 0%! (2,2,2,2) ......... errada, 0%! [2,2,2,2,2]........ errada, 0%! [2,2,2,2,2] ....... errada, 0%! [1,2,3,4] ......... errada, 0%!
x=s[i+1]-3
), não sendo permitidos
os "slices" (por exemplo, s[1:4]=[3]
); se não sabe o que
são "slices", não se preocupe porque não se espera que saiba.
Docentes
Turmas Docente xxx --------------------------------------- T TP1 TP2 P1 Armando Matos acm P5 P6 Ana Paula Tomás apt P4 Luis Antunes lfa P2 P3 Sérgio Crisóstomo slc --------------------------------------- email de cada docente: xxx@dcc.fc.up.pt
Emacs: atalhos do teclado
Para instalar python no seu sistema operativo (linux, windows, mac-os), procure em
Para instalar python e emacs no sistema Windows é necessário que o emacs saiba o endereco do interpretador de python. Uma hipótese é sugerida pelo seguinte exemplo
Localiza�'ão do programa 'emacs': C:\emacs-22.3-bin-i386\emacs-22.3\bin\runemacs.exe "home": C:\Documents and Settings\acm\Application Data file O ficheiro de configura�'ão '.emacs' está no "home". --------------------------------------- Localiza�'ão do interpretador de pyhon (python command line) C:\Python25\python --------------------------------------- conteúdo poss�-vel do ficheiro '.emacs' - a parte importante é a linha ...'(python-python-command "C:\\Python25\\python") Quase tudo são comentários... C:\Documents and Settings\acm\Application Data\.emacs: (custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(python-python-command "C:\\Python25\\python") '(show-paren-mode t) '(tool-bar-mode nil) '(transient-mark-mode t)) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. )
Ver.
>>> s="aiai" # s passa s ser uma string (objecto da classe str) >>> type(s) <type 'str'> # ... como se vê! >>> dir(s) # Os métodos das strings: ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] print a.lower.__doc__ # Documenta�'ão sobre "lower" S.lower() -> string Return a copy of the string S converted to lowercase. >>> from math import * >>> help("math") ... ...