Objects and Classes¶
In this lesson, we'll practice type annotations and class-building to create some Ed posts!
!pip install -q nb_mypy
%reload_ext nb_mypy
%nb_mypy mypy-options --strict
[notice] A new release of pip is available: 25.0.1 -> 25.1.1 [notice] To update, run: pip install --upgrade pip
Version 1.0.5
Group Activity: Ed Posting¶
Define a class EdPost
that represents a question on the discussion board. The EdPost
class should have an initializer that takes an argument for each of the 4 fields your class should have. Each field should use the same names as its parameter, except that it needs to be declared private.
- The
bool
flag that marks the post as private or public. This field does not have a default value. IfTrue
, then the post is public. IfFalse
, then the post is private. - The
str
title of the post. This field does not have a default value. - The
str
tag of the post. If the parameter is not given, the tag field should be'General'
. - The
list[str]
comments on the post. If the parameter is not given, the comments field should be[]
.
Your class should have the following methods.
- An initializer that takes the parameters to initialize the fields as described above (in that order).
- A method
get_title
that returns the title of the post. - A method
get_tag
that returns the tag on the post - A method
add_comment
that adds a comment (str
) to this post. - A method
display
that prints out information about the post the following format, replacing the uppercase placeholders forTITLE
,TAG
,COMMENT
, and...
accordingly. The comments should appear in the order they were added, one on each line and indented by two spaces.
TITLE (TAG)
Comments:
COMMENT
COMMENT
COMMENT
...
If the post is private, then the display
method should only print "Private post!"
instead (with no comment or tag information).
Here's an example call:
post1 = EdPost(True, "Typo in spec?", "Education")
post1.add_comment("There was a typo!")
post1.add_comment("And maybe another typo?")
post2 = EdPost(True, "What's Wen's favorite cat?")
post2.add_comment("There can't be just one!")
post3 = EdPost(False, "I need help!", "Processing")
post1.display()
print()
post2.display()
print()
post3.display()
And its output:
Typo in spec? (Education)
Comments:
There was a typo!
And maybe another typo?
What's Wen's favorite cat? (General)
Comments:
There can't be just one!
Private post!
class EdPost:
def __init__(self, is_public: bool, title: str, tag: str = 'General',
comments: list[str] | None = None) -> None:
self._is_public = is_public
self._title = title
self._tag = tag
if comments is None:
self._comments = []
else:
self._comments = comments
def get_title(self) -> str:
return self._title
def get_tag(self) -> str:
return self._tag
def add_comment(self, comment: str) -> None:
self._comments.append(comment)
def display(self) -> None:
if self._is_public:
print(f'{self._title} ({self._tag})')
print('Comments:')
for comment in self._comments:
print(' ' + comment)
else:
print("Private post!")
post1 = EdPost(True, 'Typo in spec?', 'Assignment 1')
post1.add_comment('There was a typo!')
post1.add_comment('And maybe another typo?')
post2 = EdPost(True, "What's Wen's favorite cat?")
post2.add_comment("There can't be just one!")
post3 = EdPost(False, "I need help!", "Processing")
post3.add_comment("TA response")
post1.display()
print()
post2.display()
print()
post3.display()
Typo in spec? (Assignment 1) Comments: There was a typo! And maybe another typo? What's Wen's favorite cat? (General) Comments: There can't be just one! Private post!
Whole Class Activity¶
Uh-oh, looks like we forgot a very important feature of Ed posts-- their authors! Let's make an AuthoredEdPost
class to take in a string author
parameter (if none is provided, the author
should be "Anonymous"
). Authors can write Ed posts, but they can also add comments! All methods in the AuthoredEdPost
class are the same as those in the EdPost
class, with some excpetions. Do the following tasks in the AuthoredEdPost
class:
- Add the
author
parameter to the initializer. If no author is provided, default to"Anonymous"
. This parameter should be a string. - Add a method
get_author()
that returns the author of a post. - Add a method
get_commenters()
that returns a dictionary where the keys represent the authors of comments and the values are a list of that author's comments. (Hint: you may need to create a new field to help with this!) - Update the
add_comment()
method so that you are keeping track of the author of each comment in addition to the comment itself. If there is no author given, default to"Anonymous"
. - Change the
display
method so that it aligns with the following format:
TITLE (TAG) by AUTHOR
Comments:
COMMENT_AUTHOR: COMMENT
COMMENT_AUTHOR: COMMENT
COMMENT_AUTHOR: COMMENT
...
AUTHOR
is the author of the EdPost
, while each COMMENT_AUTHOR
is the author of their respective comment.
class AuthoredEdPost:
def __init__(self, is_public: bool, title: str, tag: str = 'General',
comments: list[str] | None = None, author: str = 'Anonymous') -> None:
self._is_public = is_public
self._title = title
self._tag = tag
if comments is None:
self._comments = []
else:
self._comments = comments
# adding author and commenter fields
self._author = author
self._commenters: dict[str, list[str]] = {}
def get_title(self) -> str:
return self._title
def get_tag(self) -> str:
return self._tag
# add getter method for the author
def get_author(self) -> str:
return self._author
# add getter method for the commenters
def get_commenters(self) -> dict[str, list[str]]:
return self._commenters
def add_comment(self, comment: str, author: str = 'Anonymous') -> None:
self._comments.append(comment)
# Add to the commenters dictionary
if author not in self._commenters:
self._commenters[author] = [comment]
else:
self._commenters[author].append(comment)
def display(self) -> None:
if self._is_public:
# Update the format of the display to show the authors of comments and posts
print(f'{self._title} ({self._tag}) by {self._author}')
print('Comments:')
for author, comment_list in self._commenters.items():
for comment in comment_list:
print(' ' + author + ": " + comment)
else:
print("Private post!")
Now, let's mess around with authored Ed posts!
post3 = AuthoredEdPost(True, "Who's the best superhero?", "Social")
post3.add_comment("Superman!")
post3.add_comment("Clearly it's Batman", "Vatsal")
post3.add_comment("Any X-men fans?", "Suh Young")
post4 = AuthoredEdPost(True, "Does Kevin like cats?")
post4.add_comment("No comment", "Kevin")
post3.display()
print()
post4.display()
Who's the best superhero? (Social) by Anonymous Comments: Anonymous: Superman! Vatsal: Clearly it's Batman Suh Young: Any X-men fans? Does Kevin like cats? (General) by Anonymous Comments: Kevin: No comment