Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
*Expert Elite*
Kent1Cooper
Posts: 5,795
Registered: ‎09-13-2004
Message 11 of 18 (252 Views)

Re: Assign variable if item is a member of a list?

01-19-2013 05:51 AM in reply to: mid-awe

Without loading it up and trying it, I suspect what you need to do is to change this section:

....

     (cond
       ((foreach PLANT PALM (member PLANT PALM)) "PALM")
       ((foreach PLANT TREE (member PLANT TREE)) "TREE")
       ((foreach PLANT SHRUB (member PLANT SHRUB)) "SHRUB")
     )

....

to just this:

....

     (cond
       ((member PLANT PALM) "PALM")
       ((member PLANT TREE) "TREE")
       ((member PLANT SHRUB) "SHRUB")
     )

....

Kent Cooper
*Expert Elite*
pbejse
Posts: 2,502
Registered: ‎11-24-2009
Message 12 of 18 (250 Views)

Re: Assign variable if item is a member of a list?

01-19-2013 06:24 AM in reply to: mid-awe

So you basically want to  process every item on the list if and only if the block associated with the list exists on the drawing session

 

Here's a demo: You may need to add your list before you try this code :

 

(Defun c:demo ( / MasterList Palm Tree shrub dictname)    
(vl-load-com)
;;;	This section will create a master list filtering out items  	;;;
;;;	if the block does not exist in the drawing session		;;;
(if  (setq MasterList (mapcar 'cadr
	(vl-remove-if-not
	  	'(lambda (i)(tblsearch "block" (car i)))
	        '(("Palms_DYN" PALM) ("Tree_DYN"  TREE)("SHRUB_DYN" SHRUB)))))
;;;	This section will iterate thru the remaining list variables	;;;
  
  	(foreach lst MasterList
          	(setq dictname (vl-symbol-name lst))
          	(foreach key (eval lst)
                  	(princ (strcat "\n" key ": " (rtos (dict-get dictname key) 2 0)))
                  )
          )
  (princ "\nBlocks Not found")
  )
  (princ)
  )

 

HTH

Valued Mentor
martti.halminen
Posts: 344
Registered: ‎12-31-2009
Message 13 of 18 (234 Views)

Re: Assign variable if item is a member of a list?

01-21-2013 03:19 AM in reply to: Kent1Cooper

Kent1Cooper wrote:

 

...

 

But you're not correct about the second problem, though I grant that it might be better not to use that word as an argument, just to avoid any possible confusion.  "List" as used there is not a variable in the usual sense [there is no (setq List ...) happening], but rather a place-holder argument inside the (foreach) function.  Yes, the AutoLISP Reference describes it as assigning each item to a variable named for the 'name' argument, but it's not in the same way as (setq) does it.  Think of it as being like a localized variable in a (defun)'d routine or command, in that it has no meaning, nor any effect on anything else, outside the (foreach) function in which it is used.  It does work.  If I do this:

 

(setq ListA '(1 2 3) ListB '(4 5 6) ListC '(7 8 9))

 

and then run that routine, removing the [...etc....] part from the top line, and using [for example] 6 for YourItem, it puts into VariableForUseLater the correct list:

 

!VariableForUseLater

(4 5 6)

 

And similarly finds the correct list with other YourItem values.  And it has no effect on the (list) function, which continues to function normally afterwards.


I don't know the compiler internals, but running the interpreter in the VLIDE Console window I seem to be getting
different results:

 

$ (setq lista '(1 2 3) listb '(4 5 6) listc '(7 8 9))
(7 8 9)
_$ (setq MasterList (list ListA ListB ListC))
((1 2 3) (4 5 6) (7 8 9))
_$ (foreach List MasterList

  (if (member YourItem List)

    (setq VariableForUseLater List)

  ); if

); foreach
; User warning: assignment to protected symbol: LIST <- (1 2 3)
_1_$

 

...............
LOG Trace stack
...............
<1> :smileytongue:ROTECT-ASSIGN LIST := (1 2 3)
[2] (FOREACH ...)
[3] (#<USUBR @2c4512d0 -top->)
<4> :USER-INPUT (foreach List MasterList
    (if (member YourItem List)
        (setq VariableForUseLater List)))
<5> :CALLBACK-ENTRY
[6] (C:VLIDE)
<7> :CALLBACK-ENTRY

 

 

- On the other hand, the assignment disappears outside the FOREACH call, so this would only produce an error if I tried to call the LIST function inside the FOREACH loop:

 

_$ (foreach list '((1)(2)) (print (list list)))
; User warning: assignment to protected symbol: LIST <- (1)
_1_$
; continue after break loop
; error: bad function: (1)

_1$ list
(1)
_1$
; reset after error
_$ list
#<SUBR @28058e08 LIST>

--

*Expert Elite*
Kent1Cooper
Posts: 5,795
Registered: ‎09-13-2004
Message 14 of 18 (222 Views)

Re: Assign variable if item is a member of a list?

01-21-2013 05:30 AM in reply to: martti.halminen

martti.halminen wrote:
.... 

- On the other hand, the assignment disappears outside the FOREACH call, so this would only produce an error if I tried to call the LIST function inside the FOREACH loop:

....


It did occur to me later that there could be a problem in that circumstance, so your suggestion not to use that as an argument name is certainly worthwhile.

Kent Cooper
Mentor
mid-awe
Posts: 1,230
Registered: ‎12-08-2004
Message 15 of 18 (216 Views)

Re: Assign variable if item is a member of a list?

01-21-2013 07:08 AM in reply to: pbejse

Thank you all for your help. Maybe this should not have been so difficult but it was. I really appreciate everyones help and now this is working exactly as I need it to. A great solution here saving me hundreds of lines of code. Again, thank you all. :smileyvery-happy:

Mentor
mid-awe
Posts: 1,230
Registered: ‎12-08-2004
Message 16 of 18 (209 Views)

Re: Assign variable if item is a member of a list?

01-21-2013 11:03 AM in reply to: pbejse

I have one more quick question.

 

I tried to use :

 

(foreach PLANT (vl-sort PLANTS '(lambda (x y) (< (car x) (car y))))
  (setq CATEGORY (vl-symbol-name PLANT))
  (foreach PLANTNAME (eval PLANT)
    (if	(>= (dict-get CATEGORY PLANTNAME) 1)
      (princ (strcat "\n\t "
		     PLANTNAME
		     " : "
		     (rtos (dict-get CATEGORY PLANTNAME) 2 0)
	     )
      )
    )
    (setq total (+ total (dict-get CATEGORY PLANTNAME)))
  )
)

 To get the list alphabetized, but it didn't work. How can I do it correctly?

 

Thank you.

*Expert Elite*
pbejse
Posts: 2,502
Registered: ‎11-24-2009
Message 17 of 18 (197 Views)

Re: Assign variable if item is a member of a list?

01-21-2013 06:58 PM in reply to: mid-awe

mid-awe wrote:

I have one more quick question.

 

 To get the list alphabetized, but it didn't work. How can I do it correctly?

 

Thank you.


Since  the plant lists are hard-coded, you can sort the lists PALM/TREE/SHRUBS then paste the sorted list in your code:

 

(acad_strlsort palm)

("Bismark" "Blue Fan" "Date" "Fan" "Pindo" "Pineapple" "Ponytail" "Pygmy" "Queen" "Sabal" "Sago" "Windmill")

(acad_strlsort shrub)

(acad_strlsort tree)

 

That way you dont have to sort the list everytime you use your routine

 

HTH

 

Cheers

 

Mentor
mid-awe
Posts: 1,230
Registered: ‎12-08-2004
Message 18 of 18 (170 Views)

Re: Assign variable if item is a member of a list?

01-22-2013 02:31 PM in reply to: pbejse

Thank you. I had a crazy idea about haveing the entire list sorted, but then I realized it makes little sense because they are categorized :smileylol:

Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!