If [Contains] Conditionals

If [Contains] Conditionals

Anonymous
Not applicable
3,260 Views
16 Replies
Message 1 of 17

If [Contains] Conditionals

Anonymous
Not applicable

Hi,

 

What I'm trying to do:

If my variable revnum contains A call that function

If my variable revnum contains B call that function

If my variable revnum contains C call that function

ELSE, call this function

 

I'm trying to make my statements more efficient verse using many conditionals, as the count can go up to 20 for each letter. Sample Code:

  (cond ((= revnum "A1") (Arecord)) ; If input equals
        ((= revnum "A2") (Arecord))
		((= revnum "A3") (Arecord))
        ((= revnum "B1") (Brecord))
		((= revnum "B2") (Brecord))
        ((= revnum "B3") (Brecord))
		((= revnum "C1") (Crecord))
        ((= revnum "C2") (Crecord))
		((= revnum "C3") (Crecord))
		(t (other_issue)) ; Else statement
  )

If you have documentation resources directly related to AutoLISP I would very much appreciate it, I'm having trouble finding centralized, in-depth documentation similar to other programming languages.

 

0 Likes
Accepted solutions (2)
3,261 Views
16 Replies
Replies (16)
Message 2 of 17

Anonymous
Not applicable

Modified code formatting, it didn't paste right:

  (cond ((= revnum "A1") (Arecord)) ; If input equals
        ((= revnum "A2") (Arecord))
	((= revnum "A3") (Arecord))
        ((= revnum "B1") (Brecord))
	((= revnum "B2") (Brecord))
        ((= revnum "B3") (Brecord))
	((= revnum "C1") (Crecord))
        ((= revnum "C2") (Crecord))
	((= revnum "C3") (Crecord))
	(t (other_issue)) ; Else statement
  )

 

0 Likes
Message 3 of 17

ronjonp
Mentor
Mentor
Accepted solution

One quick simplification is to use WCMATCH like so:

(cond ((wcmatch revnum "A[1-3]") (arecord))
      ((wcmatch revnum "B[1-3]") (brecord))
      ((wcmatch revnum "C[1-3]") (crecord))
      (t (other_issue))
)
0 Likes
Message 4 of 17

SeeMSixty7
Advisor
Advisor

Since you are comparing for the first letter, simply snag the first letter and compare for "A" instead

 

((= (strcase (substr revnum 1 1)) "A") (ARecord))

...

 

 

Good luck

0 Likes
Message 5 of 17

ronjonp
Mentor
Mentor

@SeeMSixty7 wrote:

Since you are comparing for the first letter, simply snag the first letter and compare for "A" instead

 

((= (strcase (substr revnum 1 1)) "A") (ARecord))

...

 

 

Good luck


Along the same lines I'd approach like so 🙂

((wcmatch (strcase revnum) "A*") (arecord))
Message 6 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... the count can go up to 20 for each letter. ....

If you have documentation resources directly related to AutoLISP I would very much appreciate it....


 

If it can go up to 20, neither Message 2 or 3 will help you.  Messages 4 & 5 should, or if you might sometimes have a value like "AsBuilt" [i.e. starting with "A" but not followed by a number], you could use:

  (wcmatch revnum "A#*")

The # is a wildcard for any numerical character, and the * for any character or multiple characters [including none], so it would also recognize "A123".

 

For AutoLisp documentation, see the >AutoLisp Reference< [here for 2020, but it's rare for there to be any change from version to version].

Kent Cooper, AIA
Message 7 of 17

Anonymous
Not applicable

I tried to keep this generalized to make it more benficial to the community, however it looks like I need to get a bit more specific! Here is a more realistic scenario of typical input:

 

(defun type_issue ()
  
	(cond ((wcmatch revnum "[A-Z]") (rev_issue))
	      ((wcmatch revnum "[0-99]") (rev_issue))
	      ((wcmatch revnum "RD[0-99]") (record))
	      (t (alert "Bad Input! Acceptable input is <[A-Z]> for Preliminary Issues, <[0-99]> for Construction Issues, <RD[1-99]> for Record Issues. Check the Rev. Number on titleblock and run the command again."))
	)
    (princ)
)	

 

 

 

In other words, If we're A-Z call this function, if we're 1-99 call that function, if we're RD1-99 call this function, and if we're none of those we have non-standardized input. What is my best approach to this scenario?

 

0 Likes
Message 8 of 17

Anonymous
Not applicable

Kent,

 

Thank you very much for this information!

 

As per the wildcard, I see how I can implement # for my 1-99 numerical range, and RD# for my RD1-99 alphanumerical range. How could I implement for my A-Z range? Is there another wildcard available for alpha characters?

0 Likes
Message 9 of 17

SeeMSixty7
Advisor
Advisor

Check for the "RD*" condition first.

0 Likes
Message 10 of 17

ronjonp
Mentor
Mentor

@Anonymous wrote:

I tried to keep this generalized to make it more benficial to the community, however it looks like I need to get a bit more specific! Here is a more realistic scenario of typical input:

 

(defun type_issue ()
  
	(cond ((wcmatch revnum "[A-Z]") (rev_issue))
	      ((wcmatch revnum "[0-99]") (rev_issue))
	      ((wcmatch revnum "RD[0-99]") (record))
	      (t (alert "Bad Input! Acceptable input is <[A-Z]> for Preliminary Issues, <[0-99]> for Construction Issues, <RD[1-99]> for Record Issues. Check the Rev. Number on titleblock and run the command again."))
	)
    (princ)
)	

 

 

 

In other words, If we're A-Z call this function, if we're 1-99 call that function, if we're RD1-99 call this function, and if we're none of those we have non-standardized input. What is my best approach to this scenario?

 


Look into WCMATCH more. Your last example has me a bit confused compared to your first post ?

 

Are you looking for something like this?

;; This will match an alphabetic character followed by digits up to 99.
(wcmatch revnum "@#,@##")
0 Likes
Message 11 of 17

Kent1Cooper
Consultant
Consultant
Accepted solution

Your first condition should work, but the brackets with hyphen in (wcmatch) are for range of a single character, so you can't do [1-99].  Try something like this:

....
(cond
((wcmatch revnum "[A-Z]") (rev_issue)) ((wcmatch revnum "RD#*") (record))
((<= 0 (atoi revnum) 99) (rev_issue)); check value as number rather than text (t (alert "Bad Input! Acceptable input is <[A-Z]> for Preliminary Issues, <[0-99]> for Construction Issues, <RD[1-99]> for Record Issues. Check the Rev. Number on titleblock and run the command again.")) )
....

 

I put the "RD" check before  the numerical-value check, because (atoi) returns 0 for any string that doesn't start with a number, so it would be "satisfied" under the test of numerical value if zero is a possibility.  But is it?  Would you ever have a Revision Number 0?  Also, might it ever be a lower-case letter?  Those variants can be dealt with if needed.

 

As before, "RD#*" will recognize anything starting with RD and with a number character next, whether or not there are more characters or what they are.  If such value would never be other than numbers following the RD, you could use simply "RD*".

Kent Cooper, AIA
0 Likes
Message 12 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... I see how I can implement # for my 1-99 numerical range, and RD# for my RD1-99 alphanumerical range. ....


[The # is for a single character, so (wcmatch)ing to "#" would recognize "0" through "9" but not  "10" through "99", and likewise, "RD#" would recognize "RD0" through "RD9" but not  "RD10" through "RD99".]

Kent Cooper, AIA
0 Likes
Message 13 of 17

ronjonp
Mentor
Mentor

Since you're calling the same function for A-Z and 0-99 you could approach it like so.

((wcmatch revnum "[A-Z],[0-99]") (rev_issue))
0 Likes
Message 14 of 17

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

Since you're calling the same function for A-Z and 0-99 you could approach it like so.

((wcmatch revnum "[A-Z],[0-99]") (rev_issue))

No, you couldn't.  [0-99] is invalid -- the hyphenated range in brackets is for single  characters.

Kent Cooper, AIA
0 Likes
Message 15 of 17

ronjonp
Mentor
Mentor

@Kent1Cooper wrote:

@ronjonp wrote:

Since you're calling the same function for A-Z and 0-99 you could approach it like so.

((wcmatch revnum "[A-Z],[0-99]") (rev_issue))

No, you couldn't.  [0-99] is invalid -- the hyphenated range in brackets is for single  characters.


DOH .. very true 🙂

Back to:

((wcmatch revnum "[A-Z],#,##") (rev_issue))
0 Likes
Message 16 of 17

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

.... if we're 1-99 call that function....


Here's another kind of interesting way to check whether a text string represents an integer:

 

  (= (itoa (atoi revnum)) revnum)

 

That returns T if the 'revnum' variable string represents an integer and only an integer, of any number of digits [though I don't imagine you're likely to get as far as 3-digit revision numbers], including negative integers, without the need to account for possible different numbers of digits, or to use (wcmatch) and wildcards.

 

It returns nil for anything containing any alphabetic characters, no matter where in the string, or punctuation characters other than an initial minus sign, or decimal numbers.

Kent Cooper, AIA
0 Likes
Message 17 of 17

Anonymous
Not applicable

Thank you all for the help! I really appreciate it.