[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Re: First lisp program

William James

9/6/2015 3:34:00 AM

Dmitry Jouravlev wrote:

> I'm learning lisp, and i have written my first program - it calculates
> frequencies of words and letters in a text file.
>
> I would appreciate if anyone wanted to comment on anything that can be
> improved in it.
>
> ;---------------------------------------------------------------
> (defclass frequency-counter ()
> ((counter :initform (make-hash-table :test 'equal))))
>
> ;---------------------------------------------------------------
> (defmethod add-counter ((c frequency-counter) word)
> (with-slots (counter) c
> (incf (gethash (string-downcase word) counter 0))))
>
> ;---------------------------------------------------------------
> (defmacro sort-in-place (var &rest params)
> `(setq ,var (sort ,var ,@params)))
>
> ;---------------------------------------------------------------
> (defmethod print-frequency-counter ((c frequency-counter) freq-sort)
> (with-slots (counter) c
> (let ((freq-list ())
> (sort-function (if freq-sort #'> #'string<))
> (sort-key (if freq-sort #'second #'first)))
> (maphash
> #'(lambda (k v)
> (push (list k v) freq-list))
> counter)
> (sort-in-place freq-list sort-function :key sort-key)
> (dolist (pair freq-list)
> (format t "~&~A: ~A" (first pair) (second pair))))))
>
> ;---------------------------------------------------------------
> (defun print-frequencies (words letters freq-sort)
> (format t "~&-----~&Words~&-----")
> (print-frequency-counter words freq-sort)
> (format t "~&-----~&Letters~&-----")
> (print-frequency-counter letters freq-sort))
>
> ;---------------------------------------------------------------
> (defun read-word (infile)
> (loop for c = (read-char infile nil)
> until (or (not (characterp c))
> (not (alphanumericp c)))
> when (alphanumericp c) collect c))
>
> ;---------------------------------------------------------------
> (defun skip-whitespace (infile)
> (loop for c = (read-char infile nil)
> until (or (not (characterp c))
> (alphanumericp c))
> finally (when (characterp c)
> (unread-char c infile))))
>
> ;---------------------------------------------------------------
> (defun read-words (infile)
> (skip-whitespace infile)
> (loop for word = (read-word infile)
> until (null word)
> do (skip-whitespace infile)
> collect word))
>
> ;---------------------------------------------------------------
> (defun charlist-to-string (word)
> (coerce word 'string))
>
> ;---------------------------------------------------------------
> (defun count-word-frequency (infile words letters)
> (mapcar
> #'(lambda (word)
> (add-counter words
> (charlist-to-string word))
> (mapcar
> #'(lambda (letter)
> (add-counter letters letter))
> word))
> (read-words infile)))
>
> ;---------------------------------------------------------------
> (defun run-word-frequency (filename &optional (freq-sort))
> (let ((words (make-instance 'frequency-counter))
> (letters (make-instance 'frequency-counter)))
> (with-open-file (infile filename)
> (count-word-frequency infile words letters))
> (print-frequencies words letters freq-sort)))



Gauche Scheme:

(use srfi-13 :only (string-tokenize))
(use srfi-42 :only (do-ec))

(define (string->word-list str)
(string-tokenize str #[[:alnum:]]))

(define (print-table table sort-by-freq)
(for-each
(^x (print (car x) ": " (cdr x)))
(apply sort (hash-table->alist table)
(if sort-by-freq
(list > cdr)
(list (^(a b) (negative? (compare a b))) car)))))

(define (print-freqs words letters sort-by-freq)
(print "----- words -----")
(print-table words sort-by-freq)
(print "----- letters -----")
(print-table letters sort-by-freq))

(define (run-word-frequency file :optional (sort-by-freq #f))
(let ((word-table (make-hash-table 'string=?))
(letter-table (make-hash-table)))
(define (handle-line line)
(let1 words (string->word-list line)
(dolist (word words)
(hash-table-update! word-table word ($ + 1 $) 0)
(do-ec (: c word)
(hash-table-update! letter-table c ($ + 1 $) 0)))))
(with-input-from-file file (cut generator-for-each handle-line read-line))
(print-freqs word-table letter-table sort-by-freq)))

The file "data.txt" contains:

The foo or the bar of 1984.
Just in the nick of time?

gosh> (run-word-frequency "data.txt")
----- words -----
1984: 1
Just: 1
The: 1
bar: 1
foo: 1
in: 1
nick: 1
of: 2
or: 1
the: 2
time: 1
----- letters -----
1: 1
4: 1
8: 1
9: 1
J: 1
T: 1
a: 1
b: 1
c: 1
e: 4
f: 3
h: 3
i: 3
k: 1
m: 1
n: 2
o: 5
r: 2
s: 1
t: 4


gosh> (run-word-frequency "data.txt" #t)
----- words -----
of: 2
the: 2
or: 1
bar: 1
nick: 1
foo: 1
The: 1
in: 1
time: 1
1984: 1
Just: 1
----- letters -----
o: 5
e: 4
t: 4
h: 3
i: 3
f: 3
r: 2
n: 2
u: 1
c: 1
m: 1
8: 1
J: 1
4: 1
a: 1
s: 1
9: 1
T: 1
b: 1
k: 1
1: 1

--
An important part of the explanation is the role of mass media in Sweden. Not a
single TV-program, radio program, or big newspaper would give space to critics
of the multicultural project.
fjordman.blogspot.ca/2005/05/is-swedish-democracy-collapsing.html