diff --git a/pyphoon.py b/pyphoon.py index 30ac0fb..97db6ca 100644 --- a/pyphoon.py +++ b/pyphoon.py @@ -34,22 +34,26 @@ from moons import backgrounds # If you change the aspect ratio, the canned backgrounds won't work. ASPECTRATIO = 0.5 -def putmoon(pctphase, lines, atfiller, hemisphere): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,too-many-arguments - """Print the moon""" +def putmoon(fracphase, lines, hemisphere, atfiller='@'): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,too-many-arguments + """Print the moon + + Arguments: + fracphase: A float 0 <= n < 1 representing the current point in the cycle + lines: An integer representing the number of lines in the output + hemisphere: A string 'north' or 'south' representing the observer's hemisphere + atfiller: What character to use in place of '@' + """ output = "" - def putchar(char): - nonlocal output - output += char # Find the length of the atfiller string atflrlen = len(atfiller) # Fix waxes and wanes direction for south hemisphere if hemisphere == 'south': - pctphase = 1 - pctphase + fracphase = 1 - pctphase - angphase = pctphase * 2.0 * math.pi + angphase = fracphase * 2.0 * math.pi mcap = -math.cos(angphase) # Figure out how big the moon is @@ -75,7 +79,7 @@ def putmoon(pctphase, lines, atfiller, hemisphere): # pylint: disable=too-many- # Now output the slice col = 0 while col < colleft: - putchar(' ') + output += ' ' col += 1 while col <= colright: if hemisphere == 'north': @@ -97,13 +101,13 @@ def putmoon(pctphase, lines, atfiller, hemisphere): # pylint: disable=too-many- "!!!!!!")) if char != '@': - putchar(char) + output += char else: - putchar(atfiller[atflridx]) + output += atfiller[atflridx] atflridx = (atflridx + 1) % atflrlen col += 1 - putchar('\n') + output += '\n' lin += 1 return output diff --git a/xaphoon.py b/xaphoon.py index 8b29987..ea8d94a 100755 --- a/xaphoon.py +++ b/xaphoon.py @@ -26,6 +26,28 @@ def to_timestr(t, date=False, local=True): return t.strftime('%Y-%m-%d %H:%M:%S') return t.strftime('%H:%M:%S') +def fmt(cols, t, az, el, phase, illum, moonrise, transit, moonset, hemi): + """Formats data into string to print""" + _date = t.utc_datetime().astimezone().strftime('%Y-%m-%d %H:%M:%S') # 18 chars + _azel = f"Az:{az.degrees:.0f}° El:{el.degrees:.0f}°".ljust(16) # 16 chars + _phil = f"Ph: {phase.degrees:.0f}° Ill:{illum*100:.0f}%".rjust(16) # 16 chars + _r = f"R:{to_timestr(moonrise)}" # 10 chars + _t = f"T:{to_timestr(transit)}" # 10 chars + _s = f"S:{to_timestr(moonset)}" # 10 chars + # TODO: 21 needs to scale + _moon = putmoon(phase.degrees/360, 21, hemi) # ! scalable width + + # 2 groups of spacing, filling cols minus total RTS width + _rts_spacing = ' '*int((cols-30)/2) + + ret = f"{_date.center(cols)}\n" + ret += f"{_azel}{' '*(cols-32)}{_phil}\n" + # split moon on newlines, right-pad to center moon in original width, center to center + # in new width, then rejoin with newlines and tack an extra newline on the end + ret += '\n'.join([line.ljust(44).center(cols) for line in _moon.split('\n')]) + '\n' + ret += f"{_r}{_rts_spacing}{_t}{_rts_spacing}{_s}" + return ret + def main(): """Main function @@ -41,6 +63,10 @@ def main(): parser.add_argument("elevation", help="Observer elevation in meters", type=int) + parser.add_argument("-l", "--lines", + help="Number of lines for the output to use (default 25)", + default=25, + type=int) parser.add_argument("-c", "--columns", help="Number of columns for the output to use (default 70)", default=70, @@ -53,15 +79,12 @@ def main(): t = ts.from_datetime(datetime.fromtimestamp(args.time, timezone.utc)) # current time - print(f"Current time: {to_timestr(t)}") - obs_geo = skyfield.api.wgs84.latlon(args.lat, args.lon, elevation_m=args.elevation) # geographic position vector obs = earth + obs_geo # barycentric position vector moon_apparent = obs.at(t).observe(moon).apparent() el, az, _ = moon_apparent.altaz('standard') - print(f"Az: {az.degrees:.0f}° El: {el.degrees:.0f}°") # Find relevant moonrise. el is based on apparent location, so accounts # for atmospheric refraction. y shouldn't be needed unless user is near @@ -76,17 +99,16 @@ def main(): # Find first moonset in the next 24 hours after moonrise. moonset = almanac.find_settings(obs, moon, moonrise, moonrise+1)[0][0] - print(f"Rise: {to_timestr(moonrise)} Set: {to_timestr(moonset)}") transit = almanac.find_transits(obs, moon, moonrise, moonrise+1)[0] - print(f"Transit: {to_timestr(transit)}") phase = almanac.moon_phase(eph, t) - print(f"Phase: {phase.degrees:.0f}°") - illum = moon_apparent.fraction_illuminated(sun) - print(f"Illumination: {illum*100:.0f}%") + hemi = 'north' if args.lat > 0 else 'south' - print(putmoon(phase.degrees/360, 21, '@', 'north' if args.lat > 0 else 'south')) + #print(phase.degrees/360*100) + #print(putmoon(phase.degrees/360, 21, 'north' if args.lat > 0 else 'south')) + print(fmt(args.columns, t, az, el, phase, illum, moonrise, transit, moonset, hemi)) + #print(putmoon(phase.degrees/360, 21, '@', hemi)) main()