PDA

View Full Version : Using 'if" to test for a real or integer


Rick Stanich
2009-07-20, 04:42 PM
I get a value from a user, the value will either be a integer or a real. If its a real I want to increment the number after the decimal by 1, thus, 1.1 would become 1.2, 1.3, and so on. If the value is an integer I want ot increment the number by 1, thus, 1 would become 2, 3 and so on.

The code below counts by integers and works very well.

;;TAG1.LSP Copyright 1998 HyperPics all rights reserved
;;
;; Author: Lee Ambrosius,
;; HyperPics

;;TAG1.zip
;;The tag allows the user to place a numbered bubble at any give point.
;;The number counts upward in an increment of one from the users defined number.


(defun MYERROR (S) ;;error trap program
(if (/= S "\nFunction cancelled" )
(prompt "\nEnding Tag1 routine..." ) )
(setvar "OSMODE" OS)
(setvar "CMDECHO" CMD)
(command ".Error (MYERROR)" "end")
(setq *ERROR* OLDERR )
(princ)
)


(defun c:bn ()
(graphscr)
(setq CMD (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq OLDERR *ERROR*)
(setq *ERROR* MYERROR )
(command "._undo" "begin")
(setq OS (getvar "osmode"))
(setvar "osmode" 0)
(initget 1)
(setq TAGNUM (getint "\nTag starting number: "))
(while (setq PT (getpoint "\nInput center point for tag: "))
(command "circle" PT (/ (getvar "dimscale") 10.0)
"text" "m" PT (/ (/ (getvar "dimscale") 4.0) 6) 0 (itoa TAGNUM)
)
(setq TAGNUM (1+ TAGNUM))
)
(redraw)
(setvar "osmode" OS)
(setvar "cmdecho" CMD)
(setq *ERROR* OLDERR )
(command "Error (OLDERR)" "end")
(princ)
)

(princ)
(prompt "\nEnter bn for the balloon routine.")
(princ)


My initial thought is to alter this line:
(setq TAGNUM (getint "\nTag starting number: "))
to
(setq TAGNUM (getstring "\nTag starting number: "))
Test for a decimal and then re-evaluate TAGNUM as either a real or an integer.
My failure, I am having trouble establishing an "if" statement that tests for the decimal.

I think to much in line with VB. :lol:

Any hints, tips or examples is appreciated. (I am using several lsp routines to re-learn some lisp.)

Opie
2009-07-20, 04:55 PM
Search the returned string for a decimal. If found, convert to a real number, else convert to an integer.

Bruno.Valsecchi
2009-07-20, 05:56 PM
Change to:

(setq TAGNUM (getreal "\nTag starting number: ") ndec (if (eq (fix tagnum) tagnum) 0 1))
(while (setq PT (getpoint "\nInput center point for tag: "))
(command "_.circle" PT (/ (getvar "dimscale") 10.0)
"_.text" "_m" PT (/ (/ (getvar "dimscale") 4.0) 6) 0 (rtos TAGNUM (getvar "lunits") ndec)
)
(if (eq (fix tagnum) tagnum)
(setq TAGNUM (1+ TAGNUM) ndec 0)
(setq tagnum (+ 0.1 tagnum) ndec 1)
)
)

Rick Stanich
2009-07-20, 05:59 PM
Thats one of my stumbling blocks, defining whether a decimal is in the string.

Rick Stanich
2009-07-20, 06:15 PM
Change to:

(setq TAGNUM (getreal "\nTag starting number: ") ndec (if (eq (fix tagnum) tagnum) 0 1))
(while (setq PT (getpoint "\nInput center point for tag: "))
(command "_.circle" PT (/ (getvar "dimscale") 10.0)
"_.text" "_m" PT (/ (/ (getvar "dimscale") 4.0) 6) 0 (rtos TAGNUM (getvar "lunits") ndec)
)
(if (eq (fix tagnum) tagnum)
(setq TAGNUM (1+ TAGNUM) ndec 0)
(setq tagnum (+ 0.1 tagnum) ndec 1)
)
)


Nice! This will make me read stuff to fully understand ;)
Only problem with this is it counts to x.9 and then starts the next as an integer:
1.8, 1.9, 2.0
I didnt expect that. I was expecting:
1.80, 1.9, 1.10, 1.11, etc

I want (would like) to continue counting until I break from the routine and re-establish the count.

This is trickier than I thought! AutoLisp doesn't seem to count as I thought it would.

Bruno.Valsecchi
2009-07-20, 11:29 PM
Oops,

You're rigth, try this:

(setq TAGNUM (getreal "\nTag starting number: ") ndec (if (eq (fix tagnum) tagnum) 0 1))
(while (setq PT (getpoint "\nInput center point for tag: "))
(command "_.circle" PT (/ (getvar "dimscale") 10.0)
"_.text" "_m" PT (/ (/ (getvar "dimscale") 4.0) 6) 0 (rtos TAGNUM (getvar "lunits") ndec)
)
(if (zerop ndec)
(setq TAGNUM (1+ TAGNUM))
(setq tagnum (+ 0.1 tagnum))
)
)

rkmcswain
2009-07-21, 12:07 AM
I get a value from a user, the value will either be a integer or a real. If its a real...

Maybe I'm missing something, but why not just use the (type) function?

Opie
2009-07-21, 03:50 AM
Because he wants the user to provide an answer that could be either one. AFAIK, there is not an getxxx function that will allow for either/or.

irneb
2009-07-21, 07:19 AM
You were on the correct track. Just needed 2 more functions read and type. The read function converts a string to any possible value. So a string of "123" becomes the integer 123, a string of "12.3" becomes a real of 12.3. Then simply set a variable to use as your increment value.(if (and (setq TAGNUM (getstring "\nTag starting number: ")) ;Get a string from the user
(setq TAGNUM (read TAGNUM)) ;Convert the string to a value
)
(cond ;Check what type of value
((= (type TAGNUM) 'REAL) (setq INC 0.1)) ;It's a real number, set increment to 0.1
((= (type TAGNUM) 'INT) (setq INC 1)) ;It's an integer, set increment to 1
(t (princ "\nThat's not a number.")) ;May want to get new input from user
)
(princ "\nUser didn't specify anything.") ;Did the user want to cancel or use the previous default?
)Then in the while loop, change the increment TAGNUM line to:(setq TAGNUM (+ TAGNUM INC))The nice thing about this is that even if the user specifies 1.0 as a start number ... it's read as a real so it gets incremented by 0.1. Whereas with the fix idea, you're checking for the decimal portion of a real number instead.

rkmcswain
2009-07-21, 02:24 PM
Because he wants the user to provide an answer that could be either one. AFAIK, there is not an getxxx function that will allow for either/or.

Ok, then how about this....


(defun myfun (/ a)
(setq a (getreal "\Enter a number: "))
(if (eq (fix a) a)
(fix (1+ a))
(+ 0.1 a)
)
)

Rick Stanich
2009-07-21, 03:59 PM
Ref: irneb's post

I have integrated your code and I amnot getting the "real" values to work, it errors out. The "integer" portion of the code seems to work fine.

(defun MYERROR (S) ;;error trap program
(if (/= S "\nFunction cancelled" )
(prompt "\nEnding Tag1 routine..." ) )
(setvar "OSMODE" OS)
(setvar "CMDECHO" CMD)
(command ".Error (MYERROR)" "end")
(setq *ERROR* OLDERR )
(princ)
)


(defun c:bn4 ()
(graphscr)
(setq CMD (getvar "cmdecho"))
(setvar "cmdecho" 0)
(setq OLDERR *ERROR*)
(setq *ERROR* MYERROR )
(command "._undo" "begin")
(setq OS (getvar "osmode"))
(setvar "osmode" 0)
(initget 1)

(if (and (setq TAGNUM (getstring "\nTag starting number: ")) ;Get a string from the user
(setq TAGNUM (read TAGNUM)) ;Convert the string to a value
)
(cond ;Check what type of value
((= (type TAGNUM) 'REAL) (setq INC 0.1)) ;It's a real number, set increment to 0.1
((= (type TAGNUM) 'INT) (setq INC 1)) ;It's an integer, set increment to 1
(t (princ "\nThat's not a number.")) ;May want to get new input from user
)
(princ "\nUser didn't specify anything.") ;Did the user want to cancel or use the previous default?
)
(while (setq PT (getpoint "\nInput center point for tag: "))
(command "circle" PT (/ (getvar "dimscale") 10.0)
"text" "m" PT (/ (/ (getvar "dimscale") 4.0) 6) 0 (itoa TAGNUM)
)
(setq TAGNUM (+ TAGNUM INC))
)

(redraw)
(setvar "osmode" OS)
(setvar "cmdecho" CMD)
(setq *ERROR* OLDERR )
(command "Error (OLDERR)" "end")
(princ)
)

(princ)
(prompt "\nEnter bn4 for the balloon routine.")
(princ)


When the code errors it jumps to "MYERROR". If I disable MYERROR then I get a circle with no numeric value inside.

Please excuse the poor formatting, I dont have an editor that can indent or format Lisp properly. Unfortunately I am stuck using NT4.OLD.

irneb
2009-07-21, 04:25 PM
It's due to the (itoa TAGNUM) that you're calling to place the bubble's text. There's a few ways of getting round this. The easiest would be to use (vl-princ-to-string TAGNUM) instead, but seeing as you're on R14 it may not work.

2nd option, change to (rtos (* 1.0 TAGNUM) 2 1). This converts the integer to a real in all instances, and then uses the rtos (real to string) to change that to a string. However, this will then display 1.0 ... 2.0 ... 3.0 .... for integer values as well.

3rd option: omit the (itoa ...) from the last command call inside the while. Then directly following add: (cond ;Check what type of value
((= (type TAGNUM) 'REAL) (command (rtos TAGNUM 2 1)))
((= (type TAGNUM) 'INT) (command (itoa TAGNUM)))
)

Rick Stanich
2009-07-21, 04:39 PM
Im remembering some things, I did sumize that "(itoa TAGNUM)" was the problem, however I didnt come up with a solution yet. Until your post. ;)

Your are correct, R14 rejects "(vl-princ-to-string TAGNUM)". I used the 3rd option which works quite well.

Thanks to all that participated, this has been a real treat and jogged some memories (havent used Lisp since circa 1996 ish).

irneb
2009-07-21, 05:02 PM
Glad to help 8)

CAB2k
2009-07-26, 10:12 PM
My version.
;; CAB 07.26.09 Version 1.0

(defun c:bn4 (/ num num$ inc pt)
(defun txt2num (txt) ; CAB 10/2005
(cond
((distof txt 5))
((distof txt 2))
((distof txt 1))
((distof txt 4))
((distof txt 3))
)
)


(or OldNum (setq OldNum "1"))
(while
(cond
((= "" (setq num$ (getstring t (strcat "\nTag starting number: <" OldNum "> "))))
(null (setq num (distof OldNum)))
)
((setq num (txt2num Num$)) ; got some kind of number
nil
)
((princ "\nMust enter a number or numeric symbol,"))
)
)

(if num
(progn
(graphscr)
(command "._undo" "begin")
(if (= num (fix num)) ; test for intiger
(setq num (fix num))
)
(if (= (type num) 'REAL)
(setq inc 0.1
OldNum (rtos num 2 1))
(setq inc 1
OldNum (itoa num))
)
(while (setq PT (getpoint (strcat "\nInput center point for tag: ["OldNum"]")))
(entmake
(list
(cons 0 "CIRCLE")
(cons 6 "BYLAYER")
(cons 8 "text")
(cons 10 pt)
(cons 39 0.0)
(cons 40 (/ (getvar "dimscale") 10.0)) ; radius
(cons 62 256)
(cons 210 (list 0.0 0.0 1.0))
)
)

(entmakex
(list
(cons 0 "TEXT")
(cons 1 OldNum) ;* (the string itself)
(cons 6 "BYLAYER") ; Linetype name
(cons 7 "STANDARD") ;* Text style name, defaults to STANDARD, not current
;;(cons 8 "0") ; layer
(cons 10 pt) ;* First alignment point (in OCS)
(cons 11 pt) ;* Second alignment point (in OCS)
(cons 39 0.0) ; Thickness (optional; default = 0)
(cons 40 (/ (/ (getvar "dimscale") 4.0) 6)) ;* Text height
(cons 41 1.0) ; Relative X scale factor, Width Factor, defaults to 1.0
(cons 50 0.0) ; Text rotation ange
(cons 51 0.0) ; Oblique angle
(cons 62 256) ; color
(cons 71 0) ; Text generation flags
(cons 72 1) ; Horizontal text justification type
(cons 73 2) ; Vertical text justification type
(cons 210 (list 0.0 0.0 1.0))
)
)

(setq num (+ num inc))
(if (< inc 1)
(setq OldNum (rtos num 2 1))
(setq OldNum (itoa num))
)
)
(command "._undo" "end")
)
)
(princ)
)
(prompt "\nEnter bn4 for the balloon routine.")
(princ)