Permalink
Browse files

pyphoon commited

1 parent e902eb3 commit 25d461e59982f6b76cd54c2e5ad94df5ec7641c5 @chubin committed Mar 5, 2016
Showing with 920 additions and 0 deletions.
  1. +46 −0 README.md
  2. +174 −0 bin/pyphoon
  3. +442 −0 lib/astro.py
  4. BIN lib/astro.pyc
  5. +258 −0 lib/moons.py
  6. BIN lib/moons.pyc
View
@@ -1,2 +1,48 @@
# pyphoon
Phase of the Moon (Python version)
+
+![Screenshots](http://igor.chub.in/pyphoon/screenshot.png)
+
+Based on the original version of Jef Poskanzer <jef@mail.acme.com>
+written in Pascal in 1979 (and later translated by himself into C, and now by me into Python).
+
+# Usage
+
+~~~~
+$ pyphoon --help
+usage: pyphoon [-h] [-n LINES] [date]
+
+Show Phase of the Moon
+
+positional arguments:
+ date Date for that the phase of the Moon must be shown.
+ Today by default
+
+optional arguments:
+ -h, --help show this help message and exit
+ -n LINES, --lines LINES
+ Number of lines to display (size of the moon)
+
+~~~~
+
+By default the number of lines is 30 and the date is today.
+
+The Moon is (at the moment) shown only for the northern hemisphere.
+
+Supported dateformats:
+
+* 2016-Mar-01
+* 2016-03-01
+* 03-01-2016
+* 03/01/2016
+* etc.
+
+Displayed information:
+
+* time after the previous state (-)
+* time to the next state (+)
+
+# Dependencies
+
+* dateutil
+
View
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+#
+# pyphoon - Phase of the Moon (Python version)
+# Igor Chubin <igor@chub.in>, 05.03.2016,
+#
+# Based on the original version of Jef Poskanzer <jef@mail.acme.com>
+# written in Pascal in 1979 (and later translated to C)
+#
+
+import sys
+import os
+import argparse
+import datetime
+import dateutil.parser
+import time
+
+from math import cos, sqrt
+
+sys.path.append(os.path.join(os.path.dirname( os.path.dirname(__file__) ), "lib"))
+from astro import unix_to_julian, phase, phasehunt2
+from moons import background6, background18, background19, background21, background22, background23, background24, background29, background32
+
+def fatal( message ):
+ print >>sys.stderr, message
+ sys.exit(1)
+
+#
+# Global defines and declarations.
+#
+SECSPERMINUTE = 60
+SECSPERHOUR = (60 * SECSPERMINUTE)
+SECSPERDAY = (24 * SECSPERHOUR)
+
+PI = 3.1415926535897932384626433
+
+DEFAULTNUMLINES = 23
+
+QUARTERLITLEN = 16
+QUARTERLITLENPLUSONE = 17
+
+# If you change the aspect ratio, the canned backgrounds won't work.
+ASPECTRATIO = 0.5
+
+def putseconds( secs ):
+ days = secs / SECSPERDAY
+ secs = secs - days * SECSPERDAY
+ hours = secs / SECSPERHOUR
+ secs = secs - hours * SECSPERHOUR
+ minutes = secs / SECSPERMINUTE
+ secs = secs - minutes * SECSPERMINUTE
+
+ return "%ld %2ld:%02ld:%02ld" % (days, hours, minutes, secs)
+
+def putmoon( t, numlines, atfiller ):
+ output = [""]
+ def putchar(c):
+ output[0] += c
+ def fputs(s):
+ output[0] += s
+
+ qlits = [
+ "New Moon + ",
+ "First Quarter +",
+ "Full Moon + ",
+ "Last Quarter + ",
+ ]
+ nqlits = [
+ "New Moon - ",
+ "First Quarter -",
+ "Full Moon - ",
+ "Last Quarter - ",
+ ]
+
+ # Find the length of the atfiller string
+ atflrlen = len( atfiller )
+
+ # Figure out the phase
+ jd = unix_to_julian( t )
+ pctphase, cphase, aom, cdist, cangdia, csund, csuang = phase( jd )
+ angphase = pctphase * 2.0 * PI
+ mcap = -cos( angphase )
+
+ # Figure out how big the moon is
+ yrad = numlines / 2.0
+ xrad = yrad / ASPECTRATIO
+ numcols = xrad * 2
+
+ # Figure out some other random stuff
+ midlin = numlines / 2
+ phases, which = phasehunt2( jd )
+
+ # Now output the moon, a slice at a time
+ atflridx = 0
+ lin = 0
+ while lin < numlines:
+ # Compute the edges of this slice
+ y = lin + 0.5 - yrad
+ xright = xrad * sqrt( 1.0 - ( y * y ) / ( yrad * yrad ) )
+ xleft = -xright
+ if ( angphase >= 0.0 and angphase < PI ):
+ xleft = mcap * xleft
+ else:
+ xright = mcap * xright
+
+ colleft = int(xrad + 0.5) + int(xleft + 0.5)
+ colright = int(xrad + 0.5) + int(xright + 0.5)
+
+ # Now output the slice
+ col = 0
+ while col < colleft:
+ putchar(' ')
+ col += 1
+ while col <= colright:
+ if 6 == numlines:
+ c = background6[lin][col]
+ elif 18 == numlines:
+ c = background18[lin][col]
+ elif 19 == numlines:
+ c = background19[lin][col]
+ elif 21 == numlines:
+ c = background21[lin][col]
+ elif 22 == numlines:
+ c = background22[lin][col]
+ elif 23 == numlines:
+ c = background23[lin][col]
+ elif 24 == numlines:
+ c = background24[lin][col]
+ elif 29 == numlines:
+ c = background29[lin][col]
+ elif 32 == numlines:
+ c = background32[lin][col]
+ else:
+ c = '@'
+ if c != '@':
+ putchar( c )
+ else:
+ putchar( atfiller[atflridx] )
+ atflridx = ( atflridx + 1 ) % atflrlen
+ col += 1
+
+ if numlines <= 27:
+ # Output the end-of-line information, if any
+ fputs( "\t " )
+ if lin == midlin - 2:
+ fputs( qlits[int(which[0] * 4.0 + 0.001)] )
+ elif lin == midlin - 1:
+ fputs( putseconds( int( ( jd - phases[0] ) * SECSPERDAY ) ) )
+ elif lin == midlin:
+ fputs( nqlits[int(which[1] * 4.0 + 0.001)] )
+ elif lin == midlin + 1:
+ fputs( putseconds( int( ( phases[1] - jd ) * SECSPERDAY ) ) )
+
+ putchar( '\n' )
+ lin += 1
+
+ return output[0]
+
+parser = argparse.ArgumentParser(description='Show Phase of the Moon')
+parser.add_argument('-n','--lines', help='Number of lines to display (size of the moon)', required=False, default=DEFAULTNUMLINES)
+parser.add_argument('date', help='Date for that the phase of the Moon must be shown. Today by default', nargs='?', default=datetime.date.today().strftime("%Y-%m-%d"))
+args = vars(parser.parse_args())
+
+try:
+ d = time.mktime( dateutil.parser.parse(args['date']).timetuple() )
+except Exception, e:
+ fatal("Can't parse date: %s" % args['date'])
+
+try:
+ n = int( args['lines'] )
+except Exception, e:
+ print e
+ fatal("Number of lines must be integer")
+print putmoon( d, n, '@' )
+
Oops, something went wrong.

0 comments on commit 25d461e

Please sign in to comment.