Home > Back-end >  class object list not keeping memory appended objects - python
class object list not keeping memory appended objects - python

Time:01-13

I am new to python and just started learning about object oriented. I have a list of emails objects with class variable default is_spam = False

What I want to do is once a user marks email "i" as mark as spam, append that email to spam email(spam_inbox) list.

The problem is it seems every time I run the program, the spam_inbox resets to an empty list and return just latest element recently appended.

I was curious to know what I am doing incorrect; below is my code:

class Email():
    has_been_read = False
    is_spam = False

    def __init__(self,email_contents,from_address, ):
        self.email_contents= email_contents
        self.from_address = from_address

    def __str__(self):
        return f"{self.email_contents} from {self.from_address}"
    
    def mark_as_read(self):
        self.has_been_read = True
    
    def mark_as_spam(self):
        self.is_spam = True

mailbox = ["[email protected], testing class variable in python",
        "[email protected], testing variable in python"]
user_choice =""

#while loop user to choose an option
while user_choice != "quit":
    user_choice = input("What would you like to do - read/mark spam/send/quit? ")
    if user_choice == "mark spam":
        get_spam_emails()

#get spam email is defined as 
spam_inbox = []
def get_spam_emails():
    user_choose = int(input("\nWhich email would you like to mark spam? Enter index number(eg: 0 for the first email): ")) 
    user_marked_spam = inbox[user_choose].mark_as_spam()
    print(user_marked_spam)
    spam_inbox.append(user_marked_spam)
    print("=======")
    return spam_inbox

I expected to have a spam list which increases in size every time a user select an email to mark as spam. get_spam_emails() to return a list like below in case both emails were marked as spam:

spam_inbox = ["[email protected], testing class variable in python",
        "[email protected], testing variable in python"]

Maany thanks

CodePudding user response:

Complete edit of my answer for a more complete OO approach based on eli_257's comments. I have added classes for the MailServer and MailBox. You can add to these, or extend them, for other methods you will almost surely need, full CRUD for each object type.

Save it as a .py file and run it. Each time through it should pick random emails to set as spam...

All objects have methods to accomplish their tasks. For example, class MailBox has the method to move an email from the Inbox the SpamBox.

import uuid
import random
import copy


class Email:
    """A class that represents an email.
    
    """
    
    def __init__(self, email_contents, from_address, ):
        self.email_contents = email_contents
        self.from_address = from_address
        self.is_spam = False
        self.has_been_read = False
        self.email_id = uuid.uuid4()

    def to_str(self):
        return f"{self.email_contents} from {self.from_address}"

    def mark_as_read(self):
        self.has_been_read = True


class MailBox:
    """A class to represent all email boxes for a user
    """

    def __init__(self, **kwargs):  # use Key Word Args to capture init properties
        self.username = kwargs['username'] if 'username' in kwargs else ''
        if 'email_address' not in kwargs:
            print("Email Address is a required parameter for creating MailBox!")
        else:
            self.email_address = kwargs['email_address']
        self.inbox = {}
        self.spam_box = {}

    def add_to_inbox(self, email_to_add):
        """

        :type email_to_add: Email
        """
        email_id = email_to_add.email_id
        self.inbox[email_id] = email_to_add

    def move_to_spam(self, email_to_move):
        email_id = email_to_move.email_id
        self.spam_box[email_id] = email_to_move
        del self.inbox[email_id]

    def mark_spam_emails(self, spam_email):
        # Simulate user input
        username = self.username
        spam_email.is_spam = True
        self.move_to_spam(spam_email)
        email_from = spam_email.from_address
        print(f"Email from '{email_from}' added to SpamBox for user '{username}"'')


class MailServer:
    """A class to hold MailBox objects

    """

    def __init__(self, **kwargs):
        self.mailboxes = {}
        if 'username' in kwargs:
            self.username = kwargs['username']
            self.mailbox = kwargs['mailbox']
            self.add_mailbox(username=self.username, mailbox=self.mailbox)

    def add_mailbox(self, username, mailbox):
        self.mailboxes[username] = mailbox


if __name__ == '__main__':
    # Everything below the line above only runs if you are running this .py 
    # file as a script.  It will not run if you import this .py as a module
    #
    # Everything that follows is code to test the objects/ methods.  
    # There is a probably quite a few more tests that would be needed.
    #
    # test data for users mail boxes, each with 2 emails.
    test_data = {
        'tom': {
            'email_address': '[email protected]',
            'emails': [
                {
                    'email_contents': "Hi, Top. Welcome to python.",
                    'from_address': "[email protected]"
                },
                {
                    'email_contents': "Thanks for subscribing, Tom!",
                    'from_address': "[email protected]"
                },
            ]
        },
        'bob': {
            'email_address': '[email protected]',
            'emails': [
                {
                    'email_contents': "Hi, Bob. Welcome to python.",
                    'from_address': "[email protected]"
                },
                {
                    'email_contents': "Thanks for subscribing, Bob!",
                    'from_address': "[email protected]"
                },
            ]
        }
    }

    # Create a MailServer to hold mailboxes...
    email_server = MailServer()
    # Create the Users and populate their mailboxes with emails
    for username in test_data:
        email_data = test_data[username]
        email_address = email_data['email_address']
        user_emails = email_data['emails']
        user_mailbox = MailBox(email_address=email_address,
                               username=username
                               )
        # Add this user and their inbox to the mail server        
        email_server.add_mailbox(email_address, user_mailbox)
        for user_email_data in user_emails:
            from_address = user_email_data['from_address']
            email_contents = user_email_data['email_contents']
            new_email = Email(email_contents=email_contents, from_address=from_address)
            user_mailbox.add_to_inbox(new_email)

    # Test Code to go through users mail boxes and mark email as spam
    for username in email_server.mailboxes:
        user_mailbox = email_server.mailboxes[username]
        user_inbox_ref = user_mailbox.inbox
        # Make a deepcopy of the inbox dictionary, as it will likely change size and 
        #  the iterator will not like that... 
        user_inbox = copy.deepcopy(user_inbox_ref)
        for email_id in user_inbox:
            # Random(ish) decision on whether email is spam
            is_spam = bool(random.getrandbits(1))
            email_to_set_as_spam = user_inbox[email_id]
            email_from_address = email_to_set_as_spam.from_address
            if is_spam:
                print(f"Moving email from '{email_from_address}' to Spam Box for user '{username}'.")
                user_mailbox.move_to_spam(email_to_set_as_spam)
            else:
                print(f"Email from '{email_from_address}' Not Spam for user '{username}'.")
  • Related