domingo, 15 de novembro de 2009

Problema 6.12

Este problema tem um enunciado simples mas vai originar um programa extenso. Temos que gerar pares de números e guardar os ditos num ficheiro num formado definido. Depois temos que ler os dados a partir do ficheiro, interpretá-los como coordenadas no plano, e usar uma tartaruga para desenhar segmentos de recta que unam esses pontos. Vejamos o código.


import random
import cTurtle

def gera_pares(n):
res = [(random.randint(1,6), random.randint(1,6)) for i in range(n)]
return res

def cria_ficheiro(nome,dados):
f_out = open(nome,'w')
for par in dados:
linha = str(par[0]) + '\t' + str(par[1]) + '\n'
f_out.write(linha)
f_out.close()

def le_ficheiro(nome):
f_in = open(nome,'r')
dados = []
linha = f_in.readline()
while linha !='' and linha != '\n':
pos = linha[:-1].split()
dados.append((int(pos[0]), int(pos[1])))
linha = f_in.readline()

f_in.close()
return dados

def visualiza(tartaruga,dados):
dados = [(20 * dado[0],20 * dado[1]) for dado in dados] # para se poder ver
tartaruga.up()
tartaruga.goto(dados[0])
tartaruga.down()

for ponto in dados[1:]:
tartaruga.goto(ponto)


def main612(ficheiro, num_pontos):
# Formação dos dados
pares = gera_pares(num_pontos)
cria_ficheiro(ficheiro,pares)
# Leitura dos dados
pares_tartaruga = le_ficheiro(ficheiro)
# Visualização
tartaruga= cTurtle.Turtle()
visualiza(tartaruga,pares_tartaruga)
tartaruga.exitOnClick()


Com a definição gera_pares fabricamos a lista de pares de inteiros, entre 1 e 6. Usamos listas por compreensão.

Criamos o ficheiro, escrevendo os dados linha a linha. Como não nos podemos esquecer que num ficheiro de texto tudo tem que ser do tipo cadeia de caracteres, temos que fazer a conversão dos tipos. Entre dois números colocamos uma tabulação, e, no final a mudança de linha.

A leitura do ficheiro é agora a operação inversa, não havendo muito a acrescentar, pois retoma programas já criados.

A visualização parte da lista das coordenadas e faz mover uma tartaruga na tela de acordo com esses valores.

O programa principal, isto é, aquele que vai ser chamado, denominado main612, limita-se a dividir em três partes o programa: geração dos números, leitura dos dados e visualização.

6 comentários:

  1. a minha solução foi a seguite :
    import random
    from cTurtle import *
    def fic12 ():
    lista=['red','green','blue','black','orange']
    n=input ("quantos pares pretende :")
    a =open('C:\\Users\\nhuk the one\\Desktop\\IprpExercicios\\textot.txt','w')

    for i in range (n):
    x= random.randint (-400,400)
    y=random.randint(-300,300)
    z= str (x) +" "+str(y)+"\n"
    a.write(z)
    a.close()
    d=open('C:\\Users\\nhuk the one\\Desktop\\IprpExercicios\\textot.txt','r')
    for i in range (n):
    pencolor(lista[random.randint(0,4)])
    pensize(random.randint(1,5))
    aux=d.readline()
    aux=aux.split()
    x=int(aux[0])
    y=int(aux[1])
    goto(x,y)
    fic12()


    eu meti as cores e o tamanho da caneta para ficar mais interessante.

    ResponderEliminar
  2. pelo o programa que o professor fez, acho que interpretei mal o enuciado mas o que vale é que ja pratiquei um bocado.

    ResponderEliminar
  3. A sua solução está globalmente correcta (há o detalhe de os números serem entre 1 e 6). A core e a espessura do traço acrescentam uma dimensão estética interessante. A minha crítica tem mais que ver com o facto de ter uma solução numa única definição. Assim o seu programa não tem modularidade, é de leitura difícil, não promove a reutilização de código. O programa é pequeno, eu sei, mas não usar bons princípios de programação, mesmo em casos simples, faz com que quando os problemas sejam complexos vá sentir grandes dificuldades. Uma das regras fundamentais em programação é dividir para reinar. Pense nisso!

    ResponderEliminar
  4. Mais um apontamento sobre a solução. Como os números são pequenos, entre 1 e 6, multiplico as coordenadas por 20 para ampliar. Não é uma solução bonita. melhor será usar o método setWorldCoordinates. Por exemplo, colocar antes de passar ao desenho, cTurtle.setWorldCoordinates(0,0,7,7).

    ResponderEliminar
  5. Professor, na linha 19 do seu código o que significa dizer: (linha != '\n') e de que forma é que esta condição influencia o ciclo while?

    ResponderEliminar
  6. Adriano Vinhas:

    O operador "!=" significa diferente. ´\n´é o caracter de controle para nova linha. Assim a linha 19:

    while linha != '' and linha !='\n':

    deve ser lida como:

    enquanto o ficheiro não chegou ao fim (primeira condição) e a linha não for vazia (segunda condição).

    Se não tiver esta segunda condição e o ficheiro tiver linhas vazias a separar os dados o programa daria erro.

    ResponderEliminar