Reading In text file.

Discussion of Common Lisp
Mercenary85
Posts: 10
Joined: Tue Apr 06, 2010 9:56 pm

Re: Reading In text file.

Post by Mercenary85 » Wed Apr 07, 2010 2:34 pm

nuntius wrote:Yes. (setf x y) stores y into the place currently known as x.
So my above code should work then?

a buddy of mine suggested these

Code: Select all

(setf example-list (read-file "data.txt"))
(loop for data in example-list do
   (setf ternary-tree (insert data ternary-tree))
)


(defun read-file (file-name)
 (setf file-stream (open file-name :if-does-not-exist nil))
  (setf file-data (read file-stream))
 file-data
)
as 2 possible ones. but he doesn't know lisp "that" well so i was unsure.

edit: ok i tried doing that. It printed out the list correctly...but still didnt hold the value for *imalist*
There has to be an easy way to do this I know, im just missing it

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Reading In text file.

Post by gugamilare » Wed Apr 07, 2010 3:56 pm

Mercenary85 wrote:
nuntius wrote:Yes. (setf x y) stores y into the place currently known as x.
So my above code should work then?
The code you created is very close to a solution, don't give up yet ;). But, unfortunately, it does not do anything since read-integers-from-file is not defined yet. Maybe you meant the function read-setup to be that function? In this case you need to rename your function to read-integers-from-file or the function you are calling to read-setup.

In any case, read-setup will not read the integers from the file. Nothing is returned by your call to loop; in order to make loop to construct and return a list, you should use collect.

For example, all the numbers are printed, but only an empty list is returned (nil = empty list):

Code: Select all

cl-user> (loop for i from 1 to 10
              do (print (list i)))

(1) 
(2) 
(3) 
(4) 
(5) 
(6) 
(7) 
(8) 
(9) 
(10) nil
On the other hand, here a list with numbers is created and returned:

Code: Select all

cl-user> (loop for i from 1 to 10
              collect i)
(1 2 3 4 5 6 7 8 9 10)
Another thing: you don't need to use coerce. The function read does not return a line from the file, it returns the integers directly.

One thing is not clear: the format of the file. You said that the file contains only numbers, which, to me, means something like this:

Code: Select all

23 45 73 18
but your buddy's code suggest that the file contains a list of numbers enclosed by parenthesis, which is this:

Code: Select all

(23 45 73 18)
In the first case, you need a loop. In the second case, you just need a single read from the file, because the function read will automatically construct a list when it encounters parenthesis.

By the way, your buddy's code has a bunch of problems, I don't recommend you to use it:
  • He uses variables (meant to be local) without declaring them with let;
  • He uses variables (meant to be global) without declaring them using defvar or defparameter, like you did with *imalist*;
  • He opens a file and doesn't close it afterwards. This is not a problem in you code because you are using with-open-file

Mercenary85
Posts: 10
Joined: Tue Apr 06, 2010 9:56 pm

Re: Reading In text file.

Post by Mercenary85 » Wed Apr 07, 2010 3:58 pm

ya see i tried this

Code: Select all

(defun read-setup (thefile)
(with-open-file (stream thefile)
    (loop for line = (read stream nil 'end)
          until (eq line 'end)           
          do (print (list (coerce line 'integer) 
                            )     
              )     
     )
)
)
(defparameter *imalist* (list))

(setf *imalist* (read-setup "thefile.txt"))

then tried (print *imalist*) and it printed nothing :(
but it printed the numbers out correctly however.
SO CLose yet so far away. what exactly am I missing? why isn't it keeping it as a variable *imalist*?
Either way my buddys code is def wrong, ignore that it exists. since the file just has numbers NOT enclosed by parenthesis.
Last edited by Mercenary85 on Wed Apr 07, 2010 4:00 pm, edited 1 time in total.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Reading In text file.

Post by gugamilare » Wed Apr 07, 2010 3:59 pm

Mercenary85 wrote:ya see i tried this

Code: Select all

(defun read-setup (thefile)
(with-open-file (stream thefile)
    (loop for line = (read stream nil 'end)
          until (eq line 'end)           
          do (print (list (coerce line 'integer) 
                            )     
              )     
     )
)
)
(defparameter *imalist* (list))

(setf *imalist* (read-setup "thefile.txt"))

then tried (print *imalist*) and it printed nothing :(
but it printed the numbers out correctly however.
SO CLose yet so far away. what exactly am I missing? why isn't it keeping it as a variable *imalist*?
You missed my post.

Mercenary85
Posts: 10
Joined: Tue Apr 06, 2010 9:56 pm

Re: Reading In text file.

Post by Mercenary85 » Wed Apr 07, 2010 4:06 pm

Code: Select all

(defun read-setup (file)
  (with-open-file (stream file :direction :input)
    (loop for input = (read stream nil stream)
          until (eq input stream) collect input)))

(defparameter *imalist* (list))

(setf *imalist* (read-setup "thefile.txt"))
would something like this work? it seems to work but I want to make sure im doing it right


edit: CRAP CRAP CRAP. the data i test with is enclosed in paraenthesis (1 5 27 18 19) like that. any way i can modify above code to work? with paranthesis

edit2: Yup it works 100% besides the parenthesis modifier
Last edited by Mercenary85 on Wed Apr 07, 2010 4:10 pm, edited 1 time in total.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Reading In text file.

Post by gugamilare » Wed Apr 07, 2010 4:10 pm

Mercenary85 wrote:

Code: Select all

(defun read-setup (file)
  (with-open-file (stream file :direction :input)
    (loop for input = (read stream nil stream)
          until (eq input stream) collect input)))

(defparameter *imalist* (list))

(setf *imalist* (read-setup "thefile.txt"))
would something like this work? it seems to work but I want to make sure im doing it right


edit: CRAP CRAP CRAP. the data i test with is enclosed in paraenthesis (1 5 27 18 19) like that. any way i can modify above code to work? with paranthesis
Your code does work for files without parenthesis.

If it is enclosed by parenthesis, you don't need the loop, just make a single read from the file.

Mercenary85
Posts: 10
Joined: Tue Apr 06, 2010 9:56 pm

Re: Reading In text file.

Post by Mercenary85 » Wed Apr 07, 2010 4:13 pm

gugamilare wrote:
Mercenary85 wrote:

Code: Select all

(defun read-setup (file)
  (with-open-file (stream file :direction :input)
    (loop for input = (read stream nil stream)
          until (eq input stream) collect input)))

(defparameter *imalist* (list))

(setf *imalist* (read-setup "thefile.txt"))
would something like this work? it seems to work but I want to make sure im doing it right


edit: CRAP CRAP CRAP. the data i test with is enclosed in paraenthesis (1 5 27 18 19) like that. any way i can modify above code to work? with paranthesis
Your code does work for files without parenthesis.

If it is enclosed by parenthesis, you don't need the loop, just make a single read from the file.
problem is the file looks like this

Code: Select all

(36 535 369 837 738 110 817 240 478 483 667 436 186 323 782 256 64 977
815 126 701 888 46 350 830 689 187 833 531 776 979 147 856 949 901 189
92 981 572 307 821 397 911 776 737 899 872 224 674 752 820 541 680 496
532 461 483 642 172 316 312 1 940 957 589 217 671 114 244 109 232 912
575 259 67 86 413 722 540 140 441 791 412 823 492 54 956 572 570 801 15
974 674 529 48 563 748 523 717 10 622 278 229 625 533 880 14 298 992 200
928 210 744 101 172 592 496 472 294 224 678 249 709 438 895 152 129 999
973 354 532 976 669 965 837 585 665 140 574 111 361 701 451 319 114 869
985 49 767 682 215 839 932 645 814 730 187 597 767 856 960 654 642 828
948 667 714 275 623 187 804 535 284 452 261 473 734 982 699 567 431 867
613 858 891 355 153 450 508 881 65 147 161 850 986 401 339 167 53 145)

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Reading In text file.

Post by gugamilare » Wed Apr 07, 2010 4:17 pm

Mercenary85 wrote:problem is the file looks like this

Code: Select all

(36 535 369 837 738 110 817 240 478 483 667 436 186 323 782 256 64 977
815 126 701 888 46 350 830 689 187 833 531 776 979 147 856 949 901 189
92 981 572 307 821 397 911 776 737 899 872 224 674 752 820 541 680 496
532 461 483 642 172 316 312 1 940 957 589 217 671 114 244 109 232 912
575 259 67 86 413 722 540 140 441 791 412 823 492 54 956 572 570 801 15
974 674 529 48 563 748 523 717 10 622 278 229 625 533 880 14 298 992 200
928 210 744 101 172 592 496 472 294 224 678 249 709 438 895 152 129 999
973 354 532 976 669 965 837 585 665 140 574 111 361 701 451 319 114 869
985 49 767 682 215 839 932 645 814 730 187 597 767 856 960 654 642 828
948 667 714 275 623 187 804 535 284 452 261 473 734 982 699 567 431 867
613 858 891 355 153 450 508 881 65 147 161 850 986 401 339 167 53 145)
Yes, I got that. Like I said, you need to replace your loop with a single call to read.

Mercenary85
Posts: 10
Joined: Tue Apr 06, 2010 9:56 pm

Re: Reading In text file.

Post by Mercenary85 » Wed Apr 07, 2010 5:31 pm

How do i go about "not" reading the parenthesis parts??

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Reading In text file.

Post by gugamilare » Wed Apr 07, 2010 5:49 pm

Mercenary85 wrote:How do i go about "not" reading the parenthesis parts??
You don't need to "not" read the parenthesis. If some file contains something like this:

Code: Select all

(1 2 3 4 5)
then you open that file using with-open-file and you call read directly on the file, the value returned is the list (1 2 3 4 5). You don't even need to create a loop to read the list.

Your Professor put the parenthesis in the file to make it simpler to read it ;)

Post Reply