• Reading data into list from "include" file

    From Axel Reichert@21:1/5 to All on Mon Dec 18 19:00:22 2023
    Hello,

    I have an ASCII file that gets written by some other (non-lispy) process
    and contains (a known number of) integers, one per line, e.g. like this:

    8
    7
    7
    5

    Now I want to read these numbers into a list, so that instead of
    hard-coding the numbers like

    (let ((my-list (list 8 7 7 5)))
    (do-something-with-the-list))

    I can have something like

    (let ((my-list (unknown-code-to-read-from-an-include-file)))
    (do-something-with-the-list))

    Unfortunately, I have no elegant solution how "unknown-code-to-read-from-an-include-file" should look (in Common Lisp
    or Emacs Lisp). The best I could come up with is

    (require 'f) ; An Emacs library for file handling
    (let ((my-list (mapcar #'string-to-number
    (split-string (f-read "ascii-file.el")))))
    (do-something-with-the-list))

    "f-read" returns a string, so I need to convert into a list of strings
    and then into a list of numbers. Works, but looks clumsy.

    A simple "load-file" will not do, since it just returns T (for successful reading), not the three integer numbers read, so "my-list" is no list,
    but the truthiness value.

    Any ideas?

    Best regards

    Axel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Julieta Shem@21:1/5 to Axel Reichert on Mon Dec 18 15:22:41 2023
    Axel Reichert <mail@axel-reichert.de> writes:

    Hello,

    I have an ASCII file that gets written by some other (non-lispy) process
    and contains (a known number of) integers, one per line, e.g. like this:

    8
    7
    7
    5

    Now I want to read these numbers into a list, so that instead of
    hard-coding the numbers like

    (let ((my-list (list 8 7 7 5)))
    (do-something-with-the-list))

    I can have something like

    (let ((my-list (unknown-code-to-read-from-an-include-file)))
    (do-something-with-the-list))

    Unfortunately, I have no elegant solution how "unknown-code-to-read-from-an-include-file" should look (in Common Lisp
    or Emacs Lisp). The best I could come up with is

    (require 'f) ; An Emacs library for file handling
    (let ((my-list (mapcar #'string-to-number
    (split-string (f-read "ascii-file.el")))))
    (do-something-with-the-list))

    "f-read" returns a string, so I need to convert into a list of strings
    and then into a list of numbers. Works, but looks clumsy.

    A simple "load-file" will not do, since it just returns T (for successful reading), not the three integer numbers read, so "my-list" is no list,
    but the truthiness value.

    Any ideas?

    The task seems straightforward and it looks you solved it. It will look
    a lot better if you abstract your strategy away in a procedure. So your
    code will look like

    (do-something-with (file->list-of-numbers "ascii.file.txt")).

    I don't much ELISP, but we might not be too far off with

    (defun file->list-of-numbers (fname)
    (mapcar #'string-to-number
    (split-string (f-read fname))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Madhu@21:1/5 to All on Wed Dec 20 17:24:43 2023
    * Julieta Shem <87jzpb74lq.fsf@ yaxenu.org> :
    Wrote on Mon, 18 Dec 2023 15:22:41 -0300:
    Axel Reichert <mail @axel-reichert.de> writes:
    I have an ASCII file that gets written by some other (non-lispy) process
    and contains (a known number of) integers, one per line, e.g. like this:

    8
    7
    7
    5

    Now I want to read these numbers into a list, so that instead of
    hard-coding the numbers like

    (let ((my-list (list 8 7 7 5)))
    (do-something-with-the-list))

    <snip>
    (require 'f) ; An Emacs library for file handling
    (let ((my-list (mapcar #'string-to-number
    (split-string (f-read "ascii-file.el")))))
    (do-something-with-the-list))

    "f-read" returns a string, so I need to convert into a list of strings
    and then into a list of numbers. Works, but looks clumsy.

    A simple "load-file" will not do, since it just returns T (for successful
    reading), not the three integer numbers read, so "my-list" is no list,
    but the truthiness value.

    Any ideas?

    The task seems straightforward and it looks you solved it. It will look
    a lot better if you abstract your strategy away in a procedure. So your
    code will look like

    (do-something-with (file->list-of-numbers "ascii.file.txt")).

    I don't much ELISP, but we might not be too far off with

    (defun file->list-of-numbers (fname)
    (mapcar #'string-to-number
    (split-string (f-read fname))))

    In elisp, for the specific case where Axel controls the file being read
    it may be as simple to leverage the lisp reader.

    (car (read-from-string (concat "(" (f-read "file.txt") ")")))

    (with-temp-buffer
    (insert "(")
    (insert-file-contents "/dev/shm/barf")
    (goto-char (point-max))
    (insert ")")
    (goto-char (point-min))
    (read (current-buffer)))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Axel Reichert@21:1/5 to Julieta Shem on Thu Dec 21 20:15:01 2023
    Julieta Shem <jshem@yaxenu.org> writes:

    The task seems straightforward and it looks you solved it. It will look
    a lot better if you abstract your strategy away in a procedure. So your
    code will look like

    (do-something-with (file->list-of-numbers "ascii.file.txt")).

    Yes, sure, that is better. Thanks!

    Axel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Axel Reichert@21:1/5 to Madhu on Thu Dec 21 20:13:53 2023
    Madhu <enometh@meer.net> writes:

    (car (read-from-string (concat "(" (f-read "file.txt") ")")))

    Nice, thanks! I had found "read-from-string", but could not come up with
    the idea to create a Lisp expression.

    Best regards

    Axel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Axel Reichert@21:1/5 to Spiros Bousbouras on Thu Dec 21 20:24:07 2023
    Spiros Bousbouras <spibou@gmail.com> writes:

    A simple "load-file" will not do, since it just returns T (for successful
    reading), not the three integer numbers read, so "my-list" is no list,
    but the truthiness value.

    Actually LOAD returns T for successful *evaluation* .In your example , it read and evaluated each of the forms 8 , 7 , 7 , 5 .Each of those evaluates to itself [i.e. the respective number] so obviously the evaluation was successful.

    Yes, sure, my formulation was too short for still being precise. I meant
    to state it like you did above. Thanks for the clarification.

    Best regards

    Axel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Axel Reichert@21:1/5 to Raymond Wiker on Thu Dec 21 20:21:42 2023
    Raymond Wiker <rwiker@gmail.com> writes:

    For people who don't like extended loop,

    ... count me in.

    (defun read-numbers-from-file/2 (file-path n)
    (with-open-file (f file-path :direction :input)
    (let ((res nil))
    (dotimes (i n)
    (push (parse-integer (read-line f nil)) res))
    (nreverse res))))

    Yes, that will be the Common Lisp version. Thanks to you, too!

    Axel

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to Raymond Wiker on Wed Jul 10 16:13:08 2024
    Raymond Wiker wrote:

    For people who don't like extended loop, I think this a better implementation:

    (defun read-numbers-from-file/2 (file-path n)
    (with-open-file (f file-path :direction :input)
    (let ((res nil))
    (dotimes (i n)
    (push (parse-integer (read-line f nil)) res))
    (nreverse res))))

    Gauche Scheme

    (with-input-from-file "output.dat"
    (lambda res
    (until (read) eof-object? => x
    (push! res x))
    (reverse res)))

    ===>
    (4 3 2 1 3 4 2 1 4 2 3 1 2 4 3 1 3 2 4 1 2 3 4 1 4 3 1 2
    3 4 1 2 4 1 3 2 1 4 3 2 3 1 4 2 1 3 4 2 4 2 1 3 2 4 1 3
    4 1 2 3 1 4 2 3 2 1 4 3 1 2 4 3 3 2 1 4 2 3 1 4 3 1 2 4
    1 3 2 4 2 1 3 4 1 2 3 4)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to B. Pym on Thu Jul 11 10:46:59 2024
    B. Pym wrote:

    Raymond Wiker wrote:

    For people who don't like extended loop, I think this a better implementation:

    (defun read-numbers-from-file/2 (file-path n)
    (with-open-file (f file-path :direction :input)
    (let ((res nil))
    (dotimes (i n)
    (push (parse-integer (read-line f nil)) res))
    (nreverse res))))

    Gauche Scheme

    (with-input-from-file "output.dat"
    (lambda res
    (until (read) eof-object? => x
    (push! res x))
    (reverse res)))

    ===>
    (4 3 2 1 3 4 2 1 4 2 3 1 2 4 3 1 3 2 4 1 2 3 4 1 4 3 1 2
    3 4 1 2 4 1 3 2 1 4 3 2 3 1 4 2 1 3 4 2 4 2 1 3 2 4 1 3
    4 1 2 3 1 4 2 3 2 1 4 3 1 2 4 3 3 2 1 4 2 3 1 4 3 1 2 4
    1 3 2 4 2 1 3 4 1 2 3 4)



    (define (collect-till pred gen key)
    (do ((x (gen) (gen))
    (res '() (cons x res)))
    ((pred x) (reverse res))))

    (with-input-from-file "output.dat"
    (lambda _
    (collect-till eof-object? read +)))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to B. Pym on Thu Jul 11 16:01:13 2024
    B. Pym wrote:

    B. Pym wrote:

    Raymond Wiker wrote:

    For people who don't like extended loop, I think this a better implementation:

    (defun read-numbers-from-file/2 (file-path n)
    (with-open-file (f file-path :direction :input)
    (let ((res nil))
    (dotimes (i n)
    (push (parse-integer (read-line f nil)) res))
    (nreverse res))))

    Gauche Scheme

    (with-input-from-file "output.dat"
    (lambda res
    (until (read) eof-object? => x
    (push! res x))
    (reverse res)))

    ===>
    (4 3 2 1 3 4 2 1 4 2 3 1 2 4 3 1 3 2 4 1 2 3 4 1 4 3 1 2
    3 4 1 2 4 1 3 2 1 4 3 2 3 1 4 2 1 3 4 2 4 2 1 3 2 4 1 3
    4 1 2 3 1 4 2 3 2 1 4 3 1 2 4 3 3 2 1 4 2 3 1 4 3 1 2 4
    1 3 2 4 2 1 3 4 1 2 3 4)



    (define (collect-till pred gen key)
    (do ((x (gen) (gen))
    (res '() (cons x res)))
    ((pred x) (reverse res))))

    (with-input-from-file "output.dat"
    (lambda _
    (collect-till eof-object? read +)))

    (with-input-from-file "output.dat"
    (lambda _ (collect-while + read)))


    Given:

    (define (collect-while pred gen . opt-key)
    (let ((key (if (pair? opt-key) (car opt-key) values)))
    (do ((x (gen) (gen))
    (res '() (cons (key x) res)))
    ((or (eof-object? x) (not (pred x))) (reverse res)))))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)