Jump to content

Get External Data From a File


The Buzzard

Recommended Posts

Hi,

 

I am progressing with my Flange lisp and everything seems to be coming together. I am working on getting external data to be used for variables in the program. I found a routine on Afralisp that will do this and it works well for its intended purpose, However there are a few things about it that I do not like.

 

1. I would like to have the data in the *.dim file spaced without commas.

2. If a *.dim file is missing, I would like the program to alert the user then have the program go back to the main menu where the user can exit to fix the problem or continue with another type flange who's dim files are available.

 

Any help would be greatly appreciated.

Thanks

 

Here is what I have:

 

This is the function to access the external data.

AF_SFS lisp subfunction

;/////////////////////////////////////////////////////////////////////////////////////////
;
; Set Flange Selection Function.
;
; OD = Outside Dia.
; TH = Thickness for all flanges except Lap Joint
; TJ = Thickness for Lap Joint
; RD = Raised Face Dia.
; HD = Hub Dia.
; HK = Hub OD at conn. for Weld Neck
; NH = Number of Holes
; HR = Hole Radius
; BC = Bolt Circle
; B1 = Flange ID for Slip-On
; B2 = Flange ID for Weld Neck & Socket Weld
; B3 = Flange ID for Lap Joint
; B4 = Flange ID for Threaded
; FT = Raised Face Thickness
; L1 = Flange Length for Threaded, Slip-On & Socket Weld
; L2 = Flange Length for Weld Neck
; L3 = Flange Length for Lap Joint
; CE = Center Line Extention
;
(defun AF_SFS ()
 (AF_CPS)
 (setq SELECTION  (nth (atoi AF:TYPE) DATA1)
       TYPE       (car SELECTION)
       AF:CLASSES (nth (atoi AF:CLASS)(cdr SELECTION))
       CLASS      (car AF:CLASSES)
       SIZE       (nth (atoi AF:SIZE)(cdr AF:CLASSES))
       VIEW        AF:VIEW
       DFLG        AF:DFLG
       FACE        AF:FACE
       DUNT        AF:DUNT
       DLST nil SIZE  (strcat "*"SIZE))
 (cond
   ((= CLASS "150#") (setq FNAM "AF150.dim"))
   ((= CLASS "300#") (setq FNAM "AF300.dim"))
   ((= CLASS "400#") (setq FNAM "AF400.dim"))
   ((= CLASS "600#") (setq FNAM "AF600.dim"))
   ((= CLASS "900#") (setq FNAM "AF900.dim"))
   ((= CLASS "1500#")(setq FNAM "AF1500.dim"))
   ((= CLASS "2500#")(setq FNAM "AF2500.dim")))
 (setq FILE (findfile FNAM) FP (open FILE "R") ITEM (read-line FP))
 (while ITEM
   (if	(= ITEM SIZE)
     (setq DATA2 (read-line FP) ITEM nil)
     (setq ITEM (read-line FP))))
 (if DATA2
   (progn
     (setq MAXS (strlen DATA2) CNT 1 CHR 1)
     (while (< CNT MAXS)
(if (/= "," (substr DATA2 CNT 1))
  (setq CHR  (1+ CHR))
  (setq	NUM  (atof (substr DATA2 (1+ (- CNT CHR)) CHR))
	DLST (append DLST (list NUM)) CHR 1))
(setq CNT (1+ CNT)))
     (setq NUM (atof (substr DATA2 (1+ (- CNT CHR))))        	
    DLST (append DLST (list NUM)))))
 (close FP)
 (mapcar 'set '(OD TH TJ RD HD HK NH HR BC B1 B2 B3 B4 FT L1 L2 L3 CE) DLST)
 (setq NH (rtos NH 2 0))
 (setq NH (atoi NH))
 (cond
   ((= AF:VIEW "FACE")(AF_CFV))
   ((= AF:VIEW "SIDE")(AF_CSV)))
 (AF_PL)
 (princ))
;
;///////////////////////////////////////////////////////////////////////////////////////// 

 

This is a small part of the external data to be accessed

AF150.dim

;
; 150# Flange Dimension List
;
; OD = Outside Dia.
; TH = Thickness for all flanges except Lap Joint
; TJ = Thickness for Lap Joint
; RD = Raised Face Dia.
; HD = Hub Dia.
; HK = Hub OD at conn. for Weld Neck
; NH = Number of Holes
; HR = Hole Radius
; BC = Bolt Circle
; B1 = Flange ID for Slip-On
; B2 = Flange ID for Weld Neck & Socket Weld
; B3 = Flange ID for Lap Joint
; B4 = Flange ID for Threaded
; FT = Raised Face Thickness
; L1 = Flange Length for Threaded, Slip-On & Socket Weld
; L2 = Flange Length for Weld Neck
; L3 = Flange Length for Lap Joint
; CE = Center Line Extention
;
;OD |TH  |TJ  |RD  |HD  |HK  |NH |HR  |BC  |B1  |B2  |B3  |B4 |FT    |L1  |L2  |L3  |CE |
*1/2
3.50,0.38,0.44,1.38,1.19,0.84,4.0,0.31,2.38,0.88,0.62,0.90,0.5,0.0625,0.56,1.81,0.62,0.5 

Link to comment
Share on other sites

  • Replies 35
  • Created
  • Last Reply

Top Posters In This Topic

  • The Buzzard

    19

  • Lee Mac

    17

Top Posters In This Topic

Posted Images

These may provide some food for thought:

 

(defun _ReadNextifFoo ( file foo / f n ) ;; Lee Mac

 (cond (  (not (setq f (open file "r"))) nil)

       (t (while (and (setq n (read-line f)) (not (foo n))))

          (setq n (read-line f))
          (close f)
       )
 )
 n
)

;|
(_ReadNextifFoo <filename> <predicate function>)

Example:

File Contains:

string1
string2
string3
*string4
string5

(_ReadNextifFoo <filename> (lambda ( line ) (wcmatch line "`**")))

==>>  string5
|;

(defun StringParser ( str del ) ;; Lee Mac
 
 (if (setq pos (vl-string-search del str))
   (cons (substr str 1 pos)
         (StringParser (substr str (+ pos 1 (strlen del))) del))
   (list str)
 )
)

;|
(StringParser <string> <delimiter>)

Example:

String: "This;is;a;test"

(StringParser <string> ";")

==>>  ("This" "is" "a" "test")
|;

Link to comment
Share on other sites

These may provide some food for thought:

 

(defun _ReadNextifFoo ( file foo / f n ) ;; Lee Mac

 (cond (  (not (setq f (open file "r"))) nil)

       (t (while (and (setq n (read-line f)) (not (foo n))))

          (setq n (read-line f))
          (close f)
       )
 )
 n
)

;|
(_ReadNextifFoo <filename> <predicate function>)

Example:

File Contains:

string1
string2
string3
*string4
string5

(_ReadNextifFoo <filename> (lambda ( line ) (wcmatch line "`**")))

==>>  string5
|;

(defun StringParser ( str del ) ;; Lee Mac
 
 (if (setq pos (vl-string-search del str))
   (cons (substr str 1 pos)
         (StringParser (substr str (+ pos 1 (strlen del))) del))
   (list str)
 )
)

;|
(StringParser <string> <delimiter>)

Example:

String: "This;is;a;test"

(StringParser <string> ";")

==>>  ("This" "is" "a" "test")
|;

Lee,

 

Your right about food for thought. More like Chinese food. "Egg Foo Lisp"

 

I read those examples and I am more confused. I would assume these are two separate examples. The first one I do not have a clue. The second seems to deal with the situation I have now. I do not want to write the file with commas If I can avoid it at all. Could you clarify both of them a bit. I do not want you to think that I am pushing this off, But I am not exactly sure how these are suppose to work or what the advantage is here. I do not want you to assume also from what I think I know is correct. I may be missing something here.

 

I would appreciate it Thanks,

 

I was looking to do something along the lines of writing the dim file something like this:

(1/2   3.50 0.38 0.44 1.38 1.19 0.84 4.0 0.31 2.38 0.88 0.62 0.90 0.5 0.0625 0.56 1.81 0.62 0.5)

Link to comment
Share on other sites

The first is an example of a function that will read a file, and evaluate each line of the file using a supplied predicate function - if the predicate function returns true, the function will stop reading and return the next line.

 

The second is a function that will separate a string using a specified character delimiter, which could be any character of your choosing.

 

 

Using your supplied example, you could construct something like this:

 

(defun GetDimVariables ( file flag / _ReadNextifFoo StringParser l )

 (defun _ReadNextifFoo ( file foo / f n ) ;; Lee Mac

   (cond (  (not (setq f (open file "r"))) nil)

         (t (while (and (setq n (read-line f)) (not (foo n))))

            (setq n (read-line f))
            (close f)
         )
   )
   n
 )

 (defun StringParser ( str del ) ;; Lee Mac
 
   (if (setq pos (vl-string-search del str))
     (cons (substr str 1 pos)
           (StringParser (substr str (+ pos 1 (strlen del))) del))
     (list str)
   )
 )

 (mapcar (function distof)

   (cond (  (not (findfile file)) nil)

         (  (setq l (_ReadNextifFoo file (lambda ( line ) (eq line flag))))

            (StringParser l ",")
         )
   )
 )
)

 

(GetDimVariables <filename>  "*1/2")

Link to comment
Share on other sites

The first is an example of a function that will read a file, and evaluate each line of the file using a supplied predicate function - if the predicate function returns true, the function will stop reading and return the next line.

 

The second is a function that will separate a string using a specified character delimiter, which could be any character of your choosing.

 

 

Using your supplied example, you could construct something like this:

 

(defun GetDimVariables ( file flag / _ReadNextifFoo StringParser l )

 (defun _ReadNextifFoo ( file foo / f n ) ;; Lee Mac

   (cond (  (not (setq f (open file "r"))) nil)

         (t (while (and (setq n (read-line f)) (not (foo n))))

            (setq n (read-line f))
            (close f)
         )
   )
   n
 )

 (defun StringParser ( str del ) ;; Lee Mac
 
   (if (setq pos (vl-string-search del str))
     (cons (substr str 1 pos)
           (StringParser (substr str (+ pos 1 (strlen del))) del))
     (list str)
   )
 )

 (mapcar (function distof)

   (cond (  (not (findfile file)) nil)

         (  (setq l (_ReadNextifFoo file (lambda ( line ) (eq line flag))))

            (StringParser l ",")
         )
   )
 )
)

 

(GetDimVariables <filename>  "*1/2")

So if I want say to do something like this on the second function it would be possible?:

 

3.50 | 0.38 | 0.44 | 1.38 |

 

Also when you say predicate, I think you are referring to the lines identifier?

Link to comment
Share on other sites

Yes, the StringParser delimiter argument can be any string.

 

A predicate function is that which returns true/false, in this case it is a function taking one argument and returning true if that argument meets our test condition.

Link to comment
Share on other sites

Yes, the StringParser delimiter argument can be any string.

 

A predicate function is that which returns true/false, in this case it is a function taking one argument and returning true if that argument meets our test condition.

Thank you so much for that, I think you also clarified some other confusion I was having with the existing file I am using. I will mess with this idea bit and see where I can take it.

 

 

Thank you again,

The Buzzard

Link to comment
Share on other sites

Be sure to study the functions I have provided in my earlier posts - they have many uses, and will help with your programming ability.

Link to comment
Share on other sites

Be sure to study the functions I have provided in my earlier posts - they have many uses, and will help with your programming ability.

Lee,

 

I am almost afraid to ask, What is foo?

 

Also you do not use findfile. How come?

Link to comment
Share on other sites

It is merely a symbol that represents a general function, for more information on the term used, see here.

 

I do use findfile, but 'open' in the subfunction is sufficient for that purpose.

Link to comment
Share on other sites

Lee,

 

I doubt I am doing this correctly. The code below, I do not get any errors and I do not get any returned values. If I move the dim file out of the ACAD support path the program does not seem to notice either.

 

;
; Set Flange Selection Function.
;
; OD = Outside Dia.
; TH = Thickness for all flanges except Lap Joint
; TJ = Thickness for Lap Joint
; RD = Raised Face Dia.
; HD = Hub Dia.
; HK = Hub OD at conn. for Weld Neck
; NH = Number of Holes
; HR = Hole Radius
; BC = Bolt Circle
; B1 = Flange ID for Slip-On
; B2 = Flange ID for Weld Neck & Socket Weld
; B3 = Flange ID for Lap Joint
; B4 = Flange ID for Threaded
; FT = Raised Face Thickness
; L1 = Flange Length for Threaded, Slip-On & Socket Weld
; L2 = Flange Length for Weld Neck
; L3 = Flange Length for Lap Joint
; CE = Center Line Extention
;
(defun AF_SFS ()
 (AF_CPS)
 (setq SELECTION  (nth (atoi AF:TYPE) DATA1)
       TYPE       (car SELECTION)
       AF:CLASSES (nth (atoi AF:CLASS)(cdr SELECTION))
       CLASS      (car AF:CLASSES)
       SIZE       (nth (atoi AF:SIZE)(cdr AF:CLASSES))
       VIEW        AF:VIEW
       DFLG        AF:DFLG
       FACE        AF:FACE
       DUNT        AF:DUNT
       SLST       (strcat "*"SIZE))
 (cond
   ((= CLASS "150#") (GetDimVariables "AF150.dim" SLST))
   ((= CLASS "300#") (GetDimVariables "AF300.dim" SLST))
   ((= CLASS "400#") (GetDimVariables "AF400.dim" SLST))
   ((= CLASS "600#") (GetDimVariables "AF600.dim" SLST))
   ((= CLASS "900#") (GetDimVariables "AF900.dim" SLST))
   ((= CLASS "1500#")(GetDimVariables "AF1500.dim" SLST))
   ((= CLASS "2500#")(GetDimVariables "AF2500.dim" SLST)))
)

(defun GetDimVariables ( file flag / _ReadNextifFoo StringParser l )

 (defun _ReadNextifFoo ( file foo) ;; Lee Mac

   (cond (  (not (setq f (open file "r"))) nil)

         (t (while (and (setq n (read-line f)) (not (foo n))))

            (setq n (read-line f))
            (close f)
         )
   )
   n
 )

 (defun StringParser ( str del ) ;; Lee Mac
 
   (if (setq pos (vl-string-search del str))
     (cons (substr str 1 pos)
           (StringParser (substr str (+ pos 1 (strlen del))) del))
     (list str)
   )
 )

 (mapcar (function distof)

   (cond (  (not (findfile file)) nil)

         (  (setq l (_ReadNextifFoo file (lambda ( line ) (eq line flag))))

            (StringParser l ",")
         )
   )
 )
)
; 

Link to comment
Share on other sites

Ok,

 

I see what I did wrong.

 

  (cond
   ((= CLASS "150#") (setq FNAM (findfile "AF150.dim"))(GetDimVariables FNAM SLST)) 

 

Now I got values.

 

Command: !N
"3.50 | 0.38 | 0.44 | 1.38 | 1.19 | 0.84 | 4.0 | 0.31 | 2.38 | 0.88 | 0.62 | 
0.90 | 0.5 | 0.0625 | 0.56 | 1.81 | 0.62 | 0.5" 

Link to comment
Share on other sites

Buzzard,

 

The findfile is already used within the GetDimVariables function.

 

The point of the function is to return the list of values should it be successful, else return nil. Hence in this way it can be used in a boolean check.

 

Notice that, if at any point, either the subfunctions or the main function fail, the whole function returns nil without error.

Link to comment
Share on other sites

Buzzard,

 

The findfile is already used within the GetDimVariables function.

 

The point of the function is to return the list of values should it be successful, else return nil. Hence in this way it can be used in a boolean check.

 

Notice that, if at any point, either the subfunctions or the main function fail, the whole function returns nil without error.

Thats just the trouble, When I used it as previous I did not get the values. I thought that was the idea. I assumed it did not know where the file was.

Link to comment
Share on other sites

You need to use it in a conditional, there should be no assumption.

 

By the way, you should never ever use LISP function syntax as variable names - you are redefining the symbol in this way. Are you using the VLIDE to write the code? If so, functions should show in blue - it greatly reduces the risk of this mistake.

Link to comment
Share on other sites

You need to use it in a conditional, there should be no assumption.

 

By the way, you should never ever use LISP function syntax as variable names - you are redefining the symbol in this way. Are you using the VLIDE to write the code? If so, functions should show in blue - it greatly reduces the risk of this mistake.

Not sure what you are talking about there. What protected name did I use?

 

FNAM SLST is all I used here.

Link to comment
Share on other sites

This is how I might approach the problem:

 

(defun c:test ( / class size a b c )

 (setq class "150#" size "*1/2")

 (if
   (mapcar (function set) '( a b c )
     (GetDimVariables
       (strcat "AF" (substr class 1 (1- (strlen class))) ".dim") size
     )
   )

   (mapcar (function print) (list a b c))
 )
 (princ)
)
     

(defun GetDimVariables ( file flag / _ReadNextifFoo StringParser l )

 (defun _ReadNextifFoo ( file foo) ;; Lee Mac

   (cond (  (not (setq f (open file "r"))) nil)

         (t (while (and (setq n (read-line f)) (not (foo n))))

            (setq n (read-line f))
            (close f)
         )
   )
   n
 )

 (defun StringParser ( str del ) ;; Lee Mac
 
   (if (setq pos (vl-string-search del str))
     (cons (substr str 1 pos)
           (StringParser (substr str (+ pos 1 (strlen del))) del))
     (list str)
   )
 )

 (mapcar (function distof)

   (cond (  (not (findfile file)) nil)

         (  (setq l (_ReadNextifFoo file (lambda ( line ) (eq line flag))))

            (StringParser l ",")
         )
   )
 )
)

Link to comment
Share on other sites

TYPE       (car SELECTION)

Ok,

 

I see that now. I will have to fix that.

 

So thats what causing the nil value?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...