I have a column named 'Jul' which contains some values like '123' and '-'. I'm trying to get sum of column by adding values and neglecting '-'. I tried:
object julysum;
julysum = Convert.ToDouble(FormattedPurchaseSummaryTable.Compute("SUM(Jul)", "Jul != '-'"));
but i'm getting error: Cannot interpret token '!' at position 5.
How can i resolve this error?
There is no != operator.
You likely want <>.
Please read here for more information on what operators are available: https://learn.microsoft.com/en-us/dotnet/api/system.data.datacolumn.expression?redirectedfrom=MSDN&view=netframework-4.7.2#operators
Blam's answer already pointed you towards the expression language. Having fixed the first issue, we need to fix the second which is that Jul is a string, not an integer (or float, etc). So we need to convert it as well.
But, per Compute I don't think it'll support a complex expression within the SUM to do the CONVERT.
So I think what you need to do is to add a new DataColumn with an expression something like:
IIF(Jul != '-',CONVERT(Jul,'System.Int32'),0)
And then compute your SUM over this new column instead.
Related
I found this codegolf answer for the FizzBuzz test, and after examining it a bit I realized I had no idea how it actually worked, so I started investigating:
for(int i=1; i<101;i++)
System.Console.Write($"{(i%3*i%5<1?0:i):#}{i%3:;;Fizz}{i%5:;;Buzz}\n");
I put it into dotnetfiddle and established the 1st part works as follows:
{(BOOL?0:i):#}
When BOOL is true, then the conditional expression returns 0 otherwise the number.
However the number isn't returned unless it's <> 0. I'm guessing this is the job the of :# characters. I can't find any documentation on the :# characters workings. Can anyone explain the colon/hash or point me in the right direction?
Second part:
{VALUE:;;Fizz}
When VALUE = 0 then nothing is printed. I assume this is determined by the first ; character [end statement]. The second ; character determines 'if VALUE <> 0 then print what's after me.'
Again, does anyone have documentation on the use of a semicolon in string interpolation, as I can't find anything useful.
This is all covered in the String Interpolation documentation, especially the section on the Structure of an Interpolated String, which includes this:
{<interpolatedExpression>[,<alignment>][:<formatString>]}
along with a more detailed description for each of those three sections.
The format string portion of that structure is defined on separate pages, where you can use standard and custom formats for numeric types as well as standard and custom formats for date and time types. There are also options for Enum values, and you can even create your own custom format provider.
It's worth taking a look at the custom format provider documentation just because it will also lead you to the FormattableString type. This isn't well-covered by the documentation, but my understanding is this type may in theory allow you to avoid re-parsing the interpolated string for each iteration when used in a loop, thus potentially improving performance (though in practice, there's no difference at this time). I've written about this before, and my conclusion is MS needs to build this into the framework in a better way.
Thanks to all the commenters! Fast response.
The # is defined here (Custom specifier)
https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings#the--custom-specifier
The "#" custom format specifier serves as a digit-placeholder symbol.
If the value that is being formatted has a digit in the position where
the "#" symbol appears in the format string, that digit is copied to
the result string. Otherwise, nothing is stored in that position in
the result string. Note that this specifier never displays a zero that
is not a significant digit, even if zero is the only digit in the
string. It will display zero only if it is a significant digit in the
number that is being displayed.
The ; is defined here (Section Seperator):
https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings#the--section-separator
The semicolon (;) is a conditional format specifier that applies
different formatting to a number depending on whether its value is
positive, negative, or zero. To produce this behavior, a custom format
string can contain up to three sections separated by semicolons...
I am trying to put a negative number in a textbox, however whenever i click on the textbox and try to type for they hyphen it creates the error, also I don't want it to create this same error if i accidentally leave the textbox blank. as it has done before
TextBox tbox = this.Controls.Find("Team" + r.ToString() + "Q" + c.ToString(), true).FirstOrDefault() as TextBox;
int t1 = Convert.ToInt32(tbox.Text);
if (r == 1) team1score += t1;`
Yes, it's probably because when you type -, the CalculateTotals method is called and it tries to convert - to an integer, and fails. You don't show how you're doing the conversion, which is the most important part of your code. You probably should do something like this:
int myInt;
if (!int.TryParse(senderTB.Text, out myInt))
{
// The value in the textbox isn't an integer.
// Use 0 as the default.
myInt = 0;
}
That's not entirely correct, though, because the user might type something like 4000000000, which is larger than an int.
A quick fix would be to modify your regular expression so that it requires at least one number:
Regex reg = new Regex(#"^-?[0-9]+$");
Replacing the * with a + won't allow just a hyphen to match. This will fix your immediate problem, but it's not complete error checking. But it might be good enough for your purposes.
In general, you can easily use regular expressions to validate the form of a signed integer (i.e. an optional hyphen followed by one or more digits), but it's very difficult to use regular expressions to make sure the number is within the range of a signed integer. Making sure that the number is not less than -2147483648 or greater than 2147483647 is rather difficult to do with regular expressions.
You probably want a combination of the approaches: use the regular expression to prevent the user from typing illegal characters into the text box, and use int.TryParse to validate the number in your computeTotals method. And rather than defaulting to a value of 0, have the program display a message box informing the user of the error.
I tried to convert incremented value to string.
i++.ToString()
The above statement working fine.
++i.ToString()
This one showing error line. Why?
Because in the second expression the ToString() method of i is called first and the ++ operator is meaningless for strings. On the other hand, in your first expression, the integer i is get incremented by one and the method ToString() is called. So you get the string representation of your number. You could conver it, as already ulugbek-umirov pointed out in his comment:
(++i).ToString();
Please have a look here.
It is caused by the different operator precendence of i++ and ++i.
i++ belongs to "Primary" whereas ++i belongs to the "Unary" group. But since the . belongs also to "Primary" is has a higher precendence . So .ToString is executed first. You cannot use ++ operator on a string.
You can wrap it in paranthesis:
(++i).ToString()
Reference: Operators
Because the second means:
++(i.ToString()) // Oops, compiler error
and string type can not be incremented.
(++i).ToString() will do the trick.
The error is caused by the precedence of the operators being applied.
In your instruction you're trying to apply an int-increment to a string.
If you want to post increment you should do:
(++i).ToString();
Answers and comments saying that this is due to anything "executing first" are misleading. This problem is due to the higher precedence of . relative to ++(prefix). Order of evaluation has nothing to do with it really - especially since ++i.ToString() does not compile and therefore there is no evaluation at all (hence no order in which it happens).
See also precedence vs associativity vs order.
You have to options
make it in 2 times:
i++;
i.ToString();
Use parenthesis to set priority (first increase then convert to string)
(++i).ToString();
or
(i++).ToString();
Because when ++ is used as a postfix, it will increase its value immediately then covert it to string using ToString();
Instead if you use ++ as prefix operator then it will convert the existing value to string using ToString() then it will try to increment the value, so in this case you are getting error on increment a string value...
so try using parenthesis for increasing its precedence as (++i).ToString();
I have been developing an application that one of it's responsability is provide to user an page that it's possible to write math expression in EXCEL WAY.
It is an application in ASP.NET MVC, and it's use the SpreadSheetGear library to EXECUTE excel expression.
As it's show below, The page has an texarea to write expression and two button on the right. The green one is for VALIDATE THE EXPRESSION and the red one is for clean textarea.
A,B,C are parameter, that application will replace for values. Notice that it is not possible to know the parameter data type. I mean, if I write a concatenate function, It is necessary that user use double quotes (") to delimitate string. For example
CONCATENATE("A","B") thus, is necessary that user KNOW functions parameters and its correlate data types.
My main issue is how to validate the expression?
SpreadSheetGear there isn't any method to perform this validation.
The method spreadsheetgear provides to perform an formula is:
string formula = "{formula from textarea}"
worksheet.EvaluateValue(formula)
and it's expect and string.
As I don't know what formula user will write, or how many parameters this formula has and what are the parameters data type, it's kind difficult to validate.
Now my question is?
How could I validate the expression?
I think in an alternative: Provide to user and page with textbox for each parameter in the expression. The user will be able to provide some data and validate the RESULT of formula. If the sintaxe of formula is wrong the application throw an exception.
It would be a good solution, but for each "PROCESS" that user will interact to, He'll write 10, 15 formulas, and maybe it would be little painful.
Anyone could provide me an Good solution for that?
Thank you!
https://sites.google.com/site/akshatsharma80/home/data-structures/validate-an-arithmetic-expression
refer this site for validation
This is a very late response but I have been working on expression evaluators in Excel with VBA for a while and I might shed some light. I have three solutions to try but all have limitations.
1) Ask the user to put a '$' after a variable name to signify a string (or some other unique character). Drawback is that it is not as simple as typing a single letter for a variable.
2) Assume all variables entered are double precision. Then change the variable to strings in all combinations until one combination works. Could be very time consuming to try all the combinations if the user enters lots of individual variables.
3) Assume all variables entered are double precision. But then have a list in your program of functions that require strings for parameters. Then you could parse the expression, lookup the functions in your list and then designate the parameters that require string input with a string signifier (like in step 1). This will not account for user defined functions.
Now to test out the function, replace all the numeric variables with '1' and all the string variables with "a", then EvaluateValue. If you get a result or an error signifying a calculation error, it is good.
BTW, in order to parse the expression, I suggest the following method. I do not know C#, only VB, so I will only talk in general terms.
1) Take your expression string and do a search and replace of all the typical operators with the same operator but with a backslash ("\") in front and behind the operator (you can use any other character that is not normally used in Excel formulas if you like). This will delineate these operators so that you can easily ignore them and split up your expression into chunks. Typically only need to delineate +,-,/,*,^,<,>,= and {comma}. So search for a "+" and replace it with a "\+\" and so on. For parenthesis, replace "(" and ")" with "(\\" and "\\)" respectively.
So your sample formula "SUM(A, SQRT(B, C)) * PI()" will look like this:
"SUM(\\A\,\ SQRT(\\B\,\ C\\)\\) \*\ PI(\\\\)"
You can also clean up the string a bit more by eliminating any spaces and by eliminating redundant backslashes by replacing every three consecutive backslashes with a single one (replace "\\" with "\").
2) In Visual Basic there is a command called 'Split' that can take a string like this and split it into a one dimensional array using a delimiter (in this case, the backslash). There must be an equivalent in C# or you can just make one. Your array will look like this: "SUM(", "", "A", ",", "SQRT(", "", "B", etc.
Now iterate through your array, starting at the first element and then skipping every other element. These elements will either be a number (a numeric test), a variable, a function (with have a "(" at the end of it), a parenthesis or blank.
Now you can do other checks as you need and replace the variables with actual values.
3) When you are done, rejoin the array back into a string, without any delimiters, and try the Evaluate function.
I wonder if there is a better way to parse signed integer using Sprache parser framework.
There is well known parser definition for integers without sign
Parse.Number.Select(int.Parse)
But I want to parse integers with - prefix as well.
What I have got right now is Parse.Regex(#"\-?\d+").Select(int.Parse).
Is there a better way to do that without using regular expressions?
For example use Parse.Char('-').Optional() and then parse following number.
Thanks
The way I do this is similar to the following:
from op in Parse.Optional(Parse.Char('-').Token())
from num in Parse.Decimal
from trailingSpaces in Parse.Char(' ').Many()
select decimal.Parse(num) * (op.IsDefined ? -1 : 1);
Of course, leave out the trailingSpaces portion depending on the context of what you're parsing.