gnucash maint: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Wed Feb 20 06:15:40 EST 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/e3160af4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/60558f6a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b1cd7393 (commit)
	from  https://github.com/Gnucash/gnucash/commit/11083d60 (commit)



commit e3160af417b1ab8ca52bda9be7a02304cb5708cc
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Feb 8 14:25:50 2019 +0800

    [report-utilities] fix (gnc:make-stats-collector)
    
    allows it to compare numbers with +/-inf.0 -- 10E9 is an arbitrary
    number to compare numbers.
    
    (< N +inf.0) is guaranteed to be #t for all numbers N whereby N is not
    also +inf.0.

diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index e1b650e3a..355c42174 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -177,40 +177,35 @@ construct gnc:make-gnc-monetary and use gnc:monetary->string instead.")
 ;; yes.  I think that would still be faster.
 
 (define (gnc:make-stats-collector)
-  (let ;;; values
-      ((value 0)
-       (totalitems 0)
-       (max -10E9)
-       (min 10E9))
-    (let ;;; Functions to manipulate values
-	((adder (lambda (amount)
-		  (if (number? amount) 
-		      (begin
-			(set! value (+ amount value))
-			(if (> amount max)
-			    (set! max amount))
-			(if (< amount min)
-			    (set! min amount))
-			(set! totalitems (+ 1 totalitems))))))
-	 (getnumitems (lambda () totalitems))
-	 (gettotal (lambda () value))
-	 (getaverage (lambda () (/ value totalitems)))
-	 (getmax (lambda () max))
-	 (getmin (lambda () min))
-	 (reset-all (lambda ()
-		    (set! value 0)
-		    (set! max -10E9)
-		    (set! min 10E9)
-		    (set! totalitems 0))))
-      (lambda (action value)  ;;; Dispatch function
-	(case action
-	  ((add) (adder value))
-	  ((total) (gettotal))
-	  ((average) (getaverage))
-	  ((numitems) (getnumitems))
-	  ((getmax) (getmax))
-	  ((getmin) (getmin))
-	  ((reset) (reset-all))
+  (let ((value 0)
+        (totalitems 0)
+        (maximum -inf.0)
+        (minimum +inf.0))
+    (let ((adder (lambda (amount)
+                   (when (number? amount)
+                     (set! value (+ amount value))
+                     (if (> amount maximum) (set! maximum amount))
+                     (if (< amount minimum) (set! minimum amount))
+                     (set! totalitems (1+ totalitems)))))
+          (getnumitems (lambda () totalitems))
+          (gettotal (lambda () value))
+          (getaverage (lambda () (/ value totalitems)))
+          (getmax (lambda () maximum))
+          (getmin (lambda () minimum))
+          (reset-all (lambda ()
+                       (set! value 0)
+                       (set! maximum -inf.0)
+                       (set! minimum +inf.0)
+                       (set! totalitems 0))))
+      (lambda (action value)
+        (case action
+          ((add) (adder value))
+          ((total) (gettotal))
+          ((average) (getaverage))
+          ((numitems) (getnumitems))
+          ((getmax) (getmax))
+          ((getmin) (getmin))
+          ((reset) (reset-all))
           (else (gnc:warn "bad stats-collector action: " action)))))))
 
 (define (gnc:make-drcr-collector)
diff --git a/gnucash/report/report-system/test/test-report-utilities.scm b/gnucash/report/report-system/test/test-report-utilities.scm
index 35ead6a81..f58878fb1 100644
--- a/gnucash/report/report-system/test/test-report-utilities.scm
+++ b/gnucash/report/report-system/test/test-report-utilities.scm
@@ -22,6 +22,7 @@
   (test-commodity-collector)
   (test-get-account-balances)
   (test-monetary-adders)
+  (test-make-stats-collector)
   (test-end "report-utilities"))
 
 (define (NDayDelta t64 n)
@@ -503,3 +504,50 @@
      "gnc:monetary+ with >1 currency fails"
      #t
      (gnc:monetary+ usd10 usd10 eur8))))
+
+(define (test-make-stats-collector)
+  (test-begin "gnc:make-stats-collector")
+  (let ((s (gnc:make-stats-collector)))
+    (test-equal "initial s is 0"
+      0
+      (s 'total #f))
+
+    (s 'add 5)
+    (test-equal "s+=5 is 5"
+      5
+      (s 'total #f))
+
+    (s 'add 9)
+    (test-equal "s+=9 is 14"
+      14
+      (s 'total #f))
+
+    (test-equal "avg(s) is 7"
+      7
+      (s 'average #f))
+
+    (s 'add 1E12)
+    (s 'add -1E13)
+
+    (test-equal "max(s) is now 1E12"
+      1E12
+      (s 'getmax #f))
+
+    (test-equal "min(s) is now -1E13"
+      -1E13
+      (s 'getmin #f))
+
+    (s 'add 9E12)
+    (test-equal "newavg(s) is 2.8"
+      2.8
+      (s 'average #f))
+
+    (test-equal "num(s) is 5"
+      5
+      (s 'numitems #f))
+
+    (s 'reset #f)
+    (test-equal "after reset num(s) is 0"
+      0
+      (s 'numitems #f)))
+  (test-end "gnc:make-stats-collector"))

commit 60558f6ad185a66c1da67f0fd0123c4b26d3381f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Feb 6 21:41:20 2019 +0800

    [report-utilities] (gnc:account-get-balances-at-dates) documentation
    
    the algorithm assumes dates-list is sorted chronologically. enforce
    it, and document.

diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index 02ceb4140..e1b650e3a 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -431,7 +431,7 @@ flawed. see report-utilities.scm. please update reports.")
 ;; this function will scan through the account splitlist, building
 ;; a list of balances along the way at dates specified in dates-list.
 ;; in:  account
-;;      dates-list (list of time64)
+;;      dates-list (list of time64) - NOTE: IT WILL BE SORTED
 ;;      split->amount - an unary lambda. calling (split->amount split)
 ;;      returns a number, or #f which effectively skips the split.
 ;; out: (list bal0 bal1 ...), each entry is a gnc-monetary object
@@ -445,7 +445,7 @@ flawed. see report-utilities.scm. please update reports.")
   (define (amount->monetary bal)
     (gnc:make-gnc-monetary (xaccAccountGetCommodity account) bal))
   (let loop ((splits (xaccAccountGetSplitList account))
-             (dates-list dates-list)
+             (dates-list (stable-sort! dates-list <))
              (currentbal 0)
              (lastbal 0)
              (balancelist '()))

commit b1cd7393b6908a99268c085db01f3bb543634bd5
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Jan 7 23:56:13 2019 +0800

    [report-utilities] gnc:account-get-balances-at-dates adjustment
    
    (Release Note - developer section)
    
    Modification to gnc:account-get-balances-at-dates.
    
    formerly it would accept an optional #:ignore-closing? boolean to skip
    closing transactions.
    
    it would be more general to accept a #:split->amount function whose
    default is xaccSplitGetAmount. calling (split->amount split) should
    return amount from the split. if the function returns #f, it
    effectively skips the split. this will allow a more general
    account-balance list accumulator, allowing novel balance strategies
    e.g. split->amount may test split void status and return the split
    xaccSplitVoidFormerAmount, test description/memo and return an amount
    depending on description contents, or test the split and return 1 or 0
    which will return a tally of splits.
    
    the direct equivalence for the previous #:ignore-closing? keyword
    argument is #:split->amount (lambda (s) (and (not (xaccTransGetIsClosingTxn
    (xaccSplitGetParent s))) (xaccSplitGetAmount s)))
    
    NOTE: the modifications to category-barchart.scm and net-charts.scm
    will use the #:split->amount kwarg as well.
    
    This function is extensively tested in the commit
    53cab269f467cf73ff7e20cde797cd08212b9435

diff --git a/gnucash/report/report-system/report-utilities.scm b/gnucash/report/report-system/report-utilities.scm
index 3402ac524..02ceb4140 100644
--- a/gnucash/report/report-system/report-utilities.scm
+++ b/gnucash/report/report-system/report-utilities.scm
@@ -432,9 +432,16 @@ flawed. see report-utilities.scm. please update reports.")
 ;; a list of balances along the way at dates specified in dates-list.
 ;; in:  account
 ;;      dates-list (list of time64)
-;;      ignore-closing? - if #true, will skip closing entries
+;;      split->amount - an unary lambda. calling (split->amount split)
+;;      returns a number, or #f which effectively skips the split.
 ;; out: (list bal0 bal1 ...), each entry is a gnc-monetary object
-(define* (gnc:account-get-balances-at-dates account dates-list #:key ignore-closing?)
+;;
+;; NOTE a prior incarnation accepted a #:ignore-closing? boolean
+;; keyword which can be reproduced via #:split->amount (lambda (s)
+;; (and (not (xaccTransGetIsClosingTxn (xaccSplitGetParent s)))
+;; (xaccSplitGetAmount s)))
+(define* (gnc:account-get-balances-at-dates
+          account dates-list #:key (split->amount xaccSplitGetAmount))
   (define (amount->monetary bal)
     (gnc:make-gnc-monetary (xaccAccountGetCommodity account) bal))
   (let loop ((splits (xaccAccountGetSplitList account))
@@ -460,10 +467,7 @@ flawed. see report-utilities.scm. please update reports.")
      (else
       (let* ((this (car splits))
              (rest (cdr splits))
-             (currentbal (if (and ignore-closing?
-                                  (xaccTransGetIsClosingTxn (xaccSplitGetParent this)))
-                             currentbal
-                             (+ (xaccSplitGetAmount this) currentbal)))
+             (currentbal (+ (or (split->amount this) 0) currentbal))
              (next (and (pair? rest) (car rest))))
 
         (cond
diff --git a/gnucash/report/standard-reports/category-barchart.scm b/gnucash/report/standard-reports/category-barchart.scm
index 35c9d2b26..ae3a6ab88 100644
--- a/gnucash/report/standard-reports/category-barchart.scm
+++ b/gnucash/report/standard-reports/category-barchart.scm
@@ -361,12 +361,18 @@ developing over time"))
           (define account-balances-alist
             (map
              (lambda (acc)
-               (cons acc
-                     (map
-                      (if (reverse-balance? acc) gnc:monetary-neg identity)
-                      (gnc:account-get-balances-at-dates
-                       acc dates-list
-                       #:ignore-closing? (gnc:account-is-inc-exp? acc)))))
+               (let ((ignore-closing? (not (gnc:account-is-inc-exp? acc))))
+                 (cons acc
+                       (map
+                        (if (reverse-balance? acc) gnc:monetary-neg identity)
+                        (gnc:account-get-balances-at-dates
+                         acc dates-list
+                         #:split->amount
+                         (lambda (s)
+                           (and (or ignore-closing?
+                                    (not (xaccTransGetIsClosingTxn
+                                          (xaccSplitGetParent s))))
+                                (xaccSplitGetAmount s))))))))
              accounts))
 
           ;; Creates the <balance-list> to be used in the function
diff --git a/gnucash/report/standard-reports/net-charts.scm b/gnucash/report/standard-reports/net-charts.scm
index 12e10085e..8defa587e 100644
--- a/gnucash/report/standard-reports/net-charts.scm
+++ b/gnucash/report/standard-reports/net-charts.scm
@@ -251,10 +251,16 @@
     ;; gets an account alist balances
     ;; output: (list acc bal0 bal1 bal2 ...)
     (define (account->balancelist account)
-      (cons account
-            (gnc:account-get-balances-at-dates
-             account dates-list
-             #:ignore-closing? (gnc:account-is-inc-exp? account))))
+      (let ((ignore-closing? (not (gnc:account-is-inc-exp? account))))
+        (cons account
+              (gnc:account-get-balances-at-dates
+               account dates-list
+               #:split->amount
+               (lambda (s)
+                 (and (or ignore-closing?
+                          (not (xaccTransGetIsClosingTxn
+                                (xaccSplitGetParent s))))
+                      (xaccSplitGetAmount s)))))))
 
     ;; This calculates the balances for all the 'account-balances' for
     ;; each element of the list 'dates'. Uses the collector->monetary



Summary of changes:
 gnucash/report/report-system/report-utilities.scm  | 83 +++++++++++-----------
 .../report-system/test/test-report-utilities.scm   | 48 +++++++++++++
 .../report/standard-reports/category-barchart.scm  | 18 +++--
 gnucash/report/standard-reports/net-charts.scm     | 14 ++--
 4 files changed, 111 insertions(+), 52 deletions(-)



More information about the gnucash-changes mailing list