summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2014-12-16 23:48:41 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2014-12-16 23:53:15 +0100
commitc1558d34d78842ad022963dee591ab963e50053d (patch)
treeac2c8eb1d2e05ba09d0e441e47d48ae2259263ae
parent389274c1c47664d0ba0924507efdf6d09c4e7b4c (diff)
downloadorg-mode-c1558d34d78842ad022963dee591ab963e50053d.tar.gz
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 <not.com@gmail.com> <http://permalink.gmane.org/gmane.emacs.orgmode/93505>
-rw-r--r--doc/org.texi13
-rw-r--r--lisp/org-colview.el34
2 files changed, 29 insertions, 18 deletions
diff --git a/doc/org.texi b/doc/org.texi
index d617259..03f0e91 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 c7ddb64..a8de39e 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.