Navigation

    Fuze Arena Logo
    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Users
    • Groups
    • Help
    • Discord

    Function to tell if a string contains a number

    Coding
    3
    11
    493
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • pianofire
      pianofire Fuze Team last edited by pianofire

      I was asked about this on Discord: Function to tell if a string contains a number (doesn't check for sign)

      loop
        clear()
        printAt ( 0, 0, isNumber( "123678" ) )  
        printAt ( 0, 1, isNumber( "1236.78" ) )  
        printAt ( 0, 2, isNumber( "12xxx36.78" ) )  
        update()
      repeat
      
      // Return true if string variable contains a number
      function isNumber( variable )
        result = false
        index = strFind( variable, "." )
        if index >= 0 then
          result = isInteger ( variable[ 0:index - 1 ] ) and isInteger( variable[ index + 1: ] )
        else
          result = isInteger( variable )
        endif
      return result
      
      // Return true if string variable contains an integer
      function isInteger( variable )
        result = true
        int index = 0
        while index < len( variable ) and result loop
          value = chrval( variable[ index ] )
          if value < 48 or value > 57 then
            result = false
          endif  
          index += 1
        repeat
      return result
      
      1 Reply Last reply Reply Quote 3
      • PB____
        PB____ last edited by PB____

        @pianofire This might be a stupid question, but what does this notation do: variable[ 0:index - 1 ] and variable[ index + 1: ]? I don't recall sing that before in the documentation.

        1 Reply Last reply Reply Quote 1
        • pianofire
          pianofire Fuze Team last edited by

          @PB____ Not a stupid question. Have a look at this: https://fuzearena.com/forum/topic/70/hints-and-tips/10

          1 Reply Last reply Reply Quote 2
          • PB____
            PB____ last edited by

            @pianofire nice & thanks! I wish I knew this earlier...

            1 Reply Last reply Reply Quote 0
            • Discostew
              Discostew F last edited by Discostew

              This post is deleted!
              1 Reply Last reply Reply Quote 0
              • Discostew
                Discostew F last edited by

                Well, here I was trying to sound smart, only to realize my method has an issue. While you can use float() to help convert and check, it truncates whatever is invalid and onward. So if you had a string like "10x589.0", using float() would return 10. So I need to go back and see how to deal with that, without looping.

                1 Reply Last reply Reply Quote 0
                • pianofire
                  pianofire Fuze Team last edited by

                  @Discostew maybe convert it back to a string and compare the length with the original?

                  1 Reply Last reply Reply Quote 0
                  • Discostew
                    Discostew F last edited by Discostew

                    @pianofire Problem with doing that is with converting a float to a string, it may include extra 0s to the fraction portion that may not be in the original string, so the length may not be the same. But, I just made a revision to the function. No floats used.

                    function isNumber( variable )
                      int result = false
                      if( len( variable ) > 0 ) then
                        if(( len( variable ) > 1 ) and (variable[ 0 ] == "-" )) then
                          variable = "1" + variable[1:]
                        else
                          variable = "1" + variable
                        endIf
                        int cut = len( str( int( variable )))
                        variable = variable[ cut: ]
                        if( len( variable ) > 0 ) then
                          if(( len( variable ) > 1 ) and ( variable[ 0 ] == "." )) then
                            cut = len( str( int( "1" + variable[1:] )))
                            variable = variable[ cut: ]
                            result = len( variable ) == 0
                          endIf
                        else
                          result = 2
                        endIf
                      endIf
                    return result
                    

                    You may be wondering why I tack on a "1" to the string. It's to make sure we have a correct number of characters to cull if a number starts with leading 0s. Converting a string like "1000" to an int then back to a string will still be "1000", but a string like "0010" converted to an int then back to a string will be "10", so the length doesn't match.

                    So now, you have a function to check if a string is a number, but what if you wanted to check if the number is specifically an integer? Or a float? Well, those are simple.

                    function isInteger( variable )
                      int result = false
                      if( isNumber( variable )) then
                        result = strFind( variable, "." ) == -1
                      endIf
                    return result
                    
                    function isFloat( variable )
                      int result = false
                      if( isNumber( variable )) then
                        result = strFind( variable, "." ) != -1
                      endIf
                    return result
                    

                    You can technically exclude those specific functions as I made one slight alteration to the code. With true and false, a value of 0 means false and a non-0 is true. But, it's now set to where you can specifically check what type the number is, as a return value of 1 means it's a float, and a return value of 2 means it's an integer.

                    1 Reply Last reply Reply Quote 1
                    • pianofire
                      pianofire Fuze Team last edited by pianofire

                      @Discostew I was thinking of starting a section for "Approved" user defined functions that people could download and use in their code (with attribution) and I was wondering if you would let me use this one as the first?

                      I have also added the unit test code from @PB____ (again if that is OK with them?)

                      // function:    isNumber
                      // description: find out if a string variable contains (only) a numeric value
                      // author :     @Discostew
                      // arguments :
                      //     variable: string to be tested
                      // returns :
                      //     0 : not a numeric value
                      //     1 : a float
                      //     2 : an integer
                      function isNumber( variable )
                          int result = false
                          if ( len( variable ) > 0 ) then
                              if ( ( len ( variable ) > 1 ) and ( variable[ 0 ] == "-" ) ) then
                                  variable = "1" + variable[ 1: ]
                              else
                                  variable = "1" + variable
                              endIf
                              int cut = len( str( int( variable ) ) )
                              variable = variable[ cut: ]
                              if ( len( variable ) > 0 ) then
                                  if ( ( len ( variable ) > 1 ) and ( variable[ 0 ] == "." ) ) then      
                                      cut = len( str( int( "1" + variable[ 1: ] ) ) )
                                      variable = variable[ cut: ]
                                      result = len (variable ) == 0
                                  endIf
                              else
                                  result = 2
                              endIf
                          endIf
                      return result
                      
                      // Unit test code by @PB____
                      
                      // print with new line
                      function printLn( value )
                          print( value, "\n" )
                      return void
                      
                      // join a series of values together in a string
                      function join(values)
                          string result = ""
                          int i
                          for i = 0 to len( values ) loop
                              result += str( values[ i ] )
                          repeat
                      return result
                      
                      // assert that value1 is equal to value2
                      function assertEqual( value1, value2 )
                          string str1 = str( value1 )
                          string str2 = str( value2 )
                          string outcome = ""
                          if str1 == str2 then
                              ink( lime )
                              outcome = "success"
                          else
                              ink( red )
                              outcome = "fail"
                          endif
                          println( join( [ "assert ", str1, " equals to ", str2, ": ", outcome ] ) )
                      return void
                      
                      // print test description
                      function description( text )
                          ink( { 0.5, 0.5, 0.5, 1 } )
                          println(text)
                      return void
                      
                      // run unit tests with the specified delay at the end
                      function runUnitTests( duration )
                          description( "test integer" )
                          string stringVar = "12345"
                          int output = isNumber( stringVar )
                          assertEqual( output, 2 )
                          
                          description( "test float" )
                          string stringVar = "3.1415926"
                          int output = isNumber( stringVar )
                          assertEqual( output, 1 )
                      
                          description( "test negative" )    
                          string stringVar = "-10"
                          int output = isNumber(stringVar)
                          assertEqual( output, 2 )
                      
                          description( "test text" )
                          string stringVar = "the quick brown fox"
                          int output = isNumber( stringVar )
                          assertEqual( output, 0 )
                      
                          description( "test mixed" )
                          string stringVar = "10x589.0"
                          int output = isNumber( stringVar )
                          assertEqual( output, 0 )
                      
                          description( "test float with no integer part" )
                          string stringVar = ".5"
                          int output = isNumber( stringVar )
                          assertEqual( output, 1 )
                      
                          update()
                          sleep( duration )
                      return void
                      
                      runUnitTests( 10 )
                      
                      1 Reply Last reply Reply Quote 2
                      • PB____
                        PB____ last edited by

                        Of course, happy to be a part of it :)
                        Especially when sharing functions like this, I think including unit tests with them is a great idea :)

                        1 Reply Last reply Reply Quote 1
                        • Discostew
                          Discostew F last edited by

                          @pianofire Go right ahead. This is for the benefit of the community.

                          1 Reply Last reply Reply Quote 2
                          • First post
                            Last post