segunda-feira, 8 de dezembro de 2014

A minha lista telefónica

É tempo de desenvolver uma aplicação interactiva que permita manter actualizada a minha lista de contactos telefónicos. Para simplificar vamos admitir que a lista apenas vai conter o nome e o número. Em abstracto existem várias operações que vou pretender poder fazer: adicionar um número, remover um número, procurar um número, carregar a lista de contactos, salvar um lista de contactos.

Sendo uma lista de contactos telefónicos que quero manter permanentemente, é óbvio que ela vai estar guardada num ficheiro. Por outro lado, a actualização da lista vai obrigar a operações que me interessa que sejam feitas de forma simples e eficiente. Veremos que um modo de o conseguir é ter os contactos armazenados na memória como um dicionário, de chave igual ao nome e valor igual ao número de telefone.

. Este tipo de programas interactivos tem uma estrutura clássica, ou se quiserem, existe um padrão de desenho para o resolver. Fundamentalmente teremos um ciclo potencialmente infinito que em cada repetição imprime um menu de opções e depois, em função das nossas escolhas lança o respectivo programa. Mostremos então esse padrão.
def main():
    lista_tele = {}
    while True:
        mostra_menu()
        menu_escolhas = int(input("Escolha a sua opção (1-7): "))
        if menu_escolhas == 1:
            mostra_lista(lista_tele)
        elif menu_escolhas == 2:
            print("Acrescentar Nome e Número")
            nome = input("Nome: ")
            telefone = input("Número: ")
            acrescenta_numero(lista_tele, nome, telefone)
        elif menu_escolhas == 3:
            print("Retira Nome e Número")
            nome = input("Nome: ")
            retira_contacto(lista_tele, nome)
        elif menu_escolhas == 4:
            print("Procura Número")
            nome = input("Nome: ")
            print(procura_numero(lista_tele, nome))
        elif menu_escolhas == 5:
            nome_ficheiro = input("Ficheiro a carregar: ")
            carrega_lista(lista_tele, nome_ficheiro)
        elif menu_escolhas == 6:
            nome_ficheiro = input("Ficheiro a salvar: ")
            salva_lista(lista_tele, nome_ficheiro)
        elif menu_escolhas == 7:
            break
        else:
            mostra_menu()
     
    print("Fim")
    
def mostra_menu():
    pass

def mostra_lista(lista_tele):
    pass

def acrescenta_numero(lista_tele,nome,telefone):
    pass
    
def retira_contacto(lista_tele, nome):
    pass

def procura_numero(lista_tele,nome):
    pass

def carrega_lista(lista_tele, nome_ficheiro):
    pass

def salva_lista(lista_tele,nome_ficheiro):
    pass

if __name__ == '__main__':
    main()

Este programa já pode ser corrido, para testes primitivos, embora não faça nada ainda de relevante. Vamos então completar o que falta, começando pelo mais simples, a função que mostra o menu de opções.
def mostra_menu():
    print("1. Mostra Lista Telefónica")
    print("2. Acrescentar Entrada (Nome, Número)")
    print("3. Retirar Entrada (Nome, Número)")
    print("4. Procurar Número")
    print("5. Carregar Lista Telefónica")
    print("6. Salvar Lista Telefónica")
    print("7. Terminar")
    print()
Vamos agora passar às funções mais interessantes e que se baseiam nas escolhas já enunciadas: a lista está guardada num ficheiro externo e é manipulada internamente como um dicionário. Carregar a lista telefónica consiste então em ler um ficheiro e guardar essa informação num dicionário.
def carrega_lista(lista_tele, nome_ficheiro):
    with open(nome_ficheiro,'r') as f_ent:
        for contacto in f_ent:
            dados = contacto[:-1]
            nome, numero = dados.split()
            lista_tele[nome] = numero
        return lista_tele
Este programa pode ser testado de forma autónoma, bastando apenas existir previamente um pequeno ficheiro com uma lista telefónica. Por exemplo, com o ficheiro
ernesto   123
patricia  456
daniela 789
pedro 012
ao corremos o programa o resultado será:
{'pedro': '012', 'ernesto': '123', 'patricia': '456', 'daniela': '789'}
Notar que os nomes e os números são tratados como cadeia de caracteres. Vamos agora escrever o código da função inversa, ou seja, salvar uma lista telefónica interna guardada num dicionário num ficheiro.
def salva_lista(lista_tele,nome_ficheiro):
    with open(nome_ficheiro,'w') as f_saida:
        for chave,valor in lista_tele.items():
            contacto = chave + '  ' + valor + '\n'
            f_saida.write(contacto)
Não há muitas observações a fazer. Apenas notar que usamos espaços em branco para separar o nome do número e que cada contacto termina com a marca de fim de linha. Vamos agora implementar as funções que internamente manipulam a lista telefónica.
def acrescenta_numero(lista_tele,nome,telefone):
    lista_tele[nome] = telefone
    return lista_tele
    
def retira_contacto(lista_tele, nome):
    if nome in lista_tele:
        del lista_tele[nome]
        return lista_tele
    else:
        print('Contacto inexistente')

def procura_numero(lista_tele,nome):
    if nome in lista_tele:
        print(lista_tele[nome])
    else:
        print('Contacto inexistente’)
São programas muito simples. Apenas temos o cuidado de verificar que o contacto existe na lista. Fica por resolver a função que mostra a lista telefónica. Também não apresenta grande dificuldade. O único aspecto que requere a nossa atenção é que a visualização seja feita por ordem dos nomes.
def mostra_lista(lista_tele):
    for nome,numero in sorted(lista_tele.items()):
        print()
        print('Nome: %s\nNúmero: %s' % (nome,numero))
E pronto. Agora pode divertir-se. Mas lembre-se que se trata de uma solução simples e com algumas fragilidades. Em particular, não esta muito protegida contra erros na entrada de dados, ou não está previsto que uma pessoa possa ter mais do que um telefone. Pense nestas e noutras questões e melhore a solução apresentada.

Sem comentários:

Enviar um comentário