text Calc lisp revision

text Calc lisp revision

mosadelewa
Contributor Contributor
1,469 Views
15 Replies
Message 1 of 16

text Calc lisp revision

mosadelewa
Contributor
Contributor

can anyone help me revise this routine so that the multiply function is the default so I don't have to type "M" to activate it?
also, the default is replacing the existing text with the answer. thank you

 

(defun c:cal()

(initget "A S M D")
(setq app(getkword "\nWhat application would you like to do:\(Add,Subtract,Multiply,Divide)"))
(if(or (= app "S")(= app "D"))(princ "\nDon't forget order counts. So pick carefully."))
(princ "\nSelect numbers to calculate:")
(setq cal(ssget '((0 . "TEXT"))))
(setq n 0)
(setq l(sslength cal))
(while(/= l n)
(get_info)
(if(= nu3 0.0)
(progn
(ssdel (ssname cal n) cal)
(setq l(- l 1))
(setq n(- n 1))
)
)
(setq n(+ n 1))
)
(setq n 0)
(setq l(sslength cal))
(cond
((= app "A")
(addc))
((= app "S")
(subc))
((= app "M")
(multc))
((= app "D")
(divdc))
)
;(initget "Replace Write")
;(princ "\nAnswer= ")
;(princ nu5)
;(setq tx1(getkword"\nWhat do you want do with the answer\(Replace, Write to screen):"))
;(cond
;((= tx1 "Replace")
(setq tx2(ssget '((0 . "TEXT"))))
(setq n 0)
(setq l(sslength tx2))
(while(/= n l)
(setq tx3(entget(ssname tx2 n)))
(setq tx4(subst(cons 1 (rtos nu5 2 2))(assoc 1 tx3) tx3))
(entmod tx4)
(setq n(+ 1 n))
)
)
;((= tx1 "Write")
;(setq nu5(rtos nu5 2 1))
;(command "layer" "m" "sr_text_n" "c" "3" "" "")
;(command "textstyle" "sr-romands2")
(princ "\nPick point for text insertion")
;(command "text" "j" "m" pause "" "" nu5 )
😉
😉

(princ)

😉

 

(defun get_info()
(setq nu1(entget (ssname cal n)))
(setq nu2(cdr(assoc 1 nu1)))
(setq nu3(atof nu2))
)

(defun addc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(+ nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)

(defun subc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(- nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)

)


(defun multc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(* nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)


(defun divdc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(/ nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)

0 Likes
Accepted solutions (2)
1,470 Views
15 Replies
Replies (15)
Message 2 of 16

Kent1Cooper
Consultant
Consultant

Is it acceptable to have to press Enter to accept M as the default, which saves you all of one keystroke?  Because unfortunately, I don't think this kind of thing:

  "Select objects to Multiply together or [Add/Subtract/Divide]: "

can be done with (ssget) allowing multiple objects, to go right into selection without specifying a math function when the one you want is to Multiply.  It could be with (entsel) for selecting a single one, but it requires the use of keywords, which (ssget) can't do.

 

Or, is it acceptable to always need to select things one at a time, regardless of the function to be applied?  If adding or multiplying, where order doesn't matter, with (ssget) you could pick things collectively in a Window or with a Lasso, but the prompt situation above isn't available.  But I can imagine having a prompt like the one above be workable, if the selection is always by (entsel) selecting one thing at a time, though as many times as you want.  You need to do that for divide and subtract anyway, when order matters, unless the things happen to be in the right kind of arrangement that you can do (ssget) with a Fence and get them in the right order.

 

[By the way, I think there are much simpler ways to do those math operations, by converting the selection set into a list and using (apply) on it with the math function specified.]

Kent Cooper, AIA
Message 3 of 16

mosadelewa
Contributor
Contributor

thank you, Kent for replying.

could you please make the required modification to the lisp? 

0 Likes
Message 4 of 16

Kent1Cooper
Consultant
Consultant

[That doesn't answer my questions.]

Kent Cooper, AIA
0 Likes
Message 5 of 16

dbroad
Mentor
Mentor

@mosadelewa Welcome to the newsgroup. Did you write the function in your OP?  If not, be sure to attribute the author.

 

Important preface:  Never write commands that replace better written built-in commands.  C:CAL is a transparent calculator that can be used in the command line and is extremely functional, supporting many complex features and algebraic notation.

 

Suggested partial code alternative:

 

 

(defun c:test (/ app lst result)
  ;;DCBroad - 1/19/2023
  (initget "Add Subtract Multiply Divide")
  (setq	app (cond ((getkword
		     "\nWhat application would you like to do?<Multiply>: [Add Subtract Multiply Divide]"
		     )
		   )
		  (t "Multiply")
		  )
	)
  (if (ssget '((0 . "text,mtext") (1 . "#*")))
    ;;Text items must begin with a number
    (progn (vlax-for n (vla-get-activeselectionset
			 (vla-get-activedocument (vlax-get-acad-object))
			 )
	     (setq lst (cons (vla-get-textstring n) lst))
	     )
	   (setq result	(apply (cdr (assoc app
					   '(("Add" . +)
					     ("Subtract" . -)
					     ("Divide" . /)
					     ("Multiply" . *)
					     )
					   )
				    )
			       (mapcar 'atof (reverse lst))
			       )
		 )
	   (princ result)		;result is number, not text at this point
	   ;;make other decisions about what to do with the result.
	   )
    )
  (princ)
  )

 

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 6 of 16

Kent1Cooper
Consultant
Consultant

@dbroad wrote:

....

....
     "\nWhat application would you like to do?<Multiply>: [Add Subtract Multiply Divide]"
....
		  (t "Multiply")
....
  (if (ssget '((0 . "text,mtext") (1 . "#*")))
....

First line quoted above:  needs slashes between options, if it's to work with picking an option in the prompt itself:
"\nWhat application would you like to do?<Multiply>: [Add/Subtract/Multiply/Divide]"

 

Second line:  A small thing, but in this case [with only one thing to do or return under that condition] the t is not needed -- simply ("Multiply") will do.

 

Third line:  That raises another question in my mind for the OP.  @mosadelewa, would any of your Text/Mtext objects' numerical values ever be negative?  A negative value will be omitted by that filter, because the number-character # wildcard won't recognize a first-character hyphen/minus-sign.  Or similarly, might there ever be decimal values with no zero preceding the decimal point?

Kent Cooper, AIA
0 Likes
Message 7 of 16

dbroad
Mentor
Mentor
Accepted solution

@Kent1Cooper Yep, thanks. I had the slashes at one point and then cut and pasted his. When modifying it, I didn't add the slashes back.  I understand that the T isn't needed but I usually add it anyway as a message that this is the last condition. Also a good point about the negative sign.  Current version doesn't select if first character is a negative sign.  Too bad LISP doesn't have regular expressions.  See revised top section:

(defun c:test (/ app lst result)
  ;;DCBroad - 1/19/2023
  (initget "Add Subtract Multiply Divide")
  (setq	app (cond ((getkword
		     "\nWhat application would you like to do<Multiply>: [Add/Subtract/Multiply/Divide]"
		     )
		   )
		  (t "Multiply")
		  )
	)
  (if (ssget '((0 . "text,mtext") (-4 . "<OR")(1 . "#*")(1 . "-#*")(-4 . "OR>")))

 

Architect, Registered NC, VA, SC, & GA.
Message 8 of 16

mosadelewa
Contributor
Contributor

Kent,

Thank you for your help, You are the MAN!

I just added this part to prompt the user to select an existing text to be replaced with the result. and it worked.

 

(princ "Select Text to be changed...\n")
(setq tx2 (ssget '((0 . "TEXT"))))
(setq n 0)
(setq l(sslength tx2))
(while(/= n l)
(setq tx3(entget(ssname tx2 n)))
(setq tx4(subst(cons 1 (rtos result 2 2))(assoc 1 tx3) tx3))
(entmod tx4)
(setq n(+ 1 n))
)

0 Likes
Message 9 of 16

calderg1000
Mentor
Mentor
Accepted solution

Regards @mosadelewa 

I only made small edits to your code...Select with the mouse pointer "M" or press "ENTER" to access multiplication.

 

 

(defun c:c-cal( / app cal n l tx2 tx3 tx4)
(setvar 'Dynmode 1)
(initget "A S M D")
(setq app(getkword "\nWhat application would you like to do: Add/Subtract/Multiply/Divide: [A/S/M/D]<M>"))
(if(or (= app "S")(= app "D"))
(princ "\nDon't forget order counts. So pick carefully."))
(princ "\nSelect numbers to calculate:")
(setq cal(ssget '((0 . "TEXT"))))
(setq n 0)
(setq l(sslength cal))
(while(/= l n)
(get_info)
(if(= nu3 0.0)
(progn
(ssdel (ssname cal n) cal)
(setq l(- l 1))
(setq n(- n 1))
)
)
(setq n(+ n 1))
)
(setq n 0)
(setq l(sslength cal))
(cond
((= app "A")
(addc))
((= app "S")
(subc))
((= app "M")
 (multc))
 ((= app nil)
(multc))
((= app "D")
(divdc))
(t nil)
)
(princ "\nPick point for text insertion")
	(while (null (setq tx2 (ssget "_+.:E:S" '((0 . "TEXT")))))
		(princ "\n¡Empty selection or not a valid Text!")
	)
(setq n 0)
(setq l(sslength tx2))
(while(/= n l)
(setq tx3(entget(ssname tx2 n)))
(setq tx4(subst(cons 1 (rtos nu5 2 2))(assoc 1 tx3) tx3))
(entmod tx4)
(setq n(+ 1 n))
)
(princ)
  )

;_
(princ)
(defun get_info()
(setq nu1(entget (ssname cal n)))
(setq nu2(cdr(assoc 1 nu1)))
(setq nu3(atof nu2))
)

(defun addc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(+ nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)

(defun subc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(- nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)

(defun multc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(* nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)

(defun divdc()
(get_info)
(setq nu4 nu3)
(setq n(+ 1 n))
(while(/= l n)
(get_info)
(setq nu5(/ nu4 nu3))
(setq nu4 nu5)
(setq n(+ 1 n))
)
)

 

 

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Message 10 of 16

mosadelewa
Contributor
Contributor

Thank you, Carlos! this also works, great job!👍

 

0 Likes
Message 11 of 16

Sea-Haven
Mentor
Mentor

You can do something like this if you want it allows you to preset which button to use or can save the last button selection.

 

SeaHaven_0-1674188287976.png

Its a library function happy to post.

Message 12 of 16

mosadelewa
Contributor
Contributor

Sea-haven,

an improvement to this routine will be greatly appreciated, please post a complete routine with your dialogue box. 

0 Likes
Message 13 of 16

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:
....  @mosadelewa, would any of your Text/Mtext objects' numerical values ever be negative?  ....  Or similarly, might there ever be decimal values with no zero preceding the decimal point?

And a further question:  Might any of them ever be zero?  If so, in the division operation you would need to check for that, and either bypass any zero value(s) after the first number, or scold the User for picking such a number to divide by.  If the first number is zero, then in either the multiplication or division operation you could skip the math entirely, and simply return zero.

Kent Cooper, AIA
Message 14 of 16

Sea-Haven
Mentor
Mentor

Here is your sample.

 

 

 

 

(if (not AH:Butts)(load "Multi radio buttons.lsp")) ; loads the program if not loaded already
; the 3 means button 3 is preset can be a variable
(setq app (ah:butts 3 "V"   '("Choose " "+ Add" "- Subtract" "* Multiply" "/ Divide" ))) 	; ans holds the button picked value as a string
; or can use the value in variable but
if(or (= app "- Subtract")(= app "/ Divide"))
.....

 

 

 

 

 

 

0 Likes
Message 15 of 16

mosadelewa
Contributor
Contributor

Hi Sea-Haven,

you lost me, can you send a complete lisp that works, I don't know how to add this part to the existing routine 

thank you.

0 Likes
Message 16 of 16

Sea-Haven
Mentor
Mentor

Replace 

 

 

(initget "A S M D")
(setq app(getkword "\nWhat application would you like to do: Add/Subtract/Multiply/Divide: [A/S/M/D]<M>"))

with

(if (not AH:Butts)(load "Multi radio buttons.lsp")) ; loads the program if not loaded already
(setq app (ah:butts 3 "V"   '("Choose " "+ Add" "- Subtract" "* Multiply" "/ Divide" )))

 

 

 

 

 

(cond
((= app "+ Add")
(addc))
((= app "- Subtract")
(subc))
((= app "* Multiply")
 (multc))
 ((= app nil)
(multc))
((= app "/ Divide")
(divdc))
(t nil)
)

 

 

If you want can change question to "+" "-" "*" "/" only.

 

 

 

0 Likes