Program design: real estate
About this video
The narrator designs a real estate marketplace where a Property has a list of Room objects. Instead of storing totals that could get out of sync, the property calculates stats from its rooms with methods for total square footage, price per square foot, and a case-insensitive find_rooms that returns matching room objects.
You'll be able to
- model a has-a relationship where one class stores a list of objects of another class.
- explain why calculating a value from stored data is better than storing a duplicate.
- write methods that loop over composed objects and use their attributes with dot syntax.
- calculate price per square foot from a price and a total area.
Key words
- object composition
- A design where one object has other objects, like a property that has rooms.
- square footage
- The area of a room or home measured in square feet.
- duplicate information
- The same data stored in more than one place, which can become out of sync.
- price per square foot
- A property's price divided by its total square feet, used to compare properties.
- case insensitive
- Matching text without caring about capital letters, for example by converting both to lowercase.
Transcript
- [Instructor] Let's design a program with object composition. We are building a real estate marketplace where agents list properties for sale. The listing for each property tells us what kind of home it is, its asking price, and then information about its individual rooms.
In our class design, then, we might say that a property has a list of rooms. Each room keeps track of its own information, like its kind, its square footage, and its level. The property can then use its rooms to calculate stats that buyers care about, like the total square footage or the number of bedrooms.
Let's start by modeling those two classes, a property and a room. We said a room has three attributes, a kind, a level, and the number of square feet. Pretty straightforward. And we'll just add a quick string method so we can display a room nicely. To test that, let's go back to main and create a room object.
For example, we might have a kitchen on level two that's 160 square feet. And if we print that room, we'll get our nice string representation. Cool, time for the composition piece. Let's define our property class. Like our outline said, a property has a kind, a price, and a list of rooms.
We might say that a property owns a room because a specific room can't belong to multiple properties. That doesn't really make sense. And a property's rooms very rarely change over time, but a property can have 10 rooms, 20 rooms, so I don't really want to create all of those room objects inside the property class.
Thinking about the users of this program, a real estate agent will probably enter all of the data for a property at once. So for now, I'm not gonna worry too much about how to add or remove rooms. Instead, let's just set the property's rooms all in one assignment.
Okay, now what does our property class use those rooms for? Well, good program design means that we don't wanna duplicate information, because if I store the same information in multiple places, it's very likely to become out of sync over time. Someone updates the value in one place, but forget to update it in the other.
So while I do wanna display the total square footage of the property, I don't wanna store that as an attribute on the property since I already store the square feet of each room. That means instead we want a method that can calculate the total square footage from the list of rooms.
So our get_sq_ft method will iterate over our list of rooms. That loop variable room holds a room object, but we don't wanna add the object to our running total, we wanna add the object square feet attribute. So we need dot syntax here. One quick related stat, buyers often wanna know the price per square foot so they can compare against other properties.
So let's add another method for that calculation. The price per square feet is just the price of the property over its total square feet, which we can use our get_sq_ft method to calculate. And then we'll just round that to two decimal points. All right, before I get too carried away, let's test those two methods.
We call the get_sq_ft and get price_per_sq_ft methods on our house object. Now, one last feature. Buyers often wanna look up information about a particular kind of room in a property. Like maybe they wanna know how many square feet the kitchen is, or how many bedrooms and bathrooms there are.
So we wanna be able to ask a property, give me all of the rooms of this kind. I'm just sketching out here what that might look like, though of course this gives an error right now. So let's go back to the property class and add that find_rooms method. We want this method to return the actual room objects so the caller can access whatever data they want.
But some properties might have several rooms of the same kind. So we'll wanna return a list of room objects in case there are multiple matches. We'll iterate over our list of rooms and check if the room's kind is equal to the kind that we're looking for. Let's make that match case insensitive and convert them both to lowercase.
And if it does match, we wanna append that whole room object. And then at the end, we return our accumulated result. Let's run that to check and we see a match of two bedrooms and two bathrooms. This summary will look great on our property listing page so our buyers can quickly see the property square feet, number of beds, and number of baths.
And if it piques their interest, they can easily drill down into more details about the property's individual rooms.
Video © Khan Academy, used under CC BY-NC-SA. Watch on Khan Academy. Puzzicle is not affiliated with Khan Academy.