From: Surendra Singhi
Subject: read - comma
Date: 
Message-ID: <cmr69s$cdb$1@news.asu.edu>
Hi,
  How to read a comma separated list from a file.
For example,  " 2, 3, 5, 6,".

Thanks,
Surendra Singhi

From: Jeff M.
Subject: Re: read - comma
Date: 
Message-ID: <1100030292.077839.79400@f14g2000cwb.googlegroups.com>
Sounds suspiciously like homework, but this was just recently covered.
You might want to try a search. Google found this:

http://groups-beta.google.com/group/comp.lang.lisp/browse_thread/thread/7e268f9b579c45a5/d8618d42238c2e2f?_done=%2Fgroup%2Fcomp.lang.lisp%2Fsearch%3Fgroup%3Dcomp.lang.lisp%26q%3Dcsv%26qt_g%3D1%26searchnow%3DSearch+this+group%26&_doneTitle=Back+to+Search&&d#d8618d42238c2e2f
Jeff M.
From: David Sletten
Subject: Re: read - comma
Date: 
Message-ID: <9zbkd.80242$Kl3.71438@twister.socal.rr.com>
Jeff M. wrote:

> Sounds suspiciously like homework, but this was just recently covered.

This guy _grades_ the homework!

David Sletten
From: GP lisper
Subject: Re: read - comma
Date: 
Message-ID: <1100045028.TnRr1037vUhF8u9nlNCO6Q@teranews>
On Tue, 09 Nov 2004 22:31:33 GMT, <·····@slytobias.com> wrote:
> Jeff M. wrote:
>
>> Sounds suspiciously like homework, but this was just recently covered.
>
> This guy _grades_ the homework!
>
> David Sletten


I always loved getting teachers like that...just had to read TWO
chapters ahead to bollix them.


-- 
Brownian motion is correctly colored.
From: Surendra Singhi
Subject: Re: read - comma
Date: 
Message-ID: <cmrqjj$3u$1@news.asu.edu>
GP lisper wrote:
> On Tue, 09 Nov 2004 22:31:33 GMT, <·····@slytobias.com> wrote:
> 
>>Jeff M. wrote:
>>
>>
>>>Sounds suspiciously like homework, but this was just recently covered.
>>
>>This guy _grades_ the homework!
>>
>>David Sletten
> 
> 
> 
> I always loved getting teachers like that...just had to read TWO
> chapters ahead to bollix them.
> 
> 
I teach nothing, I just grade homeworks.
From: Jeff
Subject: Re: read - comma
Date: 
Message-ID: <oddkd.387374$D%.182755@attbi_s51>
David Sletten wrote:

> Jeff M. wrote:
> 
> > Sounds suspiciously like homework, but this was just recently
> > covered.
> 
> This guy grades the homework!

Heh, good to know ;)

But, then it should be a trivial problem, too. If the goal isn't
speed/optimization, this becomes a simple 3 line piece of code with a
regex package:

(defun csv (text)
  (loop for i in (re:split text #/[,\s]+/)
        collect (read-from-string i)))

If the goal was speed/optimization (which, I gather from subsequent
emails, was the goal), then that should have been stated.

Still, good to know that he's not a student and thanks for letting me
know for future reference ;)

Jeff M.

-- 
(surf-to "http://www.retrobyte.org/")
(mail-to (concatenate 'string "massung" ·@" "gmail.com"))
From: David Sletten
Subject: Re: read - comma
Date: 
Message-ID: <Lkdkd.80318$Kl3.16026@twister.socal.rr.com>
Jeff wrote:


> Still, good to know that he's not a student and thanks for letting me
> know for future reference ;)
> 
You're not the one I was chastising...

David Sletten
From: Jeff
Subject: Re: read - comma
Date: 
Message-ID: <mDdkd.319006$wV.99516@attbi_s54>
David Sletten wrote:

> Jeff wrote:
> 
> > Still, good to know that he's not a student and thanks for letting
> > me know for future reference ;)
> > 
> You're not the one I was chastising...
> 

Haha! Even better ;)
From: JP Massar
Subject: Re: read - comma
Date: 
Message-ID: <ne82p0p1bo9bj731lrd1emvptb64letcde@4ax.com>
On Tue, 09 Nov 2004 12:37:34 -0700, Surendra Singhi
<·········@netscape.net> wrote:

>Hi,
>  How to read a comma separated list from a file.
>For example,  " 2, 3, 5, 6,".
>
` 
One way would be to use READ-LINE to get a string, then change all the
comma characters in the string to spaces, using SUBSTITUTE, then use
READ-FROM-STRING to read successive integers.

Another way would be to use a string-splitting function to divide the
string into substrings using the commas as separators, then mapcar
PARSE-INTEGER over the strings.

There is no string-splitting function in Common Lisp.  There have been
many posted to this list at one time or another.  

For instance, here's a generalized sequence splitter:

http://www.cliki.net/SPLIT-SEQUENCE
From: Surendra Singhi
Subject: Re: read - comma
Date: 
Message-ID: <cmrbl2$dnv$1@news.asu.edu>
JP Massar wrote:

> On Tue, 09 Nov 2004 12:37:34 -0700, Surendra Singhi
> <·········@netscape.net> wrote:
> 
> 
>>Hi,
>> How to read a comma separated list from a file.
>>For example,  " 2, 3, 5, 6,".
>>
> 
> ` 
> One way would be to use READ-LINE to get a string, then change all the
> comma characters in the string to spaces, using SUBSTITUTE, then use
> READ-FROM-STRING to read successive integers.
> 
> Another way would be to use a string-splitting function to divide the
> string into substrings using the commas as separators, then mapcar
> PARSE-INTEGER over the strings.
> 
> There is no string-splitting function in Common Lisp.  There have been
> many posted to this list at one time or another.  
> 
> For instance, here's a generalized sequence splitter:
> 
> http://www.cliki.net/SPLIT-SEQUENCE
> 
> 


Isn't there any better way of doing that, for example while reading the 
line from the stream can't we set a de-limiter or something, which will 
read till it finds a comma, then skip over the comma and move over  to 
the next line.

Something like read-line which instead of using newline as the delimiter 
uses commas to separate the line.

-Surendra Singhi
From: Wade Humeniuk
Subject: Re: read - comma
Date: 
Message-ID: <wwakd.140585$9b.89886@edtnps84>
Surendra Singhi wrote:

> 
> 
> Isn't there any better way of doing that, for example while reading the 
> line from the stream can't we set a de-limiter or something, which will 
> read till it finds a comma, then skip over the comma and move over  to 
> the next line.

Yes there is, (is it better though?)

CL-USER 5 > (setf *ignore-comma-readtable* (copy-readtable))
#<READTABLE 20675D84>

CL-USER 6 > (set-syntax-from-char #\, #\space *ignore-comma-readtable*)
T

CL-USER 7 > (let ((*readtable* *ignore-comma-readtable*))
               (with-input-from-string (stream "2,3,4, 6")
                 (loop for i = (read stream nil nil)
                       while i collect i)))
(2 3 4 6)


Wade
From: Surendra Singhi
Subject: Re: read - comma
Date: 
Message-ID: <cmre7p$eat$2@news.asu.edu>
Wade Humeniuk wrote:

> Surendra Singhi wrote:
> 
>>
>>
>> Isn't there any better way of doing that, for example while reading 
>> the line from the stream can't we set a de-limiter or something, which 
>> will read till it finds a comma, then skip over the comma and move 
>> over  to the next line.
> 
> 
> Yes there is, (is it better though?)
> 

Whats the problem with it?

-Surendra

> CL-USER 5 > (setf *ignore-comma-readtable* (copy-readtable))
> #<READTABLE 20675D84>
> 
> CL-USER 6 > (set-syntax-from-char #\, #\space *ignore-comma-readtable*)
> T
> 
> CL-USER 7 > (let ((*readtable* *ignore-comma-readtable*))
>               (with-input-from-string (stream "2,3,4, 6")
>                 (loop for i = (read stream nil nil)
>                       while i collect i)))
> (2 3 4 6)
> 
> 
> Wade
From: Wade Humeniuk
Subject: Re: read - comma
Date: 
Message-ID: <c3fkd.140730$9b.125467@edtnps84>
Surendra Singhi wrote:
> 
> 
> Wade Humeniuk wrote:
> 
>> Surendra Singhi wrote:
>>
>>>
>>>
>>> Isn't there any better way of doing that, for example while reading 
>>> the line from the stream can't we set a de-limiter or something, 
>>> which will read till it finds a comma, then skip over the comma and 
>>> move over  to the next line.
>>
>>
>>
>> Yes there is, (is it better though?)
>>
> 
> Whats the problem with it?

Nothing technical, if you understand the limitations of this method and your file
is consistent.  (If the file contains other kinds of syntax then this could cause
other problems).  If two solutions solve the same problem, how can one tell which one
is better?  (The computer does not care, so it boils down to human values) (Or perhaps
there is some ultimate objective measurement?)

Wade

> 
> -Surendra
> 
>> CL-USER 5 > (setf *ignore-comma-readtable* (copy-readtable))
>> #<READTABLE 20675D84>
>>
>> CL-USER 6 > (set-syntax-from-char #\, #\space *ignore-comma-readtable*)
>> T
>>
>> CL-USER 7 > (let ((*readtable* *ignore-comma-readtable*))
>>               (with-input-from-string (stream "2,3,4, 6")
>>                 (loop for i = (read stream nil nil)
>>                       while i collect i)))
>> (2 3 4 6)
>>
>>
>> Wade
From: Surendra Singhi
Subject: Re: read - comma
Date: 
Message-ID: <cms8bt$3jo$1@news.asu.edu>
Wade Humeniuk wrote:

> Surendra Singhi wrote:
> 
>>
>>
>> Wade Humeniuk wrote:
>>
>>> Surendra Singhi wrote:
>>>
>>>>
>>>>
>>>> Isn't there any better way of doing that, for example while reading 
>>>> the line from the stream can't we set a de-limiter or something, 
>>>> which will read till it finds a comma, then skip over the comma and 
>>>> move over  to the next line.
>>>
>>>
>>>
>>>
>>> Yes there is, (is it better though?)
>>>
>>
>> Whats the problem with it?
> 
> 
> Nothing technical, if you understand the limitations of this method and 
> your file
> is consistent.  (If the file contains other kinds of syntax then this 
> could cause
> other problems).  If two solutions solve the same problem, how can one 
> tell which one
> is better?  (The computer does not care, so it boils down to human 
> values) (Or perhaps
> there is some ultimate objective measurement?)
> 
> Wade
> 

I can see the problem, I tried to modify it and use it in a different 
style, but I goofed up somewhere and my interpreter stopped responding 
and I was forced to kill the lisp process.


Surendra  Singhi
From: Wade Humeniuk
Subject: Re: read - comma
Date: 
Message-ID: <pjrkd.79432$E93.40213@clgrps12>
Surendra Singhi wrote:

> 
> I can see the problem, I tried to modify it and use it in a different 
> style, but I goofed up somewhere and my interpreter stopped responding 
> and I was forced to kill the lisp process.
> 

I think you clobbered your readtable.  Just be more careful (don't
give up too easily)

Wade
From: Frank Buss
Subject: Re: read - comma
Date: 
Message-ID: <cmrbfi$gku$1@newsreader2.netcologne.de>
Surendra Singhi <·········@netscape.net> wrote:

>   How to read a comma separated list from a file.
> For example,  " 2, 3, 5, 6,".

I assume you want to read only one line, every item is an integer and 
empty entries should be ignored (after your last comma). Here is a 
recursive solution:

(defun split (string delimiter)
  (when (= 0 (length delimiter)) (error "delimiter length = 0"))
  (let ((start (search delimiter string)))
    (if (not start)
        (if (= 0 (length string))
            nil 
          (list string))
      (let ((value (string-trim '(#\Space) (subseq string 0 start)))
            (rest (subseq string (+ start (length delimiter)))))
        (if (= 0 (length value))
            (split rest delimiter) 
          (cons value (split rest delimiter)))))))

(defun read-comma-line-integer-list (filename)
  (with-open-file (s filename)
    (mapcar #'parse-integer (split (read-line s) ","))))

with a file like your example (without quotation marks) you can use it 
like this:

(read-comma-line-integer-list "c:\\tmp\\line.txt") => (2 3 5 6)

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Surendra Singhi
Subject: Re: read - comma
Date: 
Message-ID: <cmre3r$eat$1@news.asu.edu>
Frank Buss wrote:

> Surendra Singhi <·········@netscape.net> wrote:
> 
> 
>>  How to read a comma separated list from a file.
>>For example,  " 2, 3, 5, 6,".
> 
> 
> I assume you want to read only one line, every item is an integer and 
> empty entries should be ignored (after your last comma). Here is a 
> recursive solution:
> 
> (defun split (string delimiter)
>   (when (= 0 (length delimiter)) (error "delimiter length = 0"))
>   (let ((start (search delimiter string)))
>     (if (not start)
>         (if (= 0 (length string))
>             nil 
>           (list string))
>       (let ((value (string-trim '(#\Space) (subseq string 0 start)))
>             (rest (subseq string (+ start (length delimiter)))))
>         (if (= 0 (length value))
>             (split rest delimiter) 
>           (cons value (split rest delimiter)))))))
> 
> (defun read-comma-line-integer-list (filename)
>   (with-open-file (s filename)
>     (mapcar #'parse-integer (split (read-line s) ","))))
> 
> with a file like your example (without quotation marks) you can use it 
> like this:
> 
> (read-comma-line-integer-list "c:\\tmp\\line.txt") => (2 3 5 6)
> 

I wrote this piece of function:

(defun read-till-delimiter (stream delimiter)
   (let (str)
     (loop for char = (read-char stream nil stream)
	  until (or (eq char stream) (eq char delimiter))
	  do (setf str (concatenate 'string (string char) str)))
     (nreverse str)))

But I still feel it is too inefficient, especially the concatenation 
part and then reversing the string.

And if you want to extract integer form the string which you have read, 
you can use:

(read (make-string-input-stream "20"))

This, may also be not very efficient, I am not sure.


-Surendra
From: Frank Buss
Subject: Re: read - comma
Date: 
Message-ID: <cmrh0v$pmp$1@newsreader2.netcologne.de>
Surendra Singhi <·········@netscape.net> wrote:

> I wrote this piece of function:
> 
> (defun read-till-delimiter (stream delimiter)
>    (let (str)
>      (loop for char = (read-char stream nil stream)
>        until (or (eq char stream) (eq char delimiter))
>        do (setf str (concatenate 'string (string char) str)))
>      (nreverse str)))
> 
> But I still feel it is too inefficient, especially the concatenation 
> part and then reversing the string.

but if you don't need to read large files, it doesn't matter. Don't do 
premature optimization.

Another short solution (perhaps not so elegant and error prone):

(with-open-file (s "c:\\tmp\\line.txt")
  (loop as n = (read-delimited-list #\, s)
        collect n
        while (< (file-position s) (file-length s)))))

> And if you want to extract integer form the string which you have read, 
> you can use:
> 
> (read (make-string-input-stream "20"))
> 
> This, may also be not very efficient, I am not sure.

you can use parse-integer, which is faster, but this is not so important, 
but it might be important for security reasons, for example, if line.txt 
contains this:

#.(+ 40 70) 2, 3, 5, 6,

my code above returns this:

((110 2) (3) (5) (6))

-- 
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Pascal Bourguignon
Subject: Re: read - comma
Date: 
Message-ID: <87u0ryjwso.fsf@naiad.informatimago.com>
Surendra Singhi <·········@netscape.net> writes:
> I wrote this piece of function:
> 
> (defun read-till-delimiter (stream delimiter)
>    (let (str)
>      (loop for char = (read-char stream nil stream)
> 	  until (or (eq char stream) (eq char delimiter))
> 	  do (setf str (concatenate 'string (string char) str)))
>      (nreverse str)))
> 
> But I still feel it is too inefficient, especially the concatenation
> part and then reversing the string.


Don't worry about inefficient, it's plain wrong!

You cannot use EQ to compare characters. You must use EQL.  This is
particularly true when comparing character coming from I/O, because in
that case you may get characters with attributes, such as control,
meta, shift, etc. For example with clisp:

[10]> (ext:with-keyboard (read-char ext:*keyboard-input*))
#S(SYSTEM::INPUT-CHARACTER :CHAR #\d :BITS 0 :FONT 0 :KEY NIL)


(defun read-till-delimiter (stream delimiter)
    (loop with buffer = (make-array '(80) :element-type 'character
                                          :adjustable t
                                          :fill-pointer 0)
          for ch = (read-char stream nil stream)
          until (or (eq ch stream) (eql ch delimtier))
          do (vector-push-extend ch buffer)
          finally (return (coerce buffer 'string))))


> And if you want to extract integer form the string which you have
> read, you can use:
> 
> (read (make-string-input-stream "20"))
> 
> This, may also be not very efficient, I am not sure.

PARSE-INTEGER

-- 
__Pascal Bourguignon__
From: Surendra Singhi
Subject: Re: read - comma
Date: 
Message-ID: <cmva0a$jlr$1@news.asu.edu>
Pascal Bourguignon wrote:
> Surendra Singhi <·········@netscape.net> writes:
> 
>>I wrote this piece of function:
>>
>>(defun read-till-delimiter (stream delimiter)
>>   (let (str)
>>     (loop for char = (read-char stream nil stream)
>>	  until (or (eq char stream) (eq char delimiter))
>>	  do (setf str (concatenate 'string (string char) str)))
>>     (nreverse str)))
>>
>>But I still feel it is too inefficient, especially the concatenation
>>part and then reversing the string.
> 
> 
> 
> Don't worry about inefficient, it's plain wrong!
> 
> You cannot use EQ to compare characters. You must use EQL.  This is
> particularly true when comparing character coming from I/O, because in
> that case you may get characters with attributes, such as control,
> meta, shift, etc. For example with clisp:
> 
> [10]> (ext:with-keyboard (read-char ext:*keyboard-input*))
> #S(SYSTEM::INPUT-CHARACTER :CHAR #\d :BITS 0 :FONT 0 :KEY NIL)
> 
> 
> (defun read-till-delimiter (stream delimiter)
>     (loop with buffer = (make-array '(80) :element-type 'character
>                                           :adjustable t
>                                           :fill-pointer 0)
>           for ch = (read-char stream nil stream)
>           until (or (eq ch stream) (eql ch delimtier))
>           do (vector-push-extend ch buffer)
>           finally (return (coerce buffer 'string))))

How about this one?

(defun read-till-delimiter (stream delimiter)
   (with-output-to-string (str)
     (loop for ch = (read-char stream nil stream)
	  until (or (eq ch stream) (eql ch delimiter))
	  do (princ ch str))))

Will it be comparable in performance to the last one?
Is there any way to check the assembly of the code?

Thanks,
Surendra Singhi
From: Marco Baringer
Subject: Re: read - comma
Date: 
Message-ID: <m2y8h8ka78.fsf@bese.it>
Surendra Singhi <·········@netscape.net> writes:

> Will it be comparable in performance to the last one?
> Is there any way to check the assembly of the code?

TIME, DISASSEMBLE and your implementations profiling tools could help.

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen
From: Pascal Bourguignon
Subject: Re: read - comma
Date: 
Message-ID: <87ekj0h2ke.fsf@naiad.informatimago.com>
Paul Foley <···@below.invalid> writes:

> On Thu, 11 Nov 2004 02:05:15 -0700, Surendra Singhi wrote:
> 
> > How about this one?
> 
> > (defun read-till-delimiter (stream delimiter)
> >   (with-output-to-string (str)
> >     (loop for ch = (read-char stream nil stream)
> > 	  until (or (eq ch stream) (eql ch delimiter))
> > 	  do (princ ch str))))
> 
> Warning: (eq ch delimiter) is wrong.  You need EQL there.

Yes, that's why it is there.

-- 
__Pascal Bourguignon__