Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^7: How to write testable command line script? (updated)

by AnomalousMonk (Archbishop)
on Nov 26, 2018 at 16:36 UTC ( [id://1226363]=note: print w/replies, xml ) Need Help??


in reply to Re^6: How to write testable command line script?
in thread How to write testable command line script?

This is no different from any decimal ...

But if I have the decimal number -345, this is
    -(3*10^2 + 4*10^1 + 5*10^0)
or
    -1 * (3*10^2 + 4*10^1 + 5*10^0)
or
    -3*10^2 + -4*10^1 + -5*10^0
or
    -3*10^2 - 4*10^1 - 5*10^0
and not
    -3*10^2 + 4*10^1 + 5*10^0
and similarly for numbers represented in sexagesimal base.

Negative numbers are only permitted in the degree column.

Unfortunately, if one has a d/m/s tuple  @dms = (3, 4, 5) one cannot negate it by writing -@dms. One has to negate each element:
    @neg_dms = map -1*$_, @dms;
or (-3, -4, -5). IIUC, the notation -3° 4' 5" is equivalent to the tuple (-3°, -4', -5") analogously to decimal notation. Klaf is describing and giving an example of base-60 subtraction with borrowing, but that is not fundamentally different from base-10 subtraction.

Update 1: Added the "Negative numbers ..." quote before the second paragraph for clarification, and various other minor wording changes and additions.

Update 2: Here's the Klaf subtraction example in terms of normalizing everything to decimal arc-seconds, doing a decimal subtraction and reducing arc-seconds to a d/m/s tuple:

c:\@Work\Perl\monks\thechartist>perl -wMstrict -le "sub dms_2_secs { my ($degs, $mins, $secs) = @_; ;; return $degs * 3600 + $mins * 60 + $secs; } ;; sub secs_2_dms { use integer; ;; my ($secs) = @_; ;; my $degs = $secs / 3600; $secs %= 3600; my $mins = $secs / 60; $secs %= 60; ;; return $degs, $mins, $secs; } ;; my $klaf_arc_secs = dms_2_secs(83, 18, 21) - dms_2_secs(39, 41, 28); my @klaf_dms = secs_2_dms($klaf_arc_secs); print qq{(@klaf_dms)}; " (43 36 53)
(Update: The Klaf addition example also works correctly.) (Update: Moreover, the reversed subtraction  dms_2_secs(39, 41, 28) - dms_2_secs(83, 18, 21) yields the expected (-43 -36 -53) tuple.)


Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re^8: How to write testable command line script? (updated)
by thechartist (Monk) on Nov 26, 2018 at 17:47 UTC

    I agree that this alternate method is correct; my question now is if my transliteration of his base 60 algorithm has flaws that I did not initially see. I want to make an argument that these are 2 separate ways of describing the same point, but I do not have a proof yet.

      ... these are 2 separate ways of describing the same [angle] ...

      There are an infinite number of ways to describe any angle. I see nothing inherently wrong with representing -0° 1' 0" (or 0°, -1', 0" in a different notation) as  (-1, 59, 0) internally as long as this tuple (and all such "weird" tuples; there are many in the test sets) correctly reduce to whatever you define as a "standard" representation (and the aforementioned tuple does reduce to  (0, -1, 0) as shown below). In the end, it's all a matter of the constraints you choose to impose on, e.g., notation and internal representation, user input, user output, etc., etc. These are all programmer choices.

      c:\@Work\Perl\monks\thechartist>perl -wMstrict -le "use TrigCalc qw(reduce); ;; my @dms = reduce(-1, 59, 0); print qq{(@dms)}; " (0 -1 0)
      That said, simplest is usually best, so my choice for the internal representation of this angle would be -60 arc-seconds (or maybe decimal degrees, or radians, or whatever).


      Give a man a fish:  <%-{-{-{-<

        Thanks for coming back to this. I was about to go into detail showing how my representation, at least for the purposes of addition and subtraction, was equivalent, but you had already done that for me.

        After starting this script, I later realized that my initial algorithm did not handle division correctly. I believe you method of converting everything to seconds is the most general and will likely be what I implement when I revise this.

Re^8: How to write testable command line script?
by thechartist (Monk) on Nov 26, 2018 at 16:57 UTC

    So far, the reduce sub is consistent with all of the examples in his text. User input would accept negative in the minute and second fields (unlike some other calculators), it just won't provide output with negatives in those fields, which are appropriately carried to the next highest term, as is done in this calculator http://www.mathopenref.com/dmscalculator.html

      But with the http://www.mathopenref.com/dmscalculator.html calculator, if I enter 0° 0' 59" and then add -0° 1' 0", I get -0° 0' 1". Surely the only way that can happen is if -0° 1' 0" represents a negative angle of 0° 1' 0", i.e., an angle of -1'. (Understandably, the calculator won't let you enter angles like 0° -1' 0" or 0° 0' 60".)


      Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1226363]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-26 00:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found