funlib.lsp - my function's library

For the Compleat Fan
Locked
Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

funlib.lsp - my function's library

Post by Dmi »

I decide to publish my library with the functions I found useful.
http://en.feautec.pp.ru/SiteNews/funlib_lsp
renewed versions of "dofile" and "rawk", list grouping and other small stuff...
WBR, Dmi

Fanda
Posts: 253
Joined: Tue Aug 02, 2005 6:40 am
Contact:

Post by Fanda »

It could be nice to have the 'lesser' and 'greater' functions on a system level. I have seen that somebody has it as '--' and '++'.
It improves readability and also it could be faster because we pass only 1 parameter (++ x), not two (+ x 1).

Something like this:
(+ 1 (rand (- (factorial len) 1)))

Would look like this:
(++ (rand (-- (factorial len))))

Lutz, how do you like it?

----------------

'group' on a system level would be nice too :-))
Jeremy Dunn proposed: (group lst n bool)

Code: Select all

;; This function performs a multiple slice on a given list
;; One supplies a list and an integer n. The list is broken into a list of sublists of
;; length n. If n is negative the list items are collected going from the end of the list
;; to the beginning. If the optional bool argument is supplied then remaining elements are
;; included in the result.
;; (group '(1 2 3 4 5 6 7) 3)       -> ((1 2 3)(4 5 6))
;; (group '(1 2 3 4 5 6 7) 3 true)  -> ((1 2 3)(4 5 6)(7))
;; (group '(1 2 3 4 5 6 7) -3 true) -> ((1)(2 3 4)(5 6 7))
(define (group lst n bool , len num rep rem start)
  (setq num (abs n))
  (if (< n 0)
      (reverse (map reverse (group (reverse lst) num bool)))
      (= n 0)
      nil
      (begin
        (setq len   (length lst)
              rep   (/ len num)
              rem   (% len num)
              start '()
        )
        (if (< num len)
            (begin
              (dotimes (x rep)
                (setq start (cons (slice lst (* x num) num) start)))
              (if (and bool (> rem 0))
                  (setq start (cons (slice lst (* num rep) rem) start)))
              (reverse start))
            (list lst))))) 
taken from here:
http://www.alh.net/newlisp/phpbb/viewtopic.php?t=765

---------------------

Dmi: Could you please give me an example for 'group-by'? Thank you!

Fanda

Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

Post by Dmi »

group-by works like this:
call-log is (date time duration client)
...and I slightly format the console output

Code: Select all

> call-log
((2005 10 1 9 4 20 1 "User1")
 (2005 10 1 17 5 31 19 "Kassa3")
 (2005 10 1 18 15 44 13 "Kassa6") 
 (2005 10 2 12 9 55 2 "Kassa6") 
 (2005 10 2 14 58 44 5 "Kassa6") 

 (2005 10 2 17 17 47 2 "User2") 
 (2005 10 2 17 19 28 3 "User2") 
 (2005 10 2 17 52 45 3 "User1")) 
> (group-by call-log '(-1) '(0 1 2 3 4 5 6))
((("User2") ((2005 10 2 17 17 47 2) (2005 10 2 17 19 28 3)))
 (("Kassa6") ((2005 10 1 18 15 44 13)
              (2005 10 2 12 9 55 2)
              (2005 10 2 14 58 44 5))) 
 (("Kassa3") ((2005 10 1 17 5 31 19))) 
 (("User1") ((2005 10 1 9 4 20 1) (2005 10 2 17 52 45 3)))) 
> (group-by call-log '(0 1 2 3) '(6 7))
(((2005 10 2 17) ((2 "User2") (3 "User2") (3 "User1")))
 ((2005 10 2 14) ((5 "Kassa6"))) 
 ((2005 10 2 12) ((2 "Kassa6"))) 
 ((2005 10 1 18) ((13 "Kassa6"))) 
 ((2005 10 1 17) ((19 "Kassa3"))) 
 ((2005 10 1 9) ((1 "User1")))) 
So, for my 'call-log' list, I can to group by client, or by day+hour, or whatever else...
Next, having the grouped list, I can get a complex statistics by any parameter.
If base list have a complex structure, for ex.:
(((year month day) (hour min sec) duration client)......)
then I can simply use 'map' to preprocess it like this:
(group-by (map (fn (x) (append (x 0) (x 1) x)) call-log) '(0 1 2 3) (-2 -1))
(modification of the last example)
WBR, Dmi

Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

Bugfixed version issued

Post by Dmi »

'dofile' function is now havy tested in a real life.
Bugfixed and compatible with newlisp 8.7.0 or greater.

Improved 'group':
care about group length may not be greater than list length
can group from the end if group length is negative

Introduced 'group-all' - like a 'group' but not truncates the rest slice if it's not full.

Introduced 'ecase' - 'case', that evaluates e key arguments.
Introduced 'append-one' - nondestructive append one non-list element to the list.
WBR, Dmi

Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

new version post

Post by Dmi »

since the last post I've collected a nice set. here is it:
http://en.feautec.pp.ru/store/libs/
a brief list:

Code: Select all

(global 'dofile 'dostring 'rawk 'rcase 'inc-p 'dec-p 'group 'group-all
        'group-by 'try 'lesser 'greater 'append-one 'ecase 'ifempty 'dirname
        'push-end 'file-tree 'newlisp-version 'int10 'doc)
WBR, Dmi

Sammo
Posts: 180
Joined: Sat Dec 06, 2003 6:11 pm
Location: Loveland, Colorado USA

Post by Sammo »

Here is a pair of newLisp macros that implements Fanda's '++' and '--' ideas.

If passed an integer or an integer expression, the '++' macro increments the integer or expression value by 1 or by the value of the optional second parameter. For example:

Code: Select all

>(++ 1)
2
>(++ (+ 1 2 3))
7
>(++ (+ 1 2 3) 5)
11
If passed a symbol, '++' increments the symbol's value and returns the updated value. For example:

Code: Select all

>(set 'var 1)
1
>var
1
>(++ var)
2
>var
2
>(++ var 2)
4
>var
4
The '--' macro behaves similarly. Here are the macros:

Code: Select all

(define-macro (++ _a _b)
  (if (symbol? _a)
    (set _a (+ (eval _a) (or _b 1)))
  ;else
    (+ (eval _a) (or _b 1)) ))

Code: Select all

(define (-- _a _b)
  (if (symbol? _a)
    (set _a (- (eval _a) (or _b 1)))
  ;else
    (- (eval _a) (or _b 1)) ))

Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

Post by Dmi »

++ and -- now in funlib.lsp

Thanks!
WBR, Dmi

Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

Post by Dmi »

Small improvement to ++:
_b must be evaluated before usage, to allow something like:
(++ var (length something))

Code: Select all

(define-macro (++ _a _b)
  "(++ a b) - increment a by b. a can by either a symbol or a value"
  (if (symbol? _a)
    (set _a (+ (eval _a) (or (eval _b) 1)))
    (+ (eval _a) (or (eval _b) 1)) ))
Also I found some (documented) note about (inc):
(inc 'sym value) - with second argument, always converts sym to a float despite both arguments may be integers.
If I use 'sym as an integer argument in the dynamic library calls, after calling (inc 'sym 1) it becames unusable for that.
So ++ can be well integer-only replacement.
(funlib.lsp updated)
WBR, Dmi

Dmi
Posts: 408
Joined: Sat Jun 04, 2005 4:16 pm
Location: Russia
Contact:

Post by Dmi »

And, finally, a version w/o macro:

Code: Select all

(define (++ _a01 _b01)
  "(++ int-a int-b) - increment int-a by int-b. int-a can be either a symbol or a value"
  (if (symbol? _a01)
    (set _a01 (+ (eval _a01) (or _b01 1)))
    (+ (eval _a01) (or _b01 1))))

(define (p++ _a01 _b01)
  "(p-- int-sym int-num) - post-increment int-sym by int-num"
  (let (_old (eval _a01))
    (++ _a01 (or _b01 1))
  _old))

Code: Select all

> (set 'a 1)
1
> (++ 'a)
2
> a
2
> (p++ 'a 2)
2
> a
4
WBR, Dmi

Locked