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}'.")