Попытка удалить элемент из списка с помощью классов - PullRequest
0 голосов
/ 29 июня 2019

Я работаю над попыткой реализовать опцию удаления записи для этой программы адресной книги, над которой я работаю, которая использует объектно-ориентированное программирование. Проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь удалить элемент из списка, он удаляет все элементы, кроме последнего элемента.

Я попытался создать список и пройти по нему внутри функции remove_entry в классе AddressBook вместо того, чтобы пытаться удалить элемент непосредственно из списка self.people, который я инициализировал в функции init моего класса Address Book. Это похоже на то, что я сделал с функцией display_summaries в классе контроллера, но это не решило мою проблему. Когда я попытался это сделать, он не удалил никаких элементов из списка.

# Imports
import pickle
import os.path

# Constants
SAVE_FILE_NAME = 'address_book_contents.pickle'
INSTRUCTIONS = '''Address Book Application
Press:
a to add an entry
r to remove an entry
d to display a list of all entries in summary form
s to display a list of all entries sorted alphabetically in summary form
i to print these instructions again
q to quit
'''
CONFIRM_QUIT_MESSAGE = 'Are you sure you want to quit (Y/n)? '
SUMMARY_TEMPLATE = "%s %s DOB: %s email: %s"

### Classes Section
class AddressBook (object):
    ''' 
    This class holds and manages a list of my contacts 
    '''

    def __init__ (self):
        ''' Set people attribute to an empty list '''
        self.people = []

    def add_entry (self, new_entry):
        ''' Adds a new entry to the list of people in the address
        book. The new_entry is an instance of the AddressEntry
        class'''
        #Adds the entry to people list
        self.people.append(new_entry)

    def remove_entry(self, entry):
        '''Removes an entry from the list of people in the address book.
        Entry is an index and comes from the remove_entry function in
        the Controller class '''
        try:
            entry = int(entry)
            #return self.people.remove(self.people[entry-1])

        except IndexError:
            #print("INVALID ENTRY! There is no entry in the address book for the number you entered")
            return "INVALID ENTRY! There is no entry in the address book for the number you entered"
        except ValueError:
            return "INVALID ENTRY! Please enter an integer number instead of a character"
        else:
            entry = int(entry)
            del self.people[entry-1]

    def is_list_empty (self):
        return self.people

    def save(self):
        with open(SAVE_FILE_NAME, 'wb') as file_object:
            pickle.dump(self, file_object)



class AddressEntry (object):
    '''
    This class has one instance for each person's details
    '''
    def __init__ (self, first_name=None, last_name=None, email=None, DOB=None):
        '''Initializes attributs f_name, l_name, email, and birthday.
        Each arg is a string.
        Birthday should be a string in the format MM DD, YYYY
        '''
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
        self.DOB = DOB

    #Function that overites default __repr__ so that print(person1) actually prints the values we passed into __init__
    def __repr__ (self):
        '''Given an AddressEntry object self return a readable string
        representation
        '''
        template = "AddressEntry(first_name = '%s', "+\
                "last_name = '%s', "+\
                "email = '%s', "+\
                "DOB = '%s')"

        attributes = (self.first_name, self.last_name, self.email, self.DOB)

        return template%attributes



class Controller(object):

    def __init__(self):
        self.address_book = self.load()
        if self.address_book is None:
            self.address_book = AddressBook()

        self.run_interface()

    def load(self):
        if os.path.exists(SAVE_FILE_NAME) is True:
            with open(SAVE_FILE_NAME, 'rb') as file_object:
                address_book = pickle.load(file_object)
            return address_book
        else:
            return None

    def run_interface(self):

        print(INSTRUCTIONS)
        while True:
            command = input('What would you like to do? (press i to see all the options again) ')
            type(command)
            if command == 'a':
                self.add_entry()
            elif command == 'r':
                self.remove_entry()
            elif command == 'd':
                print("Displaying summaries of all people stored in the address book")
                self.display_summaries()
            elif command == 's':
                self.sort_entries()
            elif command == 'i':
                print(INSTRUCTIONS)
            elif command == 'q':
                user_quit = input(CONFIRM_QUIT_MESSAGE)
                type(user_quit)
                if user_quit == 'Y' or user_quit == 'y':
                    print('\nSaving...')
                    self.address_book.save()
                    print("\nThank you for using my address book application; come again soon!")
                    break
                elif user_quit == 'N' or user_quit == 'n':
                    continue
            else:
                print("I don't recognize that instruction (%s) "%command)

    def add_entry(self):
        print("Adding a new person to the address book")
        print("What is the person's: ")
        first_name = input("First Name? ")
        type(first_name)
        if first_name == 'q':
            print('Not Adding')
            return
        last_name = input("Last Name? ")
        type(last_name)
        if last_name == 'q':
            print('Not Adding')
            return
        email = input("Email Address? (if they don't have one, just enter None) ")
        type(email)
        if email == 'q':
            print('Not Adding')
            return
        DOB = input("Date of Birth? (Enter in the format MM DD, YYYY) ")
        type(DOB)
        if DOB == 'q':
            print('Not Adding')
            return

        new_entry = AddressEntry(first_name, last_name, email, DOB)
        self.address_book.add_entry(new_entry)
        values = (first_name, last_name)
        print("Added address entry for %s %s\n"%values)

    def display_summaries(self):
        '''for index, e in enumerate(self.address_book.people):
            values = (e.first_name, e.last_name, e.DOB, e.email)
            entry = SUMMARY_TEMPLATE%values
            print("%s: %s"%(index+1, entry))'''
        if self.address_book.is_list_empty() == []:
            print("Cannot display summaries because the address book is empty")
            return
        else:
            list1 = []
            for i in self.address_book.people:
                values = (i.first_name, i.last_name, i.DOB, i.email)
                list1.append(values)

            list1 = sorted(list1)

            for index, e in enumerate(list1):
                entry = SUMMARY_TEMPLATE%e
                print("%s: %s"%(index+1, entry))

    def remove_entry(self):
        print("Removing a person from the address book\n")
        if self.address_book.is_list_empty() == []:
            print("There are no entries to remove from the address book")
            return
        else:
            self.display_summaries()
            while True:
                user_input = input("\nEnter the number of the entry you would like to remove: ")
                type(user_input)
                if user_input == 'q':
                    print("Exiting remove entry")
                    return

                if self.address_book.remove_entry(user_input) == "INVALID ENTRY! There is no entry in the address book for the number you entered":
                    print(self.address_book.remove_entry(user_input))
                elif self.address_book.remove_entry(user_input) == "INVALID ENTRY! Please enter an integer number instead of a character":
                    print(self.address_book.remove_entry(user_input))
                else:
                    print("Entry number "+user_input+" has been removed")
                    break

    def sort_entries(self):
        print("Sorting Entries")
        if self.address_book.is_list_empty() == []:
            print("Cannot sort because the address book is empty")
            return
        else:
            list1 = []
            for i in self.address_book.people:
                values = (i.first_name, i.last_name, i.DOB, i.email)
                list1.append(values)

            list1 = sorted(list1)

            for index, e in enumerate(list1):
                entry = SUMMARY_TEMPLATE%e
                print("%s: %s"%(index+1, entry))



### Main section
controller = Controller()

Это вывод, который я получаю при попытке удалить только первый элемент из списка:

What would you like to do? (press i to see all the options again) r
Removing a person from the address book

1: Eric s DOB: 1 email: 1
2: Joe J DOB: 1 email: N
3: Joe S DOB:  email: 


Enter the number of the entry you would like to remove: 1
Entry number 1 has been removed

What would you like to do? (press i to see all the options again) d
Displaying summaries of all people stored in the address book
1: Joe S DOB:  email: 

Я ожидаю получить:

Enter the number of the entry you would like to remove: 1
Entry number 1 has been removed

What would you like to do? (press i to see all the options again) d
Displaying summaries of all people stored in the address book
1: Joe J DOB: 1 email: N
2: Joe S DOB:  email: 

1 Ответ

0 голосов
/ 29 июня 2019

Ваша главная проблема в этом маленьком блоке:

if self.address_book.remove_entry(user_input) == "INVALID ENTRY! There is no entry in the address book for the number you entered":
    print(self.address_book.remove_entry(user_input))
elif self.address_book.remove_entry(user_input) == "INVALID ENTRY! Please enter an integer number instead of a character":
    print(self.address_book.remove_entry(user_input))
else:
    print("Entry number "+user_input+" has been removed")
    break

В методе remove_entry класса Controller.

Обратите внимание, что как в if, так и в elif вы фактически вызываете функцию каждый раз с выражением self.address_book.remove_entry(user_input). Так что происходит при первой проверке if первой записи удаляется, а затем также при проверке elif второй записи удаляется!

Что вы хотите сделать, это вызвать функцию удаления один раз , а затем выполнить проверки. Примерно так:

remove_result = self.address_book.remove_entry(user_input)

if remove_result == "INVALID ENTRY! There is no entry in the address book for the number you entered":
    print(remove_result)
elif remove_result == "INVALID ENTRY! Please enter an integer number instead of a character":
    print(remove_result)
else:
    print("Entry number "+user_input+" has been removed")
    break

Кроме того, в вашем коде есть несколько проблем или просто неправильно напечатанный код. Если вы новичок, я бы посоветовал начать с более простых проектов, чтобы освоить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...