lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 3de3cf5 2/6: s12n(c14n)


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 3de3cf5 2/6: s12n(c14n)
Date: Tue, 28 Feb 2017 22:02:58 -0500 (EST)

branch: master
commit 3de3cf5adac2870863db8a2048b83c0658640ea4
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    s12n(c14n)
    
    Simplification of canonicalization. Suppose a thirty-seven-year-old who
    plans to retire at age sixty-five wants to take a $1000 one-time-only
    withdrawal upon retirement:
    
      0 retirement; 1000; 0
    
    Formerly, canonicalization transmogrified that into:
    
      0 retirement; 1000 29; 0
    
    which is obviously correct: 29 = 65 - 37 + 1, "1" being the (implicit)
    width of the middle interval. Now, the original string is returned:
    still correct, but simpler for end users.
    
    Added a unit test with a comment explaining why
      0 retirement; 1000 #1; 0
    is not canonicalized in the same way.
---
 input_sequence.cpp      | 11 ++++++++--
 input_sequence_test.cpp | 58 ++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/input_sequence.cpp b/input_sequence.cpp
index e4b5286..fd20f10 100644
--- a/input_sequence.cpp
+++ b/input_sequence.cpp
@@ -326,8 +326,15 @@ std::string InputSequence::canonical_form() const
                 break;
             case e_duration:
                 {
-                int const z = i.end_duration;
-                s = " " + value_cast<std::string>(z);
+                if(1 == i.end_duration - i.begin_duration)
+                    {
+                    ; // Do nothing: leave 's' empty.
+                    }
+                else
+                    {
+                    int const z = i.end_duration;
+                    s = " " + value_cast<std::string>(z);
+                    }
                 }
                 break;
             case e_attained_age:
diff --git a/input_sequence_test.cpp b/input_sequence_test.cpp
index 1721cfa..ed33f2f 100644
--- a/input_sequence_test.cpp
+++ b/input_sequence_test.cpp
@@ -212,7 +212,7 @@ void input_sequence_test::test()
     double const d[n] = {1, 2, 3, 3, 3};
     std::string const e("1; 2; 3");
     census += e + "\t\t\t\n";
-    std::string const g("1 1; 2 2; 3");
+    std::string const g("1; 2; 3");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -254,7 +254,7 @@ void input_sequence_test::test()
     double const d[n] = {1, 1, 3, 3, 3, 5, 7, 7, 7};
     std::string const e("1 [0, 2); 3 [2, 5); 5 [5, 6); 7");
     census += e + "\t\t\t\n";
-    std::string const g("1 2; 3 5; 5 6; 7");
+    std::string const g("1 2; 3 5; 5; 7");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -265,7 +265,7 @@ void input_sequence_test::test()
     std::string const e("1; 1 (0, 2]; 3 (2, 5]; 5 (5, 6]; 7");
     census += e + "\t\t\t\n";
     // Should the first two intervals be combined?
-    std::string const g("1 1; 1 3; 3 6; 5 7; 7");
+    std::string const g("1; 1 3; 3 6; 5; 7");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -275,7 +275,7 @@ void input_sequence_test::test()
     double const d[n] = {1, 1, 1, 1, 2, 3, 4, 5, 5};
     std::string const e("1 [0, 4); 2 5; 3 #1; 4 @97; 5");
     census += e + "\t\t\t\n";
-    std::string const g("1 4; 2 5; 3 #1; 4 @97; 5");
+    std::string const g("1 4; 2; 3 #1; 4 @97; 5");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -285,7 +285,7 @@ void input_sequence_test::test()
     double const d[n] = {1, 3, 5, 7, 7};
     std::string const e("1 [0, 1); 3 [1, 2); 5 (1, 2]; 7");
     census += e + "\t\t\t\n";
-    std::string const g("1 1; 3 2; 5 3; 7");
+    std::string const g("1; 3; 5; 7");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -344,7 +344,7 @@ void input_sequence_test::test()
     double const d[n] = {0, 1, 0, 3, 0, 5, 7, 7, 7};
     std::string const e("1 [1, 2); 3 [3, 3]; 5 (4, 5]; 7");
     census += e + "\t\t\t\n";
-    std::string const g("0 1; 1 2; 0 3; 3 4; 0 5; 5 6; 7");
+    std::string const g("0; 1; 0; 3; 0; 5; 7");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -354,7 +354,7 @@ void input_sequence_test::test()
     double const d[n] = {0, 1, 1, 3, 3, 5, 5, 7, 7};
     std::string const e("0; 1 (0, 8]; 3 (2, 7]; 5 (4, 6]; 7");
     // census: invalid expression cannot be pasted into GUI
-    std::string const g("0 1; 1 9; 3 8; 5 7; 7");
+    std::string const g("0; 1 9; 3 8; 5 7; 7");
     char const* m =
         "Interval [ 9, 3 ) is improper: it ends before it begins."
         ;
@@ -385,7 +385,7 @@ void input_sequence_test::test()
     double const d[n] = {0, 12, 0, 27, 0, 1, 7, 7, 7, 7};
     std::string const e("12 [1, @92); 27 address@hidden, @93]; 1 (@94, #1]; 
7");
     census += e + "\t\t\t\n";
-    std::string const g("0 1; 12 @92; 0 @93; 27 @94; 0 @95; 1 #1; 7");
+    std::string const g("0; 12 @92; 0 @93; 27 @94; 0 @95; 1 #1; 7");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -397,7 +397,7 @@ void input_sequence_test::test()
     double const d[n] = {0, 12.25, 0, 27.875, 0, 1.0625, 7.5, 7.5, 7.5, 7.5};
     std::string const e("12.25 [1,@92); 27.875 address@hidden,@93]; 
1.0625(@94,#1]; 7.5");
     census += e + "\t\t\t\n";
-    std::string const g("0 1; 12.25 @92; 0 @93; 27.875 @94; 0 @95; 1.0625 #1; 
7.5");
+    std::string const g("0; 12.25 @92; 0 @93; 27.875 @94; 0 @95; 1.0625 #1; 
7.5");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -415,7 +415,7 @@ void input_sequence_test::test()
     InputSequence const seq(v);
     BOOST_TEST(v == seq.seriatim_keywords());
     BOOST_TEST_EQUAL
-        ("alpha 1; beta 3; gamma 4; eta"
+        ("alpha; beta 3; gamma; eta"
         ,canonicalized_input_sequence(v)
         );
     }
@@ -566,7 +566,7 @@ void input_sequence_test::test()
     double const d[n] = { 0 ,  0 ,  0 ,  0 ,  0 };
     std::string const e("q [1, 3); p [3, maturity)");
     census += "\tquarterly [1, 3); monthly [3, maturity)\t\t\n";
-    std::string const g("z 1; q 3; p");
+    std::string const g("z; q 3; p");
     strvec const k{"p", "q", "z"};
     bool const o = true;
     std::string w("z");
@@ -584,7 +584,7 @@ void input_sequence_test::test()
     double const d[n] = { 0 ,  0 ,  0 ,  0 ,  0 };
     std::string const e("q [1, 3); p [3, maturity)");
     census += "sevenpay [1, 3); glp [3, maturity)\t\t\t\n";
-    std::string const g("0 1; q 3; p");
+    std::string const g("0; q 3; p");
     strvec const k{"p", "q", "z"};
     check(__FILE__, __LINE__, n, d, e, g, "", k, c);
     }
@@ -607,7 +607,7 @@ void input_sequence_test::test()
     double const d[n] = {0, 0, 0, 0, 0, 1000, 0, 0, 0, 0};
     std::string const e("0 retirement; 1000; 0 maturity");
     census += e + "\t\t\t\n";
-    std::string const g("0 retirement; 1000 6; 0");
+    std::string const g("0 retirement; 1000; 0");
     check(__FILE__, __LINE__, n, d, e, g);
     InputSequence const seq(e, 10, 90, 95, 0, 2002);
     std::vector<ValueInterval> const& i(seq.intervals());
@@ -619,6 +619,34 @@ void input_sequence_test::test()
     BOOST_TEST_EQUAL(e_maturity  , i[2].end_mode  );
     }
 
+    // Duration keywords, with a one-year-long event at retirement.
+    // This differs from the immediately preceding example. If it
+    // were canonicalized the same way, the difference between the
+    // two would be nullified.
+    //
+    // One could argue that an interval of implicit length one ought
+    // to be considered as
+    //   begin-point, #1
+    // instead of
+    //   begin-point, 1+begin-point
+    // but that's six of one vs. half a dozen of the other.
+    {
+    int const n = 10;
+    double const d[n] = {0, 0, 0, 0, 0, 1000, 0, 0, 0, 0};
+    std::string const e("0 retirement; 1000 #1; 0 maturity");
+    census += e + "\t\t\t\n";
+    std::string const g("0 retirement; 1000 #1; 0");
+    check(__FILE__, __LINE__, n, d, e, g);
+    InputSequence const seq(e, 10, 90, 95, 0, 2002);
+    std::vector<ValueInterval> const& i(seq.intervals());
+    BOOST_TEST_EQUAL(e_inception      , i[0].begin_mode);
+    BOOST_TEST_EQUAL(e_retirement     , i[0].end_mode  );
+    BOOST_TEST_EQUAL(e_retirement     , i[1].begin_mode);
+    BOOST_TEST_EQUAL(e_number_of_years, i[1].end_mode  );
+    BOOST_TEST_EQUAL(e_number_of_years, i[2].begin_mode);
+    BOOST_TEST_EQUAL(e_maturity       , i[2].end_mode  );
+    }
+
     // Test a simple parser error.
     {
     int const n = 2;
@@ -662,7 +690,7 @@ void input_sequence_test::test()
     double const d[n] = {10, 11, 12, 13, 14, 15, 15, 15, 15};
     std::string const e("10; 11; 12; 13; 14; 15");
     census += e + "\t\t\t\n";
-    std::string const g("10 1; 11 2; 12 3; 13 4; 14 5; 15");
+    std::string const g("10; 11; 12; 13; 14; 15");
     check(__FILE__, __LINE__, n, d, e, g);
     }
 
@@ -673,7 +701,7 @@ void input_sequence_test::test()
     double const d[n] = { 0 ,  0 ,  0 ,  0 ,  0 };
     std::string const e("a; m");
     census += "\tannual; monthly\t\t\n";
-    std::string const g("a 1; m");
+    std::string const g("a; m");
     strvec const k{"a", "m"};
     bool const o = true;
     std::string w("a");



reply via email to

[Prev in Thread] Current Thread [Next in Thread]