An object of this class represents the
day-notes element, containing all the records for
one day and within one state. Here is the interface:
# - - - - - c l a s s D a y N o t e s - - - - - class DayNotes: """Represents one day's notes within one state. Exports: DayNotes(noteSet, regionCode, date, daySummary, dayLoc): [ (noteSet is the containing BirdNoteSet object) and (regionCode is the enclosing region as a case-insensitive US postal state code or the foreign equivalent, e.g., "nm") and (date is the fieldwork date as "YYYY-MM-DD") and (daySummary is a summary of the field day as a DaySummary) and (dayLoc is the default location as a Loc instance) -> noteSet +:= a new DayNotes object representing those values return that new DayNotes object ] .noteSet: [ as passed to constructor, read-only ] .txny: [ self.noteSet.txny passthrough, read-only ] .regionCode: [ as passed to constructor, read-only ] .date: [ as passed to constructor, read-only ] .daySummary: [ as passed to constructor, read-only ] .dayLoc: [ as passed to constructor, read-only ] .title(): [ return date+region+dayLoc.name ] .defaultLoc(): [ return the day's default location as a Loc instance ] .addLoc(loc): [ loc is a location as a Loc instance -> if self has no location with the same code -> self := self with that location added else -> raise KeyError ] .lookupLoc(locCode): [ locCode is a location code as a string -> if locCode is defined in self (case-sensitive) -> return that location as a Loc instance else -> raise KeyError ] .addForm(birdForm): [ birdForm is a set of one or more sightings of the same kind of bird as a BirdForm object -> self := self with birdForm added ] .lookupForm(birdId): [ birdId is an instance of abbr.BirdId -> if self has a BirdForm for birdId -> return that BirdForm else -> raise KeyError ] .genForms(): [ generate the bird records in self in phylogenetic order, with records assigned to the same taxon sorted by English name ] .genFormsSeq(): [ generate the bird records in self in the order they were added ] .writeNode(parent, byPhylo=False): [ parent is an et.Element instance -> if byPhylo -> parent := parent with a new et.Element node added representing self with forms in phylogenetic order else -> parent := parent with a new et.Element node added representing self with forms in the order they were added In any case -> return that new et.Element ] DayNotes.readNode(noteSet, txny, dayNode): [ (noteSet is a BirdNoteSet instance) and (txny is a Txny object) and (dayNode is a DAY_NOTES_N et.Element) -> if all the taxa under dayNode are defined in txny -> return a new DayNotes object made from dayNode else -> raise IOError ]
Here is the internal state of this class. We want to be
able to access the contained
objects in either of two orders:
In the order the records were added. When transcribing notes written in the field, we want to preserve the order of those records so that we can rearrange the records into that order for proofreading.
In taxonomic order. The taxonomic key provided in the
Txny object will sort records into rough
taxonomic order. However, in some cases there maybe
different bird codes that are placed under the same
taxonomic key. For example, the hybrids
Mallard×Pintail and Mallard×Northern
Shoveler will both be placed in genus Anas, but we want to alphabetize them
using their English names.
This is a good place to demonstrate Python's ability to use a tuple as a dictionary key. We'll use a two-element tuple, where the first element is the taxonomic key, and the second element is the complete English name, e.g., “Shoveler, Northern”.
State/Invariants: ._numberAdded: [ the number of BirdForm objects that have ever been added to self ] ._seqMap: [ a dictionary whose keys are integers defining the order in which BirdForm objects were added, and each corresponding value is that BirdForm object ] ._txMap: [ a dictionary whose keys are tuples (txKey, name) where txKey is the form's taxonomic key in self.noteSet.txny and name is the full English name, and each corresponding value is the BirdForm object for that name ] """