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>
This commit is contained in:
parent
389274c1c4
commit
c1558d34d7
13
doc/org.texi
13
doc/org.texi
|
@ -5569,7 +5569,7 @@ optional. The individual parts have the following meaning:
|
||||||
@{@@min@} @r{Minimum age (in days/hours/mins/seconds).}
|
@{@@min@} @r{Minimum age (in days/hours/mins/seconds).}
|
||||||
@{@@max@} @r{Maximum 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).}
|
@{@@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
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
|
@ -5578,11 +5578,12 @@ include. Subsequent columns referencing the same property will all display the
|
||||||
same summary information.
|
same summary information.
|
||||||
|
|
||||||
The @code{est+} summary type requires further explanation. It is used for
|
The @code{est+} summary type requires further explanation. It is used for
|
||||||
combining estimates, expressed as low-high ranges. For example, instead
|
combining estimates, expressed as @samp{low-high} ranges or plain numbers.
|
||||||
of estimating a particular task will take 5 days, you might estimate it as
|
For example, instead of estimating a particular task will take 5 days, you
|
||||||
5--6 days if you're fairly confident you know how much work is required, or
|
might estimate it as 5--6 days if you're fairly confident you know how much
|
||||||
1--10 days if you don't really know what needs to be done. Both ranges
|
work is required, or 1--10 days if you don't really know what needs to be
|
||||||
average at 5.5 days, but the first represents a more predictable delivery.
|
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
|
When combining a set of such estimates, simply adding the lows and highs
|
||||||
produces an unrealistically wide result. Instead, @code{est+} adds the
|
produces an unrealistically wide result. Instead, @code{est+} adds the
|
||||||
|
|
|
@ -952,12 +952,16 @@ display, or in the #+COLUMNS line of the current buffer."
|
||||||
valflag (and val (string-match "\\S-" val)))
|
valflag (and val (string-match "\\S-" val)))
|
||||||
(cond
|
(cond
|
||||||
((< level last-level)
|
((< level last-level)
|
||||||
;; put the sum of lower levels here as a property
|
;; Put the sum of lower levels here as a property. If
|
||||||
(setq sum (+ (if (and (/= last-level inminlevel)
|
;; values are estimate, use an appropriate sum function.
|
||||||
(aref lvals last-level))
|
(setq sum (funcall
|
||||||
(apply fun (aref lvals last-level)) 0)
|
(if (eq fun 'org-estimate-combine) #'org-estimate-combine
|
||||||
(if (aref lvals inminlevel)
|
#'+)
|
||||||
(apply fun (aref lvals inminlevel)) 0))
|
(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?
|
flag (or (aref lflag last-level) ; any valid entries from children?
|
||||||
(aref lflag inminlevel)) ; or inline tasks?
|
(aref lflag inminlevel)) ; or inline tasks?
|
||||||
str (org-columns-number-to-string sum format printf)
|
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
|
(while l
|
||||||
(setq sum (+ (string-to-number (pop l)) (/ sum 60))))
|
(setq sum (+ (string-to-number (pop l)) (/ sum 60))))
|
||||||
sum))
|
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.]+\\) *\\("
|
((string-match (concat "\\([0-9.]+\\) *\\("
|
||||||
(regexp-opt (mapcar 'car org-effort-durations))
|
(regexp-opt (mapcar 'car org-effort-durations))
|
||||||
"\\)") s)
|
"\\)") s)
|
||||||
|
@ -1079,9 +1086,6 @@ display, or in the #+COLUMNS line of the current buffer."
|
||||||
(while l
|
(while l
|
||||||
(setq sum (+ (string-to-number (pop l)) (/ sum 60))))
|
(setq sum (+ (string-to-number (pop l)) (/ sum 60))))
|
||||||
sum))
|
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)))))
|
(t (string-to-number s)))))
|
||||||
|
|
||||||
(defun org-columns-uncompile-format (cfmt)
|
(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)
|
(defun org-estimate-mean-and-var (v)
|
||||||
"Return the mean and variance of an estimate."
|
"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)))
|
(high (float (cadr v)))
|
||||||
(mean (/ (+ low high) 2.0))
|
(mean (/ (+ low high) 2.0))
|
||||||
(var (/ (+ (expt (- mean low) 2.0) (expt (- high mean) 2.0)) 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)
|
(defun org-estimate-print (e &optional fmt)
|
||||||
"Prepare a string representation of an estimate.
|
"Prepare a string representation of an estimate.
|
||||||
This formats these numbers as two numbers with a \"-\" between them."
|
This formats these numbers as two numbers with a \"-\" between them."
|
||||||
(if (null fmt) (set 'fmt "%.0f"))
|
(let ((fmt (or fmt "%.0f"))
|
||||||
(format "%s" (mapconcat (lambda (n) (format fmt n)) e "-")))
|
(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)
|
(defun org-string-to-estimate (s)
|
||||||
"Convert a string to an estimate.
|
"Convert a string to an estimate.
|
||||||
|
|
Loading…
Reference in New Issue