Jump to content

Toggle a variable N times


Grrr

Recommended Posts

Hi fellas,

I know about this way of toggling:

(defun c:test (/)
 (if (= (getvar "MyVariable") 1)
 (setvar "MyVariable" 0)
 (setvar "MyVariable" 1)
 )
 (princ (strcat "\nMyVariable is set to \"" (rtos(getvar "MyVariable") 2 0) "\" "  ))
 (princ)
)

But I'm trying to find out how to toggle with more than two values (in the example values are 0 and 1).

 

For the example I look:

If I had values 0 10 25 33 and 4, starting from zero,

launch the command and the value is changed to 10

launch the command again, and the value is changed to 25

launch the command again, and the value is changed to 33

launch the command again, and the value is changed to 4

launch the command again, and the value is changed to 0

 

For short, every re-launching of the command is changing the value to the next one from the list and the cycle is in that range (the last item of the list becomes first again).

 

Sorry for the long description (I don't know how is called this way of toggling), and thanks for the help in advance!

Link to comment
Share on other sites

(defun C:TOGGLE ()
 (setvar 'myvar
   (nth
     (rem (1+ (vl-position (getvar 'myvar) '(0 10 25 33 4))) 5)
     '(0 10 25 33 4)
   )
 )
 (print (getvar 'myvar))
 (princ)
)

Link to comment
Share on other sites

Just to offer an alternative, using the USERI1 system variable as an example:

(defun-q c:test ( / lst )
   (setq lst '(0 10 25 33 4))
   (setq c:test (vl-list* '( / lst ) (list 'setq 'lst (list 'quote (append (cdr lst) (list (car lst))))) (cddr c:test)))
   (setvar 'useri1 (car lst))
)

Link to comment
Share on other sites

Thank you for answering!

I'm trying to understand how the both methods work (check my comments).

 

Lee Mac's method:

(defun-q c:test ( / lst )                                                                                                  ; defun a quote?
   (setq lst '("A" "B" "C" "D" "E"))	                                                                                   ; construct the list
   (setq c:test (vl-list* '( / lst ) (list 'setq 'lst (list 'quote (append (cdr lst) (list (car lst))))) (cddr c:test)))  ; ????
   (setq storedvalue (car lst))                                                                                           ; set a quote and apply the first item from the list to it (car reports first item in the list)
   (princ (strcat "\nMyVariable is set to \"" storedvalue "\" "  ))                                                       ; print the quote for check
   (princ)														   ; exit silently
)														           ; end of quote definition

The third row blows my mind!

 

 

Stefan's method:

(defun C:test2 ( / )                                                    ; defun
 (setq storedvalue                                                     ; set a quote
   (nth                                                                ; returns the Nth element of the list.
     (rem (1+ (vl-position storedvalue '("A" "B" "C" "D" "E"))) 5)     ; for the Nth item move the quote one position next in the list (of 5 items)
     '("A" "B" "C" "D" "E")                                            ; show the whole list for Nth
   )                                                                   ; end of Nth
 )                                                                     ; end of quote
 (princ (strcat "\nMyVariable is set to \"" storedvalue "\" "  ))      ; print the quote for check
 (princ)                                                               ; exit silently
)                                                                       ; end of defun

 

 

Previously I had this thought but,

for the first time I see a defuning quote, are there any other examples of that? When would one use it?

Link to comment
Share on other sites

Lee Mac's method:

(defun-q c:test ( / lst )                                                                       
   (setq c:test (vl-list* '( / lst ) (list 'setq 'lst (list 'quote (append (cdr lst) (list (car lst))))) (cddr c:test)))  ; ????

The third row blows my mind!

 

The defun-q function defines a function as a list, and as such, the list may subsequently be edited (as opposed to the use of defun, in which the returned symbol is a pointer to the memory location for the function, and provides no further access or information concerning the content of the function definition). This opens the possibility of allowing a function to redefine its own function definition, perhaps enabling 'machine learning' of sorts.

 

The third line of the function redefines the first two lines of its own function definition, substituting a new setq expression with the permuted list - this can be observed by evaluating the function symbol through the Visual LISP IDE console following each evaluation:

_$ c:test
((/ LST) (SETQ LST (QUOTE (0 10 25 33 4))) (SETQ C:TEST (VL-LIST* (QUOTE (/ LST)) (LIST (QUOTE SETQ) (QUOTE LST) (LIST (QUOTE QUOTE) (APPEND (CDR LST) (LIST (CAR LST))))) (CDDR C:TEST))) (SETVAR (QUOTE USERI1) (CAR LST)))
_$ (c:test)
0
_$ c:test
((/ LST) (SETQ LST (QUOTE (10 25 33 4 0))) (SETQ C:TEST (VL-LIST* (QUOTE (/ LST)) (LIST (QUOTE SETQ) (QUOTE LST) (LIST (QUOTE QUOTE) (APPEND (CDR LST) (LIST (CAR LST))))) (CDDR C:TEST))) (SETVAR (QUOTE USERI1) (CAR LST)))
_$ (c:test)
10
_$ c:test
((/ LST) (SETQ LST (QUOTE (25 33 4 0 10))) (SETQ C:TEST (VL-LIST* (QUOTE (/ LST)) (LIST (QUOTE SETQ) (QUOTE LST) (LIST (QUOTE QUOTE) (APPEND (CDR LST) (LIST (CAR LST))))) (CDDR C:TEST))) (SETVAR (QUOTE USERI1) (CAR LST)))

For completeness, it is worth noting that a defun-q expression can also be defined literally if the expression adheres to the required list structure, for example:

_$ (setq plus2 '(( x ) (+ x 2)))
((X) (+ X 2))
_$ (plus2 3)
5

Here is another demonstration which may also interest you.

Link to comment
Share on other sites

This opens the possibility of allowing a function to redefine its own function definition

That sounds very exciting! But I have to come up with some new ideas for that. :)

 

 

Anyway my idea was to set N quotes with strings (first I thought about toggling variables).

But maybe I'll have to check your "tip of the day" and "clock" routines.

The whole concept is to set a reactor with a delay (like 20 or 30 minutes) and on every half hour to print a tip in command line.

 

 

Another thing I did was to toggle the autocad's background color (In other words I modified your routine with your modifications! :D)

(defun-q c:TBG ( / lst ) 

   (setq lst '( 0 1644825 3289650 4934475 6579300 8224125 9868950 11513775 13158600 14803425 16448250 14803425 13158600 11513775 9868950 8224125 6579300 4934475 3289650 1644825 ))
   (setq c:TBG (vl-list* '( / lst ) (list 'setq 'lst (list 'quote (append (cdr lst) (list (car lst))))) (cddr c:TBG)))
   (setq storedvalue (car lst))

   (if tbg:flg
       (progn (setq col storedvalue tbg:flg nil)(setq stor-RGB (Bits->RGB storedvalue)) (princ (strcat "\nBackground color is set to \"" (rtos storedvalue 2 0)  "\" " "\n"  )))
       (progn (setq col storedvalue  tbg:flg  t )(setq stor-RGB (Bits->RGB storedvalue)) (princ (strcat "\nBackground color is set to \"" (rtos storedvalue 2 0)  "\" " "\n"  )))
   )
   (foreach prp '(graphicswinmodelbackgrndcolor modelcrosshaircolor)
       (vlax-put-property (acdisp) prp (setq col (- 16777215 col)))
   )
   (princ)
   (vla-Regen (vla-get-ActiveDocument (vlax-get-acad-object)) acActiveViewport)

(defun acdisp nil
   (eval
       (list 'defun 'acdisp 'nil
           (vla-get-display (vla-get-preferences (vlax-get-acad-object)))
       )
   )
   (acdisp)
)
(vl-load-com)


(defun Bits->RGB(Bits / r g)
 (if(and(< -1 Bits)(> 16777216 Bits))
 (list(setq r(/ Bits 65536))
      (setq g(/(- Bits(* r 65536))256))
      (- Bits(+(* r 65536)(* g 256)))
      ); end list
   ); end if
 ); end Bits->RGB

   (princ)
); end of function

 

Thank you guys for inventing and helping to invent such awesome stuff!

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...