Author Topic: Greater than or equal to...  (Read 12176 times)

0 Members and 1 Guest are viewing this topic.

Water Bear

  • Guest
Greater than or equal to...
« on: April 15, 2004, 04:54:06 PM »
I'm trying to read an external file that requires a number to fall within a range using this list as an example
Quote
*****          test file  (gage,stock,slips)             *****
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75
*54
22.0,60.0,1.75
*72
20.0,30.0,1.75
*100
18.0,30.0,1.75

And using this code...
Code: [Select]
(defun shop_spec (/); item data dline maxs count chrct numb size)
  (setq size  (max 60.0 36.0 28.0 24.0) ;<==sample sizes
dlist nil
file  (findfile "specs.dat")
fp    (open file "r")
item  (read-line fp)
) ;setq

  (while item
    (setq item (atof (substr item 2)))
    (if (>= item size );<====== this is the problem, I believe
      (setq data (read-line fp)
   item nil
   ) ;setq
      (setq item (read-line fp))
      ) ;if
    )...yadayada)

if the largest size is 60.0 it should be reading the line immediately following the *54 (because it falls between 54 and 72)... but it doesn't it skips to the next line (because 54 is NOT greaterthan or equal), however if I reverse those two it will read the first line it comes to (*12)  :shock:

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Greater than or equal to...
« Reply #1 on: April 15, 2004, 06:10:24 PM »
I changed your code a little, but I believe it's doing what you're asking it to do.
Code: [Select]

(defun shop_spec (/ size dlist file fp line item data)

   (setq size  (max 60.0 36.0 28.0 24.0) ;<==sample sizes
         dlist nil
         file  (findfile "specs.dat")
         fp    (open file "r")
         ) ;setq

   (while
     (setq line (read-line fp))

      (setq item (atof (substr line 2)))
      (if (>= item size) ;<====== this is the problem, I believe
        (setq data (read-line fp)); <-- where i'm confused
        ) ;if

     (if data
        (princ (strcat "\n" data))
        )
     
      (princ)
      ) ; while
   (close fp)
   )
TheSwamp.org  (serving the CAD community since 2003)

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Greater than or equal to...
« Reply #2 on: April 15, 2004, 06:36:56 PM »
Re-reading your post.......... I think you need to store the previous line each time through the while statement.
TheSwamp.org  (serving the CAD community since 2003)

Water Bear

  • Guest
Greater than or equal to...
« Reply #3 on: April 15, 2004, 06:38:41 PM »
Maybe I should post the entire code.
Code: [Select]
(defun C:Test (/ item data dline maxs count chrct numb size)
  (setq size  (max 60.0 36.0 28.0 24.0) ;<==sample sizes
dlist nil
file  (findfile "specs.dat")
fp    (open file "r")
item  (read-line fp);<==just to hold file header
) ;setq

  (while item
    (setq item (atof (substr item 2)))
    (if (>= item size) ;<================== here
      (setq data (read-line fp)
   item nil
   ) ;setq
      (setq item (read-line fp))
      ) ;if
    ) ;while
  (if data
    (progn
      (setq maxs  (strlen data)
   count 1
   chrct 1
   ) ;setq
      (while (< count maxs)
(if (/= "," (substr data count 1))
 (setq chrct (1+ chrct))
 (setq numb  (atof
(substr data
(1+ (- count chrct))
chrct
)
)
dlist (append dlist (list numb))
chrct 1
) ;setq
 ) ;if
(setq count (1+ count))
) ;while
      (setq numb  (atof
   (substr data
   (1+ (- count chrct))
   )
   )
   dlist (append dlist (list numb))
   ) ;setq
      ) ;progn
    ) ;if data
  (close fp)
  (mapcar 'set '(a b c) dlist)
  )
This is what I had originally. The last line should set three variables from the list (in this case the ones listed in betweem *54 and *72

Mark

  • Custom Title
  • Seagull
  • Posts: 28762
Greater than or equal to...
« Reply #4 on: April 15, 2004, 06:49:17 PM »
Quote

*54
22.0,60.0,1.75  <-- is this what you're after ?
*72
TheSwamp.org  (serving the CAD community since 2003)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #5 on: April 15, 2004, 07:33:54 PM »
Code: [Select]
(defun shop_spec (/ size dlist file fp line item data)

  (setq size  (max 60.0 36.0 28.0 24.0) ;<==sample sizes
        dlist nil
        file  (findfile "specs.dat")
        fp    (open file "r")
        loop  t
  ) ;setq

  (while loop
    (cond
      ((setq line (read-line fp)) ; not eof
       (cond
         ((= (substr line 1 2) "**") ; header line
          ;;  do nothing
         )
         ((= (substr line 1 1) "*") ; flag line so test it
          (if (>= (atof (substr line 2)) size) ; we passed the dataline
            (progn
              (if (setq data lastline) ; not nil
                (setq loop nil) ; exit loop
                (alert "/nERROR size < smallest flag.")
              )
            )
          )
         )
         (t ; this is a data line, so save it
          (setq dataline line)
         )
       ) ; end cond stmt
      )
      (t
       (alert "/nERROR end of file.")
       (setq loop nil)
      )
    ) ; end cond stmt
  ) ; while
  (close fp)
  data ; return data      
) ; end defun
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Water Bear

  • Guest
Greater than or equal to...
« Reply #6 on: April 15, 2004, 08:09:22 PM »

Thanks for the help guys, but I have to allow for my own thickness...I still can't get it to work!
Quote
***** test file (gage,stock,slips) *****
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75
*54
22.0,60.0,1.75
*72
20.0,30.0,1.75
*100
18.0,30.0,1.75
I'm trying to set this up:
1-a duct less or equal to 12 is made of 26 ga., 96 in long, 1/2 in for connection
2-a duct greater than 12 but less than 31 24ga., 60 in long, 1.75 for connection
3-a duct greater than 31 but less than 54 22ga., 60 in long, 1.75 for connection
4-a duct greater than 54 but less than 72 20ga., 60 in long, 1.75 for connection
5-anything larger than 72 18ga., 30 in long, 1.75 for connections

In the sample, the largest size is 60.0, therefore we should use option 4 ,but because of this part of the code:
Quote
(while item
    (setq item (atof (substr item 2)))
    (if   (>= item size)         ;<================== here
      (setq data (read-line fp)
       item nil
       )            ;setq
      (setq item (read-line fp))
      )               ;if
    )        
It skips to the next line and reads the *72 line

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #7 on: April 15, 2004, 09:19:00 PM »
This has the data line first, before the 12

Code: [Select]
***** test file (gage,stock,slips) *****
26.0,96.0,0.5
*12  
24.0,60.0,1.75
*31
22.0,60.0,1.75
*54
20.0,30.0,1.75
*72
18.0,30.0,1.75
*100


Code: [Select]
(defun shop_spec (size / dlist file fp line item data)

  (setq dlist nil
        file  (findfile "specs.dat")
        fp    (open file "r")
        loop  t
  ) ;setq

  (while loop
    (cond
      ((setq line (read-line fp)) ; not eof
       (cond
         ((= (substr line 1 2) "**") ; header line
          ;;  do nothing
         )
         ((= (substr line 1 1) "*") ; flag line so test it
          (if (>= (atof (substr line 2)) size); we passed the dataline
            (progn
              (if (setq data dataline) ; not nil
                (setq loop nil) ; exit loop
                (setq data (read-line fp))
              )
            )
          )
         )
         (t ; this is a data line, so save it
          (setq dataline line)
         )
       ) ; end cond stmt
      )
      (t
       (alert "/nERROR end of file.")
       (setq loop nil)
      )
    ) ; end cond stmt
  ) ; while
  (close fp)
  data ; return data      
) ; end defun


(defun c:test ()
  (foreach sz (list 60.0 36.0 28.0 24.0)
    (princ (strcat "\n" (rtos sz 2 1) " = " (shop_spec sz)))
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #8 on: April 15, 2004, 09:34:57 PM »
This way has the data line after the 12


Code: [Select]
***** test file (gage,stock,slips) *****
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75
*54
22.0,60.0,1.75
*72
20.0,30.0,1.75
*100
18.0,30.0,1.75


Code: [Select]
(defun shop_spec (size / dlist file fp line item data)

  (setq dlist nil
file  (findfile "specs.dat")
fp    (open file "r")
loop  t
  ) ;setq

  (while loop
    (cond
      ((setq line (read-line fp)) ; not eof
       (cond
((= (substr line 1 2) "**") ; header line
 ;;  do nothing
)
((= (substr line 1 1) "*") ; flag line so test it
 (if (>= (atof (substr line 2)) size); max found
   (progn
     (setq loop nil) ; exit loop
     (setq data (read-line fp))
   )
 )
)
       ) ; end cond stmt
      )
      (t
       (alert "/nERROR end of file.")
       (setq loop nil)
      )
    ) ; end cond stmt
  ) ; while
  (close fp)
  data ; return data      
) ; end defun


(defun c:test ()
  (foreach sz (list 10.0 60.0 36.0 28.0 75.0)
    (princ (strcat "\n" (rtos sz 2 1) " = " (shop_spec sz)))
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Water Bear

  • Guest
Greater than or equal to...
« Reply #9 on: April 15, 2004, 09:39:18 PM »
Where does the variable "dataline" come from?
Quote
(cond
      ((setq line (read-line fp)) ; not eof
       (cond
         ((= (substr line 1 2) "**") ; header line
          ;;  do nothing
         )
         ((= (substr line 1 1) "*") ; flag line so test it
          (if (>= (atof (substr line 2)) size); we passed the dataline
            (progn
              (if (setq data dataline) ; not nil;<== dataline??
                (setq loop nil) ; exit loop
                (setq data (read-line fp))
              )
            )
          )
         )
         (t ; this is a data line, so save it
          (setq dataline line)
         )
       ) ; end cond stmt

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #10 on: April 15, 2004, 09:57:22 PM »
It is used in the first routine to hold the dataline before the flag line

Code: [Select]
(while loop
    (cond
      ((setq line (read-line fp)) ; not eof
       (cond
         ((= (substr line 1 2) "**") ; header line
          ;;  do nothing
         )
         ((= (substr line 1 1) "*") ; flag line so test it
          (if (>= (atof (substr line 2)) size); we passed the dataline
            (progn
              (if (setq data dataline) ; not nil
                (setq loop nil) ; exit loop
                (setq data (read-line fp))
              )
            )
          )
         )
         (t ; this is a data line, so save it
          (setq dataline line)  ; <<<===== HERE is where it is updated
         )
       ) ; end cond stmt
      )
      (t
       (alert "/nERROR end of file.")
       (setq loop nil)
      )
    ) ; end cond stmt
  ) ; while
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Water Bear

  • Guest
Greater than or equal to...
« Reply #11 on: April 15, 2004, 10:22:58 PM »
So you're saying that I have to run something like the first routine to hold the dataline, then run the second to trap it?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #12 on: April 15, 2004, 11:28:53 PM »
Nice chicken..

I should have been more clear.

The last routine expects the data file like this:

***** test file (gage,stock,slips) *****
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75


Note that the data line follows the code flag line *12 followed by 26.0,96.0,0.5
====================================================================================

The routine before that expects the data line to be before the code flag like this:

***** test file (gage,stock,slips) *****
26.0,96.0,0.5
*12  
24.0,60.0,1.75
*31

Note that the code line follows the data line 26.0,96.0,0.5 followed by *12

Just two options & how the data format affects the coding.
I got carried away, what can I say...

CAB
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #13 on: April 15, 2004, 11:58:44 PM »
Last one :)

Data format:

Code: [Select]
***** test file (gage,stock,slips) *****
***  Ducts < 12 inch use the data line following the 12
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75
*54
22.0,60.0,1.75
*72
20.0,30.0,1.75
*100
18.0,30.0,1.75


Code: [Select]
(defun shop_spec (size / dlist file fp line item data)
  (setq dlist nil
        file  (findfile "specs.dat")
        fp    (open file "r")
        loop  t
  ) ;setq

  (while loop
    (cond
      ((setq line (read-line fp)) ; not eof
       (cond
         ((= (substr line 1 2) "**") ; header line
          ;;  do nothing
         )
         ((= (substr line 1 1) "*") ; flag line so test it
          (if (> (atof (substr line 2)) size) ; max found
            (progn
              (setq loop nil) ; exit loop
              (setq data (read-line fp))
            )
          )
         )
       ) ; end cond stmt
      )
      (t
       (alert "/nERROR end of file.")
       (setq loop nil)
      )
    ) ; end cond stmt
  ) ; while
  (close fp)
  data ; return data      
) ; end defun


(defun str2list (str pat / i j n lst)
  (cond
    ((/= (type str) (type pat) 'str))
    ((= str pat) '(""))
    (t
     (setq i 0
           n (strlen pat)
     )
     (while (setq j (vl-string-search pat str i))
       (setq lst (cons (substr str (1+ i) (- j i)) lst)
             i   (+ j n)
       )
     )
     (reverse (cons (substr str (1+ i)) lst))
    )
  )
)


;;================================================================

(defun c:test ()
  (foreach sz (list 12.0 60.0 36.0 28.0 78.0)
    (setq dstr  (shop_spec sz)
          dlist (str2list dstr ",")
    )
    (mapcar 'set '(a b c) dlist)
    (princ (strcat "\n" (rtos sz 2 1) " = " dstr))
  )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

NoLisper

  • Guest
Greater than or equal to...
« Reply #14 on: April 16, 2004, 05:10:07 AM »
Here's how I'll do it using a data file.
Can also be done without using a data file,
by inputting the data in the cond section.

Header line (*12 etc) must not have an extra
space before or after.

Code: [Select]


(defun getdata (xsize / datalist df found fp line)
  (setq str
    (cond
      ((<= xsize 12) "*12")
      ((< 12 xsize 32) "*31")    
      ((< 31 xsize 55) "*54")    
      ((< 54 xsize 73) "*72")    
      (T "*100")
    )
    df  (findfile "specs.dat")
    fp    (open df "r")
    datalist ""
    found nil
  )
  (while (and (not found)
              (setq line (read-line fp))
         )
    (if (= line str)
      (setq datalist (strcat datalist (read-line fp))
            found T
      )
      (if (and found fp) (close fp))
    )
  )
  (if (and fp (not found)) (close fp))
  datalist
)


SMadsen

  • Guest
Greater than or equal to...
« Reply #15 on: April 16, 2004, 07:36:00 AM »
I like to use different char's for different purposes - that way you only need to check the first char of a line. For example, semicolon for remarks, asterix for headers etc.

Otherwise, I'd write it much like CAB did:

Code: [Select]
;;; test file (gage,stock,slips)
;;; Ducts < 12 inch use the data line following the 12
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75
*54
22.0,60.0,1.75
*72
20.0,30.0,1.75
*100
18.0,30.0,1.75

==========

(defun shop_spec (size / char fn fp line lst nsize)
  (cond ((setq fn (findfile "specs.dat"))
         (setq fp (open file "r"))
         (while (setq line (read-line fp))
           (setq char (substr line 1 1))
           (cond ((= char ";"))
                 ((= char "*")
                  (and (numberp (setq nsize (read (substr line 2))))
                       (>= nsize size)
                       (setq lst (cons (read-line fp) lst))
                  )
                 )
           )
         )
         (close fp)
        )
  )
  (reverse lst)
)

(defun str2nums (aStr delim / strList pos)
  (while (setq pos (vl-string-search delim aStr 0))
    (setq strList (cons (substr aStr 1 POS) strList)
          aStr    (substr aStr (+ pos 2))
    )
  )
  (mapcar 'atof (reverse (cons aStr strList)))
)

(defun C:TEST ()
  (mapcar (function (lambda (n)(str2nums n ",")))
          (shop_spec 54)
  )
)

Water Bear

  • Guest
Greater than or equal to...
« Reply #16 on: April 16, 2004, 08:40:07 AM »
Good work guys! Now suppose I have four globals g:wid1 g:dep1 g:wid2 g:dep2 and I want the routine to get the largest number and check it against our list. Would I do something like this:
Code: [Select]
(setq size (max g:wid1 g:dep1 g:wid2 g:dep2)) and  a command such as (shop_spec size) to run it? Or is there a cleaner way?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #17 on: April 16, 2004, 11:32:53 AM »
DAMN Stig !!!!!

You make me feel like "Fred the house painter"
and I'll call you Mr. da Vinci. And you wrote the code without
even having to test it.  

Seriously though glad to see you back, you've been quiet lately.

There were three minor tweaks and I commented the code to the best of my ability.
Your original returned all data lines where ( < nsize size );
This version only returns one data line.

Code: [Select]
(defun shop_spec (size / char fn fp line lst nsize)
  ;;  if the file is found proceed
  (cond ((setq fn (findfile "specs.dat"))
         (setq fp (open fn "r")) ; open file read only
         ;;  read all line in a loop
         (while (setq line (read-line fp)) ; line is a string data type
           ;;  get the first char of the line
           (setq char (substr line 1 1))
           (cond ((= char ";")) ; do nothing character
                 ((= char "*") ; flag character
                  ;; 1st two lines need to be true to do the third
                  (and (numberp  ; verify we got a number
                         (setq nsize (read ; convert to number if it is one
                                       (substr line 2); get all but 1 char
                        )))
                       ;;  test for size match
                       (< nsize size); changed this from >=
                       ;; if line 1 & 2 are true, add data to list
                       ;;(setq lst (cons (read-line fp) lst))
                       ;; changed this to return only one data line group
                       (setq lst (read-line fp))
                  )
                 ) ; end flag
           ) ; end cond stmt
         ) ; end while
         (close fp)
        ) ; end file found
  ) ; end cond stmt
  lst ; return the list, changed from (reverse lst)
) ; end defun


;;  from a string & delimiter char return the numbers
(defun str2nums (aStr delim / strList pos)
  (while (setq pos (vl-string-search delim aStr 0))
    (setq strList (cons (substr aStr 1 POS) strList)
          aStr    (substr aStr (+ pos 2))
    )
  )
  (mapcar 'atof (reverse (cons aStr strList)))
)

(defun C:TEST ()
  ;;(setq msize (max g:wid1 g:dep1 g:wid2 g:dep2)) yes WB this will work
  (setq mSize 54) ; for test
  ;;  return a list of numbers
  (mapcar  ; repeat the function foreach item in the list
    (function (lambda (n)(str2nums n ",")))
          (list ; added this to make it a list
            (shop_spec mSize) ; this returns the data string
            )
  )
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Greater than or equal to...
« Reply #18 on: April 16, 2004, 12:52:28 PM »
Oh, thought it should return all greater than or equal to (isn't that the topic title??)  :)

I almost always make such routines build association lists .. i.e. read all data at once and then extract required item(s). Maybe thats why it returned multiple items.

Water Bear

  • Guest
Greater than or equal to...
« Reply #19 on: April 16, 2004, 01:13:11 PM »
Good stuff!!

I've been looking at your code for a while, to see how it would integrate with my routine...how can I assign each variable in this list to individual variables?
Code: [Select]
(defun C:TEST ()
  (setq msize (max #wid1 #dep1 #wid2 #dep2)) ;yes WB this will work

  ;;  return a list of numbers
  (setq dlist (mapcar ;; repeat the function foreach item in the list
     (function (lambda (n) (str2nums n ",")))
     (list ;; added this to make it a list
   (shop_spec mSize)
   ;; this returns the data string
   )
     )
)
  (mapcar 'set '(gage stock slips) dlist);<=I'm doing something wrong here
  (setq cutsheet (- stock (* slips 2.0)))
  )
I need to do other stuff with variables "gage" "stock" "slips"

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #20 on: April 16, 2004, 01:26:36 PM »
Code: [Select]
(defun C:TEST ()
  (setq msize (max g:wid1 g:dep1 g:wid2 g:dep2)) yes WB this will work
   ;;  return a list of numbers
  (setq dlist (car
    (mapcar  ; repeat the function foreach item in the list
      (function (lambda (n)(str2nums n ",")))
            (list ; added this to make it a list
              (shop_spec mSize) ; this returns the data string
              )
    )
  ))
  (mapcar 'set '(gage stock slips) dlist)
  (setq cutsheet (- stock (* slips 2.0)))
 )
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Water Bear

  • Guest
Greater than or equal to...
« Reply #21 on: April 16, 2004, 01:53:44 PM »
OK I got it CAB...since the set only contained one element you used "car" to select it...
thanx

Water Bear

  • Guest
Greater than or equal to...
« Reply #22 on: April 16, 2004, 03:10:10 PM »
CAB..still having problems note that if I use this
Quote
***** test file (gage,stock,slips) *****
*12
26.0,96.0,0.5
*31
24.0,60.0,1.75
*54
22.0,60.0,1.75
*72
20.0,30.0,1.75
*100
18.0,30.0,1.75
With this code
Code: [Select]
(defun shop_spec (size / char fn fp line lst nsize)
  ;;  if the file is found proceed
  (cond ((setq fn (findfile "specs.dat"))
         (setq fp (open fn "r")) ; open file read only
         ;;  read all line in a loop
         (while (setq line (read-line fp)) ; line is a string data type
           ;;  get the first char of the line
           (setq char (substr line 1 1))
           (cond ((= char ";")) ; do nothing character
                 ((= char "*") ; flag character
                  ;; 1st two lines need to be true to do the third
                  (and (numberp  ; verify we got a number
                         (setq nsize (read ; convert to number if it is one
                                       (substr line 2); get all but 1 char
                        )))
                       ;;  test for size match
                       (< nsize size); changed this from >=
                       ;; if line 1 & 2 are true, add data to list
                       ;;(setq lst (cons (read-line fp) lst))
                       ;; changed this to return only one data line group
                       (setq lst (read-line fp))
                  )
                 ) ; end flag
           ) ; end cond stmt
         ) ; end while
         (close fp)
        ) ; end file found
  ) ; end cond stmt
  lst ; return the list, changed from (reverse lst)
) ; end defun


;;  from a string & delimiter char return the numbers
(defun str2nums (aStr delim / strList pos)
  (while (setq pos (vl-string-search delim aStr 0))
    (setq strList (cons (substr aStr 1 POS) strList)
          aStr    (substr aStr (+ pos 2))
    )
  )
  (mapcar 'atof (reverse (cons aStr strList)))
)

(defun C:TEST ()
  ;;(setq msize (max g:wid1 g:dep1 g:wid2 g:dep2)) yes WB this will work
  (setq mSize 54) ; for test
  ;;  return a list of numbers
  (mapcar  ; repeat the function foreach item in the list
    (function (lambda (n)(str2nums n ",")))
          (list ; added this to make it a list
            (shop_spec mSize) ; this returns the data string
            )
  )
)
The test setup you have (for 54" inch duct) should be coming up with 22.0,60.0,1.75 but it comes up 24.0,60.0,1.75  :shock:

I think it's this line ===>  (< nsize size); changed this from >=
..same one that has been pestering me from the outset!

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #23 on: April 16, 2004, 03:23:59 PM »
change this line
Code: [Select]
(< nsize size); changed this from >=

to this
Code: [Select]
(<= nsize size)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Water Bear

  • Guest
Greater than or equal to...
« Reply #24 on: April 16, 2004, 04:38:56 PM »
Doesn't seem to work that way. If I draw a 24 in duct...the first item evaluated is *12  and the query is if  "nsize (*12) is less than ductsize use the next line" not right. Maybe I need to restructure the .dat file

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #25 on: April 16, 2004, 07:54:46 PM »
Ok I had to reverse the order of the data file.
And I changed the routine.

Code: [Select]

***** test file (gage,stock,slips) *****
***  1000 is for any size over 100
*1000
18.0,30.0,1.75
*100
18.0,30.0,1.75
*72
20.0,30.0,1.75
*54
22.0,60.0,1.75
*31
24.0,60.0,1.75
*12
26.0,96.0,0.5


Code: [Select]
(defun shop_spec (size / char fn fp line lst nsize)
  ;;  if the file is found proceed
  (cond ((setq fn (findfile "specs.dat"))
         (setq fp (open fn "r")) ; open file read only
         ;;  read all line in a loop
         (while (setq line (read-line fp)) ; line is a string data type
           ;;  get the first char of the line
           (setq char (substr line 1 1))
           (cond ((= char ";")) ; do nothing character
                 ((= char "*") ; flag character
                  ;; 1st two lines need to be true to do the third
                  (and (numberp  ; verify we got a number
                         (setq nsize (read ; convert to number if it is one
                                       (substr line 2); get all but 1 char
                        )))
                       (>= nsize size);  test for size match
                       ;; if line 1 & 2 are true,
                       ;; get lst if test size < code size
                       (setq lst (read-line fp))
                  )
                 ) ; end flag
           ) ; end cond stmt
         ) ; end while
         (close fp)
        ) ; end file found
  ) ; end cond stmt
  lst ; return the list, changed from (reverse lst)
) ; end defun


;;  from a string & delimiter char return the numbers
(defun str2nums (aStr delim / strList pos)
  (while (setq pos (vl-string-search delim aStr 0))
    (setq strList (cons (substr aStr 1 POS) strList)
          aStr    (substr aStr (+ pos 2))
    )
  )
  (mapcar 'atof (reverse (cons aStr strList)))
)

(defun c:test ()
  ;;(setq msize (max g:wid1 g:dep1 g:wid2 g:dep2)) yes WB this will work
  (foreach msize '(120 10 12 30 31 32 53 54 55 120) ; for test
    ;;  return a list of numbers
    (setq dlist (car
                  (mapcar ; repeat the function foreach item in the list
                    (function (lambda (n) (str2nums n ",")))
                    (list ; added this to make it a list
                      (shop_spec msize) ; this returns the data string
                    )
                  )
                )
    )
    (princ (strcat "\n" (rtos msize 2 1) " = " ))
    (princ dlist)
  )
  (print)
  (mapcar 'set '(gage stock slips) dlist)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Water Bear

  • Guest
Greater than or equal to...
« Reply #26 on: April 17, 2004, 08:25:23 AM »
That works!Tell me though, why did you have to reverse the list? I'm trying to understand how u did it.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #27 on: April 17, 2004, 10:27:40 AM »
Well I could not figure it out last night, fatigue I guess.
The problem is when size is less that than 12 which is easily
overcome by adding code *0 to the list. I did the same for the other
end by adding *1000, but could not connect the dots last night.

Here is the revised code & data file:

Code: [Select]
***** test file (gage,stock,slips) *****
***  0 to 11.9 use 26.0,96.0,0.5
*0
26.0,96.0,0.5
***  12 to 30.9 use 24.0,60.0,1.75
*12
24.0,60.0,1.75
*31
22.0,60.0,1.75
*54
20.0,30.0,1.75
*72
18.0,30.0,1.75
*100
18.0,30.0,1.75


Results:
Code: [Select]
10.0 = (26.0 96.0 0.5)
12.0 = (24.0 60.0 1.75)
30.0 = (24.0 60.0 1.75)
31.0 = (22.0 60.0 1.75)
32.0 = (22.0 60.0 1.75)
53.0 = (22.0 60.0 1.75)
54.0 = (20.0 30.0 1.75)
55.0 = (20.0 30.0 1.75)
120.0 = (18.0 30.0 1.75)



Code: [Select]
(defun shop_spec (size / char fn fp line lst nsize)
  ;;  if the file is found proceed
  (cond ((setq fn (findfile "specs.dat"))
         (setq fp (open fn "r")) ; open file read only
         ;;  read all line in a loop
         (while (setq line (read-line fp)) ; line is a string data type
           ;;  get the first char of the line
           (setq char (substr line 1 1))
           (cond ((= char ";")) ; do nothing character
                 ((= char "*") ; flag character
                  ;; 1st two lines need to be true to do the third
                  (and (numberp  ; verify we got a number
                         (setq nsize (read ; convert to number if it is one
                                       (substr line 2); get all but 1 char
                        )))
                       (>= size nsize);  test for size match
                       ;; if line 1 & 2 are true,
                       ;; get lst if test size < code size
                       (setq lst (read-line fp))
                  )
                 ) ; end flag
           ) ; end cond stmt
         ) ; end while
         (close fp)
        ) ; end file found
  ) ; end cond stmt
  lst ; return the list, changed from (reverse lst)
) ; end defun


;;  from a string & delimiter char return the numbers
(defun str2nums (aStr delim / strList pos)
  (while (setq pos (vl-string-search delim aStr 0))
    (setq strList (cons (substr aStr 1 POS) strList)
          aStr    (substr aStr (+ pos 2))
    )
  )
  (mapcar 'atof (reverse (cons aStr strList)))
)

(defun c:test ()
  ;;(setq msize (max g:wid1 g:dep1 g:wid2 g:dep2)) yes WB this will work
  (foreach msize '(10 12 30 31 32 53 54 55 120) ; for test
    ;;  return a list of numbers
    (setq dlist (car
                  (mapcar ; repeat the function foreach item in the list
                    (function (lambda (n) (str2nums n ",")))
                    (list ; added this to make it a list
                      (shop_spec msize) ; this returns the data string
                    )
                  )
                )
    )
    (princ (strcat "\n" (rtos msize 2 1) " = " ))
    (princ dlist)
  )
  (print)
  (mapcar 'set '(gage stock slips) dlist)
)

;|
***** test file (gage,stock,slips) *****
***  0 to 11.9 use 26.0,96.0,0.5
*0
26.0,96.0,0.5
***  12 to 30.9 use 24.0,60.0,1.75
*12
24.0,60.0,1.75
*31
22.0,60.0,1.75
*54
20.0,30.0,1.75
*72
18.0,30.0,1.75
*100
18.0,30.0,1.75
|;
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Greater than or equal to...
« Reply #28 on: April 17, 2004, 11:39:30 AM »
Oh wow, this looks like a cool idea. (I havent read all the posts in this thread yet so pardon my haste. ...I got excited after the first post and went and wrote a few procedures based on how i would do something like this.)

Here is what i would do. Ive even made a small demonstration to help you visualise.

With this code:
Code: [Select]
(defun index (a) (car a))
(defun value (a) (cadr a)))
(defun >=Diff (a b)
  (if (>= b a)
    (list a (- b a))))
(defun SmallestDiff (a b)
  (if (< (value a) (value b)) (index a) (index b)))


You can run tests like this to get the approperiate index you need. (Remember this is still a rough idea and would need to be refined to put it to it's fullest potental.)

Code: [Select]
Command: *Cancel*

Command: (setq test1 (>=diff 12 60))
(60 48)

Command: (setq test2 (>=diff 54 60))
(60 6)

Command: (smallestDiff test1 test2)
60


Oops I found a mistake.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Greater than or equal to...
« Reply #29 on: April 17, 2004, 03:09:09 PM »
Ok i just got done Mowing a couple of lawns and i wanted to come back to explain myself better, cause that (^) isnt a very good explination.

Here take a look at this and tell me if you think its a good idea.

Code: [Select]
;;; Toss this a number, and two index's like so:
;;; (MyTester 60 12 57)
;;; And this procedure will return the index that the
;;; number is closest to but still being greater then or equal to
(defun index (a) (car a))
(defun value (a) (cadr a)))
(defun >=Diff (a b)
  (if (>= b a)
    (list a (- b a))))
(defun SmallestDiff (a b)
  (if (< (value a) (value b)) (index a) (index b)))
(defun MyTester (nu idx1 idx2)
  (smallestdiff (>=Diff idx1 nu) (>=Diff idx2 nu)))
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Greater than or equal to...
« Reply #30 on: April 18, 2004, 02:00:49 PM »
This is the way I would approach the problem.
Code: [Select]
;;  returns largest index >=
;;  else return nil
(defun >=index (nu idx1 idx2)
  (if (>= nu (max idx1 idx2)) (max idx1 idx2)))

;;  if between returns the idx closest to
;;  else return nil
(defun >< (nu idx1 idx2)
  (if (and (> nu (min idx1 idx2)) (< nu (max idx1 idx2)))
    (if (> (- idx1 nu) (- idx2 nu)) idx2  idx1)))


;;  if between or = max returns the idx closest to
;;  else return nil
(defun ><=Max (nu idx1 idx2)
  (if (and (> nu (min idx1 idx2)) (<= nu (max idx1 idx2)))
    (if (> (abs(- idx1 nu)) (abs(- idx2 nu))) idx2  idx1)))

;;  if between or = min returns the idx closest to
;;  else return nil
(defun ><=Min (nu idx1 idx2)
  (if (and (>= nu (min idx1 idx2)) (< nu (max idx1 idx2)))
    (if (> (abs(- idx1 nu)) (abs(- idx2 nu))) idx2  idx1)))


(defun diff (nu idx)
  (abs (- nu idx)))

(defun c:test()
  (print "=============")
  (Print  (>< 30 12 54))
  (Print  (>< 10 12 54))
  (print "=============")
  (Print  (><=max 30 12 54))
  (Print  (><=max 54 12 54))
  (Print  (><=max 55 12 54))
  (Print  (><=max 12 12 54))
  (print "=============")
  (Print  (><=min 30 12 54))
  (Print  (><=min 54 12 54))
  (Print  (><=min 11 12 54))
  (Print  (><=min 12 12 54))
  (print "=============")
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10625
Greater than or equal to...
« Reply #31 on: April 18, 2004, 04:30:25 PM »
Ok i did some reading and i think Stig has it right on.

Oh BTW, Cab, Very cool.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org