Validating latex strings are numbers

I’m validating input from a MathInput component to ensure the student entered a NUMBER. I get unexpected results for input of the form 2x (any pos/neg number in front of the x with/without a space in between).

This isn’t unique to MathInput. I see this behavior trying to validate any Latex string. I am evidently missing something about applying numericValue() and isDefined() to Latex strings.

The following lines put into the CL of a Note illustrate this:

myLatexString = `-3 x`
myContent = 
  when isUndefined(numericValue(myLatexString)) "${myLatexString} is undefined" 
  otherwise "${myLatexString} is defined"
content: "${myContent}"

When I preview this, I see :
-3x is defined
(notice that the space is removed)

x^2 (with an exponent) does not do this
x 7 (with the number at the end) does not do this.
1+x (with a plus sign rather than an implicit multiplication) does not do this.

So I really have 2 questions:

  1. Can anyone enlighten me as to what’s happening, here?
  2. What’s the best way to ensure MathInput is a “plain” NUMBER?

I believe the problem is that you aren’t parsing the string to be an actual latex string.

You should do:

myLatexString.latex
Not sure if you’ve already tried this or if it fixes the problem.

Also I saw that you are a new user. Welcome!

I’m not able to do that.

First of all, myLatexString was created (in this example) from back-tick operators. In the “real” activity I’m building, myLatexString is actually myMathInput.latex. But the 3 lines I posted show the behavior w/ no MathInput components involved.

But most convincingly, what I try to add “.latex” as you suggest, I get a coding error explaining that type latex has no member latex.

I think there was a 2020 question about the same thing (ie, 2x reports as a defined numeric value from 2020.

Here’s the link. The workaround is pretty horrific for such a seemingly common validation scenario.

I guess that this is just a quirk of Desmos CL?

Yes, when coming from other coding experience, CL takes a bit of time to adjust your thinking. There are several types: string, latex (different from string), number, boolean, and some special types. Note - if you haven’t seen the documentation, it is very helpful, as it provides syntax as well as working examples of typical use cases.

When you use numericValue(), you are asking for a literal numeric value of whatever latex expression you have. So

numericValue(`2x`)

is like typing 2x into a handheld calculator and trying to get a number out of it. On the other hand,

numericValue(`2(3)`) will return 6.

So you can pass any valid latex to numericValue, and if that string when pasted into a desmos calculator row would yield a number, you will get that number returned.

On the other hand, if you are trying to do multiple calculations, you will want to know about the simpleFunction method. This takes a latex string as an argument (and additional arguments for whatever variables you want to define) and returns a function object that you can work with. For example,

myFunc = simpleFunction(`2x + y`, `x`, `y`)
val = myFunc.evaluateAt(3, 4)
str = "Your answer is `${val}`"

So in this case you would have str being “Your answer is 10". Notice the string interpolation with ${} - you can drop code into your strings this way, rather than using the content sink. You can create variables inside the CL and then in the note, at the bottom right, you will see a button to click to add in your variables. So you can set the note up how you want, and then add in the variables you want to monitor.

I hope that helps - feel free to ask follow-ups.

When you want to start matching structure of expressions, and not just numeric values, then it gets into a whole other concept of patten matching. In general you won’t want to match exact latex because of all the ways a student can enter the text. When you want to learn more about this, feel free to ask (you can also seach the forum for Patterns because there is definitely a lot there already).

In terms of exponents, fractions, and anything else, your best bet is to type your expression in Desmos, copy it, and then paste it into the CL. It will paste in as properly formatted latex for CL. For example, exponents need to have {} around them, etc.

Just to add, a good way to use this forum is to put a link to the actual activity that you are working on along with whatever the problem is. Because then we can see exactly what you want to do, and author a solution and possible alternative approaches. When I was learning, I found this very helpful compared to general explanations.

I’m not sure that there was an answer covering your dilemma.

.numericValue() will allow up to 5(?) characters and one space I think and will still output the value of the leading coefficent. The reason for this is to allow for the use of units, and why you notice some other expressions including variables being flagged with errors.

There are a few ways to disallow this. One is to use pattern matching, which can be complex depending on how permissive or restrictive you want to be. There are a LOT of pattern examples on the forum as well as some articles in the Resources section. Another simple method is to exclude the use of any variables:

isNumber = isDefined(simpleFunction(this.latex,``))

Above any arguments following the latex in simpleFunction() defines the parameters in the function. If there is no second argument, it defaults to x. So, the above overwrites the default with no variable. This will accept expressions, which patterns can mitigate as well.

Edit: using both the simpleFunction() and numericValue may be the most efficient way:

isNumber = isDefined(simpleFunction(this.latex,``)) 
       and isDefined(this.numericValue)

Oh man, I totally misread the original question :person_facepalming:

After you said that I just remembered: I had a similar conversation! I forgot about this…

It’s pretty smart.

But I got a lot out of your response, also. Thanks!

Aha units. Now I understand.

And thanks for your suggestion. That’s exactly what I needed.