@Juancho gave a great answer to a question I asked a few days ago. My question is about how to modify his elisp code.
I have an org
table
#+begin_src emacs-lisp :results none
(defun jj/factor (code)
(cond ((eq (string-to-char code) ?P) .05)
(t 0)))
(defun jj/factorlist (codelist)
(mapcar 'jj/factor codelist))
(defun jj/dotproduct (a b)
(apply '+ (mapcar* '* (jj/factorlist a) (mapcar 'string-to-number b))))
#+end_src
| | | P1 | P2 | Q1 | Q2 | E1 | E2 | F |
|--------+--------+------+------+------+------+------+------+------|
| | Totals | 20 | 40 | 50 | 45 | 100 | 100 | 200 |
|--------+--------+------+------+------+------+------+------+------|
| John | 0.10 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| Paul | 1.00 | 10 | 10 | 10 | 10 | 10 | 10 | 10 |
| George | 10.00 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Ringo | 100.00 | 1000 | 1000 | 1000 | 1000 | 1000 | 1000 | 1000 |
#+TBLFM: @3$2..@>$2='(jj/dotproduct (list @1$3..@1$>) (list $3..$>));%.2f
The function jj/dotproduct
takes the entries in the columns marked P
, multiplies them by .05
, and adds them up in the column marked Totals
.
Now, I'd like to modify jj/dotproduct
so it takes another input x
where x
any letter. This would allow me to sum the columns marked Q
, E
, and F
separately. I've tried modifying it as follows
#+begin_src emacs-lisp :results none
(defun jj/factor (code x)
(cond ((eq (string-to-char code) (string-to-char x)) .05)
(t 0)))
(defun jj/factorlist (codelist x)
(mapcar 'jj/factor codelist x))
(defun jj/dotproduct (x a b)
(apply '+ (mapcar* '* (jj/factorlist a x) (mapcar 'string-to-number b))))
#+end_src
| | | P1 | P2 | Q1 | Q2 | E1 | E2 | F |
|--------+--------+------+------+------+------+------+------+------|
| | Totals | 20 | 40 | 50 | 45 | 100 | 100 | 200 |
|--------+--------+------+------+------+------+------+------+------|
| John | 0.00 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| Paul | 0.00 | 10 | 10 | 10 | 10 | 10 | 10 | 10 |
| George | 0.00 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Ringo | 0.00 | 1000 | 1000 | 1000 | 1000 | 1000 | 1000 | 1000 |
#+TBLFM: @3$2..@>$2='(jj/dotproduct "P" (list @1$3..@1$>) (list $3..$>));%.2f
This, however, gives the wrong output. Any ideas what I've done wrong and how I can fix my code?
C-h f mapcar
. It takes two arguments -- a function and a sequence. You're now trying to pass it an additional argument, which it can't use.(mapcar 'jj/factor codelist x)
.cl-mapcar
takes arbitrary many lists (that's also the behavior of Common Lispmapcar
).