Author Topic: How lisp tell if a string is a number?  (Read 17709 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How lisp tell if a string is a number?
« Reply #15 on: March 24, 2009, 04:44:27 PM »
To solve your specific problem I would use this:
Code: [Select]
(if (and (setq num (distof str 2)) ; got a number else nil
          (setq num (fix num))      ; make an interger
          (< 0 num 1000)            ; range check
     )
   ;;  Do your plot using num var
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

VovKa

  • Water Moccasin
  • Posts: 1631
  • Ukraine
Re: How lisp tell if a string is a number?
« Reply #16 on: March 24, 2009, 05:16:19 PM »
one more, nothing but digits allowed :)
Code: [Select]
(= str (itoa (atoi str)))

hermanm

  • Guest
Re: How lisp tell if a string is a number?
« Reply #17 on: March 24, 2009, 11:11:16 PM »
Code: [Select]
;;;----------------------str2num.lsp-------------------
;;;converts a string representing a number into a real or integer
;;;----------------------------------------------------
(defun str2num (str / chlst)
  (cond
    ((member (type str) '(INT REAL)) str);is a number, so return it
    ((= (type str) 'STR)
     (progn
       (setq chlst (vl-string->list str))
       (if (member nil
                   (mapcar
                     (function (lambda (x)
                                 (and (/= x 47)
                                      (> 58 x 44)
                                 )
                               )
                     )
                     chlst
                   )
           )
         nil ; the string does not represent a number
         (if (member 46 chlst) ;contains a decimal point
           (atof str) ;real
           (atoi str) ;integer
         );if
       );if
     );progn
    )
    ((= (type str) 'SYM) (str2num (eval str)));recurse on evaluated arg
    (T nil);not a number or a string which represents a number
  )
);str2num


MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How lisp tell if a string is a number?
« Reply #18 on: March 24, 2009, 11:48:30 PM »
MP, I'm sorry, that's way beyond me.

Sorry, trying to help, not confuse.

Do all possible numbers need entering into the list-I can't believe that would be the case?

No, I showed you how to use the function (which is supposed to make your life easier). Despite the fact that said function is overkill given the typical data being numbers as strings "starting from 1 up to about 600" as you put it, I'll try to explain for completeness' sake.

Let's say the string you wish to test is "123". If it can be converted to a number you want to use it in a calculation, say multiply it by 2, returning the result to the caller, otherwise you want to tell the user the string could not be coerced to a number and return nil to the caller.

Code: [Select]
(progn

    (setq str "123")

    (if (setq num (_DistOf str))
        (* 2 num)
        (progn (princ (strcat "String \"" str "\" cannot be coerced to a number.")) nil)
    )

)

==> 246

Now try it again but pass string "ABC".

Code: [Select]
(progn

    (setq str "ABC")

    (if (setq num (_DistOf str))
        (* 2 num)
        (progn (princ (strcat "String \"" str "\" cannot be coerced to a number.")) nil)
    )

)

==> String "ABC" cannot be coerced to a number.nil

Put one more way ... using your own example from later in the thread:

Instead of this:

Code: [Select]
(IF (numberp (READ txt))
    (SETQ txt2 (ATOI txt))
)

All you would have to do is this:

Code: [Select]
(if (setq num (_DistOf txt))
    (Do_Something_With_Num num)
)

PS: Using a variable named txt2 to represent a numerical value isn't advisable from a documentation perspective.

If so that would rule out its use here (it would leaving me needing to create a random? list up to 1000).

Sorry but you completely lost me.

I can find evidence that VL-SOME is an autolisp function,  but nothing to suggest what it might do.

It's in the AutoLISP Reference:

      Checks whether the predicate (the test) is not nil for (at least) one element combination.

In layman's terms it means the function will return true (and immediately stop processing) if one of the list items produces a non nil result when used in the test function, otherwise it will return nil.

What do FIXED and RESULT need to be set to?

"You" don't need to set them to anything, they are variables local to the _DistOf function, and are set / used by same.

How do distof, x, and base get generated?  I assume one of them is the test string?

Same as preceding comment.

HTH.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How lisp tell if a string is a number?
« Reply #19 on: March 25, 2009, 02:52:41 AM »
I have, only one variant...

Code: [Select]
(wcmatch "your string 2" "*#*")

Daniel J. Ellis

  • Swamp Rat
  • Posts: 811
Re: How lisp tell if a string is a number?
« Reply #20 on: March 25, 2009, 03:28:08 AM »
MP, I'm sorry, that's way beyond me.

Sorry, trying to help, not confuse.

I get that, don't worry

Do all possible numbers need entering into the list-I can't believe that would be the case?

No, I showed you how to use the function (which is supposed to make your life easier). Despite the fact that said function is overkill given the typical data being numbers as strings "starting from 1 up to about 600" as you put it, I'll try to explain for completeness' sake.

Let's say the string you wish to test is "123". If it can be converted to a number you want to use it in a calculation, say multiply it by 2, returning the result to the caller, otherwise you want to tell the user the string could not be coerced to a number and return nil to the caller.

Code: [Select]
(progn

    (setq str "123")

    (if (setq num (_DistOf str))
        (* 2 num)
        (progn (princ (strcat "String \"" str "\" cannot be coerced to a number.")) nil)
    )

)

==> 246

Now try it again but pass string "ABC".

Code: [Select]
(progn

    (setq str "ABC")

    (if (setq num (_DistOf str))
        (* 2 num)
        (progn (princ (strcat "String \"" str "\" cannot be coerced to a number.")) nil)
    )

)

==> String "ABC" cannot be coerced to a number.nil

Put one more way ... using your own example from later in the thread:

This seems to be using the _distof function you originally posted?  It's *that* that I need explaining.  I understand that you need to run the test, then do something with the result, it's how the test is working that I don't understand.  Sorry

Instead of this:

Code: [Select]
(IF (numberp (READ txt))
    (SETQ txt2 (ATOI txt))
)

So this will work?


All you would have to do is this:

Code: [Select]
(if (setq num (_DistOf txt))
    (Do_Something_With_Num num)
)
Except that, unless I've really gotten the wrong end of the stick, that's not all you need to do.  You need the mysterious _Distof function first.


PS: Using a variable named txt2 to represent a numerical value isn't advisable from a documentation perspective.

Very true, that's one of the things that's changing as I rework the routine.

I can find evidence that VL-SOME is an autolisp function,  but nothing to suggest what it might do.

It's in the AutoLISP Reference:

      Checks whether the predicate (the test) is not nil for (at least) one element combination.

In layman's terms it means the function will return true (and immediately stop processing) if one of the list items produces a non nil result when used in the test function, otherwise it will return nil.
I must admit I tend to avoid the AutoLISP reference, it tends to say things like that that don't say what the function's supposed to do.  Can it be used on a non-list?

What do FIXED and RESULT need to be set to?

"You" don't need to set them to anything, they are variables local to the _DistOf function, and are set / used by same.

How do distof, x, and base get generated?  I assume one of them is the test string?

Same as preceding comment.

HTH.

So just trust the magic ^_^

Sorry if that sounds overly negative, but I instictively don't like using stuff that just pop in and out of existence without my understanding them.


I know you're trying to help, so thankyou.

dJE
===
dJE

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How lisp tell if a string is a number?
« Reply #21 on: March 25, 2009, 05:32:26 AM »
What is the number kept as a string?
"1e-3" - number?
"pi" - number?
" 1" - number?
"1 " - number?
" 1 " - number?
".1" - number?
"1." - number?
"1.1" - number?
"a1" - number?
"1a" - number?
"a1a" - number?
"1a1" - number?
"(1+ 2)" - number?


MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How lisp tell if a string is a number?
« Reply #22 on: March 25, 2009, 07:26:00 AM »
I must admit I tend to avoid the AutoLISP reference ...

And thus ends my participation.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: How lisp tell if a string is a number?
« Reply #23 on: March 25, 2009, 07:43:59 AM »
What is the number kept as a string?
"1e-3" - number?
"pi" - number?
" 1" - number?
"1 " - number?
" 1 " - number?
".1" - number?
"1." - number?
"1.1" - number?
"a1" - number?
"1a" - number?
"a1a" - number?
"1a1" - number?
"(1+ 2)" - number?

Using evaluate from this thread ...

Code: [Select]
(defun evaluate ( expression / result )
    (setq result
        (vl-catch-all-apply
           '(lambda ( )
                (eval
                    (if (eq 'str (type expression))
                        (read expression)
                        expression
                    )
                )
            )
        )
    )   
    result
)

Code: [Select]
(setq candidates
    '(
        "1e-3"   
        "pi"     
        " 1"     
        "1 "     
        " 1 "   
        ".1"     
        "1."     
        "1.1"   
        "a1"     
        "1a"     
        "a1a"   
        "1a1"   
        "(1+ 2)"
    )   
)

Code: [Select]
(foreach candidate candidates
    (princ (setq text (vl-string-trim " " candidate)))
    (princ (substr "       " 1 (- 6 (strlen text))))
    (princ " ... ")
    (princ (evaluate candidate))
    (princ "\n")
    (princ)
)

Result
Code: [Select]
1e-3   ... 0.001
pi     ... 3.14159
1      ... 1
1      ... 1
1      ... 1
.1     ... #<%catch-all-apply-error%>
1.     ... 1.0
1.1    ... 1.1
a1     ... nil
1a     ... nil
a1a    ... nil
1a1    ... nil
(1+ 2) ... 3

With very little effort it could be made far more robust, but alas my interest in this thread wanes.

Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How lisp tell if a string is a number?
« Reply #24 on: March 25, 2009, 08:11:29 AM »
(atoi ".1");=>> 0
(atof ".1");=>> 0.1

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: How lisp tell if a string is a number?
« Reply #25 on: March 25, 2009, 08:14:06 AM »
(atoi ".");=>> 0
(atof ".");=>> 0.0