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.)
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?
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)
vBulletin® v3.6.7, Copyright ©2000-2009, Jelsoft Enterprises Ltd.