sexta-feira, 8 de janeiro de 2010

Exame Normal

1.
(a)Identidade: referência para a zona da memória onde se encontra armazenado o objecto. Valor: o estado do objecto num dado momento, em termos simples,o seu conteúdo. Tipo: determina o conjunto de valores e as operações que podem ser efectuadas com os objectos do tipo.


(b)As chaves de um dicionário têm que ser objectos imutáveis.

2.
Nas duas primeiras linhas associamos nomes diferentes ao mesmo objecto, logo a identidade tem que ser a mesma. Na terceira linha criamos uma cópia desse objecto e associamos-lhe o nome c. Assim neste último caso a identidade tem que ser diferente. A figura ilustra a situação.





3.

Para a soma de uma constante a um vector apresentamos duas soluções.

def soma_constante(c, vector):
""" Soma a constante c a cada uma das componentes do vector v."""
return [ c + elem for elem in vector]

def soma_constante_b(c, vector):
""" Soma a constante c a cada uma das componentes do vector v."""
res= []
for elem in vector:
res.append(c+elem)
return res


4.
De um ficheiro a um dicionários de frequências. Apresenta-se primeiro uma solução simples, mas que é aceite como resposta correcta.

def fich_dic_a(ficheiro):
""" Lê o conteúdo do ficheiro e constrói um dicionário
com chave um inteiro e valor uma lista com as palavras de
comprimento igual ao valor da chave.
"""
f_in = open(ficheiro, 'r')
lista_pal = f_in.read().split()
dic = {}
for palavra in lista_pal:
comp = len(palavra)
dic[comp] = dic.get(comp,[]) + [palavra]
return dic

Agora uma solução que prevê o uso de símbolos especiais.

def fich_dic_b(ficheiro):
""" Lê o conteúdo do ficheiro e constrói um dicionário
com chave um inteiro e valor uma lista com as palavras de
comprimento igual ao valor da chave.
"""
f_in = open(ficheiro, 'r')
lista_pal = f_in.read().split()
dic = {}
especiais = ['\n','.',',','!','?']
for palavra in lista_pal:
if palavra[-1] in especiais:
palavra = palavra[:-1]
comp = len(palavra)
if comp:
dic[comp] = dic.get(comp,[]) + [palavra]
return dic

Notar o uso de uma lista onde guardamos caracteres especiais que não devem fazer parte da palavra. Notar ainda o teste ao comprimento: se um símbolo estiver isolado, ao ser retirado passa a ser uma cadeia sem caracteres e não deve ser incluída.

Finalmente, uma solução em que as palavras repetidas só são incluídas um vez.

def fich_dic_c(ficheiro):
""" Lê o conteúdo do ficheiro e constrói um dicionário
com chave um inteiro e valor uma lista com as palavras de
comprimento igual ao valor da chave.
"""
especiais = ['\n','.',',','!','?']
f_in = open(ficheiro, 'r')
lista_pal = f_in.read().split()
# filtra
lista_final = []
for palavra in lista_pal:
# símbolos especiais fora
if palavra in especiais:
continue
elif palavra[-1] in especiais:
palavra = palavra[:-1]
# repetições fora
if palavra not in lista_final:
lista_final.append(palavra)
# Constrói dicionário
dic = {}
for palavra in lista_final:
comp = len(palavra)
dic[comp] = dic.get(comp,[]) + [palavra]
return dic


5.
Nesta solução temos uma definição auxiliar (tri) para desenhar um triângulo incompleto. O programa main é responsável por usar este programa, tantas vezes quantos os triângulos incompletos que queremos desenhar, e ainda definir os valores do lado, do incremento e da rotação.

from cTurtle import *

def tri(tartaruga,lado, inc):
""" Desenha um triângulo incompleto."""
for i in range(3):
tartaruga.fd(lado)
tartaruga.rt(120)
lado = lado + inc
tartaruga.hideturtle()

def main(n):
""" Desenha n triângulos incompletos que vão rodando."""
tartaruga = Turtle()
lado = 30
inc_lado = 10
head = 0
for i in range(n):
tartaruga.setheading(heading() + head)
tri(tartaruga,lado, inc_lado)
lado = lado + 3 * inc_lado
head = head + 8

tartaruga.exitOnClick()

if __name__ =='__main__':
hideturtle()
main(5)

22 comentários:

  1. na questão de somar a constante , eu tinha feito usado o mesmo objecto e portanto não havia necessidade de usar o apend podia simplismente fazer no ciclo : resultado[i]=x+lista[i]
    depois mudei , resolvi criar mesmo um objecto :
    resultado=[] , e esqueci de mudar para o append , visto que em phyton não defenimos apriori o tamanho do vector quando fizer resultado[i]=lista[i]+x vai dar um erro , era o exercicio mais facil e valia mais .

    ResponderEliminar
  2. Pois este exercício era básico e permitia determinar quem sabia o mínimo. Daí valer 25% da nota total.

    ResponderEliminar
  3. mas ainda existe o exame de recurso , se não tirar uma nota que me deixa satisfeito(14) posso sempre ir ao exame de recurso .

    ResponderEliminar
  4. Claro! É sempre bem vindo! E eu cá estarei para tirar as dúvidas que for necessário.

    ResponderEliminar
  5. Na questão 2 afirmei que as chaves dos dicionários tinham de ser do tipo hashable, riscando o facto de serem imutáveis. O professor também contabiliza?

    ResponderEliminar
  6. é isso que é preciso , preofessores com capacidade e dispnibilidade.
    obrigado pela disponibilide e a velocidade a que responde a comentarios neste blogue .

    ResponderEliminar
  7. Sobre as chaves dos dicionários. Eu sei que dizerem que eram hashable era fácil: bastava ler o manual de referência rápida :-)! Mas será que sabem o que tal significa?? Se o explicaram, tudo bem. Mais fácil seria dizer que tinham que ser objectos imutáveis. Lembro-me bem da sua resposta (tenho passado uns dias de eremita a corrigir os vossos exames...) e tomei nota de ter colocado imutáveis, mesmo riscado!

    ResponderEliminar
  8. Outra pequena questão, os resultados estão previstos para sair quando? Já tem uma data em mente?

    ResponderEliminar
  9. Boas,
    no exercício 3, a segunda solução apresentada não está mal???
    não deveria ser:

    def soma_constante_b(c, vector):
    """ Soma a constante c a cada uma das componentes do vector v."""
    res= []
    for elem in range(len(vector)):
    res.append(c+(vector[elem]))
    return res

    Cumprimentos

    ResponderEliminar
  10. Gonçalo Pereira:

    Quando achamos que um código está errado, manda o bom senso que se faça uma coisa simples: experimentar correr o dito cujo. Sei que não o fez, pois se fizesse verificava uma coisa simples: está correcto.

    Agora, qual é o seu problema, e que muito me preocupa nesta fase, pois se trata de um erro básico? É que você pensa que só se pode percorrer uma sequência (neste caso uma lista) pelos índices. Não é verdade: também se pode fazer pelo conteúdo!!! E até mesmo pelo índice e conteúdo!!!

    Quase me esquecia: a sua solução também funciona...

    ResponderEliminar
  11. Boas...
    eu experimentei o código antes....

    desculpe a insistência, mas de forma a estar correcto, no "return vector" não deveria ser "return res"

    porque usando o código tal e qual como esta aqui, correndo

    >>> soma_constante_b(3,(1,2,3,4,5))
    (1, 2, 3, 4, 5)

    e não:
    >>> soma_constante_b(3,(1,2,3,4,5))
    [4, 5, 6, 7, 8]

    mais uma vez, desculpe a insistência...

    ResponderEliminar
  12. Manda o bom senso que o professor corra o seu próprio código :-)! Coisa que não fez! Logo, a sua observação está certa. Deve ser return res.

    ResponderEliminar
  13. professor no ultimo exercicio o professor utiliza:

    for i in range(n):
    tartaruga.setheading(heading() + head)
    tri(tartaruga,lado, inc_lado)
    lado = lado + 3 * inc_lado
    head = head + 8

    eu faria com o metodo left de modo a caneta se mover para cima para fazer o angulo correspondente, mas sei q com o setheading tambem dá. no manual rapido diz q é a orientação absoluta, ou seja neste caso ele move-se sempre 8º para cima? estou correcta?
    obrigado

    ResponderEliminar
  14. Goretti:

    O comando setheading coloca realmente a orientação de modo absoluto. No entanto, se reparar, o argumento do setheading é heading() + head. O comando heading dá-me a orientação actual da tartaruga. Assim, combinando tudo estou a dizer para rodar para a esquerda head graus. Daí que também possa ser feito com o comando left.

    ResponderEliminar
  15. :-)
    por curiosidade no exercício 3, se o vector em vez de ser uma simples lista, for uma lista com uma sub-lista no seu interior, por ex: [3,5,7,[5,6,7]] em que não se saiba em que posição é que está essa sub-lista,
    como faremos para somar a cada componente dessa lista e dessa sub-lista a uma constante???

    ps.: já tive algum tempo a tentar resolver isto, sabendo onde está a sub-lista é relativamente simples, mas se não se souber onde está a lista, não to a ver como lhe dar a volta, porque não da para saber o comprimento de números inteiros.... porque se desse, um while resolvia.....:-S

    ResponderEliminar
  16. Gonçalo Pereira:

    Se bem entendi o que quer é algo assim:

    def soma_vector(num,vec_geral):
    ..."""Existem sublistas."""
    ... aux_1 = vec_geral[:]
    ...for indice,elem in enumerate(aux_1):
    ...... if isinstance(elem, list):
    ......... aux_2 = []
    ......... for i in range(len(elem)):
    ............. aux_2.append(num + elem[i])
    .........aux_1[indice] = aux_2
    ......else:
    .........aux_1[indice] = aux_1[indice] + num
    ...return aux_1


    Achave para a solução está em fazer o teste isinstance(elem, list). Esta solução permite que existam mais do que uma sub-lista. Mas não funciiona caso existam listas, dentro de listas, dentro de listas ... como no caso de, por exemplo, lista = [1,2,3,[4,[5,6]], [[7]], [8,9]].

    Nestas situações temos que nos socorrer de artilharia mais pesada: a recursividade.

    def soma_vector_rec(num, vec_geral):
    ...if vec_geral == []:
    ......return []
    ...elif isinstance(vec_geral[0],int):
    ...... return [num + vec_geral[0]] + soma_vector_rec(num,vec_geral[1:]) ...elif isinstance(vec_geral[0], list):
    ...... return [soma_vector_rec(num,vec_geral[0])] + soma_vector_rec(num, vec_geral[1:])
    ... else:
    ......return 'ERRO'

    Esta solução funciona para todos os casos que possa imaginar... Experimetne!

    ResponderEliminar
  17. Boas...
    respondendo este programa:

    from cTurtle import *

    def triangulo(lado,aumento,pos,angulo,quantos):
    up()
    goto(pos)
    setheading(angulo)
    desvio=0
    for j in range (quantos):
    for i in range (3):
    down()
    forward(lado)
    right(120)
    lado=lado+10
    desvio=0+4
    left(desvio)
    hideturtle()
    mainloop()

    no exercício 5, já teria a cotação toda??
    Cumprimentos

    ResponderEliminar
  18. Estive a tentar resolver a pergunta 4 pelo seguinte código:

    def exame(ficheiro):
    -dic={}
    -lista=[]
    -string=''
    -abrir=open(ficheiro,"r")
    -string+=abrir.read() #string sera a cadeia de caracteres contida no ficheiro#
    -lista.append(string.split()) #aqui divido a cadeia de caracteres numa lista e junto-a a 'lista'#
    -for palavra in range(len(lista)):
    --dic[palavra]=lista[palavra]
    -print dic

    Os resultados não são o que idealizava: é-me devolvido um dicionário com apenas a chave 0 e o seu valor é a lista total. Tendo em consideraçao o código que forneço, é capaz de me indicar onde errei?

    Obrigado.

    ResponderEliminar
  19. Gonçalo:

    Não, não tinha :-(. Partindo do princípio que a indentação do código está certa:
    - desvio = 0 + 4 deve ser um lapso seu e queria dizer desvio = desvio + 4;
    - a instrução lado = lado + 10 está dentro do ciclo de desenho do triângulo? Se não tem que estar!

    - porque é que no interior do ciclo que desenha o triângulo esrtá sempre a fazer down()? Basta fazer uma vez (por exemplo depois do comando setheading.

    ResponderEliminar
  20. -Não, queria mesmo dizer desvio = 0 + 4, porque de cada vez que faz um triângulo, desvia-se 4graus...e depois faz outro triângulo, desvia-se mais 4 graus....acho que está correcto, apesar de o prof. ter feito na sua resolução a desviar-se 8 graus...

    -Sim, a instrução lado = lado + 10 esta dentro do ciclo do triângulo....

    -Por acaso, grande bug :-S

    -Obrigado pelos conselhos

    ResponderEliminar
  21. Rui Gonçalves:

    Respondido no post Erros... Fico preocupado com as dificuldades que ainda tem.

    ResponderEliminar
  22. Gonçalo Pereira:

    Qual é a lógica de fazer desvio = 0 + 4??? ZERO + 4 é sempre igual a 4! Se quer um desvio constant então definie no ínicio desvio = 4 ( enão desvio = 0) e não se incomoda mais...

    ResponderEliminar