From c1558d34d78842ad022963dee591ab963e50053d Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Tue, 16 Dec 2014 23:48:41 +0100 Subject: [PATCH] Fix low-high estimates * doc/org.texi (Column attributes): Emphasize estimates format. Document degenerate case of plain numbers. * lisp/org-colview.el (org-columns-compute): Properly sum estimates. (org-columns-string-to-number): Recognize estimates containing an unit. (org-estimate-mean-and-var, org-estimate-print): Allow numbers as a degenerate case of estimates. Reported-by: yary --- doc/org.texi | 13 +++++++------ lisp/org-colview.el | 34 ++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index d6172594c..03f0e911b 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -5569,7 +5569,7 @@ optional. The individual parts have the following meaning: @{@@min@} @r{Minimum age (in days/hours/mins/seconds).} @{@@max@} @r{Maximum age (in days/hours/mins/seconds).} @{@@mean@} @r{Arithmetic mean of ages (in days/hours/mins/seconds).} - @{est+@} @r{Add low-high estimates.} + @{est+@} @r{Add @samp{low-high} estimates.} @end example @noindent @@ -5578,11 +5578,12 @@ include. Subsequent columns referencing the same property will all display the same summary information. The @code{est+} summary type requires further explanation. It is used for -combining estimates, expressed as low-high ranges. For example, instead -of estimating a particular task will take 5 days, you might estimate it as -5--6 days if you're fairly confident you know how much work is required, or -1--10 days if you don't really know what needs to be done. Both ranges -average at 5.5 days, but the first represents a more predictable delivery. +combining estimates, expressed as @samp{low-high} ranges or plain numbers. +For example, instead of estimating a particular task will take 5 days, you +might estimate it as 5--6 days if you're fairly confident you know how much +work is required, or 1--10 days if you don't really know what needs to be +done. Both ranges average at 5.5 days, but the first represents a more +predictable delivery. When combining a set of such estimates, simply adding the lows and highs produces an unrealistically wide result. Instead, @code{est+} adds the diff --git a/lisp/org-colview.el b/lisp/org-colview.el index c7ddb64ce..a8de39e92 100644 --- a/lisp/org-colview.el +++ b/lisp/org-colview.el @@ -952,12 +952,16 @@ display, or in the #+COLUMNS line of the current buffer." valflag (and val (string-match "\\S-" val))) (cond ((< level last-level) - ;; put the sum of lower levels here as a property - (setq sum (+ (if (and (/= last-level inminlevel) - (aref lvals last-level)) - (apply fun (aref lvals last-level)) 0) - (if (aref lvals inminlevel) - (apply fun (aref lvals inminlevel)) 0)) + ;; Put the sum of lower levels here as a property. If + ;; values are estimate, use an appropriate sum function. + (setq sum (funcall + (if (eq fun 'org-estimate-combine) #'org-estimate-combine + #'+) + (if (and (/= last-level inminlevel) + (aref lvals last-level)) + (apply fun (aref lvals last-level)) 0) + (if (aref lvals inminlevel) + (apply fun (aref lvals inminlevel)) 0)) flag (or (aref lflag last-level) ; any valid entries from children? (aref lflag inminlevel)) ; or inline tasks? str (org-columns-number-to-string sum format printf) @@ -1071,6 +1075,9 @@ display, or in the #+COLUMNS line of the current buffer." (while l (setq sum (+ (string-to-number (pop l)) (/ sum 60)))) sum)) + ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent)) + (if (equal s "[X]") 1. 0.000001)) + ((memq fmt '(estimate)) (org-string-to-estimate s)) ((string-match (concat "\\([0-9.]+\\) *\\(" (regexp-opt (mapcar 'car org-effort-durations)) "\\)") s) @@ -1079,9 +1086,6 @@ display, or in the #+COLUMNS line of the current buffer." (while l (setq sum (+ (string-to-number (pop l)) (/ sum 60)))) sum)) - ((memq fmt '(checkbox checkbox-n-of-m checkbox-percent)) - (if (equal s "[X]") 1. 0.000001)) - ((memq fmt '(estimate)) (org-string-to-estimate s)) (t (string-to-number s))))) (defun org-columns-uncompile-format (cfmt) @@ -1509,7 +1513,10 @@ This will add overlays to the date lines, to show the summary for each day." (defun org-estimate-mean-and-var (v) "Return the mean and variance of an estimate." - (let* ((low (float (car v))) + (let* ((v (cond ((consp v) v) + ((numberp v) (list v v)) + (t (error "Invalid estimate type")))) + (low (float (car v))) (high (float (cadr v))) (mean (/ (+ low high) 2.0)) (var (/ (+ (expt (- mean low) 2.0) (expt (- high mean) 2.0)) 2.0))) @@ -1532,8 +1539,11 @@ and variances (respectively) of the individual estimates." (defun org-estimate-print (e &optional fmt) "Prepare a string representation of an estimate. This formats these numbers as two numbers with a \"-\" between them." - (if (null fmt) (set 'fmt "%.0f")) - (format "%s" (mapconcat (lambda (n) (format fmt n)) e "-"))) + (let ((fmt (or fmt "%.0f")) + (e (cond ((consp e) e) + ((numberp e) (list e e)) + (t (error "Invalid estimate type"))))) + (format "%s" (mapconcat (lambda (n) (format fmt n)) e "-")))) (defun org-string-to-estimate (s) "Convert a string to an estimate.