From ab648ac6ab23784a658ddbecfe5721a15ea780fe Mon Sep 17 00:00:00 2001 From: Don Cross Date: Thu, 25 Jul 2019 23:00:53 -0400 Subject: [PATCH] Finished first pass of Python documentation. Also make pydown.py generate an error, not just a warning, for missing documentation, now that all the documentation is filled out. --- generate/template/astronomy.py | 86 ++++++++++++++++++++++++++++++++++ pydown/pydown.py | 12 +++-- source/python/README.md | 85 +++++++++++++++++++++++++++++++++ source/python/astronomy.py | 86 ++++++++++++++++++++++++++++++++++ 4 files changed, 265 insertions(+), 4 deletions(-) diff --git a/generate/template/astronomy.py b/generate/template/astronomy.py index 2c81a9a7..49d20277 100644 --- a/generate/template/astronomy.py +++ b/generate/template/astronomy.py @@ -398,6 +398,15 @@ class Time: return '{:04d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}.{:03d}Z'.format(n.year, n.month, n.day, n.hour, n.minute, n.second, math.floor(n.microsecond / 1000)) def Utc(self): + """Returns the UTC date and time as a `datetime` object. + + Uses the standard [`datetime`](https://docs.python.org/3/library/datetime.html) class + to represent the date and time in this Time object. + + Returns + ------- + `datetime` + """ return _EPOCH + datetime.timedelta(days=self.ut) def _etilt(self): @@ -2680,6 +2689,41 @@ def _FindSeasonChange(targetLon, year, month, day): return time def Seasons(year): + """Finds both equinoxes and both solstices for a given calendar year. + + The changes of seasons are defined by solstices and equinoxes. + Given a calendar year number, this function calculates the + March and September equinoxes and the June and December solstices. + + The equinoxes are the moments twice each year when the plane of the + Earth's equator passes through the center of the Sun. In other words, + the Sun's declination is zero at both equinoxes. + The March equinox defines the beginning of spring in the northern hemisphere + and the beginning of autumn in the southern hemisphere. + The September equinox defines the beginning of autumn in the northern hemisphere + and the beginning of spring in the southern hemisphere. + + The solstices are the moments twice each year when one of the Earth's poles + is most tilted toward the Sun. More precisely, the Sun's declination reaches + its minimum value at the December solstice, which defines the beginning of + winter in the northern hemisphere and the beginning of summer in the southern + hemisphere. The Sun's declination reaches its maximum value at the June solstice, + which defines the beginning of summer in the northern hemisphere and the beginning + of winter in the southern hemisphere. + + Parameters + ---------- + year : int + The calendar year number for which to calculate equinoxes and solstices. + The value may be any integer, but only the years 1800 through 2100 have + been validated for accuracy: unit testing against data from the + United States Naval Observatory confirms that all equinoxes and solstices + for that range of years are within 2 minutes of the correct time. + + Returns + ------- + #SeasonInfo + """ mar_equinox = _FindSeasonChange(0, year, 3, 19) jun_solstice = _FindSeasonChange(90, year, 6, 19) sep_equinox = _FindSeasonChange(180, year, 9, 21) @@ -2749,6 +2793,31 @@ class Apsis: self.dist_km = dist_au * _KM_PER_AU def SearchLunarApsis(startTime): + """Finds the time of the first lunar apogee or perigee after the given time. + + Given a date and time to start the search in `startTime`, this function finds + the next date and time that the center of the Moon reaches the closest or + farthest point in its orbit with respect to the center of the Earth, whichever + comes first after `startTime`. The return value (of type #Apsis) also + contains an indicator of whether the event is apogee or perigee. + + The closest point is called *perigee* and the farthest point is called *apogee*. + The word *apsis* refers to either event. + + To iterate through consecutive alternating perigee and apogee events, + call #SearchLunarApsis once, then use the return value to call #NextLunarApsis. + After that, keep feeding the previous return value from `NextLunarApsis` into + another call of `NextLunarApsis` as many times as desired. + + Parameters + ---------- + startTime : Time + The date and time at which to start searching for the next perigee or apogee. + + Returns + ------- + #Apsis + """ increment = 5.0 # number of days to skip on each iteration t1 = startTime m1 = _distance_slope(+1, t1) @@ -2791,6 +2860,23 @@ def SearchLunarApsis(startTime): def NextLunarApsis(apsis): + """Finds the next lunar perigee or apogee in a series. + + This function requires an #Apsis value obtained from a call to + #SearchLunarApsis or `NextLunarApsis`. + Given an apogee event, this function finds the next perigee event, + and vice versa. + + See #SearchLunarApsis for more details. + + Parameters + ---------- + apsis : Apsis + + Returns + ------- + #Apsis + """ skip = 11.0 # number of days to skip to start looking for next apsis event time = apsis.time.AddDays(skip) next = SearchLunarApsis(time) diff --git a/pydown/pydown.py b/pydown/pydown.py index d57846f5..02191324 100755 --- a/pydown/pydown.py +++ b/pydown/pydown.py @@ -12,6 +12,10 @@ USAGE: pydown.py infile.py outfile.md """) return 1 +def Fail(message): + print('FATAL(pydown):', message) + sys.exit(1) + def LoadModule(inPythonFileName): dir = os.path.dirname(inPythonFileName) if not dir: @@ -190,7 +194,7 @@ def MdFunction(func, parent=None): md += info.Markdown() md += '\n' else: - print('pydown: WARNING - no documentation for function', func.__name__) + Fail('No documentation for function ' + func.__name__) return md def MdClass(c): @@ -214,7 +218,7 @@ def MdClass(c): md += '#### member functions\n\n' md += MdFunction(obj, parent=c) else: - print('pydown: WARNING - no documentation for class', c.__name__) + Fail('No documentation for class ' + c.__name__) return md def MdEnumType(c): @@ -231,7 +235,7 @@ def MdEnumType(c): md += info.Markdown() md += '\n' else: - print('pydown: WARNING - no documentation for enumeration class', c.__name__) + Fail('No documentation for enumeration class ' + c.__name__) return md def MdErrType(c): @@ -247,7 +251,7 @@ def MdErrType(c): md += info.Markdown() md += '\n' else: - print('pydown: WARNING - no documentation for exception class', c.__name__) + Fail('No documentation for exception class ' + c.__name__) return md def Markdown(module): diff --git a/source/python/README.md b/source/python/README.md index 870f6bae..b687e8c1 100644 --- a/source/python/README.md +++ b/source/python/README.md @@ -251,6 +251,16 @@ calculate current observational conditions. ### Returns: #Time + +### Time.Utc(self) + +**Returns the UTC date and time as a `datetime` object.** + +Uses the standard [`datetime`](https://docs.python.org/3/library/datetime.html) class +to represent the date and time in this Time object. + +### Returns: `datetime` + --- @@ -766,6 +776,25 @@ Certain values of the angle have conventional definitions: --- + +### NextLunarApsis(apsis) + +**Finds the next lunar perigee or apogee in a series.** + +This function requires an #Apsis value obtained from a call to +#SearchLunarApsis or `NextLunarApsis`. +Given an apogee event, this function finds the next perigee event, +and vice versa. +See #SearchLunarApsis for more details. + +| Type | Parameter | Description | +| --- | --- | --- | +| [`Apsis`](#Apsis) | `apsis` | | + +### Returns: #Apsis + +--- + ### NextMoonQuarter(mq) @@ -883,6 +912,31 @@ of the body at that time, as seen by the given observer. --- + +### SearchLunarApsis(startTime) + +**Finds the time of the first lunar apogee or perigee after the given time.** + +Given a date and time to start the search in `startTime`, this function finds +the next date and time that the center of the Moon reaches the closest or +farthest point in its orbit with respect to the center of the Earth, whichever +comes first after `startTime`. The return value (of type #Apsis) also +contains an indicator of whether the event is apogee or perigee. +The closest point is called *perigee* and the farthest point is called *apogee*. +The word *apsis* refers to either event. +To iterate through consecutive alternating perigee and apogee events, +call #SearchLunarApsis once, then use the return value to call #NextLunarApsis. +After that, keep feeding the previous return value from `NextLunarApsis` into +another call of `NextLunarApsis` as many times as desired. + +| Type | Parameter | Description | +| --- | --- | --- | +| [`Time`](#Time) | `startTime` | The date and time at which to start searching for the next perigee or apogee. | + +### Returns: #Apsis + +--- + ### SearchMaxElongation(body, startTime) @@ -1085,6 +1139,37 @@ limitDays : float --- + +### Seasons(year) + +**Finds both equinoxes and both solstices for a given calendar year.** + +The changes of seasons are defined by solstices and equinoxes. +Given a calendar year number, this function calculates the +March and September equinoxes and the June and December solstices. +The equinoxes are the moments twice each year when the plane of the +Earth's equator passes through the center of the Sun. In other words, +the Sun's declination is zero at both equinoxes. +The March equinox defines the beginning of spring in the northern hemisphere +and the beginning of autumn in the southern hemisphere. +The September equinox defines the beginning of autumn in the northern hemisphere +and the beginning of spring in the southern hemisphere. +The solstices are the moments twice each year when one of the Earth's poles +is most tilted toward the Sun. More precisely, the Sun's declination reaches +its minimum value at the December solstice, which defines the beginning of +winter in the northern hemisphere and the beginning of summer in the southern +hemisphere. The Sun's declination reaches its maximum value at the June solstice, +which defines the beginning of summer in the northern hemisphere and the beginning +of winter in the southern hemisphere. + +| Type | Parameter | Description | +| --- | --- | --- | +| `int` | `year` | The calendar year number for which to calculate equinoxes and solstices. The value may be any integer, but only the years 1800 through 2100 have been validated for accuracy: unit testing against data from the United States Naval Observatory confirms that all equinoxes and solstices for that range of years are within 2 minutes of the correct time. | + +### Returns: #SeasonInfo + +--- + ### SunPosition(time) diff --git a/source/python/astronomy.py b/source/python/astronomy.py index 16c18069..7e38965e 100644 --- a/source/python/astronomy.py +++ b/source/python/astronomy.py @@ -489,6 +489,15 @@ class Time: return '{:04d}-{:02d}-{:02d}T{:02d}:{:02d}:{:02d}.{:03d}Z'.format(n.year, n.month, n.day, n.hour, n.minute, n.second, math.floor(n.microsecond / 1000)) def Utc(self): + """Returns the UTC date and time as a `datetime` object. + + Uses the standard [`datetime`](https://docs.python.org/3/library/datetime.html) class + to represent the date and time in this Time object. + + Returns + ------- + `datetime` + """ return _EPOCH + datetime.timedelta(days=self.ut) def _etilt(self): @@ -4741,6 +4750,41 @@ def _FindSeasonChange(targetLon, year, month, day): return time def Seasons(year): + """Finds both equinoxes and both solstices for a given calendar year. + + The changes of seasons are defined by solstices and equinoxes. + Given a calendar year number, this function calculates the + March and September equinoxes and the June and December solstices. + + The equinoxes are the moments twice each year when the plane of the + Earth's equator passes through the center of the Sun. In other words, + the Sun's declination is zero at both equinoxes. + The March equinox defines the beginning of spring in the northern hemisphere + and the beginning of autumn in the southern hemisphere. + The September equinox defines the beginning of autumn in the northern hemisphere + and the beginning of spring in the southern hemisphere. + + The solstices are the moments twice each year when one of the Earth's poles + is most tilted toward the Sun. More precisely, the Sun's declination reaches + its minimum value at the December solstice, which defines the beginning of + winter in the northern hemisphere and the beginning of summer in the southern + hemisphere. The Sun's declination reaches its maximum value at the June solstice, + which defines the beginning of summer in the northern hemisphere and the beginning + of winter in the southern hemisphere. + + Parameters + ---------- + year : int + The calendar year number for which to calculate equinoxes and solstices. + The value may be any integer, but only the years 1800 through 2100 have + been validated for accuracy: unit testing against data from the + United States Naval Observatory confirms that all equinoxes and solstices + for that range of years are within 2 minutes of the correct time. + + Returns + ------- + #SeasonInfo + """ mar_equinox = _FindSeasonChange(0, year, 3, 19) jun_solstice = _FindSeasonChange(90, year, 6, 19) sep_equinox = _FindSeasonChange(180, year, 9, 21) @@ -4810,6 +4854,31 @@ class Apsis: self.dist_km = dist_au * _KM_PER_AU def SearchLunarApsis(startTime): + """Finds the time of the first lunar apogee or perigee after the given time. + + Given a date and time to start the search in `startTime`, this function finds + the next date and time that the center of the Moon reaches the closest or + farthest point in its orbit with respect to the center of the Earth, whichever + comes first after `startTime`. The return value (of type #Apsis) also + contains an indicator of whether the event is apogee or perigee. + + The closest point is called *perigee* and the farthest point is called *apogee*. + The word *apsis* refers to either event. + + To iterate through consecutive alternating perigee and apogee events, + call #SearchLunarApsis once, then use the return value to call #NextLunarApsis. + After that, keep feeding the previous return value from `NextLunarApsis` into + another call of `NextLunarApsis` as many times as desired. + + Parameters + ---------- + startTime : Time + The date and time at which to start searching for the next perigee or apogee. + + Returns + ------- + #Apsis + """ increment = 5.0 # number of days to skip on each iteration t1 = startTime m1 = _distance_slope(+1, t1) @@ -4852,6 +4921,23 @@ def SearchLunarApsis(startTime): def NextLunarApsis(apsis): + """Finds the next lunar perigee or apogee in a series. + + This function requires an #Apsis value obtained from a call to + #SearchLunarApsis or `NextLunarApsis`. + Given an apogee event, this function finds the next perigee event, + and vice versa. + + See #SearchLunarApsis for more details. + + Parameters + ---------- + apsis : Apsis + + Returns + ------- + #Apsis + """ skip = 11.0 # number of days to skip to start looking for next apsis event time = apsis.time.AddDays(skip) next = SearchLunarApsis(time)