Skip to content

Commit

Permalink
pyphoon commited
Browse files Browse the repository at this point in the history
  • Loading branch information
chubin committed Mar 5, 2016
1 parent e902eb3 commit 25d461e
Show file tree
Hide file tree
Showing 6 changed files with 920 additions and 0 deletions.
46 changes: 46 additions & 0 deletions README.md
@@ -1,2 +1,48 @@
# pyphoon # pyphoon
Phase of the Moon (Python version) 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

174 changes: 174 additions & 0 deletions bin/pyphoon
@@ -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, '@' )

0 comments on commit 25d461e

Please sign in to comment.