CS 115 Lab 12, Part A: Define a City class

[Back to lab instructions]


Background recap

Object-oriented programming is all about defining our own data types and the operations they support. However, there are some limitations! Consider the code:

print(5)
Python knows exactly how to print this integer. More precisely, it knows how to internally convert that integer into its string representation, and then print that.

However, if you were to write something like:

s = Student('Example McStudent', [90, 100, 95]) # using the Student class from Lab 11, Part E
print(s)
...how is Python supposed to know how you would like this printed? It doesn't know anything about the Student data type beyond what you've provided in the class definition. In Part E of Lab 11, we got around this by defining our own print method for the class, so we could do s.print() to print the student in exactly the format we desired. In Lab 12, we'll solve this problem differently: by defining a special method of our class that will cooperate with Python's provided print function.

Printing isn't the only problem! Again, with Python's provided data types, Python knows exactly what to do with something like

if 100 > 87:
or

if 'Los Angeles' < 'San Diego'
because it knows how to compare integers and strings. But if what if you tried to compare two Student objects? Python will throw up its hands: how is it supposed to know what makes one student "less than" another? In Lab 12, we'll define another special method that tells Python how the < operator works if it's comparing two objects of our new class. There are similar methods for other operators, but we won't cover those in this lab.

Lab Overview

In this part of the lab, you will implement a City class. Objects of this class have instance variables for the city's name (a string) and population (an integer). You will implement the following methods:

Instructions

  1. Enter the following code as lab12a.py:
    """
    Program: Lab 12
    Author: Your name
    Define and test a basic City class.
    """
    import sys
    
    
    class City:
        pass
    
    
    def main():
        tokyo = City('Tokyo', 13189000)
        mexico_city = City('Mexico City', 8857188)
    
    
    main()
  2. Your first task will be to define an __init__ method for the City class that saves the city name and population into the new City object. First, answer Question 1 in your writeup.
  3. Replace the pass in the implementation of City with the definition of an __init__ method that saves the city name and population into the newly created object.
  4. Copy your code into the the online Python 3 tutor and visualize it. Hit Last and then hit Back once. You should see something like this at the bottom right:
    Visualization of the two city objects and their instance variables
  5. Returning to PyCharm, add the following lines of code to your program at the end of the definition of main:
    print(tokyo)
    print(mexico_city)
    Run your program. You should see an output that looks something like
    <__main__.City object at 0xe5ec10>
    <__main__.City object at 0xe5ecd0>
    This is because we haven't told Python how to represent a city as a string.
  6. When these print statements are executed, they will automatically call the __str__ method of our City class -- if one is defined -- to get a string representation of the City object. Our next goal is to define a __str__ method. Answer Question 2 in your writeup.
  7. Inside class City, add a definition of the __str__ method. Its goal should be to return a string with the city's name and population formatted like this:
    Tokyo (pop. 13189000)
    or
    Mexico City (pop. 8857188)
    Rerun your program. You should see the two lines of output above.
  8. Add the following lines of code to the end of main():
    # Print whichever city is larger
    print('The larger city is:')
    if mexico_city < tokyo:
        print(tokyo)
    else:
        print(mexico_city)
    Run your program. It should fail because we haven't told Python what it means for one City object to be smaller than another.
  9. Inside class City, add the following method definition:
    def __lt__(self, other):
        # Return True if the population of self is less than
        # the population of other and return False otherwise
        pass
  10. Replace the pass with code that compares the populations of self and other. This code should return True if self has a lower population than other and False otherwise.
  11. Run your code one more time. You should see the following output:
    Tokyo (pop. 13189000)
    Mexico City (pop. 8857188)
    The larger city is:
    Tokyo (pop. 13189000)
  12. Continue to Part B.