need help
need help
Hello! Lisp Geeks,
This is my lisp practice project. I am trying to read an employee information from a text file, one employee info for one line and put into employee list and then to print out the result.
(defstruct employee first_name last_name mid_name birthday start_date title)
(defparameter employee_list (make-array 0 :adjustable t :fill-pointer 0))
(defun read_list (filename)
)
(defun print_list ())
Question:
How can I assigned the values from the text string to the employee structure and create employee array?
Thanks!
Joybee
This is my lisp practice project. I am trying to read an employee information from a text file, one employee info for one line and put into employee list and then to print out the result.
(defstruct employee first_name last_name mid_name birthday start_date title)
(defparameter employee_list (make-array 0 :adjustable t :fill-pointer 0))
(defun read_list (filename)
)
(defun print_list ())
Question:
How can I assigned the values from the text string to the employee structure and create employee array?
Thanks!
Joybee
Re: need help
First I'd like to point out that the standard naming convention in Lisp is to use hyphens instead of underscores, camel case, etc.joybee wrote:Hello! Lisp Geeks,
This is my lisp practice project. I am trying to read an employee information from a text file, one employee info for one line and put into employee list and then to print out the result.
(defstruct employee first_name last_name mid_name birthday start_date title)
(defparameter employee_list (make-array 0 :adjustable t :fill-pointer 0))
(defun read_list (filename)
)
(defun print_list ())
Question:
How can I assigned the values from the text string to the employee structure and create employee array?
Thanks!
Joybee
Now then, how are the lines of the text file formatted? Is this going to be CSV, or is it going to be delimited by spaces, or what?
-
- Posts: 148
- Joined: Wed Jul 30, 2008 11:26 pm
Re: need help
A few things.joybee wrote:(defstruct employee first_name last_name mid_name birthday start_date title)
(defparameter employee_list (make-array 0 :adjustable t :fill-pointer 0))
(defun read_list (filename)
)
(defun print_list ())
Question:
How can I assigned the values from the text string to the employee structure and create employee array?
An array seems like an odd choice for this program, especially for a prototype. I would think that lists will do fine for prototyping, and that any demanding application would be better served by a structure chosen for the type of lookups you will need to do.
You might also run into some trouble saving your list of employees in a variable. It could easily happen that you don't reset this variable between runs, and you end up thinking that read_list (or "read-list", as most of us would name it... well, I'd probably call it "employees-from" or something) is being properly updated, when in fact it contains garbage data from a previous run. This could be obvious to you, but I mention it because you may be used to working in a non-interactive environment where each run starts with a clean slate. Since you don't shut down your Lisp image between runs, any state you don't reset is retained — which is mostly a great thing, but can lead to silly errors. Personally, I would make read_list simply construct and return a list, and forget about side-effects. Since Lisp has a garbage collector, you can do this any time you want with no worries about memory leaks. Then you can test it by running (print_list (read_list)) at the REPL. Once you're sure read_list is working, you may want to save the data in a global variable for easy interactive testing purposes, but even so, you'll be better off if you pass that data as an argument rather than making print_list check out some hard-coded variable. (print_list employee_list), right?
As for doing the actual work, it depends, like qbg said, on your file format. Storing employee data as s-expressions is easiest. Then you can just READ from the file after setting *READ-EVAL* to nil to prevent code injection, if that's an issue. You'll get lists back, which are just about the easiest thing in the world to work with. If you've already got some files in another format, you'll just have to read lines as strings and parse them by hand.
I suspect print_list is going to be superfluous. The built-in PRINT function can print arrays and lists just fine. Lisp won't print anything interesting for your employee structure, but you can tell it what you want to see when you define the structure. Of course if there is a specific print format you'd like to see you'll need to write print_list.
Re: need help
Hello!
Thanks qbg and Paul for your help. And I really appreciate Paul's explanation, it helps me to learn some concepts. I just started to learn what a language Lisp is, it's difficult for me to apply the feature of the language in the coding while I felt coding is the best way to get some sense of programing. I made up this employee problem to learn the basic coding, so I guessed space could be the delimitier or maybe comma as the delimitier to deal with some empty fields.
I think I need to go back to do some reading and searching (Paul mentioned several new terms in his post) while you professionals help me to get start coding.
Thanks qbg and Paul for your help. And I really appreciate Paul's explanation, it helps me to learn some concepts. I just started to learn what a language Lisp is, it's difficult for me to apply the feature of the language in the coding while I felt coding is the best way to get some sense of programing. I made up this employee problem to learn the basic coding, so I guessed space could be the delimitier or maybe comma as the delimitier to deal with some empty fields.
I think I need to go back to do some reading and searching (Paul mentioned several new terms in his post) while you professionals help me to get start coding.
Re: need help
Is there a way to bind the text line I read from file directly to the structure or do I need to parse the line and assign the value individually? I just didn't get it. 
eg. one line read from the file is "Smith John H M 1018702738 1230432689 40000 Technician" in the order of last name, first name, middle init, sex, birthday, starting date, salary, title"
(defstruct employee lastname firstname middle....)
(with-open-file (in-stream ...)
(do ((line (read-line in-stream)
;;here how do I bind line to employee struct?
)
Thanks.

eg. one line read from the file is "Smith John H M 1018702738 1230432689 40000 Technician" in the order of last name, first name, middle init, sex, birthday, starting date, salary, title"
(defstruct employee lastname firstname middle....)
(with-open-file (in-stream ...)
(do ((line (read-line in-stream)
;;here how do I bind line to employee struct?
)
Thanks.
-
- Posts: 148
- Joined: Wed Jul 30, 2008 11:26 pm
Re: need help
You need to parse it and assign values individually. BTW, once you split at commas you can use READ to turn a string of digits into a number.joybee wrote:Is there a way to bind the text line I read from file directly to the structure or do I need to parse the line and assign the value individually? I just didn't get it.
Re: need help
You need to assign the values individually, but you can do so in more or less concise ways. The fastest way seems to be to modify the constructor in your defstruct declaration so that it takes slot values by order of arguments:joybee wrote:Is there a way to bind the text line I read from file directly to the structure or do I need to parse the line and assign the value individually? I just didn't get it.
eg. one line read from the file is "Smith John H M 1018702738 1230432689 40000 Technician" in the order of last name, first name, middle init, sex, birthday, starting date, salary, title"
(defstruct employee lastname firstname middle....)
(with-open-file (in-stream ...)
(do ((line (read-line in-stream)
;;here how do I bind line to employee struct?
)
Thanks.
Code: Select all
(defstruct (employee (:constructor make-employee (last-name first-name middle-initial sex
birthday starting-date salary title)))
last-name first-name middle-initial sex birthday starting-date salary title)
Now, given the arguments as a list (e.g. as returned from something like a get-employee-data function), you can call this constructor by using the "spreadable argument list designator" of apply:
Code: Select all
(apply #'make-employee (get-employee-data))
Disclaimer: I did not test any of the shown code.
"Just throw more hardware at it" is the root of all evil.
Svante
Svante
Re: need help
By the way, one thing you might want to watch out for is, what happens when the last name is "van den Heever" or something like that.joybee wrote:eg. one line read from the file is "Smith John H M 1018702738 1230432689 40000 Technician" in the order of last name, first name, middle init, sex, birthday, starting date, salary, title"