misc updates

This commit is contained in:
Zane C. B-H 2020-05-24 06:54:39 -05:00
parent 034fbb4dc5
commit 4b4256d938
3 changed files with 229 additions and 16 deletions

View File

@ -7,3 +7,4 @@ t/00-load.t
t/manifest.t
t/pod-coverage.t
t/pod.t
t/giac.t

View File

@ -3,6 +3,7 @@ package Math::Giac;
use 5.006;
use strict;
use warnings;
use File::Temp;
=head1 NAME
@ -10,45 +11,206 @@ Math::Giac - The great new Math::Giac!
=head1 VERSION
Version 0.01
Version 0.0.1
=cut
our $VERSION = '0.01';
our $VERSION = '0.0.1';
=head1 SYNOPSIS
Quick summary of what the module does.
Perhaps a little code snippet.
use Math::Giac;
my $foo = Math::Giac->new();
...
my $giac;
eval( {
$giac=$Math::Giac->new;
} );
if ( $@ ){
die("Failed to locate the giac binary");
}
=head1 EXPORT
my $results=$giac->run('sin(x)+cos(pi)-3');
print $results."\n";
A list of functions that can be exported. You can delete this section
if you don't export anything, such as for a purely object-oriented module.
$results=$giac->run('mathml(sin(x)+cos(pi)-3)');
print $results."\n";
=head1 SUBROUTINES/METHODS
=head1 METHODS
=head2 function1
=head2 new
This initiates the object.
This also checks to make sure that giac is in the path. If
that check fails, it will die.
my $giac;
eval( {
$giac=$Math::Giac->new;
} );
if ( $@ ){
die("Failed to locate the giac binary");
}
=cut
sub function1 {
sub new {
# make sure we can locate giac binary
my $the_bin = `/bin/sh -c 'which giac 2> /dev/null'`;
if ( $? != 0 ) {
die("Can't locate the giac binary");
}
my $self = { vars => {}, };
bless $self;
return $self;
}
=head2 function2
=head2 run
This returns the respected string after putting together a variable list.
The final output is what is returned, or $output[ $#output - 1 ], assuming it is
a single line one. Otherwise it works backwards to find a match.
This will remove the " from the start and return of the return, which gets added for
with latex or mathml.
This will die on a non-zero exit or no string being specified.
my $results=$giac->run('sin(x)+cos(pi)-3');
print $results."\n";
$results=$giac->run('mathml(sin(x)+cos(pi)-3)');
print $results."\n";
=cut
sub function2 {
sub run {
my $self = $_[0];
my $to_run = $_[1];
if ( !defined($to_run) ) {
die('No string specified to run');
}
$to_run =~ s/\n+$//;
my @var_list = keys( %{ $self->{vars} } );
my $vars_addon = '';
foreach my $cur_var (@var_list) {
my $vars_addon = $vars_addon . $cur_var . ':=' . $$self->{vars}{$cur_var} . "\n";
}
$to_run = $vars_addon . $to_run;
my $tmp = File::Temp->new;
print $tmp $to_run;
# run giac
my $returned = `giac < $tmp 2> /dev/null`;
if ( $? != 0 ) {
die("giac exited with a non-zero... ".$?."... ".$@);
}
my @split_returned = split( /\n/, $returned );
# if second to last is /^[0-9]+\>\>\ / thn return
if ( $split_returned[ $#split_returned - 2 ] =~ /^[0-9]+\>\>\ / ) {
# removes ", which get added for latex
$split_returned[ $#split_returned - 1 ] =~ s/^\"//;
$split_returned[ $#split_returned - 1 ] =~ s/\"$//;
return $split_returned[ $#split_returned - 1 ];
}
# if we are here, go through it and put it toghether
my $to_return = $split_returned[ $#split_returned - 1 ];
my $line = 3;
my $loop = 1;
while ($loop) {
$to_return = $split_returned[ $#split_returned - $line ] . "\n" . $to_return;
# goto the previous line and check if it matches the end condition
$line++;
if ( $split_returned[ $#split_returned - $line ] =~ /^[0-9]+\>\>\ / ) {
$loop = 0;
}
}
# remove the "s that get added for multi line...
$to_return =~ s/^\"//;
$to_return =~ s/\"$//;
return $to_return;
}
=head2 vars_clear
Removes any set variables.
As long as new was successfully called, this won't error.
$giac->vars_clear;
=cut
sub vars_clear {
my $self = $_[0];
delete( $self->{vars} );
$self->{vars} = {};
return 1;
}
=head2 vars_set
Sets the variables.
xsThis requires one argument, which is a hash reference.
=cut
sub vars_set {
my $self = $_[0];
if ( ref( $_[1] ne 'HASH' ) ) {
die('$_[1] is not a hash');
}
my $vars = $_[1];
$self->{vars} = $vars;
return 1;
}
=head1 VARIABLE HANDLING
Lets say the variable hash below is passed.
{
A=>1,
B=>3,
}
Then the resulting code will be as below.
A:=1
B:=3
Then requested item to run is then added to the end.
So if we are running 'sin(pi)+A' then we will have
the item below.
A:=1
B:=3
sin(pi)+A
=head1 AUTHOR
Zane C. Bowers-HAdley, C<< <vvelox at vvelox.net> >>

50
t/giac.t Normal file
View File

@ -0,0 +1,50 @@
#!perl
use 5.006;
use strict;
use warnings;
use Test::More;
my $extra_tests=0;
BEGIN {
use_ok( 'Math::Giac' ) || print "Bail out!\n";
}
my $the_bin = `/bin/sh -c 'which giac 2> /dev/null'`;
if ( $? eq 0 ){
$extra_tests=3;
my $worked=0;
my $giac;
eval{
$giac=Math::Giac->new;
$worked=1;
};
ok( $worked eq '1', 'init check') or diag('failed to init the module');
# basic single line return test
my $returned='';
my $extra_error='';
eval{
$returned=$giac->run("sin(pi)+3");
};
if ( $@ ){
$extra_error='... '.$@;
}
ok( $returned eq '3', 'run check') or diag('"sin(pi)+3" returned "'.$returned.'" instead of "3"'.$extra_error);
# basic multi line return test
$returned='';
$extra_error='';
eval{
$returned=$giac->run("mathml(sin(pi))");
};
if ( $@ ){
$extra_error='... '.$@;
}
ok( $returned =~ /MathML/, 'run check') or diag('"mathml(sin(pi))" returned "'.$returned.'" and does not match /MathML/'.$extra_error);
}
my $tests_ran=1+$extra_tests;
done_testing($tests_ran);