• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

player

Manipulação ficheiros

24 mensagens neste tópico

Boas.

Eu estou a fazer uma pequena agenda electrónica e até agora, ainda só adiciona Contactos e algumas informações e vai guardado-as num arquivo de texto.

Estava a pensar adicionar uma função remover e já estive a tentar mas não consigo fazer com que ele apague o Contacto nem as informações desse contacto.

Será que existe alguma maneira de apagar sem ser manualmente no ficheiro?

Cumps e obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes mostrar o teu código? É que o que escreveste é muito vago. :thumbsup:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes mostrar o teu código? É que o que escreveste é muito vago. :thumbsup:

Aqui está ele

agenda = open('c:/agenda.txt','a')
if 'Agenda Telefonica\n' in open('c:/agenda.txt','r'):
    agenda.close()
else:
    agenda.write('Agenda Telefonica\n')

def adicionar():
    agenda = open('c:/agenda.txt','a') 
    nome = raw_input('Nome Contacto: ')
    try:
        contacto = raw_input('Numero Telefone: ')
        contacto = int(contacto)
    except:
        print 'Por favor, use so numeros no contacto'
    email = raw_input('Email: ')
    agenda.write('Nome: %s\nContacto: %d\nEmail: %s\n\n' % (nome,contacto,email))
    agenda.close()

Aí está uma parte dele, aquela parte inicial, onde tem Agenda Telefonica, está meia esquisita mas até agora tem resultado.

Depois a seguir eu estava a pensar numa função remover() mas não sei como é que a função vai ao ficheiro e apague só aquele nome que eu peço e as informações desse nome.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ora, tens de ler a agenda para a memória a apagares apenas o que queres. Pegando no formato do ficheiro, assim de relance tens que fazer isto:

contactos = []
for registo in open('agenda', 'r').read()[13:].split("\n\n"):
    if registo.strip() == "": continue
    nome, contacto, email = registo.split("\n")
    contactos.append({'Nome': nome[6:], 'Contacto': int(contacto[10:]), 'Email': email[7:]})
#acabaste de ler os contactos para uma lista. agora é apagar a que não queres
del contactos[0] #apagaste o 1º contacto
#agora é só gravar
open('agenda', 'w').write("Agenda Telefonica\n" + ("\n".join(["Nome: %(Nome)\nContacto: %(Contacto)\nEmail: %(Email)\n" % registo for registo in contactos])) + "\n")

Alguma dúvida, avisa.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ora, tens de ler a agenda para a memória a apagares apenas o que queres. Pegando no formato do ficheiro, assim de relance tens que fazer isto:

contactos = []
for registo in open('agenda', 'r').read()[13:].split("\n\n"):
    if registo.strip() == "": continue
    nome, contacto, email = registo.split("\n")
    contactos.append({'Nome': nome[6:], 'Contacto': int(contacto[10:]), 'Email': email[7:]})
#acabaste de ler os contactos para uma lista. agora é apagar a que não queres
del contactos[0] #apagaste o 1º contacto
#agora é só gravar
open('agenda', 'w').write("Agenda Telefonica\n" + ("\n".join(["Nome: %(Nome)\nContacto: %(Contacto)\nEmail: %(Email)\n" % registo for registo in contactos])) + "\n")

Alguma dúvida, avisa.

Assim de repente está um bocado confuso para mim, mas ainda estou "fresco" na linguagem, mas eu vou investigar isso e fazendo uns testes com isso e ver se percebo melhor, se realmente não conseguir eu depois digo alguma coisa.

Obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em relação aos [11:], pesquisa por slicing. Tens um tutorial aqui no fórum.

Em relação ao append, usei um dicionario (dict).

Em relação à escrita, usei listas por compreensão e nas formatting strings, usei uma coisa que existe que basicamente meto o indexes do dicionário em vez de s e d, e passo como "argumento" o dict. As listas por compreensão podem ser "convertidas" para um for assim:

resultado = [instrução for elemento in lista]
#
resultado = []
for elemento in lista:
    resultado.append(instrução)

Em relação ao split, join, etc, no interpretador do python faz isto:

help("wtv".join)

help("wtv".split)

help("wtv".strip)

help([].append)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ora, tens de ler a agenda para a memória a apagares apenas o que queres. Pegando no formato do ficheiro, assim de relance tens que fazer isto:

contactos = []
for registo in open('agenda', 'r').read()[13:].split("\n\n"):
    if registo.strip() == "": continue
    nome, contacto, email = registo.split("\n")
    contactos.append({'Nome': nome[6:], 'Contacto': int(contacto[10:]), 'Email': email[7:]})

Alguma dúvida, avisa.

Obrigado pela informação acima.

Agora em relação a parte do quote, se eu entendi bem, a parte do código que está no quote vai adicionar aquelas informações a lista contactos certo? Mas que parte do código é que faz o nome,contacto e email ser um só para depois ao apagar o nome apagar o resto dos dados, tipo uma chave com 3 valores? Percebeste o que eu quis dizer?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Imagina que tens um ficheiro com 2 contactos. O que aquilo faz é ler o ficheiro todo, usar tudo menos aquela linha inicial, e partir em bocados em todos os \n\n (ou seja, depois do email e antes do "Nome:"). Esses bocados têm o formato "Nome: %s\nContacto: %d\nEmail: %s". O que faço é iterar esse conjuntos de bocados e parti-los no \n e assim fico com uma lista com "Nome: %s", "Contacto: %d" e "Email: %s" que "delego" às 3 variáveis e depois tiro o bocado que não me interessa.

No entanto, o split no final do ficheiro vai criar um elemento vazio, daí ter aquele if.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tipo, outra cena que não estou a entender muito bem é o uso do slicing, porque é que o usaste?

Desde já obrigado pela ajuda que me vais dando  :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para tirar os bocados de texto que não me interessam.

Retirar? Desculpa mas não compreendi outra vez. Então o slicing vai cortar mas não o desnecessário acho eu, por exemplo

nome = 'Rui Oliveira'
nome[6:]
'iveira'

E outra coisa, eu quando tento correr o teu código para ver o funcionamento e isso dá erro.

remover()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "F:\Agenda_Electronica2.py", line 23, in remover
    nome, contacto, email = registo.split("\n")
ValueError: too many values to unpack

E o strip(), o que é que ele faz? Simplesmente remove espaços entre strings?

Desculpa lá e obrigado.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Retirar? Desculpa mas não compreendi outra vez. Então o slicing vai cortar mas não o desnecessário acho eu, por exemplo

nome = 'Rui Oliveira'
nome[6:]
'iveira'

Exacto.

E outra coisa, eu quando tento correr o teu código para ver o funcionamento e isso dá erro.

remover()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "F:\Agenda_Electronica2.py", line 23, in remover
    nome, contacto, email = registo.split("\n")
ValueError: too many values to unpack

Mete isso dentro de um try...except como este:

try:
    nome, contacto, email = registo.split("\n")
except ValueError:
    print ">>> ", registo

E diz-me o qeq ele imprime.

E o strip(), o que é que ele faz? Simplesmente remove espaços entre strings?

Remove todo o whitespace de uma string.
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Exacto.Mete isso dentro de um try...except como este:

try:
    nome, contacto, email = registo.split("\n")
except ValueError:
    print ">>> ", registo

E diz-me o qeq ele imprime

Vai imprimir os dados que estão dentro do ficheiro agenda.txt, mas isso ocorre por causa do except não é?

E o ValueError: too many values to unpack significa o quê? Eu já estive a dar uma vista de olhos mas não percebi muito bem, li que esse erro ocorre quando não tem variáveis suficientes no for mas não consigo perceber.

E tipo o registo.split('\n') faz alguma coisa? Eu tentei com e sem o \n e o resultado é o mesmo

Obrigado  :(

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boa, mas eu quero saber o output concretamente. :(

O erro ocorre quando há mais pedaços do que eu especifiquei. Isto é, o split devolve uma lista de 4 elementos e eu tenho apenas 3 variaveis.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boa, mas eu quero saber o output concretamente. :(

O erro ocorre quando há mais pedaços do que eu especifiquei. Isto é, o split devolve uma lista de 4 elementos e eu tenho apenas 3 variaveis.

Ok então aqui está o resultado:

>>>  nica
Nome: Rui
Contacto: ************
Email: ***************
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "F:\Agenda_Electronica2.py", line 27, in remover
    contactos.append({'Nome': nome[6:], 'Contacto': int(contacto[10:]), 'Email': email[7:]})
UnboundLocalError: local variable 'nome' referenced before assignment

Em relação ao ValueError já entendi.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes pôr aí o conteudo do ficheiro? É que cheira-me que o formato do ficheiro está incorrecto.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes pôr aí o conteudo do ficheiro? É que cheira-me que o formato do ficheiro está incorrecto.

O conteúdo é basicamente aquele que aparece e está em formato txt.

O conteúdo é este

Agenda Telefonica

Nome: Rui

Contacto: *********

Email: *******************

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não é open('agenda', 'r').read()[13:].split("\n\n"): mas sim open('agenda', 'r').read()[18:].split("\n\n"):

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ainda continuo sem perceber algumas partes basicamente são estas

for registo in open('c:/agenda.txt', 'r').read()[17:].split("\n\n"):

Porque é que usaste dois \n em vez de um, o efeito é o mesmo

if registo.strip() == "": continue

O que é que o "" significa? Eu tentei fazer testes mas não tinha resultados

nome, contacto, email = registo.split("\n")

Este basicamente não o entendi todo, mas é mais aquele = e o split('\n' que estão a fazer confusão

Por agora é só mas se aparecer mais eu pergunto :(

Cumps e obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usei 2 \n porque 2 newlines significa que há uma linha vazia, enquanto que apenas 1 newline significa que se mudou apenas de linha 1 vez.

O "" é uma string vazia. Isto é, se tirarmos todo o whitespace da string registo, se ficar uma string vazia, passamos à próxima iteração do loop.

x, y, z = a é o mesmo que x = a[0]; y = a[1]; z = a[2]. Em relação ao split aí, é para dividir as linhas umas das outras.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usei 2 \n porque 2 newlines significa que há uma linha vazia, enquanto que apenas 1 newline significa que se mudou apenas de linha 1 vez.

O "" é uma string vazia. Isto é, se tirarmos todo o whitespace da string registo, se ficar uma string vazia, passamos à próxima iteração do loop.

x, y, z = a é o mesmo que x = a[0]; y = a[1]; z = a[2]. Em relação ao split aí, é para dividir as linhas umas das outras.

Aquela não percebi muito bem.

E o programa que , o erro me deste ainda continua a dar erros e eu penso que sei porque é que dá erro

contactos.append({'Nome': nome[6:], 'Contacto': int(contacto[10:]), 'Email': email[7:]})
UnboundLocalError: local variable 'nome' referenced before assignment

Eu penso que seja porque aqui também dá erro

try:
            nome, contacto, email = registo.split("\n")

E então ele vai passar ao except e só vai imprimir o registo portanto vai levantar o erro UnboundLocalError porque a variável nome ainda não tem nada definido. Está correcto não está?

E em relação a esta parte x, y, z = a é o mesmo que x = a[0]; y = a[1]; z = a[2]. Em relação ao split aí, é para dividir as linhas umas das outras. é tipo isto

nome = nome da agenda

contacto = contacto da agenda

email = email da agenda

Percebeste esta última?

Cumps e obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Lembrei-me duma coisa, tu tás em Windows não é? Eu não estava a considerar \r\n como uma combinação possível para linhas novas. Em vez de open('agenda', 'r').read()[18:].split("\n\n"), usa open('agenda', 'r').read().replace("\r\n", "\n").replace("\r", "\n")[18:].split("\n\n"). Isto serve para converter os "nova linha" do windows (\r\n) e os do mac os 9 (\r) nos "nova linha" do unix/linux (os mais usados) (\n).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então mas qual é a diferença entre elas?

Desculpa não ter postado ontem, estava com preguiça :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A diferença é que cada caracter tem um significado diferente consoante o contexto/SO.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora