First commit
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""Rektaszension und Deklination einlesen und fuer die Anzeige formatieren.
|
||||
|
||||
Die Eingabe ist bewusst tolerant, damit man beim Testen nicht auf ein Format
|
||||
festgelegt ist: 12h34m56s | 12:34:56 | "12 34 56" | 12.5824 (Stunden dezimal)
|
||||
Bei der Deklination entsprechend mit Vorzeichen und Grad/Bogenminuten.
|
||||
|
||||
Ausgegeben wird die breiteste Schreibweise, die noch in die Zeile passt --
|
||||
die tatsaechliche Zeichenbreite der Anzeige kennen wir erst nach dem Livetest.
|
||||
"""
|
||||
|
||||
import config
|
||||
|
||||
_SEPARATORS = "hHmMsSdD°'\"::,"
|
||||
|
||||
|
||||
def _split(value):
|
||||
"""Zahlenfelder aus einer Koordinatenangabe holen, Trennzeichen egal."""
|
||||
out, cur = [], ""
|
||||
for ch in str(value).strip():
|
||||
if ch.isdigit() or ch == ".":
|
||||
cur += ch
|
||||
elif ch in "+-" and not cur and not out:
|
||||
cur += ch
|
||||
else:
|
||||
if cur:
|
||||
out.append(cur)
|
||||
cur = ""
|
||||
if cur:
|
||||
out.append(cur)
|
||||
if not out:
|
||||
raise ValueError("keine Zahlen in %r gefunden" % (value,))
|
||||
return out
|
||||
|
||||
|
||||
def _to_sexagesimal(value, unit_max, name):
|
||||
"""Eingabe in (Vorzeichen, Ganzteil, Minuten, Sekunden) zerlegen."""
|
||||
fields = _split(value)
|
||||
negative = fields[0].startswith("-")
|
||||
fields[0] = fields[0].lstrip("+-")
|
||||
|
||||
if len(fields) == 1: # dezimal, z.B. 12.5824
|
||||
total = float(fields[0]) * 3600.0
|
||||
else:
|
||||
parts = [float(f) for f in fields[:3]] + [0.0] * (3 - len(fields[:3]))
|
||||
total = parts[0] * 3600.0 + parts[1] * 60.0 + parts[2]
|
||||
|
||||
total = int(round(total))
|
||||
big, rest = divmod(total, 3600)
|
||||
minutes, seconds = divmod(rest, 60)
|
||||
|
||||
if big >= unit_max:
|
||||
raise ValueError("%s: %s ausserhalb des gueltigen Bereichs" % (name, value))
|
||||
return negative, big, minutes, seconds
|
||||
|
||||
|
||||
def parse_ra(value):
|
||||
"""Rektaszension -> (Stunden, Minuten, Sekunden)."""
|
||||
_, h, m, s = _to_sexagesimal(value, 24, "Rektaszension")
|
||||
return h, m, s
|
||||
|
||||
|
||||
def parse_dec(value):
|
||||
"""Deklination -> (Vorzeichen als '+'/'-', Grad, Bogenminuten, Bogensekunden)."""
|
||||
neg, d, m, s = _to_sexagesimal(value, 91, "Deklination")
|
||||
if d > 90 or (d == 90 and (m or s)):
|
||||
raise ValueError("Deklination %s liegt ausserhalb +/-90 Grad" % (value,))
|
||||
return ("-" if neg else "+"), d, m, s
|
||||
|
||||
|
||||
def _fit(candidates, width):
|
||||
"""Erste Schreibweise nehmen, die in die Zeile passt; sonst die kuerzeste."""
|
||||
for text in candidates:
|
||||
if len(text) <= width:
|
||||
return text
|
||||
return candidates[-1][:width]
|
||||
|
||||
|
||||
def format_ra(value, width=None):
|
||||
width = config.CHARS_PER_LINE if width is None else width
|
||||
h, m, s = parse_ra(value)
|
||||
return _fit([
|
||||
"%02dh%02dm%02ds" % (h, m, s),
|
||||
"%02d:%02d:%02d" % (h, m, s),
|
||||
"%02dh%02dm" % (h, m),
|
||||
], width)
|
||||
|
||||
|
||||
def format_dec(value, width=None):
|
||||
width = config.CHARS_PER_LINE if width is None else width
|
||||
sign, d, m, s = parse_dec(value)
|
||||
deg = config.DEGREE_MARKER
|
||||
return _fit([
|
||||
"%s%02d%s%02d'%02d\"" % (sign, d, deg, m, s), # 10: mit Bogensekundenzeichen
|
||||
"%s%02d%s%02d'%02d" % (sign, d, deg, m, s), # 9: Gradzeichen, ohne " am Ende
|
||||
"%s%02d:%02d:%02d" % (sign, d, m, s), # 9: Doppelpunkte, kein Gradzeichen
|
||||
"%s%02d%s%02d'" % (sign, d, deg, m), # 7: ohne Bogensekunden
|
||||
"%s%02d:%02d" % (sign, d, m), # 6
|
||||
], width)
|
||||
Reference in New Issue
Block a user