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

0 Members and 1 Guest are viewing this topic.

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