Jump to content

Recommended Posts

Posted

Hi all,

 

I'm stuck inside the while loop and can't come out of it. Can someone help me on this (if possible please provide information on why its not closing). This is just a small function of a much larger lisp that I'm playing with and Esc to exit means complete program termination.

 

Here is how I inteded it to be used for. Once user decides to use drawshapes, and if the answer is one of the keyword (eg. Rectangle) then user should be able draw as many rectangles he likes and if Enter is hit it should come back to main menu again ask for keyword to choose (circle or ellipse).

 

Thanks in advance.

 

 
(defun drawshapes (/ dtype)
      (setvar "cmdecho" 1)
      (setq dtype T)
      (while dtype
        (initget (+ 2 4) "R P C E")
        (prompt "\n***    Enter option R, P, C, E   ***")
 (setq dtype (getkword "\nselect your option: Rectangle, Pline, Circle, Ellipse or hit Enter to close:"))
 (if dtype
               
   (cond
    ( (= dtype "R")
              (setq loop T)
              (while loop   
           (command "_.rectang")
                  (while (= 1 (logand 1 (getvar 'CMDACTIVE)))(command pause))
              ); end while
    )
    ( (= dtype "P")
              (setq loop T)
              (while loop
                  (command "_.PLINE")
           (while (= 1 (logand 1 (getvar 'CMDACTIVE)))(command pause))
              ); end while
           )
    ( (= dtype "C")
              (setq loop T)
              (while loop
                  (command "_.circle")
                  (while (= 1 (logand 1 (getvar 'CMDACTIVE)))(command pause))
              ); end while
    )
    ( (= dtype "E")
              (setq loop T)
              (while loop
           (command "Ellipse")
           (while (= 1 (logand 1 (getvar 'CMDACTIVE)))(command pause))
              ); end while
    )
     ); end cond
); end if
     ); end while
     (setvar "cmdecho" 0)
);end defun

Posted

(while dtype

to

(if dtype?

Not a master who could tell you why and exactly why but those are my first thoughts, and what I would look into

Posted

I already have (if dtype" ..below the getkword line. Isnt that the same thing? I tried changing the while to if and gives me syntax error.

 

I think I have too many times Setq for Dtype. Not sure why...I'm confused

Posted

Some where, you will have to set loop to nil.

 

Also, you can use:

(while (setq dtype (getkword "\n....

 

 

-David

Posted

Also, AFAIK, getkword really only uses 1 or 0 in the ( initget ) call.

 

-David

Posted

Well if you're going to use (while) most of the times I'll see an increment counter attached to the while..

(setq cntr 1)
actions
(setq cntr (1+ cntr))
	;increment the counter

or like david said you can (setq dtype nil)

after each of your ((= dtype) statements. That would exit the loop after one usage, but it says you want them to be able to enter many of these shapes...so you could maybe set a flag based from more user input.

 

Um, noticing in your code these:

(setq loop T)
              (while loop

 

 

means that yes indeed they should stay inside that loop until your add something that closes/exits the loop usually it's (setq loop nil) for what you've got there.

hth

Posted

also here's a snippet where i'm using a combination of initget and strcase to obtain the correct user input. The initget function will also ensure that the user selects from the predefined list, so testing for user input I didn't feel as necessary as normal

(initget "Freeze Thaw On oFF Lock Unlock eXit")        ;; establish controls
(setq lstate (strcase (getkword "\nChoose layer control [Freeze/Thaw/On/oFF/Lock/Unlock/eXit]:")))

 

wasn't sure that the arithmetic in the initget was actually doing anything, because simply tacking a (strcase) onto the second half allowed for any capitalization of the choices given, and as thus....prog only proceedes if a correct selection is made, without use of arithmetic in the initget. Wether this is more or less correct i'm not sure but it worked well for my purposes

Posted

Another example, this one credit goes to Jeffery p sanders and his importxyz.lsp. just taking an excerpt to show some exiting methods

     ;;;--- Inform the user of progress
     (if(> cellCnt 99)
       (progn
         (princ "\n Currently retrieving cells in Row ")
         (princ (strcat (itoa stRow) " of " (itoa LsRow)))
         (setq cellCnt 0)
       )
     )
     ;;;--- Increment the column
     (setq stCol(+ stCol 1))
     ;;;--- Make sure the column stays in the range
     (if(> stCol LsCol)
       (setq stCol copyCol stRow(+ stRow 1))
     )
   ) 
   ;;;--- Return the list
   cellList
 )  

 

play close attention to the variables in thatn, though..

Posted (edited)

Annnnnd one more example, hoping it helps...

(this one is Jeff Tippit, SPAUG President, www.spaug.org 's lisp)

     (setq DO_MORE "Y")
     (while (= DO_MORE "Y")
        (BIG_LOOP)
     ); End while

     (defun BIG_LOOP ()
        (USER_INPUT)
        (setq FRAMUS_DONE 0)     
        (while (/= FRAMUS_DONE 1)
           (SHOW_DIALOG)
        ); End while
        (I_OR_G)
        (initget "Y N")
        (setq DO_MORE (getkword "\nChange more blocks? Y/N <Y>: "))
           (if
              (or
                 (= DO_MORE "y")
                 (= DO_MORE "")
                 (= DO_MORE nil)
              ); End or
                 (setq DO_MORE "Y")
           ); End if
     ); End BIG LOOP

In this one just above you can see how he takes user input and decides wether to proceed the program based off of the user selection

Edited by Bhull1985
additional comments
Posted (edited)

I concur that the loop variable will keep you in the whiles forever unless you find a way to change it. Overall, your approach seems to be on the right track.

 

I prefer things to look more AutoCADish to the user. Here is an edit that fleshes out your options, adds an explicit exit option, and requires a simple return/Enter to repeat the last option. It requires an extra variable as well, which should be added to the local list. UNTESTED.

 

(setq dtype "eXit")
(while
 (or 
   (initget "Rectang Pline Circle Ellipse eXit")
   (/= "eXit" (setq dtypekey (getkword (strcat
     "[Rectang/Pline/Circle/Ellipse/eXit] <" dtype ">: "
   )          )           )            )
 )
 (if dtypekey (setq dtype dtypekey))
 (cond
   ( (= "eXit" dtype) )
   (T(command (strcat "_." dtype))
     (while (= 1 (logand 1 (getvar 'CMDACTIVE)))
       (command pause)
   ) )
 ) 
)

Well, after a quick review, I see that my cond isn't really necessary as is, since the loop should not get that far if dtype = "eXit". OOPS!:oops:

Edited by neophoible
oops!
Posted (edited)

Can you comment out those lines neo? Would like to know how some of them are used if you don't mind :)

 

Comment out as in add comments to, not....take comments out. Thanks :P

Edited by Bhull1985
clarification
Posted
Can you comment out those lines neo? Would like to know how some of them are used if you don't mind :)

 

Comment out as in add comments to, not....take comments out. Thanks :P

I'll be happy to, but I've got to go right now. I'll try to get back to it later today. But if someone else feels up to explaining, that's fine by me. If you look at it closely and try it out, it's not that hard to figure, and the meat of it is really from the OP. I just tightened it up a bit.
Posted (edited)

OK, I edited out the extraneous cond, adjusted for when getkword returns nil (used my precious cond for that!), and included a few comments. The overall goal is to provide the user a few options of what to draw using simple keywords formatted as one might find in standard AutoCAD commands. To exit, enter X (this is the initial default). Hit return to repeat the previous choice.

 

 ; initialize default value (exit seemed the obvious choice)
(setq dtype "eXit")   
; begin looping for input; stop only if user explicitly exits
(while                     
; used [b][color=blue]or[/color][/b] to avoid repetition--[b][color=blue]initget [/color][/b]always returns nil, so won't change loop
  (or      
; need to initialize for keywords                 
   (initget "Rectang Pline Circle Ellipse eXit")
; continue until explicit exit entered (except as first default)
   (/= "eXit" (setq dtype
; save the draw type variable explicitly using itself as the default
        (cond
           ( (getkword (strcat
; concatenate bracketed options with the saved default
             "\n[Rectang/Pline/Circle/Ellipse/eXit] <" dtype ">: "
           ) )             )
; dtype is set to itself if user hits enter, otherwise to the new option
           ( dtype )
        )
; close /= & setq
    )         ) 
; close or
 )
; the options are all AutoCAD commands--add the _. prefix to make sure the
;   native AutoCAD command is being used
 (command (strcat "_." dtype))
; continue in the selected command pausing for user input until finished
; this is directly from the OP
 (while  (= 1 (logand 1 (getvar 'CMDACTIVE)))
   (command pause)   
 )
)

For those wanting to actually use this for commands, perhaps I should have noted that you will probably want to turn on the variable CMDECHO like shailujp did:

(setvar "cmdecho" 1)

Edited by neophoible
added quick note about CMDECHO
Posted

Hi Neo,

 

Thanks for your complete explaination. I have incorporated this code and it works great.

It took me a while to undestand it completely :) due to my inexperience.

 

I also liked the use of strcat "_." along with standard AutoCAD commands. Just then I realized what you ment by AutoCADish.

I prefer things to look more AutoCADish to the user.

 

Thanks for your help.

Posted
Hi Neo,

 

Thanks for your complete explaination. I have incorporated this code and it works great.

It took me a while to undestand it completely :) due to my inexperience.

 

I also liked the use of strcat "_." along with standard AutoCAD commands. Just then I realized what you ment by AutoCADish.

 

 

Thanks for your help.

Glad to help, shailujp, and glad you were able to understand it.

 

Note that part of making it more AutoCADish is putting the options in square brackets, as this can make them auto-interactive via menus, for those who prefer to pick it with the mouse.

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