Author Topic: "if" help  (Read 10916 times)

0 Members and 1 Guest are viewing this topic.

rude dog

  • Guest
"if" help
« on: January 16, 2004, 12:32:55 AM »
need help combining these two functions together in a if statement im doing something incorrectly:
(DEFUN C:MC ()
(initget 1 "A S")
(setq UC (getkword "\nADDITION OR SUBTRACTION? <A/S>:"))
(if (= UC "A")(PRINC "\n......START ADDITION PROCESS......"))
(SETQ D1 (GETDIST "\nENTER FIRST DIMENSION:"))
(SETQ D2 (GETDIST "\nENTER SECOND DIMENSION:"))
(SETQ SUM (+ D1 D2))
(SETQ ANS (RTOS SUM))
(PRINC "\nTHE ANSWER IS: ")
(PROMPT ANS)          
(if (= UC "S")(PRINC "\n......START SUBTRACTION PROCESS......"))
(SETQ D3 (GETDIST "\nENTER LARGER DIMENSION FIRST:"))
(SETQ D4 (GETDIST "\nENTER SMALLER DIMENSION SECOND:"))
(SETQ SUM1 (- D3 D4))
(SETQ ANS1 (RTOS SUM1))
(PRINC "\nTHE ANSWER IS: ")
(PROMPT ANS1)              
)
(princ)

daron

  • Guest
"if" help
« Reply #1 on: January 16, 2004, 01:41:17 AM »
I'll help here, but I'd like to throw in a few personal opinions and peeves. First, caps. I know drafters are taught to write everything in caps, but when programming, or trying to view other programs, it really seems messy to see so many caps. That's personal opinion. Next, is writing statements that nobody will ever see, like: (princ ...Starting whatever process). I mean, how many people are ever going to see it. Sure, it could be nice, but you're wasting time in programming it in. Okay, enough with personal peeves. On to your code. I'm going to take some liberty and clean it up. It's also late here, so if there are errors, it's due to a delirious mind and the fact that none of this will even be tested.
Code: [Select]
(defun c:mc (/ uc d1 d2 d3 d4 sum ans) ;localize your variables
     (initget 1 "A S")
     (setq uc (getkword "\n[Addition Subtraction]? <A>:")) ;<> means default. Let's change it
     (if (or (= uc nil) (= uc "A")) ;an if statement only allows two functions, then or else. You need a way to trick the if statement into believing you only have to functions.
   (setq d1 (getdist "\nEnter First Dimension: ")
                            d2 (getdist d1 "\nEnter Second Dimension: ")
                            sum (+ d1 d2)
                            ans (rtos sum 2 0)
                      )
(setq d3 (getdist "\nEnter Larger Dimension First: ")
        d4 (getdist d3 "\nEnter Smaller Dimension Second: ")
        sum (- d3 d4)
        ans (rtos sum 2 0)
)
   )
(princ "\nThe Answer is: " ans)
)

That ought to work if your intention is to add or subtract the values of two distances. Let's see if we can't shorten this code a bit further. As you see ans didn't need to be called in both cases differently, since if only allows you to choose one or the other.

Code: [Select]
(defun additup (operand)
   (setq d1 (getdist "\nEnter First Dimension: ")
            d2 (getdist d1 "\nEnter Second Dimension: ")
            sum (operand d1 d2)
            ans (rtos sum 2 0)
    )
)
(defun c:mc (/ uc d1 d2 d3 d4 sum ans) ;localize your variables
     (initget 1 "A S")
     (setq uc (getkword "\n[Addition Subtraction]? <A>:")) ;<> means default. Let's change it
     (if (or (= uc nil) (= uc "A"))
   (additup +)
   (additup -)
     )
(princ "\nThe Answer is: " ans)
)

You can see from the second example, if the operand idea works, (someone want to test that for me?) that you can reuse the same information to add or subtract. Actually, I'm not sure what getdist will do for us in either case, since I'm not checking the help files and don't have the memory for this right now. Anyway, you can see it's cleaner, shorter and easier to understand. Well, maybe not easier yet. I assume you aren't too familiar with reusable functions and things like the operand variable I put in there. Regardless, in either case, as long as you have to real numbers to add or subtract, it wouldn't matter if you selected the largest number first or not. There are ways to ensure a positive number either way, if that's what you really want. I can't remember the name of it, but I'm sure someone will throw it out soon. I'm outta here until morning, which ain't much longer from now. I hope I did everything right.

rude dog

  • Guest
"if" help
« Reply #2 on: January 16, 2004, 02:21:59 AM »
thanks...obvious im still learning ill take all "constructive criticism"
i got coming...(abs number) is the positive integer function.
thanks again

daron

  • Guest
"if" help
« Reply #3 on: January 16, 2004, 08:53:32 AM »
That's it. Glad you were able to find that.

Columbia

  • Guest
"if" help
« Reply #4 on: January 16, 2004, 08:54:46 AM »
Just to add to what Daron has already said...

The 'if' function actually takes 3 arguments:
1. the conditional statement otherwise known as the test.
2. the "THEN" statement which must be a single statement by itself.
3. and the "ELSE" statement which also must be a single statement by itself.

Now there is a way to group multiple statements as if they are one.  And thay way is to use the 'progn' function.  For example:

Code: [Select]

(progn
  (setq a 1 b 2)
  (+ a b)
)


is treated as one statement and thus can be used within the THEN or ELSE portions of an 'if' function.

I hope this helps you some....

rude dog

  • Guest
"if" help
« Reply #5 on: January 17, 2004, 03:08:27 AM »
I know this is elementary for 99% of you (me being the 1%) but just wanted to show you how I took your advice and how it got me back on the road....I still dont feel comfortable with the indentations......
Thanks


(defun uf (math)
(setq d1 (abs (getdist "\nENTER FIRST DIMENSION:")))
(setq d2 (abs (getdist "\nENTER SECOND DIMENSION:")))
(setq sum (math d1 d2))
(setq answ (rtos sum))
)
(defun C:MC ()
(initget 1 "A S")
(setq uc (getkword "\nADDITION OR SUBTRACTION? <A/S>:"))
(if (or(= uc "A"))
(uf +)
(uf -)
)
(prompt answ)
(princ)
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
"if" help
« Reply #6 on: January 17, 2004, 05:18:36 PM »
Here is another way to skin that cat..
Ooops, sorry Keith. :)

CAB



Code: [Select]
;;;    rTotal.lsp
;;;
;;;    Display a running total on the command line
;;;    Accepts numeric entry as well as picked distance
;;;    Modes include Add, Subtract Multiply
;;;    Enter = to clear the total
;;;    Press enter to exit
;;;
(defun c:rtotal (/ p1 p2 mode total num)
  ;;  local function ===
  (defun updatetotal (dist)
    (cond
      ((= mode "ADD")
       (setq total (+ total dist))
      )

      ((= mode "Subtract")
       (setq total (- total dist))
      )
      ((= mode "Mult")
       (setq total (* total dist))
      )

    ) ; end cond stmt
    (princ "\n")
    (princ total)
    (princ "  Mode-> ")
    (princ mode)
  )
  ;;====================

  (prompt "Pick distance, enter numerical distance or math (+-/*=).")
  (setq mode  "ADD"
total 0
  )
  (initget 128)
  (while (setq p1
(getpoint "\nPick first point to get distance or enter(+-/=)")
)
    (cond
      ((= (type p1) 'list) ; first point picked
       (setq p2 (getpoint p1 "\nPick the second point."))
       (if (= (type p2) 'list) ; got second point
(updatetotal (distance p1 p2))
       ) ; endif (type p1 )
      ) ; end cond (= (type p1) 'list)

      ((= p1 "+")
       (prompt "\nADD Mode -> ON")
       (setq mode "ADD")
      )

      ((= p1 "-")
       (prompt "\nSubtract Mode -> ON")
       (setq mode "Subtract")
      )

      ((= p1 "*")
       (prompt "\nMultiply Mode -> ON")
       (setq mode "Mult")
      )

      ((= p1 "=")
       (prompt "\nTotal set to 0 \n")
       (setq total 0)
       (princ "  Mode-> ")
       (princ mode)
      )

      ((= (type p1) 'str) ; process numbers
       (if (setq num (distof p1))
(updatetotal num)
(prompt "\nInvalid entry, try again.")
       )
      )
    ) ; end cond stmt
    (initget 128)
  ) ; end while
  (princ)
) ; end defun
(prompt "\nRunning total loaded, Enter rTotal to run.")
(princ)
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.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
"if" help
« Reply #7 on: January 17, 2004, 05:34:06 PM »
Here is another way to do you routine.

Code: [Select]
(defun uf (math)
  ;;  abs is not needed because getdist is positive num
  (setq d1 (getdist "\nENTER FIRST DIMENSION:"))
  (setq d2 (getdist "\nENTER SECOND DIMENSION:"))
  ;; combined functions
  (rtos(math d1 d2)) ; this is the return value to the calling routine
)
(defun c:mc ()
  (initget 1 "A S")
  (setq uc (getkword "\nADDITION OR SUBTRACTION? <A/S>:"))
  (setq answer
(if (= uc "A")
  (uf +)
           (uf -)
         )
  )
  (prompt (strcat "\nThe total is " answer))
  (princ)
)
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: 10605
"if" help
« Reply #8 on: January 17, 2004, 06:47:28 PM »
Sorry, i just wanted to chime in here a bit. Who put the "Or" in your "if" statment? (And why?)
Quote
The or function evaluates the expressions from left to right, looking for a non-nil expression.

Arguments

expr  - The expressions to be evaluated.

Return Values

T, if a non-nil expression is found; otherwise nil, if all of the expressions are nil or no arguments are supplied.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
"if" help
« Reply #9 on: January 17, 2004, 08:11:02 PM »
Ugrrrr, I didn't remove that when I was messing around with the code :oops:

Can't believe I over looked it when I copied the code from above.

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

daron

  • Guest
"if" help
« Reply #10 on: January 18, 2004, 01:14:36 AM »
Code: [Select]
(initget "Addition Subtraction")
(setq uc (getkword "\n[Addition/Subtraction]? <A>: "))


The or was put there for a reason. ^ that is the reason.
 Run this code and right click. My previous code was untested and as such there were a few mistakes. In here, I've corrected some. Note the forward slash between addition and subtraction. Why? The square braces that surround them. If you run this code then right click, you will see the two words inside them in your popup menu, which you can then click. Also, you'll notice the lengthening of the initget string area to "Addition Subtraction". This is so that if you or anybody else using your code uses the right click option it will be a valid input. Now, the <A>. <> Letters contained within those are supposed to mean that <A> in this case is the default answer. In other words, you can hit enter to achieve the same goal as hitting A or typing Addition. Think about it. If you do this <A/S>, what is the default, A or S? If I were using this program and I got to this portion of it, how would I know what would happen if I hit enter? Well, if I don't find out what's happening when I hit enter and don't code for it, then nothing should happen. With the initget function set to 1 you disallow the user the option to hit enter and achieve what the <> are for. So, you'll notice the number 1 is now missing. Now we should get a return value when hitting enter. The answer should be nil. Therefore, we program the function to recieve nil or Addition as the same answer by writing (or (= uc nil) (= uc "Addition")). Notice I changed the option to Addition instead of A. That is why the square brackets [], will work with the right click. How does A work then, if that's all you typed? Initget allows the letter A or the whole word Addition to be used, but it only returns the full Keyword it was supplied. What if you wanted the user not to hit enter to mean A or S? What should it mean? Does the user run this command, then feel before answering A or S that he didn't want to run it? If so, and it's very possible, he is consigned to continue or hit escape. You don't want him, most likely to do that, right? It's a bad idea to force users into using escape. I have a co-worker who uses it all the time. It drives me nuts. Anyway, what can you do, right? Well, A nor S has to be the default? What do we do? Try this:
Code: [Select]
(initget "Addition Subtraction Exit")
(setq uc (getKword "\n[Addition/Subtraction]<E>xit: "))

Then instead of if, you might consider cond. Huh? I'm just getting used to if! Here's an example.
Code: [Select]
(cond ((= uc "Addition")
       (additup +)
      )
      ((= uc "Subtraction")
       (additup -)
      )
      ((or (= uc "Exit") (= uc nil))
         (a good error trap might be best here)
      )
     )

Of course, you could also leave the exit block out all together, but that would cause unexpected errors to happen when the code continues to run. I tried (exit) and (quit) but have never liked them in the past. They seem to shut down autocad, instead of just ending the command. That may not be the case, though, but sending the command to an error trap, would exit out and reset any variables that you may have needed to change on your user. That is also why you want to keep users out of the habit of hitting escape, but an error trap should also account for that. I say should because the user I mentioned before doesn't just hit escape once or twice. He hits it repeatedly very fast. I tested that once to see if I could cancel the error trap. I was able to. The values weren't reset.

rude dog

  • Guest
"if" help
« Reply #11 on: January 18, 2004, 01:44:55 AM »
Cab...nice program, pretty creative in my opinion and useful!!
daron...intresting comments dude im teaching myself out of a book, and the book only teachs you there way of doing it...im getting a broader view with yours and everyone else tips!! :wink:  daron i wrote this
code for your buddy @ work who gets on your nerves leaning on that "ESC"
button.....It's a bad idea to force users into using escape. I have a co-worker who uses it all the time. It drives me nuts.

(defun c:esc ()
(command ^c ^c ^c ^c ^c ^c ^c ^c ^c)
(princ)
); just a joke to pass the time bud :lol:

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
"if" help
« Reply #12 on: January 18, 2004, 09:57:29 AM »
Wow, lisper in training,

Sorry for butting in, :oops:  i should have recognized the name.
I now remember the thread with Rude Dog.  
Rude Dog please note that I haven't been lisping that long
and my code is prone to errors and I miss things as Se7en
pointed out. I've learned a lot here and am still learning.
Example is the info Daron was explaining, I did not know about
the right click option in getkword. Pay attention and these folks
can take you far. My problem is that i get a little crazy with
this new knowledge limited as it is.


CAB
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
"if" help
« Reply #13 on: January 18, 2004, 01:23:27 PM »
To take this a little further, we can try to eliminate the problem with users escaping out of the routine.

The traditional way of trapping errors in AutoLISP can be divided into two: normal validation within routines - such as (if (not success)(dothis)(dothat)) -  and specific error handlers. The latter are routines that are called whenever an error occurs that will halt the lisp environment.

AutoLISP comes with a predefined error handler and in many cases there is no need to create a custom error handler. But if the code changes the environment - typically by changing system variables - you would want to write code that resets the changes upon halting errors. Escaping out of a routine creates one of those halting errors.

Up until A2K there weren't many other ways to handle Escape than to write a custom error handler. But with A2K came an excellent method that, if used correctly, even allows a routine to continue after hitting Escape. Try invoking the command line version of the LAYER command, enter "Color" and hit Escape (options truncated):

Command: -LAYER
Current layer:  "0"
Enter an option [?/Make/Set/.../Color/Ltype/.../Unlock]: Color
Enter color name or number (1-255): [hit Escape]
*Cancel*
Enter an option [?/Make/Set/.../Color/Ltype/.../Unlock]:

What d'ya know, the command continues! The trick is to use VL-CATCH-ALL-APPLY. This function will trap all errors that can happen in virtually any situation; escaping, dividing by zero, setting a read-only system variable etc. Only drawbacks to the method are the bloody length of the involved function names and the syntax but luckily it's just inconvenience more than disadvantage. If you're uncomfortable with the APPLY function then read up on it and try it until it becomes second hand nature, because VL-CATCH-ALL-APPLY works in exactly the same way. It applies a function to a list of arguments.

The only difference is, that VL-CATCH-ALL-APPLY returns a so-called error-object when it detects an error. Otherwise it returns the result of the APPLY operation. The error-object can be sniffed out by using the special function VL-CATCH-ALL-ERROR-P. As the P suggests, it's a predicate function that returns T if an error-object was created, otherwise nil. Therefore, to use it in order to continue a routine, we simply determine what to do if an error occurred, or continue without fuzz if not.

To use it in a function like the one in this thread, we can decide to do nothing if an error occurred or process all valid data if no error occurred. Try hitting Escape in the following code. It will work like hitting Space to exit the routine, except it will resign with a *Cancel* as normal. Notice that escaping out of the function will also reset the system variable that was changed because it won't result in a halting error but continue to evaluate the function.

Code: [Select]
(defun C:AddDist (/ dist lst math lupr)
  ;; initialize total distance, set default operation to addition and save
  ;; setting of LUPREC
  (setq pdist 0.0
        math '+
        lupr (getvar "LUPREC")
  )
  ;; example of changing a system variable that has to be reset upon exit
  (setvar "LUPREC" 2)
  (princ "\n*Addition mode*")
  (while (and
      ;; just include INITGET here as a "dummy" value (it will always
      ;; return nil, anyways)
      (not (initget "Add Subtract"))
      ;; check if an error occurred in the following GETDIST request
      ;; notice that nil is normal behavior of the function, so it
      ;; will NOT produce an error
      (not (vl-catch-all-error-p
             (setq dist (vl-catch-all-apply 'getdist '("\nEnter dimension or [Add/Subtract]: ")))
           )
      )
      ;; because nil is not an error, check for it before continuing
      dist
    )
     (cond
       ;; if "Add" then change to addition mode
       ((= dist "Add") (setq math '+) (princ "\n*Addition mode*"))
       ;; if "Subtract" then change to subtraction mode
       ((= dist "Subtract") (setq math '-) (princ "\n*Subtraction mode*"))
       ;; if a number then process it
       (t
        (setq ndist (apply math (list pdist dist)))
        (princ "\nTotal distance: ")(princ (rtos ndist))
        (setq pdist ndist)
       )
     )
  )
  ;; this resetting of LUPREC will occur both when Escape is detected
  ;; and when the routine is exited as normal
  (setvar "LUPREC" lupr)
  (princ)
)

Mark

  • Custom Title
  • Seagull
  • Posts: 28753
Re: "if" help
« Reply #14 on: January 18, 2004, 01:43:27 PM »
Quote from: Rude Dog
need help combining these two functions together in a if statement im doing something incorrectly:

I added a couple extra IF statements in for error checking.
Code: [Select]

(defun c:mc (/ un prec uc d1 d2 sum ans)

  ;; grab the users unit settings, we'll use these
  ;; to format the output
  (setq un (getvar 'lunits)
        prec (getvar 'luprec)
        )

  ;; setup next input function leave out bit so we
  ;; can use <enter>
  (initget "Addition Subtraction")
  (setq
    uc (getkword "\nAddition or subtraction? (A/S) <Addition>:")
    ); uc = nil if user hits <enter>

  ;; [1]
  (if (or (= uc "Addition") (= uc nil))
    (progn
      (princ "\n......start addition process......")
      ;; make sure we get a dist before moving on
      (if (setq d1 (getdist "\nEnter first dimension: "))
        ;; make sure we get a dist before doing the math
        (if (setq d2 (getdist "\nEnter second dimension: "))
          (progn
            (setq sum (+ d1 d2) ; sum the dist
                  ans (rtos sum un prec) ; format the output
                  )
            ) ; progn
          ) ; if
        ) ; if
      ) ; progn
    ) ; if

  (if (= uc "Subtraction")
    (progn
      (princ "\n......start subtraction process......")
      ;; make sure we get a dist before moving on
      (if (setq d1 (getdist "\nEnter larger dimension first: "))
        ;; make sure we get a dist before doing the math
        (if (setq d2 (getdist "\nEnter smaller dimension second: "))
          (progn
            ;; use 'max' and 'min' to make sure we get the
            ;; correct numbers just in case.
            (setq sum (- (max d1 d2)(min d1 d2))
                  ans (rtos sum un prec)
                  )
            ) ; progn
          ) ; if
        ) ; if
      ) ; progn
    ) ;if

  (if ans (prompt (strcat "\nThe answer is: "ans)))
  (princ)
  )
;;; [1] would read
;;; if 'uc' equals the string 'Addition' or 'nil' then
;;; tell the user they are in addition mode then
;;; if the user enters or picks a distance 'd1' then
;;; if the user enters or picks a distance 'd2' then
;;; add 'd1' and 'd2' then
;;; format 'ans'
TheSwamp.org  (serving the CAD community since 2003)

rude dog

  • Guest
"if" help
« Reply #15 on: January 21, 2004, 12:16:06 AM »
how do you guys do it? im curious on the ones who replied to my thread....what type of schooling have you had and what other code talk are you learned in and how long have you had your hand in autolisp?
thanks to everyone for being so patient and unselfish....
ps...mark thanks for the tut on using "min" and "max" never seen code with these as part of the program before

daron

  • Guest
"if" help
« Reply #16 on: January 21, 2004, 08:48:12 AM »
Quote from: Rude Dog
A) how do you guys do it? im curious on the ones who replied to my thread....B) what type of schooling have you had and C) what other code talk are you learned in and D) how long have you had your hand in autolisp?
thanks to everyone for being so patient and unselfish....
ps...mark thanks for the tut on using "min" and "max" never seen code with these as part of the program before

A) Through the vlide.
B) Very little schooling, lots of asking knowledgable people.
C) None. Learning vba and web (html, xml, css, xsl) more to come.
D) Six years.

SMadsen

  • Guest
"if" help
« Reply #17 on: January 21, 2004, 09:59:22 AM »
A) Read, read, test, test, read, test, test, read ...
B) None, other than read, test, read, test, test, read, test, read ...
C) Bits and pieces
D) Since release 10

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
"if" help
« Reply #18 on: January 21, 2004, 10:29:10 AM »
RD, typically what you will find here are self taught code hackers that had a desire for improving their skills. Anyone who takes a class and then thinks that they have mastered programming (in any language) they are absolutely fooling themselves.
I have been pounding away at lisp since R11 and I never looked back.

A) trial and error, find code, pick it apart see what makes it tick..
B) None
C) Lisp, VB, VBA, C++, HTML and a few others that I can't remember
D) Since R11 (was that 91 or '93? I can't remember)

Study hard, live it, As you will probably note we are all CAD junkies here...we live eat and breath CAD
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Anonymous

  • Guest
"if" help
« Reply #19 on: January 21, 2004, 05:12:06 PM »
As I thought I have come to the right place :!: