TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Oak3s on August 03, 2006, 05:50:07 PM

Title: Yes or No < Yes > :
Post by: Oak3s on August 03, 2006, 05:50:07 PM
ive searched and cant find an answer. how do you go about asking a yes or no question and only accept yes, no, y, or n?
Title: Re: Yes or No < Yes > :
Post by: T.Willey on August 03, 2006, 05:53:34 PM
Code: [Select]
(initget "Yes No")
(if (/= (setq Opt (getkword "\n Select option [<Y>es/No]: ")) "No")
 (setq Opt "Yes")
)
Title: Re: Yes or No < Yes > :
Post by: Oak3s on August 03, 2006, 06:01:56 PM
thanks for the reply. im going to look closer at it. i was just about to post what i had.
Code: [Select]
(defun c:Yesno (/ tmp)
(initget 1 "Yes No")
(setq tmp (getkword "Did you get it < Yes or No > "))
)
Title: Re: Yes or No < Yes > :
Post by: T.Willey on August 03, 2006, 06:22:19 PM
I like being able to hit enter, so I just test of the other option usually.  If it's not the other option, in this case "No", then it must be yes.
Title: Re: Yes or No < Yes > :
Post by: Oak3s on August 03, 2006, 06:46:28 PM
Tim
what im seeing with your code is that if you hit n, or no you get nil. if you enter you get "yes".
but if you use the code below you can get yes or no...depending on your response. how would you go about getting yes or no...rather than nil when using a default yes as enter
Code: [Select]
(defun c:Yesno (/ tmp)
(initget 0 "Yes No")
(setq tmp (getkword "\nAre you sure? (Yes or No) < Yes >: "))

)
Title: Re: Yes or No < Yes > :
Post by: Oak3s on August 03, 2006, 06:48:32 PM
ive tried this but cant seem to get it working
Code: [Select]
(defun c:Yesno (/ tmp)
(initget 0 "Yes No")
(setq tmp (getkword "\nAre you sure? (Yes or No) < Yes >: "))
(if (null tmp)
(setq tmp "Yes"))
)
Title: Re: Yes or No < Yes > :
Post by: T.Willey on August 03, 2006, 06:55:56 PM
ive tried this but cant seem to get it working
Code: [Select]
(defun c:Yesno (/ tmp)
(initget 0 "Yes No")
(setq tmp (getkword "\nAre you sure? (Yes or No) < Yes >: "))
(if (null tmp)
(setq tmp "Yes"))
)
Works here.
Quote

Command: yesno

Are you sure? (Yes or No) < Yes >:
"Yes"

Command:
Command: (c:yesno)

Are you sure? (Yes or No) < Yes >:
"Yes"
Well, if you hit "N" or any no response, it will return nil.  If you want to change that, then you will have to return the variable tmp.  Like
Code: [Select]
(defun c:Yesno (/ tmp)
(initget 0 "Yes No")
(setq tmp (getkword "\nAre you sure? (Yes or No) < Yes >: "))
(if (null tmp)
(setq tmp "Yes"))
tmp
)
Quote
Are you sure? (Yes or No) < Yes >: n
"No"

Command:
Command: yesno

Are you sure? (Yes or No) < Yes >:
"Yes"

Command:
Command: yesno

Are you sure? (Yes or No) < Yes >: y
"Yes"
Title: Re: Yes or No < Yes > :
Post by: Oak3s on August 03, 2006, 07:12:55 PM
ive tried this but cant seem to get it working
Code: [Select]
(defun c:Yesno (/ tmp)
(initget 0 "Yes No")
(setq tmp (getkword "\nAre you sure? (Yes or No) < Yes >: "))
(if (null tmp)
(setq tmp "Yes"))
)
Works here.
Quote

Command: yesno

Are you sure? (Yes or No) < Yes >:
"Yes"

Command:
Command: (c:yesno)

Are you sure? (Yes or No) < Yes >:
"Yes"
Well, if you hit "N" or any no response, it will return nil.....<snip>
also if you hit "y" or even "yes"...the only way i can get a "Yes" is if i hit enter. any other response is giving me nil.
Title: Re: Yes or No < Yes > :
Post by: T.Willey on August 03, 2006, 07:31:23 PM
I told you why in my other post, maybe you missed it.  The things with defuns, are they return the last thing (lack of better word) evaluated. So in yours, the last thing evaluated is the if statement.  If the statement was true
"No" would be returned, if it was false, then nil was returned.  That is why I said you have to pass your variable "tmp" at the end of the function.

Is that clear.

No grumpy tone implied, sorry if it comes off that way.
Title: Re: Yes or No < Yes > :
Post by: Kerry on August 03, 2006, 07:33:04 PM
Perhaps try something like  this
.. note also the square brackets around the options ...  try a right click to display the popup options menu when the command is running, you'll see the options displayed .. which you can also click ..
Quote
(DEFUN c:Yesno (/ return)
    (INITGET 0 "Yes No")
    (OR (SETQ return (GETKWORD "\nAre you sure? [Yes/No] < Yes >: "))
        (SETQ return "Yes")
    )
    return
)
Title: Re: Yes or No < Yes > :
Post by: MP on August 03, 2006, 10:51:55 PM
Just for fun a different spin ...

I originally came from a BASIC programming background (shoot me now), so when I took on LISP I found it annoying there wasn't an equivelent to the INKEY$ function (read a keyboard character from the keyboard buffer without requiring the user to press [Enter] and without echoing it to the screen).

What to do but write my own.

This is a simple variant that doesn't faithfully replicate said function (the original function left the character in the buffer and could deal with extended keyboard codes etc. IIRC) but it's good enough for a simple Yes/No application. If you execute the function it will wait until you press one of the standard keyboard keys: a-z, A-Z, 0-9, Spacebar, Enter, Tab keys etc. but not extended codes: <F1> key etc., returning the corresponding string, like "a", "A", "0", " ", "\n" or "\t" etc.

Anyway, without further blather --

Code: [Select]
(defun GetKey ( / result )
    (while
        (null
            (eq 2
                (car
                    (setq result (grread))
                )
            )
        )
    )
    (chr (cadr result))
)

How to use? An simple example proggy --

Code: [Select]
(defun c:Foo ( / response )

    (princ "Do you really want to do it? Y/N: ")
   
    (while
        (null
            (member     
                (setq response (strcase (GetKey)))
               '("Y" "N")
            )
        )
    )
   
    (princ
        (strcat "User indicated <"
            (if (eq "Y" response)
                "Yes"
                "No"
            )
            ">."
        )
    )   

    (princ)

)

FWIW, cheers.
Title: Re: Yes or No < Yes > :
Post by: CAB on August 04, 2006, 12:15:13 AM
And one more:
Code: [Select]
(defun c:yesno (/ return)
  (initget "Yes No")
  (cond ((getkword "\nQuestion: Yes/No/<Yes>:"))
        ("Yes")
  )
)
Title: Re: Yes or No < Yes > :
Post by: CAB on August 04, 2006, 12:19:12 AM
OK just one more. :-)
Code: [Select]
(defun c:yesno (/ return)
  (initget "Yes No")
  (if (setq return (getkword "\nAre you sure? [Yes/No] < Yes >: "))
    return
    "Yes"
  )
)
Title: Re: Yes or No < Yes > :
Post by: Serge J. Gianolla on August 04, 2006, 01:01:35 AM
OK then, more versatile; one more from the ancient Maximising AutoCAD Rel. 10 the UserKeyword function:

Code: [Select]
;;;Copyright © 1987 - Present • New Riders Publications
;;;
;;;Needs bit, keyword(s), message and default.
      (defun ukword (bit kwd msg def / inp)
(if (and def (/= def "")) ;test for both nil and null string
  (setq msg (strcat "\n" msg "<" def ">: ") ;string'em  with default
bit (* 2 (fix (/ bit 2))) ;a default and no null bit code conflict so
  ) ;this reduces bit by 1 if odd, to allow null
  (if (= " " (substr msg (strlen msg) 1))
    (setq
      msg (strcat "\n" (substr msg 1 (1- (strlen msg))) ": ")
    )
    (setq msg (strcat "\n" msg ": ")) ;without default
  )
) ;if
(initget bit kwd) ;initialize the key words
(setq inp (getkword msg)) ;and use the GET command
(if inp
  inp
  def
) ;compare the results, return appropriate value
      );;;defun
use:
Code: [Select]
(setq
  answer (ukword 1
"Corner Merged Tee"
"Enter an option? [Corner/Merged cross/Tee] "
"Corner"
)
)

Edit by MP: I don't know if this code should be posted but I do know the Maximizing AutoCAD series of books was published by New Riders Publications starting in the late 80s, so I added their copyright note, though I guessed on the date. Attempting to find out if there was a "No posting" clause in the original code ...
Title: Re: Yes or No < Yes > :
Post by: MP on August 04, 2006, 09:39:36 AM
Fun variant Didge.

Is it possible to ask a different question, doesn't seem swamp worthy to me.

Edit: Thank you Didge, really appreciate it.

Title: Re: Yes or No < Yes > :
Post by: Didge on August 04, 2006, 09:42:15 AM
Couldn't help playing with MP's coding, this version returns T if the "Y" key is pressed or NIL  if the "N" key is pressed.

Code: [Select]
(defun YesNo ( prmpt / GetKey response )
  (defun GetKey ( / result )(while (null (eq 2 (car (setq result (grread))))))(chr (cadr result)))
  (princ (strcat prmpt ", Y/N: "))
  (while (null (member (setq response (strcase (GetKey))) '("Y" "N"))))
  (princ (strcat " <" (if (eq "Y" response) "Yes" "No") ">."))
  (eq response "Y")
)

;  example:   (if (yesno "Shoot?")(prompt "\nBANG")(prompt "\nDOH!!"))

EDIT: Question changed.
Title: Re: Yes or No < Yes > :
Post by: ronjonp on August 04, 2006, 11:11:47 AM
Here is another:

Code: [Select]
(if (not *YN*)
  (setq *YN* "Yes")
)
(initget 0 "Yes No")
(setq P
       (cond
((getkword
    (strcat
      "\n Do you like donuts (Y\\N) <Hit Enter for "
      *YN*
      ">: "
    )
  )
)
(*YN*)
       )
)
(setq *YN* P)
Title: Re: Yes or No < Yes > :
Post by: MP on August 04, 2006, 11:45:52 AM
And yet more fun (on the fly dcl) --

Code: [Select]
(defun GetYesNoCancel ( title question / _MakeDcl _Main )

    ;;  returns 1 for yes, -1 for no, 0 for cancel (you
    ;;  could mod to return nil for cancel if you prefer)

    (defun _MakeDcl ( / tempname handle )
        (cond
            (   (setq
                    tempname (vl-filename-mktemp "ync.tmp")
                    handle   (open tempname "w")
                )
                (foreach stream
                   '(
                        "yesnocancel : dialog {\n"
                        "    key = \"title\";\n"
                        "    label = \"Yes / No / Cancel\";\n"
                        "    spacer;spacer;\n"
                        "    :   column {\n"
                        "        :   text {\n"
                        "            alignment = centered;\n"
                        "            key = \"question\";\n"
                        "            label = \"xxxx xxxx xxxx xxxx xxxx\";\n"
                        "        }\n"
                        "    }\n"
                        "    spacer;spacer;\n"
                        "    :   row {\n"
                        "        spacer;spacer;\n"
                        "        :   button { label = \"Yes\"; "
                        "key = \"accept\"; is_default = true; }\n"
                        "        :   button { label = \"No\"; "
                        "key = \"no\"; }\n"
                        "        :   button { label = \"Cancel\"; "
                        "key = \"cancel\"; is_cancel = true; }\n"
                        "        spacer;spacer;\n"
                        "    }\n"
                        "    spacer;\n"
                        "}\n"
                    )
                    (princ stream handle)
                )   
                (close handle)
                tempname
            )
        )
    )
   
    (defun _Main ( title question / _Action dclname dclid result)

        (defun _Action ( argument )
            (setq result argument)
            (done_dialog)
        )

        (cond
            (   (and
                    (setq dclname (_MakeDcl))
                    (< 0 (setq dclid (load_dialog dclname)))
                    (new_dialog "yesnocancel" dclid)
                )

                (vl-file-delete dclname)
                (set_tile "title" title)
                (set_tile "question" question)
                (action_tile "accept" "(_Action 1)")
                (action_tile "no" "(_Action -1)")
                (action_tile "cancel" "(_Action 0)")
                (start_dialog)

                result

            )
        )
    )
   
    (_Main title question)
   
)

Example --

Code: [Select]
(GetYesNoCancel "Question of the day" "Is this superfluous?")
(http://www.theswamp.org/screens/mp/getyesnocancel.png)

:-D
Title: Re: Yes or No < Yes > :
Post by: Oak3s on August 04, 2006, 02:06:25 PM
<*blink>
a lot of different ways. thank you.
Title: Re: Yes or No < Yes > :
Post by: Oak3s on August 04, 2006, 08:47:53 PM
i am appreciative of the input and i thought i could handle it from there. but i havent been able to put it to use. here is my go at it. could someone point me in the right direction.
Code: [Select]
(DEFUN c:Yesno (/ ansr)
    (INITGET 0 "Yes No")
    (OR (SETQ ansr (GETKWORD "\nAre you sure? [Yes/No] < Yes >: "))
(SETQ ansr "Yes")
)
ansr
     (if (= ansr yes)
(setvar "osmode" 1)
     )
)
Title: Re: Yes or No < Yes > :
Post by: Kerry on August 04, 2006, 10:47:27 PM
ansr is a STRING .. so ..
Quote
    (if (= ansr "Yes")
      (setvar "osmode" 1)
     )
Title: Re: Yes or No < Yes > :
Post by: Kerry on August 04, 2006, 10:50:41 PM
.. or considering the context of your sample, perhaps something like this ..
Quote
(DEFUN c:Yesno (/ ansr)
    (INITGET 0 "Yes No")
    (IF (= "Yes" (GETKWORD "\nAre you sure? [Yes/No] < Yes >: "))
        (SETVAR "osmode" 1)
    )
)
Title: Re: Yes or No < Yes > :
Post by: T.Willey on August 06, 2006, 03:16:03 PM
.. or considering the context of your sample, perhaps something like this ..
Quote
(DEFUN c:Yesno (/ ansr)
    (INITGET 0 "Yes No")
    (IF (= "Yes" (GETKWORD "\nAre you sure? [Yes/No] < Yes >: "))
        (SETVAR "osmode" 1)
    )
)
Kerry, with this, if enter is hit, then the osmode won't get set.  That is why I usually test for the answer that is not the default, so something like
Code: [Select]

(DEFUN c:Yesno (/ ansr)
    (INITGET "Yes No")
    (IF (/= "No" (GETKWORD "\nAre you sure? [Yes/No] < Yes >: "))
        (SETVAR "osmode" 1)
    )
)

Edit:  Oops, didn't see the bit code 0 of the initget.  Sorry.
Title: Re: Yes or No < Yes > :
Post by: sinc on August 10, 2006, 12:55:20 PM
Perhaps try something like  this
.. note also the square brackets around the options ...  try a right click to display the popup options menu when the command is running, you'll see the options displayed .. which you can also click ..
Quote
(DEFUN c:Yesno (/ return)
    (INITGET 0 "Yes No")
    (OR (SETQ return (GETKWORD "\nAre you sure? [Yes/No] < Yes >: "))
        (SETQ return "Yes")
    )
    return
)

I just wanted to second that about using the square brackets for your prompt.  In the newer versions of Autocad, Autocad uses those square brackets to determine the available choices for the Dynamic Input prompt.  It also pays attention to those angle brackets, for the "default".  For example, in the following:

Code: [Select]
(initget 128 "Current Jump Options")
(setq sel
   (getpoint
(VLutil:getPointAtDist e curDist)
(strcat
"\nEnter end elev <"
(rtos CogoPtLastEl)
"> or pick grd brk "
"[Current elev/Jump to point/Options]: "
) ;_ strcat
   ) ;_ getpoint
) ;_ setq

Say the value for CogoPtLastEl is "2600.00".  The above code will result in a Dynamic Input prompt composed of a list that contains the following choices:

Code: [Select]
* 2600.00
  Current elev
  Jump to point
  Options

The "2600.00" will be flagged as the "current value" in the list.