emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* colview min/mean/max
@ 2009-05-20 11:15 Mikael Fornius
  2009-05-20 13:21 ` Mikael Fornius
  0 siblings, 1 reply; 7+ messages in thread
From: Mikael Fornius @ 2009-05-20 11:15 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]


I have changed my org-colview.el so that it is possible to get min, mean
and max values calculated instead of just sums in the table summaries.

I use orgmode as a dayplanner and physical exercise diary.

My exercise data is stored as properties in a year->month->day tree and
it is very nice for med to get an overview of my fastest run or average
heartrate over time with columnview. 

If you developers like it I can make the same changes to
org-colview-xemacs.el and document it in the manual for use in future
releases?

New column operators: min, mean, max, :min, :mean, :max. When prefixed
with ':' use timevalue output format.

Example (I measure speed in min/km):

#+COLUMNS:  %DISTANCE{+;%.1f} %HEARTRATE{mean;%.1f} %MAXHEARTRATE{max} %SPEED{:min} 

Here is the patch:

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: min/mean/max --]
[-- Type: text/x-patch, Size: 5800 bytes --]

diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 377343d..04bfeb0 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -869,12 +869,13 @@ Don't set this, this is meant for dynamic scoping.")
   (interactive)
   (let* ((re (concat "^" outline-regexp))
 	 (lmax 30) ; Does anyone use deeper levels???
-	 (lsum (make-vector lmax 0))
+	 (lvals (make-vector lmax nil))
 	 (lflag (make-vector lmax nil))
 	 (level 0)
 	 (ass (assoc property org-columns-current-fmt-compiled))
 	 (format (nth 4 ass))
 	 (printf (nth 5 ass))
+	 (fun (nth 6 ass))
 	 (beg org-columns-top-level-marker)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
     (save-excursion
@@ -892,7 +893,7 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (aref lsum last-level)   ; current sum
+	  (setq sum (apply fun (aref lvals last-level))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -908,18 +909,18 @@ Don't set this, this is meant for dynamic scoping.")
 	    (org-entry-put nil property (if flag str val)))
 	  ;; add current to current  level accumulator
 	  (when (or flag valflag)
-	    (aset lsum level (+ (aref lsum level)
-				(if flag sum (org-column-string-to-number
-					      (if flag str val) format))))
+	    (push (if flag sum
+		    (org-column-string-to-number (if flag str val) format))
+		  (aref lvals level))
 	    (aset lflag level t))
 	  ;; clear accumulators for deeper levels
 	  (loop for l from (1+ level) to (1- lmax) do
-		(aset lsum l 0)
+		(aset lvals l nil)
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (aset lsum level (+ (aref lsum level)
-			      (org-column-string-to-number (or val "0") format)))
+	  (push (org-column-string-to-number (or val "0") format)
+		(aref lvals level))
 	  (and valflag (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
@@ -990,23 +991,34 @@ Don't set this, this is meant for dynamic scoping.")
     (if (equal s "[X]") 1. 0.000001))
    (t (string-to-number s))))
 
+(defvar org-columns-compile-map
+  '((":"     add_times         +) 
+    ("+"     add_numbers       +) 
+    ("$"     currency          +) 
+    ("X"     checkbox          +) 
+    ("X/"    checkbox-n-of-m   +) 
+    ("X%"    checkbox-percent  +)
+    ("max"   add_numbers       max)               
+    ("min"   add_numbers       min)              
+    ("mean"  add_numbers       (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
+    (":max"  add_times         max)               
+    (":min"  add_times         min)              
+    (":mean" add_times         (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
+  "Operator <-> format,fuction map.")
+
 (defun org-columns-uncompile-format (cfmt)
   "Turn the compiled columns format back into a string representation."
-  (let ((rtn "") e s prop title op width fmt printf)
+  (let ((rtn "") e s prop title op op-match width fmt printf)
     (while (setq e (pop cfmt))
       (setq prop (car e)
 	    title (nth 1 e)
 	    width (nth 2 e)
 	    op (nth 3 e)
 	    fmt (nth 4 e)
-	    printf (nth 5 e))
-      (cond
-       ((eq fmt 'add_times) (setq op ":"))
-       ((eq fmt 'checkbox) (setq op "X"))
-       ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
-       ((eq fmt 'checkbox-percent) (setq op "X%"))
-       ((eq fmt 'add_numbers) (setq op "+"))
-       ((eq fmt 'currency) (setq op "$")))
+	    printf (nth 5 e)
+	    fun (nth 6 e))
+      (when (setq op-match (rassoc (list fmt fun) org-columns-compile-map))
+	(setq op (car op-match)))
       (if (and op printf) (setq op (concat op ";" printf)))
       (if (equal title prop) (setq title nil))
       (setq s (concat "%" (if width (number-to-string width))
@@ -1025,8 +1037,9 @@ title        the title field for the columns
 width        the column width in characters, can be nil for automatic
 operator     the operator if any
 format       the output format for computed results, derived from operator
-printf       a printf format for computed values"
-  (let ((start 0) width prop title op f printf)
+printf       a printf format for computed values
+fun          the lisp function to compute values, derived from operator"
+  (let ((start 0) width prop title op op-match f printf fun)
     (setq org-columns-current-fmt-compiled nil)
     (while (string-match
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
@@ -1037,20 +1050,16 @@ printf       a printf format for computed values"
 	    title (or (match-string 3 fmt) prop)
 	    op (match-string 4 fmt)
 	    f nil
-	    printf nil)
+	    printf nil
+	    fun '+) 
       (if width (setq width (string-to-number width)))
       (when (and op (string-match ";" op))
 	(setq printf (substring op (match-end 0))
 	      op (substring op 0 (match-beginning 0))))
-      (cond
-       ((equal op "+")  (setq f 'add_numbers))
-       ((equal op "$")  (setq f 'currency))
-       ((equal op ":")  (setq f 'add_times))
-       ((equal op "X")  (setq f 'checkbox))
-       ((equal op "X/") (setq f 'checkbox-n-of-m))
-       ((equal op "X%") (setq f 'checkbox-percent))
-       )
-      (push (list prop title width op f printf) org-columns-current-fmt-compiled))
+      (when (setq op-match (assoc op org-columns-compile-map))
+	(setq f (cadr op-match)
+	      fun (caddr op-match)))
+      (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
     (setq org-columns-current-fmt-compiled
 	  (nreverse org-columns-current-fmt-compiled))))
 

[-- Attachment #3: Type: text/plain, Size: 46 bytes --]


Thanks for a great mode!

-- 
Mikael Fornius

[-- Attachment #4: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: colview min/mean/max
  2009-05-20 11:15 colview min/mean/max Mikael Fornius
@ 2009-05-20 13:21 ` Mikael Fornius
  2009-05-20 13:47   ` Carsten Dominik
  0 siblings, 1 reply; 7+ messages in thread
From: Mikael Fornius @ 2009-05-20 13:21 UTC (permalink / raw)
  To: emacs-orgmode


I forgot to make org-columns-edit-attributes be fully comptiable with
new operators so I will fix this and I will make this change for
org-colview-xemacs as well.

Finally update manual and make a new post here.

-- 
Mikael Fornius

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Re: colview min/mean/max
  2009-05-20 13:21 ` Mikael Fornius
@ 2009-05-20 13:47   ` Carsten Dominik
  2009-05-20 22:42     ` Mikael Fornius
  0 siblings, 1 reply; 7+ messages in thread
From: Carsten Dominik @ 2009-05-20 13:47 UTC (permalink / raw)
  To: Mikael Fornius; +Cc: emacs-orgmode


On May 20, 2009, at 3:21 PM, Mikael Fornius wrote:

>
> I forgot to make org-columns-edit-attributes be fully comptiable with
> new operators so I will fix this and I will make this change for
> org-colview-xemacs as well.
>
> Finally update manual and make a new post here.

No hurry, better to get it complete and tested...

:-)

- Carsten

>
> -- 
> Mikael Fornius
>
>
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: colview min/mean/max
  2009-05-20 13:47   ` Carsten Dominik
@ 2009-05-20 22:42     ` Mikael Fornius
  2009-05-21  6:01       ` Carsten Dominik
  0 siblings, 1 reply; 7+ messages in thread
From: Mikael Fornius @ 2009-05-20 22:42 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1567 bytes --]


This is my suggestion of an implementation of min/mean/max computation
in columnview summaries. If you like it feel free to use it.

New operators: {min}, {max} and {mean} possibly prefixed with : for use
with timevalues.

Example from my running exercise diary:

#+COLUMNS: %DISTANCE{+;%.1f} %HEARTRATE{mean;%.1f} %SPEED{:min} %CALORIES{+}

Gives a colview with summaries:

total distance, mean heartrate, fastest speed (min/km) and total
calories.

I have tested it on emacs-23 and it works well for me now, also with the
interactive colview functions.

But you never know really. ;-) Anyway, there should not be any emacs-23
specific elisp code added afik.

(Because I do not use xemacs I have not tested it with xemacs but the
small changes I made should be compitable to both xemacs and emacs. I
would appreciate if someone on this list who uses xemacs will give it a
try for me. Thanks!)

(This fix also opens up for using user defined lisp functions to
calculate colview summaries, but I am not sure if that is something
useful. Like this:

(defun std (&rest values)
  "Compute standard deviation."
  ...)

#+COLUMNS: %DATA{eval:std}

If someone finds this attractive it would now be easy to implement as well.)

doc/org.texi               |    6 +++
lisp/org-colview-xemacs.el |   87 +++++++++++++++++++++++++-------------------
lisp/org-colview.el        |   87 +++++++++++++++++++++++++-------------------
3 files changed, 104 insertions(+), 76 deletions(-)

I have attached four small patches, one for each file changed and the
last one for all changes.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: colview.patch --]
[-- Type: text/x-patch, Size: 7760 bytes --]

diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 377343d..5e2810f 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -698,7 +698,25 @@ around it."
 		(org-columns-display-here (cdr x)))
 	      cache)))))
 
-(defun org-columns-new (&optional prop title width op fmt &rest rest)
+(defvar org-columns-compile-map
+  '(("none"  none              +)
+    (":"     add_times         +) 
+    ("+"     add_numbers       +) 
+    ("$"     currency          +) 
+    ("X"     checkbox          +) 
+    ("X/"    checkbox-n-of-m   +) 
+    ("X%"    checkbox-percent  +)
+    ("max"   max_numbers       max)               
+    ("min"   min_numbers       min)              
+    ("mean"  mean_numbers      (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
+    (":max"  max_times         max)               
+    (":min"  min_times         min)              
+    (":mean" mean_times        (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
+  "Operator <-> format,fuction map.
+Used to compile/uncompile columns format and completing read in
+interactive function org-columns-new.")
+
+(defun org-columns-new (&optional prop title width op fmt fun &rest rest)
   "Insert a new column, to the left of the current column."
   (interactive)
   (let ((editp (and prop (assoc prop org-columns-current-fmt-compiled)))
@@ -712,19 +730,18 @@ around it."
 	(setq width (string-to-number width))
       (setq width nil))
     (setq fmt (org-ido-completing-read "Summary [none]: "
-			       '(("none") ("add_numbers") ("currency") ("add_times") ("checkbox") ("checkbox-n-of-m") ("checkbox-percent"))
-			       nil t))
-    (if (string-match "\\S-" fmt)
-	(setq fmt (intern fmt))
-      (setq fmt nil))
+				       (mapcar (lambda (x) (list (symbol-name (cadr x)))) org-columns-compile-map)
+				       nil t))
+    (setq fmt (intern fmt)
+	  fun (cadr (assoc fmt (mapcar 'cdr org-columns-compile-map))))
     (if (eq fmt 'none) (setq fmt nil))
     (if editp
 	(progn
 	  (setcar editp prop)
-	  (setcdr editp (list title width nil fmt)))
+	  (setcdr editp (list title width nil fmt nil fun)))
       (setq cell (nthcdr (1- (current-column))
 			 org-columns-current-fmt-compiled))
-      (setcdr cell (cons (list prop title width nil fmt)
+      (setcdr cell (cons (list prop title width nil fmt nil fun)
 			 (cdr cell))))
     (org-columns-store-format)
     (org-columns-redo)))
@@ -869,12 +886,13 @@ Don't set this, this is meant for dynamic scoping.")
   (interactive)
   (let* ((re (concat "^" outline-regexp))
 	 (lmax 30) ; Does anyone use deeper levels???
-	 (lsum (make-vector lmax 0))
+	 (lvals (make-vector lmax nil))
 	 (lflag (make-vector lmax nil))
 	 (level 0)
 	 (ass (assoc property org-columns-current-fmt-compiled))
 	 (format (nth 4 ass))
 	 (printf (nth 5 ass))
+	 (fun (nth 6 ass))
 	 (beg org-columns-top-level-marker)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
     (save-excursion
@@ -892,7 +910,7 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (aref lsum last-level)   ; current sum
+	  (setq sum (apply fun (aref lvals last-level))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -908,18 +926,18 @@ Don't set this, this is meant for dynamic scoping.")
 	    (org-entry-put nil property (if flag str val)))
 	  ;; add current to current  level accumulator
 	  (when (or flag valflag)
-	    (aset lsum level (+ (aref lsum level)
-				(if flag sum (org-column-string-to-number
-					      (if flag str val) format))))
+	    (push (if flag sum
+		    (org-column-string-to-number (if flag str val) format))
+		  (aref lvals level))
 	    (aset lflag level t))
 	  ;; clear accumulators for deeper levels
 	  (loop for l from (1+ level) to (1- lmax) do
-		(aset lsum l 0)
+		(aset lvals l nil)
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (aset lsum level (+ (aref lsum level)
-			      (org-column-string-to-number (or val "0") format)))
+	  (push (org-column-string-to-number (or val "0") format)
+		(aref lvals level))
 	  (and valflag (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
@@ -958,7 +976,7 @@ Don't set this, this is meant for dynamic scoping.")
 (defun org-columns-number-to-string (n fmt &optional printf)
   "Convert a computed column number to a string value, according to FMT."
   (cond
-   ((eq fmt 'add_times)
+   ((memq fmt '(add_times max_times min_times mean_times))
     (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
       (format org-time-clocksum-format h m)))
    ((eq fmt 'checkbox)
@@ -992,21 +1010,17 @@ Don't set this, this is meant for dynamic scoping.")
 
 (defun org-columns-uncompile-format (cfmt)
   "Turn the compiled columns format back into a string representation."
-  (let ((rtn "") e s prop title op width fmt printf)
+  (let ((rtn "") e s prop title op op-match width fmt printf)
     (while (setq e (pop cfmt))
       (setq prop (car e)
 	    title (nth 1 e)
 	    width (nth 2 e)
 	    op (nth 3 e)
 	    fmt (nth 4 e)
-	    printf (nth 5 e))
-      (cond
-       ((eq fmt 'add_times) (setq op ":"))
-       ((eq fmt 'checkbox) (setq op "X"))
-       ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
-       ((eq fmt 'checkbox-percent) (setq op "X%"))
-       ((eq fmt 'add_numbers) (setq op "+"))
-       ((eq fmt 'currency) (setq op "$")))
+	    printf (nth 5 e)
+	    fun (nth 6 e))
+      (when (setq op-match (rassoc (list fmt fun) org-columns-compile-map))
+	(setq op (car op-match)))
       (if (and op printf) (setq op (concat op ";" printf)))
       (if (equal title prop) (setq title nil))
       (setq s (concat "%" (if width (number-to-string width))
@@ -1025,8 +1039,9 @@ title        the title field for the columns
 width        the column width in characters, can be nil for automatic
 operator     the operator if any
 format       the output format for computed results, derived from operator
-printf       a printf format for computed values"
-  (let ((start 0) width prop title op f printf)
+printf       a printf format for computed values
+fun          the lisp function to compute values, derived from operator"
+  (let ((start 0) width prop title op op-match f printf fun)
     (setq org-columns-current-fmt-compiled nil)
     (while (string-match
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
@@ -1037,20 +1052,16 @@ printf       a printf format for computed values"
 	    title (or (match-string 3 fmt) prop)
 	    op (match-string 4 fmt)
 	    f nil
-	    printf nil)
+	    printf nil
+	    fun '+) 
       (if width (setq width (string-to-number width)))
       (when (and op (string-match ";" op))
 	(setq printf (substring op (match-end 0))
 	      op (substring op 0 (match-beginning 0))))
-      (cond
-       ((equal op "+")  (setq f 'add_numbers))
-       ((equal op "$")  (setq f 'currency))
-       ((equal op ":")  (setq f 'add_times))
-       ((equal op "X")  (setq f 'checkbox))
-       ((equal op "X/") (setq f 'checkbox-n-of-m))
-       ((equal op "X%") (setq f 'checkbox-percent))
-       )
-      (push (list prop title width op f printf) org-columns-current-fmt-compiled))
+      (when (setq op-match (assoc op org-columns-compile-map))
+	(setq f (cadr op-match)
+	      fun (caddr op-match)))
+      (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
     (setq org-columns-current-fmt-compiled
 	  (nreverse org-columns-current-fmt-compiled))))
 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: colview-xemacs.patch --]
[-- Type: text/x-patch, Size: 7746 bytes --]

diff --git a/lisp/org-colview-xemacs.el b/lisp/org-colview-xemacs.el
index b46ce91..5986d43 100644
--- a/lisp/org-colview-xemacs.el
+++ b/lisp/org-colview-xemacs.el
@@ -880,7 +880,25 @@ around it."
 		(org-columns-display-here (cdr x)))
 	      cache)))))
 
-(defun org-columns-new (&optional prop title width op fmt &rest rest)
+(defvar org-columns-compile-map
+  '(("none"  none              +) 
+    (":"     add_times         +) 
+    ("+"     add_numbers       +) 
+    ("$"     currency          +) 
+    ("X"     checkbox          +) 
+    ("X/"    checkbox-n-of-m   +) 
+    ("X%"    checkbox-percent  +)
+    ("max"   max_numbers       max)               
+    ("min"   min_numbers       min)              
+    ("mean"  mean_numbers      (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
+    (":max"  max_times         max)               
+    (":min"  min_times         min)              
+    (":mean" mean_times        (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
+  "Operator <-> format,fuction map.
+Used to compile/uncompile columns format and completing read in
+interactive function org-columns-new.")
+
+(defun org-columns-new (&optional prop title width op fmt fun &rest rest)
   "Insert a new column, to the left of the current column."
   (interactive)
   (let ((n (org-columns-current-column))
@@ -895,18 +913,17 @@ around it."
 	(setq width (string-to-number width))
       (setq width nil))
     (setq fmt (org-ido-completing-read "Summary [none]: "
-			       '(("none") ("add_numbers") ("currency") ("add_times") ("checkbox") ("checkbox-n-of-m") ("checkbox-percent"))
-			       nil t))
-    (if (string-match "\\S-" fmt)
-	(setq fmt (intern fmt))
-      (setq fmt nil))
+				       (mapcar (lambda (x) (list (symbol-name (cadr x)))) org-columns-compile-map)
+				       nil t))
+    (setq fmt (intern fmt)
+	  fun (cadr (assoc fmt (mapcar 'cdr org-columns-compile-map))))
     (if (eq fmt 'none) (setq fmt nil))
     (if editp
 	(progn
 	  (setcar editp prop)
-	  (setcdr editp (list title width nil fmt)))
+	  (setcdr editp (list title width nil fmt nil fun)))
       (setq cell (nthcdr (1- n) org-columns-current-fmt-compiled))
-      (setcdr cell (cons (list prop title width nil fmt)
+      (setcdr cell (cons (list prop title width nil fmt nil fun)
 			 (cdr cell))))
     (org-columns-store-format)
     (org-columns-redo)))
@@ -1056,12 +1073,13 @@ Don't set this, this is meant for dynamic scoping.")
   (interactive)
   (let* ((re (concat "^" outline-regexp))
 	 (lmax 30) ; Does anyone use deeper levels???
-	 (lsum (make-vector lmax 0))
+	 (lvals (make-vector lmax nil))
 	 (lflag (make-vector lmax nil))
 	 (level 0)
 	 (ass (assoc property org-columns-current-fmt-compiled))
 	 (format (nth 4 ass))
 	 (printf (nth 5 ass))
+	 (fun (nth 6 ass))
 	 (beg org-columns-top-level-marker)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
     (save-excursion
@@ -1079,7 +1097,7 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (aref lsum last-level)   ; current sum
+	  (setq sum (apply fun (aref lvals last-level))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -1095,18 +1113,18 @@ Don't set this, this is meant for dynamic scoping.")
 	    (org-entry-put nil property (if flag str val)))
 	  ;; add current to current  level accumulator
 	  (when (or flag valflag)
-	    (aset lsum level (+ (aref lsum level)
-				(if flag sum (org-column-string-to-number
-					      (if flag str val) format))))
+	    (push (if flag sum
+		    (org-column-string-to-number (if flag str val) format))
+		  (aref lvals level))
 	    (aset lflag level t))
 	  ;; clear accumulators for deeper levels
 	  (loop for l from (1+ level) to (1- lmax) do
-		(aset lsum l 0)
+		(aset lvals l nil)
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (aset lsum level (+ (aref lsum level)
-			      (org-column-string-to-number (or val "0") format)))
+	  (push (org-column-string-to-number (or val "0") format)
+		(aref lvals level))
 	  (and valflag (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
@@ -1145,7 +1163,7 @@ Don't set this, this is meant for dynamic scoping.")
 (defun org-columns-number-to-string (n fmt &optional printf)
   "Convert a computed column number to a string value, according to FMT."
   (cond
-   ((eq fmt 'add_times)
+   ((memq fmt '(add_times max_times min_times mean_times))
     (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
       (format org-time-clocksum-format h m)))
    ((eq fmt 'checkbox)
@@ -1179,21 +1197,17 @@ Don't set this, this is meant for dynamic scoping.")
 
 (defun org-columns-uncompile-format (cfmt)
   "Turn the compiled columns format back into a string representation."
-  (let ((rtn "") e s prop title op width fmt printf)
+  (let ((rtn "") e s prop title op op-match width fmt printf)
     (while (setq e (pop cfmt))
       (setq prop (car e)
 	    title (nth 1 e)
 	    width (nth 2 e)
 	    op (nth 3 e)
 	    fmt (nth 4 e)
-	    printf (nth 5 e))
-      (cond
-       ((eq fmt 'add_times) (setq op ":"))
-       ((eq fmt 'checkbox) (setq op "X"))
-       ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
-       ((eq fmt 'checkbox-percent) (setq op "X%"))
-       ((eq fmt 'add_numbers) (setq op "+"))
-       ((eq fmt 'currency) (setq op "$")))
+	    printf (nth 5 e)
+	    fun (nth 6 e))
+      (when (setq op-match (rassoc (list fmt fun) org-columns-compile-map))
+	(setq op (car op-match)))
       (if (and op printf) (setq op (concat op ";" printf)))
       (if (equal title prop) (setq title nil))
       (setq s (concat "%" (if width (number-to-string width))
@@ -1212,8 +1226,9 @@ title        the title field for the columns
 width        the column width in characters, can be nil for automatic
 operator     the operator if any
 format       the output format for computed results, derived from operator
-printf       a printf format for computed values"
-  (let ((start 0) width prop title op f printf)
+printf       a printf format for computed values
+fun          the lisp function to compute values, derived from operator"
+  (let ((start 0) width prop title op op-match f printf fun)
     (setq org-columns-current-fmt-compiled nil)
     (while (string-match
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
@@ -1224,20 +1239,16 @@ printf       a printf format for computed values"
 	    title (or (match-string 3 fmt) prop)
 	    op (match-string 4 fmt)
 	    f nil
-	    printf nil)
+	    printf nil
+	    fun '+) 
       (if width (setq width (string-to-number width)))
       (when (and op (string-match ";" op))
 	(setq printf (substring op (match-end 0))
 	      op (substring op 0 (match-beginning 0))))
-      (cond
-       ((equal op "+")  (setq f 'add_numbers))
-       ((equal op "$")  (setq f 'currency))
-       ((equal op ":")  (setq f 'add_times))
-       ((equal op "X")  (setq f 'checkbox))
-       ((equal op "X/") (setq f 'checkbox-n-of-m))
-       ((equal op "X%") (setq f 'checkbox-percent))
-       )
-      (push (list prop title width op f printf) org-columns-current-fmt-compiled))
+      (when (setq op-match (assoc op org-columns-compile-map))
+	(setq f (cadr op-match)
+	      fun (caddr op-match)))
+      (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
     (setq org-columns-current-fmt-compiled
 	  (nreverse org-columns-current-fmt-compiled))))
 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: org-texi.patch --]
[-- Type: text/x-patch, Size: 774 bytes --]

diff --git a/doc/org.texi b/doc/org.texi
index de5b507..5568dee 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -4444,6 +4444,12 @@ property        @r{The property that should be edited in this column.}
                 @{X@}       @r{Checkbox status, [X] if all children are [X].}
                 @{X/@}      @r{Checkbox status, [n/m].}
                 @{X%@}      @r{Checkbox status, [n%].}
+                @{min@}     @r{Smallest number in column.}
+                @{max@}     @r{Largest number.}
+                @{mean@}    @r{Arithmetic mean of numbers.}
+                @{:min@}    @r{Smallest time value in column.}
+                @{:max@}    @r{Largest time value.}
+                @{:mean@}   @r{Arithmetic mean of time values.}
 @end example
 
 @noindent

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: colview-full.patch --]
[-- Type: text/x-patch, Size: 16280 bytes --]

diff --git a/doc/org.texi b/doc/org.texi
index de5b507..5568dee 100644
--- a/doc/org.texi
+++ b/doc/org.texi
@@ -4444,6 +4444,12 @@ property        @r{The property that should be edited in this column.}
                 @{X@}       @r{Checkbox status, [X] if all children are [X].}
                 @{X/@}      @r{Checkbox status, [n/m].}
                 @{X%@}      @r{Checkbox status, [n%].}
+                @{min@}     @r{Smallest number in column.}
+                @{max@}     @r{Largest number.}
+                @{mean@}    @r{Arithmetic mean of numbers.}
+                @{:min@}    @r{Smallest time value in column.}
+                @{:max@}    @r{Largest time value.}
+                @{:mean@}   @r{Arithmetic mean of time values.}
 @end example
 
 @noindent
diff --git a/lisp/org-colview-xemacs.el b/lisp/org-colview-xemacs.el
index b46ce91..5986d43 100644
--- a/lisp/org-colview-xemacs.el
+++ b/lisp/org-colview-xemacs.el
@@ -880,7 +880,25 @@ around it."
 		(org-columns-display-here (cdr x)))
 	      cache)))))
 
-(defun org-columns-new (&optional prop title width op fmt &rest rest)
+(defvar org-columns-compile-map
+  '(("none"  none              +) 
+    (":"     add_times         +) 
+    ("+"     add_numbers       +) 
+    ("$"     currency          +) 
+    ("X"     checkbox          +) 
+    ("X/"    checkbox-n-of-m   +) 
+    ("X%"    checkbox-percent  +)
+    ("max"   max_numbers       max)               
+    ("min"   min_numbers       min)              
+    ("mean"  mean_numbers      (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
+    (":max"  max_times         max)               
+    (":min"  min_times         min)              
+    (":mean" mean_times        (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
+  "Operator <-> format,fuction map.
+Used to compile/uncompile columns format and completing read in
+interactive function org-columns-new.")
+
+(defun org-columns-new (&optional prop title width op fmt fun &rest rest)
   "Insert a new column, to the left of the current column."
   (interactive)
   (let ((n (org-columns-current-column))
@@ -895,18 +913,17 @@ around it."
 	(setq width (string-to-number width))
       (setq width nil))
     (setq fmt (org-ido-completing-read "Summary [none]: "
-			       '(("none") ("add_numbers") ("currency") ("add_times") ("checkbox") ("checkbox-n-of-m") ("checkbox-percent"))
-			       nil t))
-    (if (string-match "\\S-" fmt)
-	(setq fmt (intern fmt))
-      (setq fmt nil))
+				       (mapcar (lambda (x) (list (symbol-name (cadr x)))) org-columns-compile-map)
+				       nil t))
+    (setq fmt (intern fmt)
+	  fun (cadr (assoc fmt (mapcar 'cdr org-columns-compile-map))))
     (if (eq fmt 'none) (setq fmt nil))
     (if editp
 	(progn
 	  (setcar editp prop)
-	  (setcdr editp (list title width nil fmt)))
+	  (setcdr editp (list title width nil fmt nil fun)))
       (setq cell (nthcdr (1- n) org-columns-current-fmt-compiled))
-      (setcdr cell (cons (list prop title width nil fmt)
+      (setcdr cell (cons (list prop title width nil fmt nil fun)
 			 (cdr cell))))
     (org-columns-store-format)
     (org-columns-redo)))
@@ -1056,12 +1073,13 @@ Don't set this, this is meant for dynamic scoping.")
   (interactive)
   (let* ((re (concat "^" outline-regexp))
 	 (lmax 30) ; Does anyone use deeper levels???
-	 (lsum (make-vector lmax 0))
+	 (lvals (make-vector lmax nil))
 	 (lflag (make-vector lmax nil))
 	 (level 0)
 	 (ass (assoc property org-columns-current-fmt-compiled))
 	 (format (nth 4 ass))
 	 (printf (nth 5 ass))
+	 (fun (nth 6 ass))
 	 (beg org-columns-top-level-marker)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
     (save-excursion
@@ -1079,7 +1097,7 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (aref lsum last-level)   ; current sum
+	  (setq sum (apply fun (aref lvals last-level))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -1095,18 +1113,18 @@ Don't set this, this is meant for dynamic scoping.")
 	    (org-entry-put nil property (if flag str val)))
 	  ;; add current to current  level accumulator
 	  (when (or flag valflag)
-	    (aset lsum level (+ (aref lsum level)
-				(if flag sum (org-column-string-to-number
-					      (if flag str val) format))))
+	    (push (if flag sum
+		    (org-column-string-to-number (if flag str val) format))
+		  (aref lvals level))
 	    (aset lflag level t))
 	  ;; clear accumulators for deeper levels
 	  (loop for l from (1+ level) to (1- lmax) do
-		(aset lsum l 0)
+		(aset lvals l nil)
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (aset lsum level (+ (aref lsum level)
-			      (org-column-string-to-number (or val "0") format)))
+	  (push (org-column-string-to-number (or val "0") format)
+		(aref lvals level))
 	  (and valflag (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
@@ -1145,7 +1163,7 @@ Don't set this, this is meant for dynamic scoping.")
 (defun org-columns-number-to-string (n fmt &optional printf)
   "Convert a computed column number to a string value, according to FMT."
   (cond
-   ((eq fmt 'add_times)
+   ((memq fmt '(add_times max_times min_times mean_times))
     (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
       (format org-time-clocksum-format h m)))
    ((eq fmt 'checkbox)
@@ -1179,21 +1197,17 @@ Don't set this, this is meant for dynamic scoping.")
 
 (defun org-columns-uncompile-format (cfmt)
   "Turn the compiled columns format back into a string representation."
-  (let ((rtn "") e s prop title op width fmt printf)
+  (let ((rtn "") e s prop title op op-match width fmt printf)
     (while (setq e (pop cfmt))
       (setq prop (car e)
 	    title (nth 1 e)
 	    width (nth 2 e)
 	    op (nth 3 e)
 	    fmt (nth 4 e)
-	    printf (nth 5 e))
-      (cond
-       ((eq fmt 'add_times) (setq op ":"))
-       ((eq fmt 'checkbox) (setq op "X"))
-       ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
-       ((eq fmt 'checkbox-percent) (setq op "X%"))
-       ((eq fmt 'add_numbers) (setq op "+"))
-       ((eq fmt 'currency) (setq op "$")))
+	    printf (nth 5 e)
+	    fun (nth 6 e))
+      (when (setq op-match (rassoc (list fmt fun) org-columns-compile-map))
+	(setq op (car op-match)))
       (if (and op printf) (setq op (concat op ";" printf)))
       (if (equal title prop) (setq title nil))
       (setq s (concat "%" (if width (number-to-string width))
@@ -1212,8 +1226,9 @@ title        the title field for the columns
 width        the column width in characters, can be nil for automatic
 operator     the operator if any
 format       the output format for computed results, derived from operator
-printf       a printf format for computed values"
-  (let ((start 0) width prop title op f printf)
+printf       a printf format for computed values
+fun          the lisp function to compute values, derived from operator"
+  (let ((start 0) width prop title op op-match f printf fun)
     (setq org-columns-current-fmt-compiled nil)
     (while (string-match
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
@@ -1224,20 +1239,16 @@ printf       a printf format for computed values"
 	    title (or (match-string 3 fmt) prop)
 	    op (match-string 4 fmt)
 	    f nil
-	    printf nil)
+	    printf nil
+	    fun '+) 
       (if width (setq width (string-to-number width)))
       (when (and op (string-match ";" op))
 	(setq printf (substring op (match-end 0))
 	      op (substring op 0 (match-beginning 0))))
-      (cond
-       ((equal op "+")  (setq f 'add_numbers))
-       ((equal op "$")  (setq f 'currency))
-       ((equal op ":")  (setq f 'add_times))
-       ((equal op "X")  (setq f 'checkbox))
-       ((equal op "X/") (setq f 'checkbox-n-of-m))
-       ((equal op "X%") (setq f 'checkbox-percent))
-       )
-      (push (list prop title width op f printf) org-columns-current-fmt-compiled))
+      (when (setq op-match (assoc op org-columns-compile-map))
+	(setq f (cadr op-match)
+	      fun (caddr op-match)))
+      (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
     (setq org-columns-current-fmt-compiled
 	  (nreverse org-columns-current-fmt-compiled))))
 
diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 377343d..5e2810f 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -698,7 +698,25 @@ around it."
 		(org-columns-display-here (cdr x)))
 	      cache)))))
 
-(defun org-columns-new (&optional prop title width op fmt &rest rest)
+(defvar org-columns-compile-map
+  '(("none"  none              +)
+    (":"     add_times         +) 
+    ("+"     add_numbers       +) 
+    ("$"     currency          +) 
+    ("X"     checkbox          +) 
+    ("X/"    checkbox-n-of-m   +) 
+    ("X%"    checkbox-percent  +)
+    ("max"   max_numbers       max)               
+    ("min"   min_numbers       min)              
+    ("mean"  mean_numbers      (lambda (&rest x) (/ (apply '+ x) (float (length x)))))
+    (":max"  max_times         max)               
+    (":min"  min_times         min)              
+    (":mean" mean_times        (lambda (&rest x) (/ (apply '+ x) (float (length x))))))
+  "Operator <-> format,fuction map.
+Used to compile/uncompile columns format and completing read in
+interactive function org-columns-new.")
+
+(defun org-columns-new (&optional prop title width op fmt fun &rest rest)
   "Insert a new column, to the left of the current column."
   (interactive)
   (let ((editp (and prop (assoc prop org-columns-current-fmt-compiled)))
@@ -712,19 +730,18 @@ around it."
 	(setq width (string-to-number width))
       (setq width nil))
     (setq fmt (org-ido-completing-read "Summary [none]: "
-			       '(("none") ("add_numbers") ("currency") ("add_times") ("checkbox") ("checkbox-n-of-m") ("checkbox-percent"))
-			       nil t))
-    (if (string-match "\\S-" fmt)
-	(setq fmt (intern fmt))
-      (setq fmt nil))
+				       (mapcar (lambda (x) (list (symbol-name (cadr x)))) org-columns-compile-map)
+				       nil t))
+    (setq fmt (intern fmt)
+	  fun (cadr (assoc fmt (mapcar 'cdr org-columns-compile-map))))
     (if (eq fmt 'none) (setq fmt nil))
     (if editp
 	(progn
 	  (setcar editp prop)
-	  (setcdr editp (list title width nil fmt)))
+	  (setcdr editp (list title width nil fmt nil fun)))
       (setq cell (nthcdr (1- (current-column))
 			 org-columns-current-fmt-compiled))
-      (setcdr cell (cons (list prop title width nil fmt)
+      (setcdr cell (cons (list prop title width nil fmt nil fun)
 			 (cdr cell))))
     (org-columns-store-format)
     (org-columns-redo)))
@@ -869,12 +886,13 @@ Don't set this, this is meant for dynamic scoping.")
   (interactive)
   (let* ((re (concat "^" outline-regexp))
 	 (lmax 30) ; Does anyone use deeper levels???
-	 (lsum (make-vector lmax 0))
+	 (lvals (make-vector lmax nil))
 	 (lflag (make-vector lmax nil))
 	 (level 0)
 	 (ass (assoc property org-columns-current-fmt-compiled))
 	 (format (nth 4 ass))
 	 (printf (nth 5 ass))
+	 (fun (nth 6 ass))
 	 (beg org-columns-top-level-marker)
 	 last-level val valflag flag end sumpos sum-alist sum str str1 useval)
     (save-excursion
@@ -892,7 +910,7 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (aref lsum last-level)   ; current sum
+	  (setq sum (apply fun (aref lvals last-level))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -908,18 +926,18 @@ Don't set this, this is meant for dynamic scoping.")
 	    (org-entry-put nil property (if flag str val)))
 	  ;; add current to current  level accumulator
 	  (when (or flag valflag)
-	    (aset lsum level (+ (aref lsum level)
-				(if flag sum (org-column-string-to-number
-					      (if flag str val) format))))
+	    (push (if flag sum
+		    (org-column-string-to-number (if flag str val) format))
+		  (aref lvals level))
 	    (aset lflag level t))
 	  ;; clear accumulators for deeper levels
 	  (loop for l from (1+ level) to (1- lmax) do
-		(aset lsum l 0)
+		(aset lvals l nil)
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (aset lsum level (+ (aref lsum level)
-			      (org-column-string-to-number (or val "0") format)))
+	  (push (org-column-string-to-number (or val "0") format)
+		(aref lvals level))
 	  (and valflag (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
@@ -958,7 +976,7 @@ Don't set this, this is meant for dynamic scoping.")
 (defun org-columns-number-to-string (n fmt &optional printf)
   "Convert a computed column number to a string value, according to FMT."
   (cond
-   ((eq fmt 'add_times)
+   ((memq fmt '(add_times max_times min_times mean_times))
     (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
       (format org-time-clocksum-format h m)))
    ((eq fmt 'checkbox)
@@ -992,21 +1010,17 @@ Don't set this, this is meant for dynamic scoping.")
 
 (defun org-columns-uncompile-format (cfmt)
   "Turn the compiled columns format back into a string representation."
-  (let ((rtn "") e s prop title op width fmt printf)
+  (let ((rtn "") e s prop title op op-match width fmt printf)
     (while (setq e (pop cfmt))
       (setq prop (car e)
 	    title (nth 1 e)
 	    width (nth 2 e)
 	    op (nth 3 e)
 	    fmt (nth 4 e)
-	    printf (nth 5 e))
-      (cond
-       ((eq fmt 'add_times) (setq op ":"))
-       ((eq fmt 'checkbox) (setq op "X"))
-       ((eq fmt 'checkbox-n-of-m) (setq op "X/"))
-       ((eq fmt 'checkbox-percent) (setq op "X%"))
-       ((eq fmt 'add_numbers) (setq op "+"))
-       ((eq fmt 'currency) (setq op "$")))
+	    printf (nth 5 e)
+	    fun (nth 6 e))
+      (when (setq op-match (rassoc (list fmt fun) org-columns-compile-map))
+	(setq op (car op-match)))
       (if (and op printf) (setq op (concat op ";" printf)))
       (if (equal title prop) (setq title nil))
       (setq s (concat "%" (if width (number-to-string width))
@@ -1025,8 +1039,9 @@ title        the title field for the columns
 width        the column width in characters, can be nil for automatic
 operator     the operator if any
 format       the output format for computed results, derived from operator
-printf       a printf format for computed values"
-  (let ((start 0) width prop title op f printf)
+printf       a printf format for computed values
+fun          the lisp function to compute values, derived from operator"
+  (let ((start 0) width prop title op op-match f printf fun)
     (setq org-columns-current-fmt-compiled nil)
     (while (string-match
 	    (org-re "%\\([0-9]+\\)?\\([[:alnum:]_-]+\\)\\(?:(\\([^)]+\\))\\)?\\(?:{\\([^}]+\\)}\\)?\\s-*")
@@ -1037,20 +1052,16 @@ printf       a printf format for computed values"
 	    title (or (match-string 3 fmt) prop)
 	    op (match-string 4 fmt)
 	    f nil
-	    printf nil)
+	    printf nil
+	    fun '+) 
       (if width (setq width (string-to-number width)))
       (when (and op (string-match ";" op))
 	(setq printf (substring op (match-end 0))
 	      op (substring op 0 (match-beginning 0))))
-      (cond
-       ((equal op "+")  (setq f 'add_numbers))
-       ((equal op "$")  (setq f 'currency))
-       ((equal op ":")  (setq f 'add_times))
-       ((equal op "X")  (setq f 'checkbox))
-       ((equal op "X/") (setq f 'checkbox-n-of-m))
-       ((equal op "X%") (setq f 'checkbox-percent))
-       )
-      (push (list prop title width op f printf) org-columns-current-fmt-compiled))
+      (when (setq op-match (assoc op org-columns-compile-map))
+	(setq f (cadr op-match)
+	      fun (caddr op-match)))
+      (push (list prop title width op f printf fun) org-columns-current-fmt-compiled))
     (setq org-columns-current-fmt-compiled
 	  (nreverse org-columns-current-fmt-compiled))))
 

[-- Attachment #6: Type: text/plain, Size: 76 bytes --]


I hope this will be useful.


Org-mode is a great mode!

--
Mikael Fornius

[-- Attachment #7: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: Re: colview min/mean/max
  2009-05-20 22:42     ` Mikael Fornius
@ 2009-05-21  6:01       ` Carsten Dominik
  2009-05-21  7:23         ` Mikael Fornius
  0 siblings, 1 reply; 7+ messages in thread
From: Carsten Dominik @ 2009-05-21  6:01 UTC (permalink / raw)
  To: Mikael Fornius; +Cc: emacs-orgmode

Hi Mikael,

I have applied this patch, thank you for your contribution!

- Carsten

On May 21, 2009, at 12:42 AM, Mikael Fornius wrote:

>
> This is my suggestion of an implementation of min/mean/max computation
> in columnview summaries. If you like it feel free to use it.
>
> New operators: {min}, {max} and {mean} possibly prefixed with : for  
> use
> with timevalues.
>
> Example from my running exercise diary:
>
> #+COLUMNS: %DISTANCE{+;%.1f} %HEARTRATE{mean;%.1f} %SPEED{:min}  
> %CALORIES{+}
>
> Gives a colview with summaries:
>
> total distance, mean heartrate, fastest speed (min/km) and total
> calories.
>
> I have tested it on emacs-23 and it works well for me now, also with  
> the
> interactive colview functions.
>
> But you never know really. ;-) Anyway, there should not be any  
> emacs-23
> specific elisp code added afik.
>
> (Because I do not use xemacs I have not tested it with xemacs but the
> small changes I made should be compitable to both xemacs and emacs. I
> would appreciate if someone on this list who uses xemacs will give  
> it a
> try for me. Thanks!)
>
> (This fix also opens up for using user defined lisp functions to
> calculate colview summaries, but I am not sure if that is something
> useful. Like this:
>
> (defun std (&rest values)
>  "Compute standard deviation."
>  ...)
>
> #+COLUMNS: %DATA{eval:std}
>
> If someone finds this attractive it would now be easy to implement  
> as well.)
>
> doc/org.texi               |    6 +++
> lisp/org-colview-xemacs.el |   87 ++++++++++++++++++++++++ 
> +-------------------
> lisp/org-colview.el        |   87 ++++++++++++++++++++++++ 
> +-------------------
> 3 files changed, 104 insertions(+), 76 deletions(-)
>
> I have attached four small patches, one for each file changed and the
> last one for all changes.
>
> <colview.patch><colview-xemacs.patch><org-texi.patch><colview- 
> full.patch>
> I hope this will be useful.
>
>
> Org-mode is a great mode!
>
> --
> Mikael Fornius
> _______________________________________________
> Emacs-orgmode mailing list
> Remember: use `Reply All' to send replies to the list.
> Emacs-orgmode@gnu.org
> http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: colview min/mean/max
  2009-05-21  6:01       ` Carsten Dominik
@ 2009-05-21  7:23         ` Mikael Fornius
  2009-05-21  8:48           ` Carsten Dominik
  0 siblings, 1 reply; 7+ messages in thread
From: Mikael Fornius @ 2009-05-21  7:23 UTC (permalink / raw)
  To: Carsten Dominik; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 599 bytes --]

Carsten Dominik <carsten.dominik@gmail.com> writes:

> I have applied this patch, thank you for your contribution!

My pleasure.

> No hurry, better to get it complete and tested...

> :-)

I should have read this advice more carefully :-)

Because before, when only sums where calculated as summaries, 0 was
placed instead of empty or non numeric properties.

This makes calcualtions wrong with min/mean/max operators.

I only use complete tables so I did not notice this before now.

So I have changed this behavior to ignore empty properties and also
hanlde cases when all properties are wrong.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-empty-properties.patch --]
[-- Type: text/x-patch, Size: 3106 bytes --]

diff --git a/lisp/org-colview-xemacs.el b/lisp/org-colview-xemacs.el
index 5986d43..c63d906 100644
--- a/lisp/org-colview-xemacs.el
+++ b/lisp/org-colview-xemacs.el
@@ -1097,7 +1097,8 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (apply fun (aref lvals last-level))
+	  (setq sum (when (aref lvals last-level)
+		      (apply fun (aref lvals last-level)))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -1123,9 +1124,10 @@ Don't set this, this is meant for dynamic scoping.")
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (push (org-column-string-to-number (or val "0") format)
+	  (when valflag
+	    (push (org-column-string-to-number val format)
 		(aref lvals level))
-	  (and valflag (aset lflag level t)))
+	    (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
 (defun org-columns-redo ()
@@ -1163,6 +1165,7 @@ Don't set this, this is meant for dynamic scoping.")
 (defun org-columns-number-to-string (n fmt &optional printf)
   "Convert a computed column number to a string value, according to FMT."
   (cond
+   ((not (numberp n)) "")
    ((memq fmt '(add_times max_times min_times mean_times))
     (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
       (format org-time-clocksum-format h m)))
diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 5e2810f..cd9ea2b 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -910,7 +910,8 @@ Don't set this, this is meant for dynamic scoping.")
 	(cond
 	 ((< level last-level)
 	  ;; put the sum of lower levels here as a property
-	  (setq sum (apply fun (aref lvals last-level))
+	  (setq sum (when (aref lvals last-level)
+		      (apply fun (aref lvals last-level)))
 		flag (aref lflag last-level) ; any valid entries from children?
 		str (org-columns-number-to-string sum format printf)
 		str1 (org-add-props (copy-sequence str) nil 'org-computed t 'face 'bold)
@@ -936,9 +937,10 @@ Don't set this, this is meant for dynamic scoping.")
 		(aset lflag l nil)))
 	 ((>= level last-level)
 	  ;; add what we have here to the accumulator for this level
-	  (push (org-column-string-to-number (or val "0") format)
+	  (when valflag
+	    (push (org-column-string-to-number val format)
 		(aref lvals level))
-	  (and valflag (aset lflag level t)))
+	    (aset lflag level t)))
 	 (t (error "This should not happen")))))))
 
 (defun org-columns-redo ()
@@ -976,6 +978,7 @@ Don't set this, this is meant for dynamic scoping.")
 (defun org-columns-number-to-string (n fmt &optional printf)
   "Convert a computed column number to a string value, according to FMT."
   (cond
+   ((not (numberp n)) "")
    ((memq fmt '(add_times max_times min_times mean_times))
     (let* ((h (floor n)) (m (floor (+ 0.5 (* 60 (- n h))))))
       (format org-time-clocksum-format h m)))

[-- Attachment #3: Type: text/plain, Size: 21 bytes --]



-- 
Mikael Fornius

[-- Attachment #4: Type: text/plain, Size: 204 bytes --]

_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: colview min/mean/max
  2009-05-21  7:23         ` Mikael Fornius
@ 2009-05-21  8:48           ` Carsten Dominik
  0 siblings, 0 replies; 7+ messages in thread
From: Carsten Dominik @ 2009-05-21  8:48 UTC (permalink / raw)
  To: Mikael Fornius; +Cc: emacs-orgmode


On May 21, 2009, at 9:23 AM, Mikael Fornius wrote:

> Carsten Dominik <carsten.dominik@gmail.com> writes:
>
>> I have applied this patch, thank you for your contribution!
>
> My pleasure.
>
>> No hurry, better to get it complete and tested...
>
>> :-)
>
> I should have read this advice more carefully :-)

:-)

Applied, thanks.

- Carsten

>
> Because before, when only sums where calculated as summaries, 0 was
> placed instead of empty or non numeric properties.
>
> This makes calcualtions wrong with min/mean/max operators.
>
> I only use complete tables so I did not notice this before now.
>
> So I have changed this behavior to ignore empty properties and also
> hanlde cases when all properties are wrong.
>
> <fix-empty-properties.patch>
>
> -- 
> Mikael Fornius

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-05-21  8:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-20 11:15 colview min/mean/max Mikael Fornius
2009-05-20 13:21 ` Mikael Fornius
2009-05-20 13:47   ` Carsten Dominik
2009-05-20 22:42     ` Mikael Fornius
2009-05-21  6:01       ` Carsten Dominik
2009-05-21  7:23         ` Mikael Fornius
2009-05-21  8:48           ` Carsten Dominik

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).