Error: trying to do math on a string

Hello,

My code in draw() get its values from a http.request pulling numbers every frame.

The program sometimes runs for a long time and sometimes very short, until the above error occurs.
And there are no obvious pattern to it.

I have tried to take every value like this value = value*1 or tonumber(value) at the beginning of the draw() but problem persist.

It looks like the values sometimes changes in the middle of a loop, but is that possible even if there is callback routine running parallel to the draw().

Does anybody have an idea for a solution or seen this before ?

Re Peter

@macflyerdk try print the value, and then you can try finding the error that way, if you don’t get a number value, you know it’s obvious… the error…
for the rest idk, let us know what the print says, and maybe give us a piece of code to look at? Could be easyer for us sometimes

@macflyerdk - it’s hard to say without being able to replicate it. It’s most likely that one of the numbers is formatted in a way that Codea doesn’t recognise, eg I’m guessing that the number “1,000” might create an error because the comma wouldn’t be taken to be numeric.

I would normally debug by printing the number (or maybe using parameter.watch) so that when the error occurred, I could see what the number was.

@macflyerdk You could save the number you’re trying to print to global data saveGlobalData(“xxx”,value) just before you print it. That way when the program stops, from another program you can readGlobalData(“xxx”) and see what the value was that caused the problem.

hmm, @Ignatz you got me thinking if the numbers I receive sometimes have a format like 1.23e10. Then maybe the e is misinterpreted.
But @dave1707 good idea to print to saveGlobalData. I can then read the values in iFunBox and see what happens. Will do that tonight and let you know

Re Peter

@macflyerdk- parameter.watch will give you the faulty string just like saveGlobaldata, without the need to go and read it back.

@Ignatz I was thinking that the program was crashing and there wasn’t anything left to look at. If it’s just giving errors and stopping, then parameter.watch is the best way.

Thanks guys for putting me on the right track.
Turned out one of my values was “00.000,” and trying to turn that into a number fails.
As I said the values comes from a http.request and I think it cannot be relied on 100% at the time, so the code has to deal with that and find the bugs and correct them before it stops the execution.

This is really one of those things I find difficult…to predict every thing that can happen, but guess that is just a programmers task :wink:

Anyway, this code snippet checks for nil and gives a zero instead if there is a bug.
And my program stays alive now.

if tonumber(value) == nil then value = 0 else value = tonumber(value) end

Re Peter

@macflyerdk Maybe you could use something like this to remove non numeric characters.


function setup()
    str="0y1.2a34,56"
    x=fix(str)
    print(x)
    print(type(x))
end

function fix(val)   
    -- remove non numeric values from a string
    -- allow only the values 0 to 9 and a decimal point
    local s=""
    for z=1,val:len() do
        local v=val:sub(z,z)
        if v>="0" and v<="9" or v=="." then
            s=s..v
        end
    end
    return(tonumber(s))
end

@dave1707 still not flawless tho, what if there are 2 ‘.’ in a string? ;p

@stevon8ter That’s the fun part. You make changes to cover whatever comes up that you don’t have so far.

value = tonumber(value or 0)

The alphabetical characters in the numbers are scientific notation. Arithmetic on numbers that use scientific notation will not have any problems, but in order to make the number correct for conversion to strings (text, print, parameter.watch, tostring, etc.) you’ll simply need to use string.format. Example:

largeNumber = 123456789012345678
print(string.format("%18.18f", largeNumber)

Note: string.format converts it to a string, trying tostring() on the output may give an error, or does nothing.