TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Hangman on October 18, 2006, 01:59:24 PM
-
Can someone tell me the difference between the two examples posted below.
example A:
... (if (= (tblsearch "style" "ARCHITXT") nil) (command ".-style" "ARCHITXT" "ARCHITXT.SHX" txtht "0.75" "" "n" "n")) ...
example B:
... (cond ( (= (strcase tstyl) "ARCHITXT") (command ".-style" "ARCHITXT" "ARCHITXT.SHX" txtht "0.75" "" "n" "n")) ...
I know one is an 'if' statement and the other is a conditional statement. :-P
but other than that, example A is doing a table search for the text style, but they both are accomplishing the same thing aren't they ??
So what is example B doing ??
What is the difference ??
Thanks.
-
I think you example B isn't complete. It should be
... (cond ( (= (strcase tstyl) "ARCHITXT") nil) (command ".-style" "ARCHITXT" "ARCHITXT.SHX" txtht "0.75" "" "n" "n")) ...
They are doing the same thing. If you only need to test for one condition, I typically use 'if', if it can have more than to values, I would use 'cond'.
Hope that makes some kind of sense.
-
Here is my take on the subject:
The if statement works like this
(if (this is true)
(then do this)
)
(if (this is true)
(then do this)
(else do this when false)
)
The (cond) stmt on the other hand executes the all of code following
a true condition and then exits the condition stmt.
(cond
((= 1 0)
none of this will get executed
because the conditions is false
) ; end cond 1
((= 1 1)
do all of this because it is true
and this
and this
) ; end cond 2
((= 2 2)
none of this will get
executed even if it is true
because the prior stmt was true
) ; end cond 3
(T
This is often placed at the last position
in a condition statement and will be executed
if all the prior conditions are false
if any one of the above conditions are true
this will not be executed
) ; end cond 4
) ; end cond stmt
The OR will process each line as long as they are false, it will quit when true is returned
(or (a. is true) ; stop here
(b. does not get this far)
)
(or (a. is false) ; keep going
(b. do this & if false keep going)
(c. do this if b was false)
)
So this will work as well with a variable with a value or nil
(setq var "Some Text")
(or var ; Stop here if the var has a value, if nil then keep going
(setq var "Some Text")
)
The AND will process each line as long as they are true, it will quit when false is returned
(and (a. is true) ; keep going
(b. do this & if true keep going)
(c. do this if b was true)
)
Note that AND & OR themselves only return true or nil,
whereas IF and COND will return the value of the expression.
(setq rtn
(or (+ 3 7) ; returns 10 which is not nil so it passes the test for true
(+ 2 4 6) ; return 12
)
)
While the value in rtn is t
(setq rtn
(if (+ 3 7) ; returns 10 which is not nil so it passes the test for true
(+ 2 4 6) ; return 12
)
)
The value in rtn is 12
(setq rtn
(if (> 3 7) ; 3 is not > 7 so this returns nil
(+ 2 4 6) ; return 12
)
)
The value in rtn is nil because there was no else line to consider
(setq rtn
(if (> 3 7) ; 3 is not > 7 so this returns nil
(+ 2 4 6)
(- 10 2)
)
)
No supprise here, the rtn value is 8
The cond statement works simular to the if
Here is an example I like
(initget 0 "Yes No")
(setq ans
(cond
((getkword "\nGive your answer. [Yes/No] <Yes>: "))
("Yes")
)
)
If the user hits the enter key nil is returned and the cond returns "Yes"
If the user enters text the text is returned
Some examples of (progn
Note that progn returns the value of the LAST evaluated expression.
(if (this is true)
(progn
do all of this
and this
and this
)
(don't do this)
); endif
(if (this is false)
(don't do this)
(progn
do all of this
and this
and this
)
)
So you see the progn is a way to group code together.
The (if) stmt will execute the group of code when true and
will execute the second group of code when false,
if there is a second group of code. If you forget the (progn) only the first
line of code will be executed if true and the rest skipped.
There are other ways to group code together and you will learn them in time.
Outa Gas,
I know it's more that you wanted to know.
See ya.
The (cond) stmt on the other hand executes all of the code following
a true condition and then exits the condition stmt. Remember true is anything not nil.
(cond
((= 1 0)
none of this will get executed
because the conditions is false
) ; end cond 1
((= 1 1)
do all of this because it is true
and this
and this
) ; end cond 2
((= 2 2)
none of this will get
executed even if it is true
because the prior stmt was true
) ; end cond 3
(T
This is often placed at the last position
in a condition statement and will be executed
if all the prior conditions are false
if any one of the above conditions are true
this will not be executed
) ; end cond 4
) ; end cond stmt
Here is a trick for the cond statement when you want to conditionally execute the cond.
Often we see it like this:
(if (something is true) ; reminder, 'true' here is really anything (not nil)
(cond
((= 1 1) ...)
((= 2 2) ...)
) ; end cond stmt
) ; endif
It can be written like this so that if something is not true the first condition is true &
nothing is done but the cond statement is satisfied that it found a true condition.
The processing skips the remaining conditions.
(cond
((not (something is true))) ; if something is not true stop here
((= 1 1) ...)
((= 2 2) ...)
) ; end cond stmt
The WHILE function as a conditional loop and continues the loop until the next
expression returns nil. Here we test the value in cnt looking for it to become 0
so that we can exit the while loop. The code within the loop is executed 5 times,
while the cnt value is 0 through 4.
(setq cnt 0)
(while (= cnt 5)
;; do some stuff
(setq cnt (1+ cnt))
)
It can also be written like this and the cnt value is 0 through 4.
(setq cnt -1)
(while (= (setq cnt (1+ cnt)) 5)
;; do some stuff
)
Sometimes the condition you want to test is set at the end of the code within
the loop. The code may look like this.
(setq continue_loop t)
(while continue_loop
;; do some stuff
(if (I want to leave the loop is true)
(setq continue_loop nil) ; flag to exit the loop
)
)
This can also be written like this:
(setq continue_loop t)
(while
(progn
;; do some stuff
(not (I want to leave the loop is true)) ; flag to exit the loop
) ; progn
)
So you see that when (I want to leave the loop is true) returns true, the not will
return nil and because it is the last expression in the progn, that is the value the
while sees. It then exits the loop.
Here is a real world example.
This is my solution for entering numbers like key words
The simulated key words would be "90 180 270 -90"
(while
(progn
(setq rang
(cond ((getint "\nEnter the rotation angle [90/180/270] <90>"))
(90)))
(if (not (vl-position rang '(90 180 270 -90)))
(not (prompt "\nError Angle must be 90 180 270, please re-enter.")))
)
)
Added a little more. :)
-
Very nice Alan.
<tips hat>
-
Very nice Alan.
<tips hat>
x 2, good job!
:)
-
Wow !!! Alan, thank you. Yeah, it was a bit more than I was looking for, but then again, I wasn't sure what I was to expect. Definately an opportunity to learn more.
Don't take me wrong here, I really do appreciate the info. It explains why a couple of my routines are not acting as they should, I was not completely understanding the conditional, the or & the and statements.
I was however, looking for some thought on the tblsearch vs cond. situation. With that info in mind, perhaps I should re-phrase my question. ^-^
In the If statement, I am doing a tblsearch for the text style. If it is not available, create it.
In the conditional statement, I am NOT doing a tblsearch, but I am doing the same thing, if it is not available, create it.
How is this accomplished ??
Is the conditional statement recreating the text style regardless, where the If statement is only creating it if it is not there ??
Tim, you put a ... nil) in the example B,
I think you example B isn't complete. It should be
... (cond ( (= (strcase tstyl) "ARCHITXT") nil) (command ".-style" "ARCHITXT" "ARCHITXT.SHX" txtht "0.75" "" "n" "n")) ...
But the = sign is refering to the "ARCHITXT". the nil would be one more parenthesis down. Would the = sign still work for the nil ??
My intention for the code would be to find the 'tstyl ARCHITXT', and replace it. Here's the bigger picture.
(progn
(cond ( (= (strcase tstyl) "ARCHITXT")
(command ".-style" "ARCHITXT" "ARCHITXT.SHX" txht "0.75" "" "n" "n")
(setq txtupd "Textstyle Updated")
)
;
( (= (strcase tstyl) "ARIAL")
(command ".-style" "ARIAL" "ARIAL.TTF" txht "0.875" "" "n" "n")
(setq txtupd "Textstyle Updated")
)
;
(T
(ALERT "The Current Text Style is Unrecognized!")
(ALERT "ARCHITXT Text Style will be substituted!")
(command ".-style" "ARCHITXT" "ARCHITXT.SHX" txht "0.75" "" "n" "n")
(setq txtupd "Alternate")
)
);end cond
(if (= txtupd "Alternate")
(setq txtupd nil))
);end progn
Perhaps I am wasting time & resources here. I don't know. I have several typical details that have an old text style with the same ARCHITXT name. Instead of fighting the system, I figured I'd just replace the text style with our current. We are running into more and more clients requesting ARIAL be used as well. But with this, if STANDARD or some other style is current, the code won't recognize it and put ARCHITXT in. If ARIAL is needed, it basically throws up a flag to the user so they know to update their text style to ARIAL.
This is a parallel to my question though, and any advice on this would be well received.
So, if the examples A and B are doing the same thing, then wouldn't this also work ??
... (if (= (tblsearch "style" (strcase tstyl) "ARCHITXT") nil) (command ".-style" "ARCHITXT" "ARCHITXT.SHX" txtht "0.75" "" "n" "n")) ...
or perhaps
... (cond ( (= (tblsearch "style" (strcase tstyl) "ARCHITXT") nil) (command ".-style" "ARCHITXT" "ARCHITXT.SHX" txtht "0.75" "" "n" "n")) ...
Thank you for your thoughts.
<<< Edited for Clarity >>>
AHaaa, there's my question:
How is the conditional statement doing a tblsearch when it is not asked to do it ?? Or could it be that the following is completely disregarded ??
... (cond ( (= (strcase tstyl) "ARCHITXT") ...
(from example B)
-
In the cond example the variable tstyl was previously set to a text style name.
Perhaps the current text style, like this
(setq tstyl (getvar "textstyle"))
(cond
( (= (strcase tstyl) "ARCHITXT")
;; if the previous expression is not nil this will continue to execute here
(command ".-style" "ARCHITXT" "ARCHITXT.SHX" txht "0.75" "" "n" "n")
(setq txtupd "Textstyle Updated")
)
But the = sign is refering to the "ARCHITXT". the nil would be one more parenthesis down. Would the = sign still work for the nil ??
My intention for the code would be to find the 'tstyl ARCHITXT', and replace it. Here's the bigger picture.
the use of (= var nil) or (= (expression) nil) is not needed & most people do it for there readability.
The reason it is not needed is that anything that is not nil or returns anything except nil will be considered to be TRUE.
Conversely anything that is nil or returns nil will cause the if or cond to pass it by.
I'll be back later....
-
The initial ``cond'' statment you posted is not doing a tablesearch, it is mearly looking up the contents of a variable.
Another very good explination for conditionals can be found here.
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1.6
-
What I did was not read carefully enough. Sorry.
I would just skip the first 'if' statement you posted, as it is not needed, unless you always want that style in there. You are only not creating it if the 'tstyl' variable is set to 'ARIAL'.
-
Thanks guys :-)
Hangman,
The cond above is NOT doing the same thing as a table search. It is comparing the variable tstyl to the string "ARCHITXT".
You are saying [is the uppercase of variable tstyl equal to the string "ARCHITXT"]
If you want to see if the style is in the drawing use the following code.
No need to strcase the variable in the tblsearch as the tblsearch ignores case
It reads like this:
If the text style in var tstyl is not in the drawing do the cond
Note that the return value from the cond statement is being saved in the variable txtup
(if (not (tblsearch "style" tstyl "ARCHITXT"))
(setq txtup
(cond ((= (strcase tstyl) "ARCHITXT")
(command ".-style" "ARCHITXT" "ARCHITXT.SHX" txht "0.75" "0" "n" "n")
"Textstyle Updated"
)
((= (strcase tstyl) "ARIAL")
(command ".-style" "ARIAL" "ARIAL.TTF" txht "0.875" "" "n" "n")
"Textstyle Updated"
)
(t
(alert (strcat "The Current Text Style is Unrecognized!"
"\nARCHITXT Text Style will be substituted!"
)
)
(command ".-style" "ARCHITXT" "ARCHITXT.SHX" txht "0.75" "" "n" "n")
"Alternate"
)
) ; end cond stmt
)
)
-
So, the tblsearch does a search of the drawing for the style, period. No variables, no if's, no conditionals, it just does the search.
Where the 'if' statement and the 'conditional' statement rely on a variable to do their search. Well, In essence I mean, as the 'if' statement causes the tblsearch to occur.
They are both doing the same thing, but one way is based on given variables where the other is open to suggestion.
Aaaah. I am in understanding. Thank you all for your comments, it has been very enlightening.
-
So, the tblsearch does a search of the drawing for the style, period.
Not actually 'search of the drawing " ...
a table is where the definitions are kept ... slightly different, but an important distinction.
-
Ahhh yes, thank you Kerry. I remember Tim mentioning the definitions from a post several months ago now that you mention it. Thanks for the clarification.