self pilot_total_hours pilot_total_hours self midair midair self narrative narrative the report id is validated when the incident is created and is available as the read-only report_id property all the other data attributes are read/write properties for examplehere is the date property' code@property def date(self)return self __date @date setter def date(selfdate)assert isinstance(datedatetime date)"invalid dateself __date date all the other properties follow the same patterndiffering only in the details of their assertionsso we won' reproduce them here since we have used assertionsthe program will fail if an attempt is made to create an incident with invalid dataor to set one of an existing incident' read/write properties to an invalid value we have chosen this uncompromising approach because we want to be sure that the data we save and load is always validand if it isn' we want the program to terminate and complain rather than silently continue the collection of incidents is held as an incidentcollection this class is dict subclassso we get lot of functionalitysuch as support for the item access operator ([]to getsetand delete incidentsby inheritance here is the class line and few of the class' methodsclass incidentcollection(dict)def values(self)for report_id in self keys()yield self[report_iddef items(self)for report_id in self keys()yield (report_idself[report_id]def __iter__(self)for report_id in sorted(super(keys())yield report_id keys __iter__ we have not needed to reimplement the initializer since dict __init__(is sufficient the keys are report ids and the values are incidents we have reimplemented the values()items()and keys(methods so that their iterators