Polishing and Refactoring
Explore techniques to polish and refactor your Python OOP project by consistently applying private data member conventions and introducing a dynamic menu-driven interface. Gain skills to improve code readability, maintainability, and user interaction while preparing your social media platform for scalability.
Chirpy has come a long way—users can now create posts, like content, comment, and even have verified accounts. However, as our platform expands, we must ensure our code structure evolves as well.
Fixing private data members
Recall our lesson on “Encapsulation and Private Data Members,” where we learned that each private data member within a class should start with a leading underscore (_). While this convention doesn’t strictly prevent access in Python, it clearly communicates to other developers that these attributes aren’t intended for direct use. More importantly, this practice supports the principle of abstraction, which involves hiding internal implementation details and exposing only essential functionalities to the outside world.
Did you know?
By convention, all data members of a class should be treated as private.
Earlier, we applied this approach only to the password attribute. Now, it’s time to consistently adopt this convention across all data members in our Chirpy project. Let’s get started and refactor our code!
from user import User
from post import Post
class VerifiedUser(User):
def __init__(self, username, display_name, password):
# Inherit attributes from User
super().__init__(username, display_name, password)
# Mark the user as verified
self.verification_badge = True
def get_verification_status(self):
return "Verified ✅" if self.verification_badge else "Regular"
# Overriding create_post() to add a "✅ " prefix to the content
def create_post(self, content):
# Add a special flair to posts created by verified users
verified_content = "✅ "+ content
post = Post(verified_content, self)
self._posts.append(post)
return postNow, all the private attributes have been fixed.
But still, our code looks a little messy.
Manually calling every function every time
Unnecessary lines of code
Scattered execution flow, making the project harder to maintain
How can we clean this up? The answer is refactoring.
This lesson focuses on improving our project’s structure, readability, and maintainability. Right now, our main file manually calls functions for different actions:
user1 = User("alex123", "Alex", "password123")chirpy_network.add_user(user1)post1 = user1.create_post("Hello world!")chirpy_network.add_post(post1)user2.like_post(post1)chirpy_network.show_followers("alex123")
While this works, it’s not scalable.
What happens when we add more features? Whenever a user wants to perform an action, we have to manually write a new function call.
Wouldn’t it be better if users could interact with the system dynamically instead of us hardcoding every step?
If we look back at our initial conversation, we’ll remember that we had an interface where, instead of manually typing all the function calls, we had a menu from which we could select options and perform the relevant action.
Let’s see that again!
A menu-based system
Instead of manually calling different actions, we’ll create an interactive menu, as we can see above, that dynamically lets users choose actions. What it will do for us is:
Organized workflow: Users see a list of available actions and choose what to do.
Less redundancy: No need to hardcode function calls for every new feature.
More user-friendly: The system guides users through interactions.
Refactoring the main execution flow
We’ll introduce a menu-driven interface where users can choose what to do at runtime.
Creating the menu system
We’ll replace our manual function calls with a loop that presents users with available actions.
def display_menu():print("\n Chirpy Social Media Platform")print("========================================")print("1. Create New Account")print("2. Post a Chirp")print("3. View All Chirps")print("4. Like a Chirp")print("5. Comment on a Chirp")print("6. View Profile")print("7. List All Users")print("8. Exit")
Handling user input with if-else
We’ll map user selections to if-else statements and those statements will point to the related function call..
The above code starts by displaying a clear menu with the available options—currently, just the option to create a new account. When the user selects the account creation option, it prompts for essential account details such as user name, display name, and password, as well as whether the user wants a verified account. Based on the user’s input, it creates either a regular user or a verified user object and then adds this user to the chirpy network. The program continuously loops, repeatedly showing the menu and handling user input, which allows multiple accounts to be created or prompts the user to re-enter their choice if they provide an invalid input.
Let’s see this refactoring in action!
from user import User
from post import Post
class VerifiedUser(User):
def __init__(self, username, display_name, password):
# Initialize using User's constructor
super().__init__(username, display_name, password)
# Privately mark the user as verified
self._verification_badge = True
# Update the private display name attribute to include a verified badge
self._display_name = "✅ " + display_name
def get_verification_status(self):
return "Verified ✅" if self._verification_badge else "Regular"
# Override create_post() to include verified flair in post content
def create_post(self, content):
verified_content = "✅ " + content
post = Post(verified_content, self)
self.posts.append(post)
return postWhen we run the above code, we’ll get a nice display menu with just one option, “Create New Account.” For now, when we select it and enter the required details, we’ll see a successful account creation message.
Challenge: Convert Chirpy into a full menu-based application
After some refactoring, Chirpy has a basic menu—users can only create an account. However, we have just scratched the surface! Your task is to transform Chirpy into a full-fledged social network by expanding the menu to offer the following interactive features:
Post a Chirp
View All Chirps
Like a Chirp
Comment on a Chirp
View Profile
List All Users
Exit
Implement each of these functionalities within your existing menu structure. Make sure the app remains intuitive, user-friendly, and interactive.
Ready to take Chirpy to new heights? Let’s get coding!
from user import User
from post import Post
class VerifiedUser(User):
def __init__(self, username, display_name, password):
# Initialize using User's constructor
super().__init__(username, display_name, password)
# Privately mark the user as verified
self._verification_badge = True
# Update the private display name attribute to include a verified badge
self._display_name = "✅ " + display_name
def get_verification_status(self):
return "Verified ✅" if self._verification_badge else "Regular"
# Override create_post() to include verified flair in post content
def create_post(self, content):
verified_content = "✅ " + content
post = Post(verified_content, self)
self.posts.append(post)
return postWhat’s next?
With this lesson, we’ve successfully transformed Chirpy into a fully functional, interactive social media platform. Users can now create accounts, post chirps, like and comment on posts, view profiles, and explore a list of all registered users. More importantly, we’ve structured our code using object-oriented programming (OOP) principles such as encapsulation, inheritance, composition, and polymorphism, ensuring our project remains scalable and maintainable.
But before we wrap up, let’s put everything we’ve learned to the test!
In the next and final lesson, you’ll complete a challenge designed to test your OOP mastery. You’ll be presented with a brand-new problem to solve, requiring you to design classes, define relationships, and structure your code efficiently—all on your own
This is your chance to put everything you’ve learned to the test.
Are you ready?