## Moonrise, Moonset

### July 1, 2014

I translated the program to Python, but never got it to work. And I don’t have a BASIC interpreter that can run the Sky & Telescope program. I would appreciate it if anyone could tell me what I have done wrong, or if there is a problem in the original program:

# moonrise / moonset from __future__ import division from math import sqrt, pi, sin, cos, atan def signum(x): if x < 0: return -1 if x > 0: return 1 return 0 def moon(B5, L5, H, Mo, D, Y): # lat, long, hours west of GMT, month, day, year # positive latitude is north, negative latitude is south # positive longitude is east, negative longitude is west # lat and long given in degrees and decimals of a degree # moon(38.6272, -90.1978, 6, 6, 30, 2014) # st louis, today # GOSUB 170 constants Ma = [[0 for x in range(4)] for y in range(4)] # we dimension to 4 instead of 3 because BASIC # arrays are 1-based and Python arrays are 0-based P2 = 2 * pi R1 = pi / 180 K1 = 15 * R1 * 1.0027379 L5 = L5 / 360 Z0 = H / 24 # GOSUB 760 calendar to julian date G = 1 if Y < 1582: G = 0 D1 = int(D); F = D - D1 - 0.5 J = -1 * int(7 * (int((Mo+9)/12) + Y) / 4) J3 = 0 # not initialized in BASIC program if G <> 0: S = signum(Mo - 9) A = abs(Mo - 9) J3 = int(Y + S * int(A / 7)) J3 = -1 * int((int(J3 / 100) + 1) * 3/4) J = J + int(275 * Mo / 9) + D1 + G * J3 J = J + 1721027 + 2*G + 367*Y if F < 0: F = F + 1 J = J - 1 T = (J - 2451545) + F # GOSUB 245 lunar sidereal time at GMT time zone T0 = T / 36525 S = 24110.5 + 8640184.813 * T0 S = S + 86636.6 * Z0 + 86400 * L5 S = S / 86400 S = S - int(S) T0 = S * 360 * R1 T = T + Z0 # POSITION LOOP for I in range(1, 4): # GOSUB 495 fundamental arguments L = 0.606434 + 0.03660110129 * T M = 0.374897 + 0.03629164709 * T F = 0.259091 + 0.03674819520 * T D = 0.827362 + 0.03386319198 * T N = 0.347343 - 0.00014709391 * T G = 0.993126 + 0.00273777850 * T L = L - int(L); M = M - int(M) F = F - int(F); D = D - int(D) N = N - int(N); G = G - int(G) L = L * P2; M = M * P2; F = F * P2 D = D * P2; N = N * P2; G = G * P2 V = 0.39558 * sin(F + N) V = V + 0.08200 * sin(F) V = V + 0.03257 * sin(M - F - N) V = V + 0.01092 * sin(M + F + N) V = V + 0.00666 * sin(M - F) V = V - 0.00644 * sin(M + F - 2*D + N) V = V - 0.00331 * sin(F - 2*D + N) V = V - 0.00304 * sin(F - 2*D) V = V - 0.00240 * sin(M - F - 2*D - N) V = V + 0.00226 * sin(M + F) V = V - 0.00108 * sin(M + F - 2*D) V = V - 0.00079 * sin(F - N) V = V + 0.00078 * sin(F + 2*D + N) U = 1 - 0.10828 * cos(M) U = U - 0.01880 * cos(M - 2*D) U = U - 0.01479 * cos(2*D) U = U + 0.00181 * cos(2*M - 2*D) U = U - 0.00147 * cos(2*M) U = U - 0.00105 * cos(2*D - G) U = U - 0.00075 * cos(M - 2*D + G) W = 0.10478 * sin(M) W = W - 0.04105 * sin(2*F + 2*N) W = W - 0.02130 * sin(M - 2*D) W = W - 0.01779 * sin(2*F + N) W = W + 0.01774 * sin(N) W = W + 0.00987 * sin(2*D) W = W - 0.00338 * sin(M - 2*F - 2*N) W = W - 0.00309 * sin(G) W = W - 0.00190 * sin(2*F) W = W - 0.00144 * sin(M + N) W = W - 0.00144 * sin(M - 2*F - N) W = W - 0.00113 * sin(M + 2*F + 2*N) W = W - 0.00094 * sin(M - 2*D + G) W = W - 0.00092 * sin(2*M - 2*D) # compute right ascension, declination, distance S = W / sqrt(U - V*V) A5 = L + atan(S / sqrt(1 - S*S)) S = V / sqrt(U); D7 = atan(S / sqrt(1 - S*S)) R5 = 60.40974 * sqrt(U) Ma[I][1] = A5 Ma[I][2] = D7 Ma[I][3] = R5 T = T + 0.5 if Ma[2][1] <= Ma[1][1]: Ma[2][1] = Ma[2][1] + P2 if Ma[3][1] <= Ma[2][1]: Ma[3][1] = Ma[3][1] + P2 Z1 = R1 * (90.567 - 41.685/Ma[2][3]) S = sin(B5 * R1); C = cos(B5 * R1) Z = cos(Z1); M8 = 0; W8 = 0 A0 = Ma[1][1]; D0 = Ma[1][2] V0 = 0 # not initialized in BASIC program for C0 in range(0, 24): P = (C0 + 1) / 24 F0 = Ma[1][1]; F1 = Ma[2][1]; F2 = Ma[3][1] A = F1 - F0; B = F2 - F1 - A F = F0 + P * (2*A + B*(2*P-1)) A2 = F F0 = Ma[1][2]; F1 = Ma[2][2]; F2 = Ma[3][2] A = F1 - F0; B = F2 - F1 - A F = F0 + P * (2*A + B*(2*P-1)) D2 = F # GOSUB 285 test an hour for an event L0 = T0 + C0 * K1; L2 = L0 + K1 if A2 <> 0: A2 = A2 + 2*pi H0 = L0 - A0; H2 = L2 - A2 H1 = (H2 + H0) / 2 # hour angle D1 = (D2 + D0) / 2 # declination if C0 <= 0: V0 = S * sin(D0) + C * cos(D0) * cos(H0) - Z V2 = S * sin(D2) + C * cos(D2) * cos(H2) - Z if signum(V0) <> signum(V2): V1 = S * sin(D1) + C * cos(D1) * cos(H1) - Z A = 2*V2 - 4*V1 + 2*V0; B = 4*V1 - 3*V0 - V2 D = B*B - 4*A*V0 if D >= 0: D = sqrt(D) if V0 0: print "MOONRISE AT", if V0 0: M8 = 1 if V0 > 0 and V2 0 and V2 1 or E < 0: E = (-1*B - D) / (2 * A) T3 = C0 + E + 1/120 H3 = int(T3); M3 = int((T3 - H3) * 60) print H3, ":", M3, H7 = H0 + E * (H2 - H0) N7 = -1 * cos(D1) * sin(H7) D7 = C * sin(D1) - S * cos(D1) * cos(H7) A7 = atan(N7 / D7) / R1 if D7 < 0: A7 = A7 + 180 if A7 360: A7 = A7 - 360 print ", AZ", A7 A0 = A2; D0 = D2; V0 = V2 # GOSUB 450 special message if M8 0 or W8 0: if M8 == 0: print "NO MOONRISE THIS DATE" if W8 == 0: print "NO MOONSET THIS DATE" else: if V2 0: print "MOON UP ALL DAY"

You can run the program at http://programmingpraxis.codepad.org/98sCt5at.

I think WordPress ate some less than signs. See line numbers 355, 360, 365, and 425.

Fixed. Thank you.

I see 2 problems so far: division and a variable F3 is introduced, that is never used. F3 should be F2. If I change all division by floating point divivion and change varaible F3 into F2, the program gives a sunrise and sunset, which is one hour earlier than the right answer. Code is on Codepad. I do not have time now to make it run in codepad, which does not run Python 2.7. I have to quit for the Soccer Worldcup.

Forget my last remark. It runs in codepad.

Thanks for finding that.

Regarding the World Cup: My statistics were low this morning, but zoomed up after Argentina scored its goal. The effect of the World Cup was very obvious. There must be a lot of my readers who like soccer.

Like you, I will be watching the USA team in a few minutes.

On Tue, Jul 1, 2014 at 2:41 PM, Programming Praxis wrote:

>

Parts of the BASIC code appear to be missing. For example, BASIC version of the Julian date subroutine (GOSUB 760) is completely different than your Python code.

Well, it’s the same arithmetic. The BASIC program assumes that you want moonrise and moonset for today, and calculates that first, then asks you to input a different day. My program just takes the month, day and year as input parameters.