I'm trying to calculate the number of success cases within a recursive function in C#, but I'm astonished by the fact that my variable is shared between all the function calls!
[update 2]
More than strange this time. doing so
i = i + validTreesFun(tree.Nodes, newWords.ToList()) ;
resets i to 0
doing this
i = validTreesFun(tree.Nodes, newWords.ToList()) + i ;
gives some results (I'm not sure if it's correct)
[updated : the full code]
public static int validTreesFun(List<Tree<char>> nodes, List<string> words)
{
int i = 0;
if (nodes == null && (words == null || words.Count == 0 || (words.Count == 1 && words.First() == "")))
return 1;
else
if (nodes == null)
return 0;
foreach (Tree<char> tree in nodes)
{
var validWords = words.Where(w => w.ToCharArray()[0] == tree.Root)
.Select(w => w);
if (validWords.Count() == 0)
return 0;
else
{
var newWords = validWords.Select(w => join( w.ToCharArray().Skip(1).ToArray()));
i += validTreesFun(tree.Nodes, newWords.ToList());
}
}
return i;
}
when debuging the variable i take the value 1 but it resets to 0 on the next iteration!!
despite the use of
i = i + ....
What is the problem in that piece of code?
Thank you
if (validWords.Count() == 0)
return 0;
Should be
if (validWords.Count() == 0)
continue;
Also, in general, I personally think it is nicer looking to only send in one element at a time to a recursive function.
public static int validTreesFun(Tree<char> node, List<string> words)
That way you don't get the same kind of mistake like above. Finally, a minor note.
w => w.ToCharArray()[0] == tree.Root
can be written as
w => w[0] = tree.Root
No local variables are not at all shared between recursive calls, you should consider some other design problem, inside and after your foreach loop, I dont see any return statements, can you post full code.
Ok, in debugging you will always observe i's current method's value, debugging is not good in recursive functions, its little hard to understand, you will have to move your control down in Call Stack in order to actually observe value of earlier caller of current function.
I would advice you to output Trace or on log file with your level of node, that will help you actual debugging.
Please use TRACE Statement as follow..
Trace.WriteLine(string.Format("{0},{1}",tree.Name,i));
Local variables are not being shared.
What you are seeing (the reset to 0) is the value of i in the (recursively) called function validTreesFun (i gets set to 0 at the start of the function).
Just looking at your code, I think a possible bug might be in someTestHere - if that is never true, then i will stay 0 in the outer scope. Otherwise it should increment by 1 for each true test.
When you are in debug mode, you indeed see that the i is reseted for the call but remain to the wanted value for the caller. Eg , the stack :
validTreesFun --i = 0 for this one
validTreesFun --i = x for this one, but if you do not go trow the calling stack, you will see 0, which is the good value for the top of the stack
Related
I was reading through some code on Github recently and i came across the following line,
if (((tmp = rx.IndexOf("<")) >= 0) && (rx.IndexOf(">") > tmp ))
specifically the
(tmp = rx.IndexOf("<") >= 0)
And the immediate use of the tmp variable in a comparison in the same line in the next part of the if statement
(rx.IndexOf(">") > tmp )
in which a variable is being set by a string,indexOf() method, and then the 'assignment statement itself' is being evaluated with a greater-or-equal-to equality operator.
At first i thought this was a typo, but on evaluating the code via a simple console app, i found it to be valid, and a great shortcut.
The question is "What is the technical term for this?" as i could find no explanation in various C# help sites.
An example console app to demonstrate how the statement was used.
public static void Main()
{
// first test - the actual code I found in gitHub
int tmp;
int tmp2;
string rx = " < test>";
// the below line is the subject of the question.
if (((tmp = rx.IndexOf("<")) >= 0) && (rx.IndexOf(">") > tmp )){
Console.WriteLine("The Close brace is after the opening brace!");
}
// additional test
int r;
Console.WriteLine(r = 25 + 3);
Console.WriteLine(r);
// and another
int w = -1;
Console.WriteLine(" The index of '<' is greater than 0 : " + _
((w = rx.IndexOf("<")) > 0).ToString() + _
" and the value of w is " + w.ToString());
}
The output of the above code is below.
Again , I understand the code works, I would like to know what is this called technically?
The Close brace is after the opening brace!
28
28
The index of '<' is greater than 0 : True and the value of w is 2
There is no "technical term".
It's an assignment, and a assignment can act as expression or a statement.
It's a statement that has a value; Or an Expression where the result value can be ignored. (Unlike x+y, the Result is not allowed to be ignored)
It's the same as the prefix and postfix operators i++;
It will look less like "inline" in a line like x = y = z;
However, it's not often used, cause it's less readable, as you just proofed.
And in your case, assigning a value and using the value in the same expression tree
highly depends on evaluation order, which is well defined, but who knows it by heart ?
This style of writing will safe you a line of code (by making one line longer)
but it will never save you any operation, hence not cause any performance.
So Read it, Understand it, but better don't use it frequent.
This is just a consequence of assignment being an expression. It is defined in the C# specification:
7.17.1 Simple Assignment
The = operator is called the simple assignment operator.
The result of a simple assignment expression is the value assigned to
the left operand. The result has the same type as the left operand and
is always classified as a value.
So the value of
tmp = rx.IndexOf("<")
is the value assigned to tmp which is rx.IndexOf("<"). This value is then compared to 0 in the outer expression.
I am wondering if there is a way to check multiple while loop conditions using the same variable. That's a bit vague, but this example should clear it up:
while (myFunction(x) == 0 || myFunction(x) == 13639 || myFunction(x) == -4261.9583)
{ x++; }
Is it possible to only evaluate myFunction(x) once per loop while checking the three conditions, so that the function doesn't have to run three separate times for a result that is the same each time?
I am doing this for optimization/efficiency purposes. myFunction() could be a pretty time-consuming function, so I want it to run the minimum amount of times necessary.
Typically I would define the value of myFunction(x) before I start the while loop, but in this case, the value of myFunction(x) will be changing as the loop goes through each iteration, since the value of x will be changing.
Yes, this can be done:
double result;
while ((result = myFunction(x)) == 0 || result == 13639 || result == -4261.9583)
{ x++; }
Three options:
Do it backwards
Check a list for the result rather than checking the result against the list.
var list = new float[] { 0F, 13639F, -4261.9583F );
while (list.Contains(myFunction(x))
{
x++;
}
Write a function
Extracting the logic to another function is always a nice way to break down the problem.
bool IsValid(float input)
{
var result = myFunction(input);
return (result == 0 || result == 13639 || result == -4261.9583);
}
while (IsValid(x))
{
x++;
}
Use while(true)
Whenver the condition of a while loop is complicated, a common option is to remove the check from the () and put it in the {} instead. When you do this, use while (true).
while (true)
{
var result = myFunction(x);
if (result != 0 && result != 13639 && result != -4261.9583) break;
x++;
}
You can do this simply by moving the check into a separate method, which takes the return value of the function as parameter, and then performs the 3 checks on the value directly and returns a boolean accordingly.
Assuming the function returns a int typed value this may for example look something like this:
bool CheckResultValue(int value) {
return value == 0 || value == 13639 || value == -4261.9583;
}
Then your while loop could look something like this:
while (CheckResultValue(myFunction(x)))
{ x++; }
This is my first time using the enumerator interface.
I am Trying to look threw a stack to find next occurrence of a string.
The loop is suppose to loop threw my tags stack and find out if a tag inside my stack is a tag i was looking for. Once the stack gets to the last tag in the stack it crashes and issues the error in the title. The last tag in the list also happens to be the first match for lookforthisTag string variable. I want the while look to exit when the if statement finds a match or when all stack items have been compared.
/*find next opening tag in stack */
int I = 1;
var enumerator = tags.GetEnumerator(); /// create a enumerator variable
/// move to the next tag in stack
while ( enumerator.MoveNext() != false || found == true || I <= countofTags)
{
htmlTags currentTag = enumerator.Current; // this line causes error.
if (currentTag.open_tag == lookforthisTag)
{
found = true;
}
I++;
}///End while.
This line
while ( enumerator.MoveNext() != false || found == true || I <= countofTags)
will execute the following logic
Does the enumerator returns true? If yes enter the loop else check
next condtion
Is found == true? If yes enter the loop, else check the next condition
Is I <= countofTags? If yes enter the loop, else exit the loop
As you can see even when the enumerator return false it enters the loop because at that point found is true, but inside the loop you call enumerator.Current and this triggers the error message.
Probably you want
while ( !found && enumerator.MoveNext() && I <= countofTags)
Consider that a normal foreach loop would do the same
htmlTags found = null;
foreach(htmlTags currentTag in tags)
{
if (currentTag.open_tag == lookforthisTag)
{
found = currentTag;
break;
}
}
if(found != null)
{
// got it...
}
or just using Linq
htmlTags found = tags.FirstOrDefault(x => x.open_tag == lookforthisTag)
if(found != null)
{
// you have found your tag.
}
I want also to mention the fact that your I <= countOfTags logic
doesn't seem to have any utility in the code shown. The variable I will be always equal to the countOfTags (or just simply equal to tags.Count) because you don't break the loop and continue till the end of the enumeration. If you want to know the 'position' of the found tag, just increment it.
I would rewrite your while condition like this:
while ( enumerator.MoveNext() && !found && I < countofTags)
Or just use linq:
tags.Single (currentTag == currentTag.open_tag == lookforthisTag)
The condition in the while will be true even if enumerator.MoveNext() will be false, because of the or conditions.
It can probably be fixed with changing the condition and also using break to get out of the loop.
like this:
while ( enumerator.MoveNext() && I <= countofTags)
{
htmlTags currentTag = enumerator.Current; // this line causes error.
if (currentTag.open_tag == lookforthisTag)
{
found = true;
break;
}
I++;
}///End while.
But, i wouldn't go this way in the first place.
Use LINQ:
var myItem = tags.FirstOrDefault(currentTag=> currentTag.open_tag == lookforthisTag);
I'm trying to write a program in C# to take a table of strings (variable names) from a database and search a directory of ~30,000 Fortran 77 source files to determine where that variable is calculated. The variables are typically calculated only 1 time in 1 of the fortran files but used many times in other files. The variables in the database table are all explicitly defined somewhere in the fortran files. So far I've accomplished most of this by first building a list of files that each variable appears in, and then searching the files in that list line by line. I've been looking for which side of the "=" sign the variable appears on by doing something like this:
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
for (int k = 0; k < fullpaths.Count; k++)
{
string line;
// Read the file and display it line by line.
System.IO.StreamReader FortranFile = new System.IO.StreamReader(fullpaths[k]);
while ((line = FortranFile.ReadLine()) != null)
{
// Search the file line-by-line for the variable
if (ci.IndexOf(line, Variable, CompareOptions.IgnoreCase) > 0)
{
// Search for the equals sign
int equalLocation = ci.IndexOf(line, "=");
if (equalLocation > 0)
{
// substring LHS
string subLineLHS = line.Substring(0, equalLocation+1);
// is the line commented out?
if (Convert.ToString(subLineLHS[0]) == "C" ||
Convert.ToString(subLineLHS[0]) == "!" ||
Convert.ToString(subLineLHS[0]) == "c" ||
Convert.ToString(subLineLHS[0]) == "*")
{
continue;
}
// ignore if the line contains a DO, IF, or WHILE loop,
// to prevent reading IF [Variable] = xxxx as being calculated.
else if ( (ci.IndexOf(subLineLHS, "IF", CompareOptions.IgnoreCase) > 0) ||
(ci.IndexOf(subLineLHS, "DO", CompareOptions.IgnoreCase) > 0) ||
(ci.IndexOf(subLineLHS, "WHILE", CompareOptions.IgnoreCase) > 0))
{
continue;
}
// find where the variable is used in the line
else if (ci.IndexOf(subLineLHS, Variable, CompareOptions.IgnoreCase) > 0 )
{
isCalculated[k] = true;
calculatedLine[k] = counter;
}
}
} //if loop
counter++;
} //while loop
FortranFile.Close();
}
The problems I'm having is with IF statements, e.g.:
IF(something == xx .AND.
1 variable == xx) THEN
...
this method would tell me that the variable is calculated on that line "variable = xx". 1-line if-statements such as IF(something) variable=xx are also ignored. Lines with multiple = signs may give me problems too.
Any suggestions on how I could get around this? Is there a better method of doing this? Please go easy on me - I'm not a programmer.
Thanks!
The most error-proof approach would be to parse the Fortran code and work from the syntax tree.
My suggestion: use ctags. See for instance Exuberant ctags; it has support for Fortran.
ctags generates an index of all named entities in a set of source code files. The index is stored in a data structure (tags) that can be read from most file editors/IDEs.
If you import that tags file in your favourite text editor, you will be able to jump to the definition of a variable when you position your cursor on it and take proper action.
The tags file is also very easy to read and parse: it structured like this.
named_entity<Tab>file_where_it_is_defined<Tab>location_in_the_file
For instance, from a set of Fortran files (this is on Linux, but Exuberant ctags offers Windows binaries):
gpar remlf90.f90 /^ xrank,npar,gpar,/;" v program:REMLF90
hashia1 ../libs/sparse2.f /^ subroutine hashia1(/;" s
hashv1 ../libs/sparse3.f /^ integer function hashv1(/;" f
hashvr_old ../libs/sparse2.f /^ integer function hashvr_old(/;" f
We can observe that the gparvariable is defined in remlf90.f90 and hashia1 is defined in ../libs/sparse2.f, etc.
I stumbled upon this while doing a review and the author is not available:
int n = Convert.ToInt32(text);
if (((n > 0) || (n < 0)) || (n == 0))
{
return 1;
}
The code in general looks solid and it's hard for me to believe that the only purpose of this snippet is to confuse reviewers, but I don't see a way for this condition to fail. Am I missing something?
This may be a remnant of a nullable type. See here at msdn for an explanation, but basically if your code was originally this:
int? n = StringToInt(text); // People roll their own functions to do this, though
// they really shouldn't
if (((n > 0) || (n < 0)) || (n == 0))
{
return 1;
}
Then this could possibly fall through. Each of the statements above would be false, as n could be null from the function, assuming it returned null on a bad input, and the code supported nullable types.
Unlikely, but when looking at "maintained code" anything is possible. But as written, it MUST return 1 (or throw an exception, as mentioned by others in this thread).
It will always return true, assuming it gets there.
Consider:
bool x = (n > 0) || (n < 0);
bool y = (n == 0);
if (x || y)
{
return 1;
}
If n is not zero then either n > 0 or n < 0 is true, so x is true and y is false.
If n is zero, n == 0 is true, so x is false and y is true.
Either way, one side of the OR is true.
That sure looks like a 100% true statement to me. All those parentheses shouldn't matter in the least, since || is associative, i.e.,
(a || b) || c == a || (b || c) == a || b || c
If you overload the relational operators for your class, it might be the case that the condition evaluates to false, but since n is an int, it always evaluates to true
It's possible that int n = Convert.ToInt32(text); could throw an exception, in which case the if statement never even gets evaluated.
See Convert.ToInt32() on MSDN.
As above, it will always be true because, by definition, any real number is either zero, less than zero or greater than zero, and you have covered all cases in your code.
Always will be 1, unless Convert.ToInt32(text) throws an exception.
I don't see how it can evaluate to false.
If, however, n was declared at a different scope where more than a single thread had access to it and one of these threads changes its value, theres quite a high chance the condition would fail.
it will always be true as you write all the states it might be (e.g < > ==)
Yes, it could also throw an exception if the conversion fails :-)