Преглед на файлове

feat: add support for Moon conjunctions

tags/v0.7.0
Jérôme Deuchnord преди 4 години
родител
ревизия
c063f6e0f5
No known key found for this signature in database GPG ключ ID: BC6F3C345B7D33B0
променени са 5 файла, в които са добавени 62 реда и са изтрити 82 реда
  1. +1
    -0
      Pipfile
  2. +8
    -1
      Pipfile.lock
  3. +3
    -3
      kosmorrolib/events.py
  4. +1
    -1
      kosmorrolib/locales/messages.pot
  5. +49
    -77
      test/events.py

+ 1
- 0
Pipfile Целия файл

@@ -8,6 +8,7 @@ pylintfileheader = "*"
pylint = "*" pylint = "*"
codecov = "*" codecov = "*"
babel = "*" babel = "*"
unittest-data-provider = "*"


[packages] [packages]
skyfield = ">=1.13.0,<2.0.0" skyfield = ">=1.13.0,<2.0.0"


+ 8
- 1
Pipfile.lock Целия файл

@@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "789ae3ae412a3b57df763f776aa8ce0497d680de59fa09ad22a9b91a4e3d6b4e"
"sha256": "67748949d467fbdca22ccc963430b21be215566f8a49b56ac734b44023ce5ff2"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@@ -315,6 +315,13 @@
], ],
"version": "==1.14.0" "version": "==1.14.0"
}, },
"unittest-data-provider": {
"hashes": [
"sha256:86bc7fb6608c2570aeedadea346fe3034afc940807dd7519e95e5dbc899ac2be"
],
"index": "pypi",
"version": "==1.0.1"
},
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",


+ 3
- 3
kosmorrolib/events.py Целия файл

@@ -22,7 +22,7 @@ from skyfield.timelib import Time
from skyfield.searchlib import find_discrete, find_maxima from skyfield.searchlib import find_discrete, find_maxima
from numpy import pi from numpy import pi


from .data import Event, Planet, ASTERS
from .data import Event, Star, Planet, ASTERS
from .core import get_timescale, get_skf_objects, flatten_list from .core import get_timescale, get_skf_objects, flatten_list




@@ -45,11 +45,11 @@ def _search_conjunction(start_time: Time, end_time: Time) -> [Event]:


for aster1 in ASTERS: for aster1 in ASTERS:
# Ignore the Sun # Ignore the Sun
if not isinstance(aster1, Planet):
if isinstance(aster1, Star):
continue continue


for aster2 in ASTERS: for aster2 in ASTERS:
if not isinstance(aster2, Planet) or aster2 == aster1 or aster2 in computed:
if isinstance(aster2, Star) or aster2 == aster1 or aster2 in computed:
continue continue


times, is_conjs = find_discrete(start_time, end_time, is_in_conjunction) times, is_conjs = find_discrete(start_time, end_time, is_in_conjunction)


+ 1
- 1
kosmorrolib/locales/messages.pot Целия файл

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: kosmorro 0.6.1\n" "Project-Id-Version: kosmorro 0.6.1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2020-03-08 10:46+0100\n"
"POT-Creation-Date: 2020-03-09 21:52+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"


+ 49
- 77
test/events.py Целия файл

@@ -1,91 +1,63 @@
import unittest import unittest


from datetime import date
from datetime import date, datetime


from kosmorrolib import events from kosmorrolib import events
from kosmorrolib.data import Event
from kosmorrolib.data import Event, ASTERS
from kosmorrolib.core import get_timescale from kosmorrolib.core import get_timescale
from unittest_data_provider import data_provider




class MyTestCase(unittest.TestCase):
class EventTestCase(unittest.TestCase):
def setUp(self) -> None:
self.maxDiff = None

def test_event_only_accepts_valid_values(self): def test_event_only_accepts_valid_values(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
Event('SUPERNOVA', None, get_timescale().now()) Event('SUPERNOVA', None, get_timescale().now())


def test_find_oppositions(self):
# Test case: Mars opposition
# Source of the information: https://promenade.imcce.fr/en/pages6/887.html#mar
o1 = (events.search_events(date(2020, 10, 13)), '^2020-10-13T23:25')
o2 = (events.search_events(date(2022, 12, 8)), '^2022-12-08T05:41')
o3 = (events.search_events(date(2025, 1, 16)), '^2025-01-16T02:38')
o4 = (events.search_events(date(2027, 2, 19)), '^2027-02-19T15:50')

for (o, expected_date) in [o1, o2, o3, o4]:
self.assertEqual(1, len(o), 'Expected 1 event for %s, got %d' % (expected_date, len(o)))
self.assertEqual('OPPOSITION', o[0].event_type)
self.assertEqual('MARS', o[0].objects[0].skyfield_name)
self.assertRegex(o[0].start_time.isoformat(), expected_date)
self.assertIsNone(o[0].end_time)
self.assertEqual('Mars is in opposition', o[0].get_description())

def test_find_conjunctions(self):
MERCURY = 'MERCURY'
JUPITER = 'JUPITER BARYCENTER'
SATURN = 'SATURN BARYCENTER'
PLUTO = 'PLUTO BARYCENTER'

c1 = (events.search_events(date(2020, 1, 2)), [([MERCURY, JUPITER], '^2020-01-02T16:41')])
c2 = (events.search_events(date(2020, 1, 12)), [([MERCURY, SATURN], '^2020-01-12T09:51'),
([MERCURY, PLUTO], '^2020-01-12T10:13'),
([SATURN, PLUTO], '^2020-01-12T16:57')])
c3 = (events.search_events(date(2020, 2, 7)), [])

for (c, expected_dates) in [c1, c2]:
self.assertEqual(len(expected_dates), len(c),
'Expected %d event(s) for %s, got %d' % (len(expected_dates), expected_dates, len(c)))

i = 0
for conjunction in c:
self.assertEqual('CONJUNCTION', conjunction.event_type)
objects, expected_date = expected_dates[i]

j = 0
self.assertRegex(conjunction.start_time.isoformat(), expected_date)
for object in objects:
self.assertEqual(object, conjunction.objects[j].skyfield_name)
j += 1

self.assertIsNone(conjunction.end_time)
self.assertRegex(conjunction.get_description(), ' are in conjunction$')

i += 1

def test_find_maximal_elongation(self):
e = events.search_events(date(2020, 2, 10))
self.assertEquals(1, len(e), 'Expected 1 events, got %d.' % len(e))
e = e[0]
self.assertEquals('MAXIMAL_ELONGATION', e.event_type)
self.assertEquals(1, len(e.objects))
self.assertEquals('MERCURY', e.objects[0].skyfield_name)
self.assertEqual('18.2°', e.details)
self.assertEquals((2020, 2, 10, 13, 46), (e.start_time.year, e.start_time.month, e.start_time.day,
e.start_time.hour, e.start_time.minute))

e = events.search_events(date(2020, 3, 24))
self.assertEquals(2, len(e), 'Expected 2 events, got %d.' % len(e))
self.assertEquals('MAXIMAL_ELONGATION', e[0].event_type)
self.assertEquals(1, len(e[0].objects))
self.assertEquals('MERCURY', e[0].objects[0].skyfield_name)
self.assertEqual('27.8°', e[0].details)
self.assertEquals((2020, 3, 24, 1, 56), (e[0].start_time.year, e[0].start_time.month, e[0].start_time.day,
e[0].start_time.hour, e[0].start_time.minute))

self.assertEquals('MAXIMAL_ELONGATION', e[1].event_type)
self.assertEquals(1, len(e[1].objects))
self.assertEquals('VENUS', e[1].objects[0].skyfield_name)
self.assertEqual('46.1°', e[1].details)
self.assertEquals((2020, 3, 24, 21, 58), (e[1].start_time.year, e[1].start_time.month, e[1].start_time.day,
e[1].start_time.hour, e[1].start_time.minute))
expected_events_provider = lambda: (
(date(2020, 2, 7), []),

(date(2020, 10, 13), [Event('OPPOSITION', [ASTERS[4]], datetime(2020, 10, 13, 23, 25))]),

(date(2022, 12, 8), [Event('CONJUNCTION', [ASTERS[1], ASTERS[4]], datetime(2022, 12, 8, 4, 18)),
Event('OPPOSITION', [ASTERS[4]], datetime(2022, 12, 8, 5, 41))]),

(date(2025, 1, 16), [Event('OPPOSITION', [ASTERS[4]], datetime(2025, 1, 16, 2, 38))]),

(date(2027, 2, 19), [Event('OPPOSITION', [ASTERS[4]], datetime(2027, 2, 19, 15, 50))]),

(date(2020, 1, 2), [Event('CONJUNCTION', [ASTERS[2], ASTERS[5]], datetime(2020, 1, 2, 16, 41))]),

(date(2020, 1, 12), [Event('CONJUNCTION', [ASTERS[2], ASTERS[6]], datetime(2020, 1, 12, 9, 51)),
Event('CONJUNCTION', [ASTERS[2], ASTERS[9]], datetime(2020, 1, 12, 10, 13)),
Event('CONJUNCTION', [ASTERS[6], ASTERS[9]], datetime(2020, 1, 12, 16, 57))]),

(date(2020, 2, 10), [Event('MAXIMAL_ELONGATION', [ASTERS[2]], datetime(2020, 2, 10, 13, 46), details='18.2°')]),

(date(2020, 3, 24), [Event('MAXIMAL_ELONGATION', [ASTERS[2]], datetime(2020, 3, 24, 1, 56), details='27.8°'),
Event('MAXIMAL_ELONGATION', [ASTERS[3]], datetime(2020, 3, 24, 21, 58), details='46.1°')]),
)

@data_provider(expected_events_provider)
def test_search_events(self, d: date, expected_events: [Event]):
actual_events = events.search_events(d)
self.assertEqual(len(expected_events), len(actual_events),
'Expected %d elements, got %d for date %s.' % (len(expected_events),
len(actual_events),
d.isoformat()))

for i, expected_event in enumerate(expected_events):
actual_event = actual_events[i]
# Remove unnecessary precision (seconds and microseconds)
actual_event.start_time = datetime(actual_event.start_time.year,
actual_event.start_time.month,
actual_event.start_time.day,
actual_event.start_time.hour,
actual_event.start_time.minute)

self.assertEqual(expected_event.__dict__, actual_event.__dict__)




if __name__ == '__main__': if __name__ == '__main__':


Зареждане…
Отказ
Запис