The User Class

Learn how to build your first user class.

Welcome to the code lab!

Great news! We’re finally rolling up our sleeves and writing our first piece of code for Chirpy! 🎉

Right now, our social media platform is just an idea—there are no users, no interactions, just an empty void. But today, that changes! We’re going to bring users to life in Chirpy by creating a User class using object-oriented programming.

Let’s get started!

What’s a class, anyway?

Press + to interact

Think of a class as a blueprint for creating objects. Imagine a cookie cutter—it defines the shape, but each cookie you make is unique. Similarly, a class defines the structure, and objects (instances) are unique creations based on that blueprint.

In Chirpy, we need a way to define users. Each user should have a property, such as a name and method, to display it. Let’s visualize how our User class should look like:

Press + to interact
We have a User class in which we have three users
1 / 4
We have a User class in which we have three users

As visualized above, each user should have:

  • A username (so they can log in).

  • A display name (so people know who they are).

We can create this blueprint using Python’s class keyword:

class User:
def __init__(self, username, display_name):
self.username = username # Store the username
self.display_name = display_name # Store the display name
User class

Let’s break our first created class and see how it works:

  • class User: This defines our User class.

  • __init__: This constructor method runs automatically when a user is created.

  • self.username and self.display_name: These store user-specific details.

Creating users

Now that we have the User class, let’s create some actual users!

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username # Store the username
self.display_name = display_name # Store the display name
# Creating users
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")

Congratulations! We now have two users in Chirpy. But how do we know they actually exist?

Let’s check!

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username # Store the username
self.display_name = display_name # Store the display name
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")
# Displaying users
print(user1.username)
print(user2.display_name)

Now, we can store user information in our program. But users in a social network don’t just exist—they interact. Let’s add a method to show their profiles.

Making users do things

We’ll add a method inside our class that lets users show their profile information.

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username
self.display_name = display_name
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")
# Adding method to show profiles of users
def show_profile(self):
print("User:", self.display_name, "(@" + self.username + ")")

Now, let’s call the newly added method and see how it works.

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username
self.display_name = display_name
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")
def show_profile(self):
print("User:", self.display_name, "(@" + self.username + ")")
# Calling the new show profile function
user1.show_profile()
user2.show_profile()

Oops! We ran into an error. It appears that the User object has no attribute as show_profile or in simple words the User class has no show_profile function.

Why it happened?

We made a mistake here; instead of adding the new function inside the User class, we defined it outside. Since it’s not part of the class, it has no relation with the users. To make it work we have to add it inside the User class. Let’s fix this!

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username
self.display_name = display_name
def show_profile(self):
print("User:", self.display_name, "(@" + self.username + ")")
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")
# Calling the new show profile function
user1.show_profile()
user2.show_profile()

Now all the issues are fixed, and we can see user details in a friendly way. Pretty cool, right?

But wait!

Press + to interact

What if we could still define the function outside the class and make it work? Let’s try this.

The only change is that instead of calling the function as user1.show_profile(), we pass the user object as an argument to the function: show_profile(user1).

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username
self.display_name = display_name
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")
def show_profile(self):
print("User:", self.display_name, "(@" + self.username + ")")
# Calling the new show profile function created outside the class
show_profile(user1)
show_profile(user2)

And it worked.

But the thing is, it’s not OOP. It’s simply procedural programming. If you define show_profile as a standalone function, it exists independently of the User class and, therefore, has no inherent connection to any user object. Because it’s not part of the class, you must explicitly pass an instance of the User class as an argument every time you call it.

In this scenario, the show_profile function can operate on any provided object that meets its requirements, but it’s your responsibility to ensure you pass the correct user object (like user1) when calling the function. This design follows a procedural programming style, meaning the data (represented by the User object) and the behavior (represented by the standalone show_profile function) remain separated rather than bundled together, which is the essence of object-oriented programming.

On the other hand, when we define a function inside a class (making it a method), we use the dot notation (user1.show_profile()) to call it. The dot notation clearly indicates that the method belongs to that particular object, tightly coupling the data and its behavior. This ensures that the method is always called on the correct instance, eliminating potential errors and enhancing code readability, maintainability, and clarity.

Challenge

Your users need personality! Let’s add bios to their profiles.

Your task

  • Add a bio attribute to the User class (a short user introduction).

  • Update the show_profile() method to display the bio only if it exists.

  • Test with two users: one with a bio and one without.

Press + to interact
class User:
def __init__(self, username, display_name):
self.username = username
self.display_name = display_name
# Add your code here
def show_profile(self):
print("User:", self.display_name, "(@" + self.username + ")")
# Add your code here
user1 = User("alex123", "Alex")
user2 = User("emma456", "Emma")
user1.show_profile()
user2.show_profile()

What’s next?

Our users exist, but they can’t do much yet! Where’s the fun in a social network without posts? Right now, users cannot share their thoughts. They need a way to post chirps—short messages that others can see.

Considering the design of our Chirpy project, would it be a good idea to store posts directly as an attribute within the User class—much like we did with a bio?

Our AI is here to assist!

In the next lesson, we’ll introduce the Post class so users can post their thoughts on Chirpy.

Stay tuned—exciting things are coming! 🔥