#! /usr/bin/perl use warnings; use strict; use 5.010; use WWW::Mechanize::GZip; use HTML::TableExtract qw(tree); use open ':std', OUT => ':utf8'; use Prompt::Timeout; use constant TIMEOUT => 3; use constant MAXTRIES => 30; my $site = 'http://www.fourmilab.ch/yoursky/cities.html'; my $mech = 'WWW::Mechanize::GZip'->new; $mech->get($site); $mech->follow_link( text => 'Portland OR' ); my $before_bound = 2457496.65; #before conjunction my $after_bound = 2457496.75; #after conjunction $mech->set_fields(qw'date 2'); my $moonstring = 5; my $jstr = 3; my $upper = $before_bound; my $lower = $after_bound; my $equal; my $equal_sec; my $now_string = localtime; my $filename = 'planet7.txt'; open( my $jh, '>>', $filename ) or die "Could not open file '$filename' $!"; say $jh "Script executed at $now_string"; my $attempts = 1; while ( ( $jstr != $moonstring ) ) { my $default = ( ( $attempts >= MAXTRIES ) ) ? 'N' : 'Y'; my $answer = prompt( "Make query number $attempts?", $default, TIMEOUT ); exit if $answer =~ /^N/i; say "upper is $upper"; say "lower is $lower"; my $guess = closetohalf( $upper, $lower ); say "guess is $guess"; $mech->set_fields( jd => $guess ); $mech->click_button( value => "Update" ); my $te = 'HTML::TableExtract'->new; $te->parse( $mech->content ); my $table = ( $te->tables )[3]; my $table_tree = $table->tree; my $venus = $table_tree->cell( 5, 1 )->as_text; my $jupiter = $table_tree->cell( 7, 1 )->as_text; $moonstring = string_to_second($venus); say "moon seconds is $moonstring"; $jstr = string_to_second($jupiter); say "jupiter seconds is $jstr"; if ( $jstr > $moonstring ) { $upper = $guess; } elsif ( $moonstring > $jstr ) { $lower = $guess; } else { $equal = $guess; say "equal, while condition should fail $equal"; $equal_sec = $moonstring; } $te->delete; $attempts++; } say $jh "equal seconds is $equal_sec"; ###redesign 4/20/16 ## determining beginning my $outer = $before_bound; my $inner = $equal; say $jh join "\t", 'moonstring', 'jstr', 'outer', 'inner', 'guess'; $attempts = 1; while ( ( abs( $outer - $inner ) > .00001 ) ) { my $default = ( ( $attempts >= MAXTRIES ) ) ? 'N' : 'Y'; my $answer = prompt( "Make query number $attempts?", $default, TIMEOUT ); exit if $answer =~ /^N/i; say "outer is $outer"; say "inner is $inner"; my $guess = closetohalf( $outer, $inner ); say "guess is $guess"; $mech->set_fields( jd => $guess ); $mech->click_button( value => "Update" ); my $te = 'HTML::TableExtract'->new; $te->parse( $mech->content ); my $table = ( $te->tables )[3]; my $table_tree = $table->tree; my $venus = $table_tree->cell( 5, 1 )->as_text; my $jupiter = $table_tree->cell( 7, 1 )->as_text; $moonstring = string_to_second($venus); $jstr = string_to_second($jupiter); say $jh join "\t", $moonstring, $jstr, $outer, $inner, $guess; if ( $moonstring < $jstr ) { $outer = $guess; } elsif ( $moonstring == $jstr ) { $inner = $guess; } else { die "retrograde motion or bad data"; } $te->delete; $attempts++; } say $jh "after beginning contraction, upper is $outer"; say $jh "after beginning contraction, lower is $inner"; my $begin_time = $inner; ## determine end time $outer = $after_bound; $inner = $equal; say $jh join "\t", 'moonstring', 'jstr', 'outer', 'inner', 'guess'; $attempts = 1; while ( ( abs( $outer - $inner ) > .00001 ) ) { my $default = ( ( $attempts >= MAXTRIES ) ) ? 'N' : 'Y'; my $answer = prompt( "Make query number $attempts?", $default, TIMEOUT ); exit if $answer =~ /^N/i; say "outer is $outer"; say "inner is $inner"; my $guess = closetohalf( $outer, $inner ); say "guess is $guess"; $mech->set_fields( jd => $guess ); $mech->click_button( value => "Update" ); my $te = 'HTML::TableExtract'->new; $te->parse( $mech->content ); my $table = ( $te->tables )[3]; my $table_tree = $table->tree; my $venus = $table_tree->cell( 5, 1 )->as_text; my $jupiter = $table_tree->cell( 7, 1 )->as_text; $moonstring = string_to_second($venus); $jstr = string_to_second($jupiter); say $jh join "\t", $moonstring, $jstr, $outer, $inner, $guess; if ( $moonstring > $jstr ) { $outer = $guess; } elsif ( $moonstring == $jstr ) { $inner = $guess; } else { die "retrograde motion or bad data"; } $te->delete; $attempts++; } say $jh "after ending contraction, outer is $outer"; say $jh "after ending contraction, inner is $inner"; my $end_time = $inner; my $jul_length = $end_time - $begin_time; my $second_length = $jul_length * 86400; say "duration in seconds is $second_length"; say $jh "duration in seconds is $second_length"; sub string_to_second { my $string = shift; my $return = 9000; if ( my $success = $string =~ /^(\d*)h\s+(\d*)m\s+(\d*)s$/ ) { $return = 3600 * $1 + 60 * $2 + $3; } else { say "string was misformed"; } return $return; } sub closetohalf { my ( $up, $low ) = @_; $low + ( $up - $low ) * ( 0.4 + rand 0.2 ); }