-
Notifications
You must be signed in to change notification settings - Fork 0
/
moon.py
executable file
·99 lines (74 loc) · 2.34 KB
/
moon.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/Users/thomas/projects/moon/.venv/bin/python
import json
from datetime import datetime
from math import radians
import ephem
try:
from sh import corelocationcli
except ImportError:
pass
def locate_obs():
geo_json_str = str(corelocationcli("-json"))
geo_json = json.loads(geo_json_str)
return geo_json
def setup_observer():
# TODO: Allow manual input of observer details
obs = ephem.Observer()
loc = locate_obs()
lat = float(loc["latitude"])
lng = float(loc["longitude"])
elv = float(loc["altitude"])
obs.lat = radians(lat)
obs.long = radians(lng)
obs.elevation = elv
return obs
try:
OBS = setup_observer()
except NameError:
OBS = ephem.Observer()
OBS.date = datetime.utcnow()
def lunar_illumination(obs=OBS):
moon = ephem.Moon()
moon.compute(obs)
illumination = round(moon.moon_phase * 100, 3)
return illumination
def next_phase_point(obs=OBS):
phase_date_map = dict(
new=ephem.next_new_moon(obs.date).datetime().date(),
first_quarter=ephem.next_first_quarter_moon(obs.date).datetime().date(),
full=ephem.next_full_moon(obs.date).datetime().date(),
last_quarter=ephem.next_last_quarter_moon(obs.date).datetime().date(),
)
phase_date_map = dict(sorted(phase_date_map.items(), key=lambda item: item[1]))
next_phase = list(phase_date_map.items())[0]
return next_phase
def intermediate_phase(phase_point):
phases_map = {
"first_quarter": "waxing_cresent",
"full": "waxing_gibbous",
"last_quarter": "waning_gibbous",
"new": "waning_crescent",
}
return phases_map[phase_point]
def phase(obs=OBS):
today = obs.date.datetime().date()
next = next_phase_point(obs)
if next[1] == today:
return next[0]
intermediate = intermediate_phase(next[0])
return intermediate
def display(obs=OBS):
phase_ = phase(obs)
phase_ = phase_.replace("_", " ").title()
lum = lunar_illumination(obs)
output = f"The Moon today is {phase_}, with {lum}% illuminated"
print(output)
next = next_phase_point(obs)
next_name = next[0].replace("_", " ").title()
if "Quarter" not in next_name:
next_name += " Moon"
next_date = next[1].isoformat()
output = f"{next_name} upcoming on {next_date}"
print(output)
if __name__ == "__main__":
display()