瀏覽代碼

Merge pull request #61 from Deuchnord/moon-conjunction

Add support for Moon conjunctions
tags/v0.7.0
Jérôme Deuchnord 5 年之前
committed by GitHub
父節點
當前提交
d7290446f6
沒有發現已知的金鑰在資料庫的簽署中 GPG 金鑰 ID: 4AEE18F83AFDEB23
共有 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__':


Loading…
取消
儲存