Each instance of this class represents one simple or compound bird identity.
# - - - - - c l a s s B i r d I d - - - - -
class BirdId:
"""Represents a single bird code, or two codes with a relationship.
Exports:
BirdId ( txny, abbr, rel=None, abbr2=None, q=None ):
[ (txny is a Txny instance) and
(q is None for okay and '?' for questionable ID) ->
if rel == REL_SIMPLE ->
if abbr is defined in txny ->
return a BirdId representing that simple form and
flag q
else -> raise KeyError
else ->
if abbr and abbr2 are both defined in txny ->
return a BirdId representing the compound form
(abbr, rel, abbr2) and flag q
else -> raise KeyError ]
.txny: [ as passed to constructor, read-only ]
.abbr: [ as passed to constructor, read-only ]
.rel: [ STANDARD_REL[rel], read-only ]
.abbr2: [ as passed to constructor, read-only ]
.q: [ as passed to constructor, read-only ]
.fullAbbr:
[ if self.rel == REL_SIMPLE -> self.abbr.rstrip()
else ->
self.abbr.rstrip() + self.rel + self.abbr2.rstrip() ]
.taxon:
[ a Taxon representing the smallest taxon in self.txny
that contains abbr and, if present, abbr2 ]
.txKey: [ taxon.txKey pass-through ]
.engComma():
[ like str() but uses inverted order, for example,
"Wigeon, American x Wigeon, European" ]
.standardize():
[ self.abbr, uppercased and blank-padded to size ABBR_L ]
.__str__():
[ return self's English name ]
BirdId.scan ( txny, scan ): # Static method
[ (txny is a Txny instance) and (scan is a Scan instance) ->
if the current line of scan starts with a simple or
compound bird code ->
scan := scan advanced past that code
return a new BirdId instance representing that code
else ->
scan := scan advanced past valid-looking parts, if any
scan +:= error message
raise ValueError ]
BirdId.scanFlat ( txny, scan ): # Static method
[ (txny is a Txny instance) and (scan is a Scan instance) ->
if the current line of scan starts with a
compound bird code in flat-field format ->
scan := scan advanced past that code
return a new BirdId instance representing that code
else ->
scan := scan advanced past valid-looking parts, if any
scan +:= error message
raise ValueError ]
BirdId.scanAbbr ( txny, scan ): # Static method
[ (txny is a Txny instance) and (scan is a Scan instance) ->
if scan starts with a bird code valid in txny ->
scan := scan advanced past that code
return that code
else ->
scan := scan advanced valid-looking parts, if any
scan +:= error message
raise ValueError ]
BirdId.scanAbbrFlat ( txny, scan ): # Static method
[ (txny is a Txny instance) and (scan is a Scan instance) ->
if scan starts with a bird code valid in txny,
right blank-padded to length ABBR_L ->
scan := scan advanced past that code
return the code without its blank padding
else ->
scan := scan advanced past valid-looking stuff if any
scan +:= error message
raise ValueError ]
BirdId.parse(txny, s):
[ (txny is a Txny instance) and (s is a string) ->
if s consists of a code valid in txny, optionally
followed by (a relationship code and a second code
valid in txny), optionally followed by '?' ->
return a BirdId representing s
else -> raise ValueError ]
State/Invariants:
self.abbr < self.abbr2
"""