Imagine you've got a while loop with an OR condition of two values. The second value has an increment (++). If the first value is true increment from the second value never seems to occur.
Let's take a look at a piece of code:
bool iterationPassed = false;
while (!iterationPassed || ++retries <= 3)
if(somethingHappened)
iterationPassed = true;
Okay, I'm very aware that this is logical. If the first value is true, there's an OR statement, why would there be a need to check the other value. But in this case, the other value is a result of another step (++) and that step never happened. So I guess incrementing or doing any sort of operation in a complex condition is a very bad practice? Also, is this language specific?
Related
The question is simple: Why does this give the wrong answer (0)
IIf(Date()>=#3/16/2018#>=Date()-30,1,0)
While this gives the correct answer (1)
IIf(Date()>=#3/16/2018# AND #3/16/2018#>=Date()-30,1,0)
More specifically, what is Access doing in the first case?
This situation is made even more curious because, when I execute this code, I get an unexpected answer (1)
IIf(Date()<=#3/16/2018#<=Date()-30,1,0)
You can't compound comparisons in Access!
Using your last example, Access first executes the first comparison:
Date()<=#3/16/2018#
That might result in True or False. Let's say it's True
Then, Access evaluates the second comparison:
True <= Date() - 30
(This is since they're processed from left to right, and the first one is true).
This doesn't make much sense, but Access can cast a boolean to a number (-1 = True, 0 = False), and a date too (for example, today = 43186, since dates are defined as the number of days elapsed since 1899-12-30).
That means the second comparison results in:
-1 <= 43186 - 30
And that's certainly true. You also see that if the first comparison is false, the second one will be true nonetheless. Your comparison will pretty much always return true.
Is there a way in Stata to execute a piece of code if and only if a previous bit of code actually made changes?
For example, I am concatenating two variables only if one of them meets a regexm() test. I understand that if I run this qualifier as an if command, it only looks at the first observation. Is there a way to run an if command, say
if regexm(var`n', ".*\)$") {
// code
}
and have the if statement return true if the conditional is true for any observation, not just the first one?
For a match in any observation to trigger code, you need to count matches first:
count if regexm(var`n', ".*\)$")
if r(N) > 0 {
// code
}
if r(N) would suffice here, as non-zero arguments are treated as true and r(N) from count can never be negative.
I tried to use the Analytik Query step to access some calculated field of the previous row. Turns out that the rows are all calculated in parallel and that accessing the previous row's fields gives you the current value they have during their processing, which is kind of random. It does not seem to be possible to obtain the final value of a field of a previous row. Or is there any other way than the Analytik Query step? I imagine all I need is a checkbox "Wait for previous rows to complete"...
What I need this for: I am processing time dependent data and doing a state recognition. When I am currently in state A, I do other stuff with my data then when I am in state B. So I need to know the state of the previous data row (which is determined not before the end of my transformation).
It can be done is Excel really easy, so I guess there must be some way in PDI. :-)
Thanks for any help!
If i have understood your question correctly, you may try using the Block this step until steps finish. This step waits until all the step copies that are specified in the dialog have finished. Read the link for more.
Hope this helps:)
I believe that it can be resolved by using the User Defined Java Class (UDJC) step.
If you sort the rows before processing them, the Sort By step would wait for the last row set by default.
Here's the most basic example of writing an output row for each input row. One important thing to keep in mind with the User Defined Java Class step, is the fact that they rewrite your whole data set, therefore need to be well thought of, especially if you do look-backs at previous rows. I hope this helps a bit.
// A class member that stores the previous row:
public Object[] previousRow;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi)
throws KettleException {
// Fetching row:
Object[] r = getRow();
// Check if r is null:
if (r == null) {
setOutputDone();
return false;
}
// Get some field's value:
String someFieldValue = get(Fields.In, "someFieldName").getString(r);
// Log value if you want:
logBasic("current field value is " + someFieldValue);
// Generate an output row object:
Object[] outputRow = RowDataUtil.createResizedCopy(r, data.outputRowMeta.size());
// Modify row's field values if needed:
get(Fields.Out, "someFieldName").setValue(outputRow, "a modified value here");
// Write row:
putRow(data.outputRowMeta, outputRow);
// Assign current row to previous row:
previousRow = r;
return true;
}
EDIT:
One more important thing to note about PDI - the blocking method, either by blocking steps or by the Sort by step, is done by checking row sets rather than single rows.
How can this be verified?
Right click --> Transformation Settings --> Miscellaneous --> Nr of rows in rowset.
The default value is 10000 rows. PDI developers often create a deadlock by using one of the blocking steps with a row set size that doesn't fit their data volume - do keep that in mind.
Use "Identify last row in a stream" & "Filter rows" transformations. The 1st transformation checks if its the last row and returns a Boolean value and the later can be used to filter the records based on the Boolean value returned.
I've been given some code to go through and find problems and things that could be improved and changed (it's a homework task, but this question is unrelated to the task itself), part of the code is:
Function CheckIfSameCell(ByVal FirstCellPosition As CellReference, ByVal SecondCellPosition As CellReference) As Boolean
Dim InSameCell As Boolean
InSameCell = False
If FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth And FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast Then
InSameCell = True
End If
CheckIfSameCell = InSameCell
End Function
I can't understand why the InSameCell is variable is created, when it can just be assigned to the function name CheckIfSameCell?
Or just use return statements as in the following?
Function CheckIfSameCell(ByVal FirstCellPosition As CellReference, ByVal SecondCellPosition As CellReference) As Boolean
If FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth And FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast Then
Return True
End If
Return False
End Function
I can understand not returning the expression in the If statement directly, to increase readability.
I know that assigning a return value to the Function name doesn't exit the function, whereas Return does, but is it just a person's style, or is there any advantage to the first version (IMO, the second is more readable)?
Maybe there used to be more checks, where value of InSameCell could change several times and only then get returned. Using return then would change behaviour.
Maybe the author wanted to avoid the tedious renaiming. You know, when you want to rename a function, and you use that function's name many times within its own body, then you have many places to replace, whereas when you introduce a variable you will only have one place to change the name in. (I know the IDE will properly do that for you; but that was not the case in VB6, and habits are difficult to break.)
Maybe the author was much more familiar with VB6 that didn't have return.
Maybe it was a matter of style or policy.
Anyway, I would write it as:
Function CheckIfSameCell(ByVal FirstCellPosition As CellReference, ByVal SecondCellPosition As CellReference) As Boolean
Return FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth AndAlso FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast
End Function
Assigning the result to the function name is an old style used in VB6 and should not be used any more in VB.NET. Use Return value!
Personally I dislike statements in the style
If condition Then
Return True
Else
Return False
End If
They are just stupid, since condition already yields the return value! Better:
Return condition
It is also the solution chosen by GSerg.
Nobody would write
If x + y = 0 Then
Return 0
ElseIf x + y = 1 Then
Return 1
ElseIf x + y = 2 Then
Return 2
ElseIf x + y = 3 Then
Return 3
...
But some people are constantly doing it when the expression is of type Boolean. I think that they do not realize that conditions are equivalent to arithmetical expressions. They are just arithmetic with Booleans instead of arithmetic with numbers.
Another misconception is that an If-statement requires some comparison like If x > 0 Then. If they have a Boolean variable b they write If b = True Then. But all the If-statement needs is a Boolean value given by a Boolean expression. This expression can be as simple as querying a variable: If b Then.
Why does this work? Because if b is True then b = True yields True and if b is False then b = True yields False. So, b = True is very much like saying x * 1. Of course, this is the same as just x.
The second method is more readable, I concur. It also happens to be my preference for returning out of methods. I really cannot think of a single downside to the latter in comparision, but can for the former. What happens if the method gets longer and someone forgets to set a Boolean flag? A subtle bug would be born. Additionally, it takes more code to write as well. In the latter approach, the code won't compile if it is missing a return, and it also will be shorter.
The only time you need local variables for the return type is when the routine needs to do some other work after the return value is first determined. In the example you post, this is not the case.
Code Complete, 2nd Edition agrees on page 391:
Use a return when it enhances readability In certain routines, once
you know the answer, you want to return it to the calling routine
immediately. If the routine is defined in such a way that it doesn’t
require any further cleanup once it detects an error, not returning
immediately means that you have to write more code.
NOTE: As other answers [1,2] have mentioned, you can reduce the method to a single code statement. Also using AndAlso should help speed up the evaluation by short-circuiting the logical expression early if the first part is false:
Return FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth
AndAlso FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast
There is one important thing with return and assigning value the the function name. If you (for whatever twisted reason) would like to write something like that
Public Function TestFunct() as Boolean
Dim testVar as Boolean = True
If testVar then
TestFunct = True
Else
TestFunct = False
EndIf
'do more stuff here
...
TestFunct = False
End Function
It will always return false. If you use returns instead it the execution will stop and the function will return correct value.
You might use a variable if for some reason it needs to appear on the right-hand side of an assignment, and you don't want to cause a recursion:
Dim Function F() As Boolean
F = True
If a = b Then
F = Not F()
End If
End Function
In short - Yes your last example is quite valid.
However, most examples used in homework are either used to show other teaching examples. The code in the homework sheet merely shows the basics of using functions in the traditional way and your 2nd example shows the next learning step and is the most compact way of achieving the desired result.
Also, the 1st example could also be used to re-enforce lessons learned earlier - e.g. about assigning variables, use of booleans etc.
One of the best ways to improve your coding skills is to repeatedly practice what you have learned.
This should be a simple question on JasperReports. I'm trying to do a simple counter over the whole report that should increment based on a condition. However, whatever I try, it seems like the counter variable is always being incremented, regardless of the variable expression. My variable's definition properties are below:
Class: Integer
Calculation: Count
Reset type: Report
Increment type: None
Variable Expression: $F{on_target}.doubleValue() >= 0.0
Initial Value: Integer.valueOf(0)
I have a total of 23 rows in the data set, and based on the criteria, the counter should eventually equal 18. I have the variable outputting in the Summary band, with Evaluation Time to Now. However, regardless of the evaluation time, and even setting the Variable Expression to Boolean.valueOf(true == false), the variable's value always ends up as 23.
What simple little thing am I forgetting?
I think I've got it. This makes vaguely no sense, but... (mind you, this is my first time working with Jasper Variables, so it was trial and error).
The Variable Expression isn't quite a Boolean, where a counter type variable isn't incremented if the expression is false, like you'd think. The variable is incremented if there is any value evaluated in the expression. Thus, for me, what ended up working is below:
$F{on_target} >= 0 ? 1 : null
Note the usage of null if the expression should be false.
It makes vague, twisted sense. But is in no way intuitive. Oh well, so it goes...
or in other words:
When you are using the Calculation:Count function of a Jasper-defined Variable you want the Variable Expression to:
resolve to non-null value to increment the counter
resolve to a null value if you do not want to increment the counter
That's why the test listed above works
As well as the setting the variable expression to:
$F{on_target} >= 0 ? 1 : null
Try also setting the initialValueExpression of the variable to 0.
This worked for me:
$F{on_target} >= 0 ? 1 : BigDecimal.ZERO
No initial variable value necessary.