Cond to check variable a is between two integers, and variable b = specific integer

Cond to check variable a is between two integers, and variable b = specific integer

asleafty
Participant Participant
686 Views
5 Replies
Message 1 of 6

Cond to check variable a is between two integers, and variable b = specific integer

asleafty
Participant
Participant

I am trying to create a simple routine to allow user input to set two variables, then I would like to use a condition statement to evaluate if the first variable is between (or equal to ) to numbers, and if the second number = a specific number. If true, I would like the routine to set a third variable to a specified value. What I think would work creates a lengthy condition statement, but I from my limited understanding it should work. The code I was working on is attached. Any advice or clarification for where I went wrong would be greatly appreciated!

0 Likes
Accepted solutions (1)
687 Views
5 Replies
Replies (5)
Message 2 of 6

Sea-Haven
Mentor
Mentor

The obvious problem, cond is looking for a number and your inputs are a string, change to getreal.

 

Do you want cfm as a string or a number ?

 

0 Likes
Message 3 of 6

pbejse
Mentor
Mentor
Accepted solution

@asleafty wrote:

I am trying to create a simple routine to allow user input to set two variables, then I would like to use a condition statement to evaluate if the first variable is between (or equal to ) to numbers, and if the second number = a specific number. If true, I would like the routine to set a third variable to a specified value.


One way

(if
    (setq lst (Cond
	      ((<= 2001 sqft 2500) '("40" "50" "55" "65" "70"))
	      ((<= 2501 sqft 3000) '("45" "55" "60" "75" "75"))
	      ((<= 3001 sqft 3500) '("50" "60" "65" "75" "80"))
	      ((<= 3501 sqft 4000) '("55" "65" "70" "80" "85"))
	    )
  	)
  	(setq cfm (nth (1- bdrm) lst))
    	(princ "\n<<< Out of range >>>")
)

Also, use getint/getreal for user prompt rather than converting the string to a number.

 

If its me i would look for patterns and use a range/list

 

HTH

 

 

 

 

0 Likes
Message 4 of 6

ВeekeeCZ
Consultant
Consultant

In addition to the above about inappropriate use of strings...

 

The COND is a great function. Very versatile. It is worth delving deeper into the algorithm of how it works.

Similarly, as AND or OR functions, it tests the test functions UNTIL something happens. Then it skips all the rest.

 

COND: It tests the test function UNTIL it gets True, then it returns the result of the return expression or the result of the test function itself if there is NO result function.

(cond ((test1)  (result1))

           ((test2))

           ((test3)  (results3))   

            ...)

 

AND: It tests the expressions UNTIL it gets NIL, then returns NIL. If never finds NIL, then returns True.

(and (expresion1) (expresion2) ...)

 

OR: It tests the expressions UNTIL it gets True, then returns True. If never finds True, then returns Nil.

(and (expresion1) (expresion2) ...)

 

So your COND could be simplified:

(defun c:cfmcalc ()

  (if (and (setq sqft (getint "\nPlan Square Footage: " ))  ;; if always integer, else use getdist
	   (setq bdrm (getint "\nPlan Bedroom Count: "))   ;; definitely always integer
	   )
    (setq cfm (cond ((> sqft 3500) 	(cond ((nth (1- bdrm) '(55 65 70 80))) (85)))
		    ((> sqft 3000)	(cond ((nth (1- bdrm) '(50 60 65 75))) (80)))
		    ((> sqft 2500)	(cond ((nth (1- bdrm) '(45 55 60 70))) (75)))
		    ((> sqft 2000)	(cond ((nth (1- bdrm) '(40 50 55 65))) (70)))
		    ))))

 

 

0 Likes
Message 5 of 6

asleafty
Participant
Participant

That's perfect! Thank you. I really appreciate the help and the quick reply!

0 Likes
Message 6 of 6

john.kaulB9QW2
Advocate
Advocate

Why are you testing if both `sqft` and `bdrm` variables get set? Your code could be simplified if you remove those boolen tests; and you can test to see if the `sqft` variable is "within range" instead (-i.e. the first logical problem is because the `cfm` variable depends on `sqft` being larger/in range so you need to check for that condition before you continue).

 

Obviously, this all falls apart if the `bdrm` value is negative--or zero--but that could be as simple of a fix as making sure you have a positive number (however, that does not explain the logic behind how the program calculated a `cfm` from a negative number but that can be for another time).

 

(defun c:cfmcalc ()
  (setq sqft (getint "\nPlan Square Footage: " ))  ;; if always integer, else use getdist

  (if (> sqft 2000)
    (progn
      (setq bdrm (getint "\nPlan Bedroom Count: ")  ;; definitely always integer
            bdrm (abs bdrm))
      (setq cfm 
            (cond 
              ((> sqft 3500) (cond ((nth (1- bdrm) '(55 65 70 80))) (85)))
              ((> sqft 3000) (cond ((nth (1- bdrm) '(50 60 65 75))) (80)))
              ((> sqft 2500) (cond ((nth (1- bdrm) '(45 55 60 70))) (75)))
              ((> sqft 2000) (cond ((nth (1- bdrm) '(40 50 55 65))) (70)))
              )
            )
      )
    )
  )

 

I also prefer to use `cond` in variable setting (and offer up default values if I can) like:

This is surprisingly effective--not fool proof--in getting values you expect from users.

(setq sqft
      (cond
        ((getint "\nPlan SqFt <2001>:"))
        (2001)))

 

another swamper