Manipulando arquivos com Pickle

Publicado por Ewerton Daniel de Lima (última atualização em 05/05/2010)

[ Hits: 8.608 ]

Download Ex1ComPickle.py




Exemplo de manipulação de arquivos em Python com a classe Pickle. O código se trata de um sistema simplificado de notas e frequência com armazenamento em arquivos.

  



Esconder código-fonte

# -*- coding: utf-8 -*-
import os, collections, pickle
#Observação: a variável limpar armazena o comando do sistema operacional responsável pela limpeza de tela
limpar = "clear"
alunosPath = "ALUNOS.DAT"
disciplinasPath = "DISCIPLI.DAT"

def ArquivoExiste(arquivo):
   try:
      f = open(arquivo, "r")
   except IOError:
      return False
   f.close()   
   return True   

def ExisteCodigo(tabela, campo, codigo):
   for el in tabela:
      if el[campo] == codigo:
         return True
   return False

def incluirAluno(alunos, disciplinas):
   tipoAluno = collections.namedtuple("Aluno", "ra nome codigoDisciplina nota1 nota2 nota3 nota4 faltas")
   os.system(limpar)   
   print("CADASTRO DE ALUNOS")
   while True:
      try:
         while True:         
            ra = int(input("Digite o RA do aluno que deseja cadastrar: "))
            if ExisteCodigo(alunos, "ra", ra):
               print("O RA inserido já está cadastrado!")
            else:
               break
      except:
         print("Erro: o RA deve ser um número inteiro!")
      else:
         break
   while True:
      try:      
         while True:         
            codigoDisciplina = int(input("Digite o código da disciplina: "))
            if not ExisteCodigo(disciplinas, "codigo", codigoDisciplina):
               print("A disciplina inserida não está cadastrada! Para cadastrar um disciplina, escolha a opção 4 no menu principal")
               input("Digite qualquer número para continuar: ")               
               return
            else:
               break
      except:
         print("Erro: o código da disciplina deve ser um número inteiro")
      else:
         break
      
      
   while True:
      try:      
         nome = input("Digite o nome do aluno (entre aspas): ")
      except:
         print("Erro: o nome do aluno deve ser digitado entre aspas")
      else:
         break
   
   while True:   
      try:
         nota1 = float(input("Entre com a nota 1: "))
         nota2 = float(input("Entre com a nota 2: "))
         nota3 = float(input("Entre com a nota 3: "))
         nota4 = float(input("Entre com a nota 4: "))
      except:
         print("Erro: as notas devem ser números reais entre 0 e 10")
      else:
         if ((nota1 or nota2 or nota3 or nota4) < 0.0) or ((nota1 or nota2 or nota3 or nota4) > 10.0):
            print("As notas devem estar entre 0 e 10, favor reinserí-las na faixa correta:")
            continue
         else:
            break
   while True:
      try:      
         faltas = int(input("Entre com as faltas do aluno na disciplina: "))
      except:
         print("Erro: o código da disciplina deve ser um número inteiro")
      else:
         break   
   aluno = tipoAluno(ra, nome, codigoDisciplina, nota1, nota2, nota3, nota4, faltas)
   os.system(limpar)
   print("CADASTRO DE ALUNOS")
   print("Dados inseridos: \n")
   print("RA: "+str(ra))
   print("Nome: "+str(nome))
   for el in disciplinas:
      if el['codigo'] == codigoDisciplina:
         disciplinaNome = el['nome']
         break
   print("Disciplina: "+str(codigoDisciplina)+" - "+disciplinaNome)
   print("Nota 1: "+str(nota1))
   print("Nota 2: "+str(nota2))
   print("Nota 3: "+str(nota3))
   print("Nota 4: "+str(nota4))
   print("Número de faltas: "+str(faltas))
   while True:
      try:      
         inserir = int(input("Digite 1 para gravar ou qualquer outro número para cancelar: "))
      except:
         print("Erro: a opção deve ser um número inteiro")
      else:
         break      
   if inserir == 1:
      alunos += [aluno._asdict()]
      f = open(alunosPath, "w")
      pickle.dump(alunos, f)
      f.close()

   return

def listarAlunos():
   f = open(alunosPath, "r")
   alunos = pickle.load(f)
   f.close()   
   print("Listando alunos: \n")
   linhasUsadas = 3
   if len(alunos) == 0:
      print("Não há alunos cadastrados")
   for i in range(len(alunos)):
      if linhasUsadas == 19:
         input("Digite qualquer número para continuar: ")
         linhasUsadas = 0
         os.system(limpar)
      print("RA: "+str(alunos[i]['ra'])),
      print(" Nome: "+str(alunos[i]['nome']))
      linhasUsadas += 1
   return alunos

def listarDisciplinas(pesos=False):
   f = open(disciplinasPath, "r")
   listaDisciplinas = pickle.load(f)
   f.close()   
   print("Listando disciplinas: \n")
   linhasUsadas = 3
   if len(listaDisciplinas) == 0:
      print("Não há disciplinas cadastradas")
   for i in range(len(listaDisciplinas)):
      if linhasUsadas == 19:
         input("Digite qualquer número para continuar: ")
         linhasUsadas = 0
         os.system(limpar)
      if pesos:
         print(str(listaDisciplinas[i]['codigo'])),
         print(" "+str(listaDisciplinas[i]['nome'])),
         print("P1:"+str(listaDisciplinas[i]['peso1'])),
         print("P2:"+str(listaDisciplinas[i]['peso2'])),
         print("P3:"+str(listaDisciplinas[i]['peso3'])),
         print("P4:"+str(listaDisciplinas[i]['peso4']))
      else:      
         print("Código: "+str(listaDisciplinas[i]['codigo'])),         
         print(" Nome: "+str(listaDisciplinas[i]['nome']))
      linhasUsadas += 1
   return listaDisciplinas

def excluirAluno(alunos):
   os.system(limpar)   
   print("EXCLUSÃO DE ALUNOS")   
   listarAlunos()
   raExcluir = input("\nDigite o RA do aluno o qual deseja excluir ou 0 para retornar: ")
   if raExcluir != 0:
      for i in range(len(alunos)):
         if alunos[i]['ra'] == raExcluir:
            alunos.remove(alunos[i])
   f = open(alunosPath, "w")
   pickle.dump(alunos, f)
   f.close()
   
   return

def alterarNotas():
   os.system(limpar)   
   print("ALTERAR NOTAS DE ALUNOS")   
   alunos = listarAlunos()
   raAlterar = input("\nDigite o RA do aluno o qual deseja alterar as notas ou 0 para retornar: ")
   if raAlterar != 0:
      for i in range(len(alunos)):
         if alunos[i]['ra'] == raAlterar:
            os.system(limpar)
            print("ALTERAR NOTAS DE ALUNOS")            
            print("\nAlterando notas do aluno: "+str(alunos[i]['nome']))
            while True:   
               try:
                  nota1 = float(input("Entre com a nota 1: "))
                  nota2 = float(input("Entre com a nota 2: "))
                  nota3 = float(input("Entre com a nota 3: "))
                  nota4 = float(input("Entre com a nota 4: "))
               except:
                  print("Erro: as notas devem ser números reais entre 0 e 10")
               else:
                  if ((nota1 or nota2 or nota3 or nota4) < 0.0) or ((nota1 or nota2 or nota3 or nota4) > 10.0):
                     print("As notas devem estar entre 0 e 10, favor reinserí-las na faixa correta:")
                     continue
                  else:
                     break
                        
            
            os.system(limpar)
            print("ALTERAR NOTAS DE ALUNOS")
            print("Novas notas inseridas: \n1a: "+str(nota1)+"\n2a: "+str(nota2)+"\n3a: "+str(nota3)+"\n4a: "+str(nota4))
            confirmacao = input("Pressione 1 para confirmar alteração ou qualquer número para cancelar: ")
            if confirmacao == 1:
               alunos[i]['nota1'] = nota1
               alunos[i]['nota2'] = nota2
               alunos[i]['nota3'] = nota3
               alunos[i]['nota4'] = nota4
            break
   f = open(alunosPath, "w")
   pickle.dump(alunos, f)
   f.close()
   return

def incluirDisciplina(disciplinas):
   tipoDisciplina = collections.namedtuple("Disciplina", "codigo nome peso1 peso2 peso3 peso4 cargaHoraria")
   os.system(limpar)   
   print("CADASTRO DE DISCIPLINAS")
   while True:
      try:
         while True:         
            codigo = int(input("Digite o código da disciplina que deseja cadastrar: "))
            if ExisteCodigo(disciplinas, "codigo", codigo):
               print("O código inserido já está cadastrado!")
            else:
               break
      except:
         print("Erro: o código deve ser um número inteiro!")
      else:
         break
               
      
   while True:
      try:      
         nome = input("Digite o nome da disciplina (entre aspas): ")
      except:
         print("Erro: o nome da disciplina deve ser digitado entre aspas")
      else:
         break
   
   while True:   
      try:
         peso1 = float(input("Entre com o peso da avaliação 1 ou 0 se não houver avaliação: "))
         peso2 = float(input("Entre com o peso da avaliação 2 ou 0 se não houver avaliação: "))
         peso3 = float(input("Entre com o peso da avaliação 3 ou 0 se não houver avaliação: "))
         peso4 = float(input("Entre com o peso da avaliação 4 ou 0 se não houver avaliação: "))
      except:
         print("Erro: os pesos das avaliações devem ser números reais")
      else:
         break
   while True:
      try:      
         cargaHoraria = int(input("Entre com a carga horária da disciplina: "))
      except:
         print("Erro: a carga horária da disciplina deve ser um número inteiro")
      else:
         break   
   disciplina = tipoDisciplina(codigo, nome, peso1, peso2, peso3, peso4, cargaHoraria)
   os.system(limpar)
   print("CADASTRO DE DISCIPLINAS")
   print("Dados inseridos: \n")
   print("Código: "+str(codigo))
   print("Nome: "+str(nome))
   print("Peso da Avaliação 1: "+str(peso1))
   print("Peso da Avaliação 2: "+str(peso2))
   print("Peso da Avaliação 3: "+str(peso3))
   print("Peso da Avaliação 4: "+str(peso4))
   print("Carga horária da disciplina: "+str(cargaHoraria))
   while True:
      try:      
         inserir = int(input("Digite 1 para gravar ou qualquer outro número para cancelar: "))
      except:
         print("Erro: a opção deve ser um número inteiro")
      else:
         break      
   if inserir == 1:
      disciplinas += [disciplina._asdict()]
      f = open(disciplinasPath, "w")
      pickle.dump(disciplinas, f)
      f.close()

   return

def excluirDisciplina(alunos, disciplinas):
   os.system(limpar)   
   print("EXCLUSÃO DE DISCIPLINAS")   
   listarDisciplinas()
   codigoExcluir = input("\nDigite o código da disciplina a qual deseja excluir ou 0 para retornar: ")

   if codigoExcluir != 0:
      for el in alunos:
         if el['codigoDisciplina']==codigoExcluir:
            print("A disciplina selecionada não pode ser excluída, pois está cadastrada para alguns alunos")
            input("Digite qualquer número para continuar: ")
            return
      for i in range(len(disciplinas)):
         if disciplinas[i]['codigo'] == codigoExcluir:
            disciplinas.remove(listaDisciplinas[i])
   f = open(disciplinasPath, "w")
   pickle.dump(disciplinas, f)
   f.close()
   
   return

def consultaAlunos(alunos, disciplinas, opcaoConsulta=""):
   os.system(limpar)
   print("MENU DE CONSULTAS\n")
   print("Listando: ")
   linhasUsadas = 3 
   for elAluno in alunos:
      posDisciplina = 0
      somaNotas = 0.0
      somaPesos = 0.0
      frequencia = 0.0
      for i in range(len(disciplinas)):
         if disciplinas[i]['codigo'] == elAluno['codigoDisciplina']:
            posDisciplina = i
      for i in range(1,5):      
         somaNotas += disciplinas[posDisciplina]['peso'+str(i)]*elAluno['nota'+str(i)]
         somaPesos += disciplinas[posDisciplina]['peso'+str(i)]
      frequencia = float(disciplinas[posDisciplina]['cargaHoraria'] - elAluno['faltas'])/float(disciplinas[posDisciplina]['cargaHoraria'])
      media = somaNotas/somaPesos
      if linhasUsadas == 19:
         input("Digite qualquer número para continuar: ")         
         os.system(limpar)
         linhasUsadas = 0
      if opcaoConsulta=="aprovados":      
         if media >= 6 and frequencia >= 0.75:
            print("RA: "+str(elAluno['ra'])+" Nome: "+elAluno['nome']+" Média: "+str(media))
      elif opcaoConsulta=="exame":
         if media < 6 and frequencia >= 0.75:
            print("RA: "+str(elAluno['ra'])+" Nome: "+elAluno['nome']+" Média: "+str(media))
      else:
         print("RA: "+str(elAluno['ra'])+" Nome: "+elAluno['nome']+" Média: "+str(media))
      linhasUsadas += 1
   input("Digite qualquer número para continuar: ")
   return

def consultaAlunosDisciplina(alunos, disciplinas):
   os.system(limpar)   
   print("MENU DE CONSULTAS\n")   
   listarDisciplinas()
   opcaoDisciplina = input("Digite o código da disciplina a qual deseja ver os alunos: ")
   os.system(limpar)
   print("MENU DE CONSULTAS\n")
   if not ExisteCodigo(disciplinas, "codigo", opcaoDisciplina):
      return   
   for el in disciplinas:
      if el['codigo'] == opcaoDisciplina:
         disciplinaNome = el['nome']
   print("Listando alunos da disciplina: "+disciplinaNome)
   linhasUsadas = 3
   for el in alunos:
      if el['codigoDisciplina'] == opcaoDisciplina:
         if linhasUsadas == 19:
            input("Digite qualquer número para continuar: ")
            linhasUsadas = 0
         print("RA: "+str(el['ra'])+" Nome: "+el['nome'])
         linhasUsadas += 1
   
   input("Digite qualquer número para continuar: ")
   return

def consulta(alunos, disciplinas):
   opcaoConsulta = 0   
   while opcaoConsulta != 6:
      os.system(limpar)
      print("MENU DE CONSULTAS\n")      
      print("1. Todos Alunos")
      print("2. Alunos Aprovados")
      print("3. Alunos para Exame")
      print("4. Disciplinas e Pesos")
      print("5. Alunos por disciplina")
      print("6. Voltar")
      opcaoConsulta = input("\nEscolha uma opção válida (1 a 6): ")
      if opcaoConsulta == 1:
         consultaAlunos(alunos, disciplinas)
      if opcaoConsulta == 2:
         consultaAlunos(alunos, disciplinas, "aprovados")
      if opcaoConsulta == 3:
         consultaAlunos(alunos, disciplinas, "exame")
      if opcaoConsulta == 4:
         os.system(limpar)
         print("MENU DE CONSULTAS")
         listarDisciplinas(True)
         input("Digite qualquer número para continuar: ") 
      if opcaoConsulta == 5:
         consultaAlunosDisciplina(alunos, disciplinas)
   return   

if not ArquivoExiste(alunosPath):
   fAlunos = open(alunosPath, "w")
   listaAlunos = []
   pickle.dump(listaAlunos,fAlunos)
   fAlunos.close()
if not ArquivoExiste(disciplinasPath):
   fDisciplinas = open(disciplinasPath, "w")
   listaDisciplinas = []
   pickle.dump(listaDisciplinas,fDisciplinas)
   fDisciplinas.close()


opcao = 0
while opcao != 7:
      fAlunos = open(alunosPath, "r")
      fDisciplinas = open(disciplinasPath, "r")
      listaAlunos = pickle.load(fAlunos)
      listaDisciplinas = pickle.load(fDisciplinas)
      fAlunos.close()
      fDisciplinas.close()
   try:   
      os.system(limpar)
      print("CONTROLE DE NOTAS E FREQUÊNCIA\n")      
      print("1. Incluir Aluno")
      print("2. Excluir Aluno")
      print("3. Alterar Notas")
      print("4. Incluir Disciplina")
      print("5. Excluir Disciplina")
      print("6. Consultar")
      print("7. Sair")
      opcao = input("\nEscolha uma opção válida (1 a 7): ")
      if opcao==1:
         incluirAluno(listaAlunos, listaDisciplinas)
      elif opcao==2:
         excluirAluno(listaAlunos)
      elif opcao==3:
         alterarNotas()
      elif opcao==4:
         incluirDisciplina(listaDisciplinas)
      elif opcao==5:
         excluirDisciplina(listaAlunos, listaDisciplinas)
      elif opcao==6:
         consulta(listaAlunos, listaDisciplinas)
   except NameError:
      print("Opção inválida")

Scripts recomendados

RenameFile

Web Scraping para coletar dados dos pilotos da Fórmula 1

subwrite - um simples editor de texto em Python

Criando um rootfs para sistemas embarcados a partir de cópia de um sistema já operando

Checando se diretorio existe


  

Comentários
[1] Comentário enviado por albfneto em 07/05/2010 - 00:43h

sempre achei o nome desse pacote engraçado... Pickle... parece... Picles! srrsrssrrsrsrs

[2] Comentário enviado por lbrusca em 12/05/2010 - 12:50h

Estou recebendo esse erro somente no Ex1ComPickle.py, voce sabe o que pode estar gerando?

$python Ex1ComPickle.py
File "Ex1ComPickle.py", line 411
try:
^
IndentationError: unindent does not match any outer indentation level


Contribuir com comentário