Can you explain to me how this code operates under the hood - recursion

def aa(a):
if a == 1:
return 1
else:
return aa(a-1) + 1
I am able to understand the above recursion and how it is working.
However I cannot understand how this recursion is working. Can you help me?
def aa(a):
if a == 1:
return 1
else:
return aa(a-1) + aa(a-1)
I tried debugging as well. The cursor was jumping places. Didnt help me figure it out .

Think of this on a simple level, say with a number like 2:
def aa(a):
if a == 1:
return 1
else:
return aa(a-1) + aa(a-1)
Since 2 is greater than 1, we go straight to the else.
The else asks for us to evaluate aa(a-1) and then add aa(a-1) to it. To do this, we must first evaluate the leftmost value of this expression;
With a starting value of 2 it's easy to see that aa(a-1) is aa(2-1) or just aa(1) which will always return a value of 1 due to the first if statement. So the else will evaluate to aa(1) + aa(1) or simply 1 + 1
So what happens when we pass an initial value of 3? The logic follows like this (bold are the functions that will be evaluated on the next line):
3 == 1 ? no
aa(3-1) + aa(3-1) // aa(2) + aa(2)
2 == 1 ? no
aa(2-1) + aa(2-1)
1 == 1 ? YEP, return 1
1 + aa(2-1)
1 == 1 ? YEP, return 1
1 + 1
2 + aa(3-1)
2 == 1 ? no
aa(2-1) + aa(2-1)
1 == 1 ? YEP, return 1
1 + aa(2-1)
1 == 1 ? YEP, return 1
1 + 1
2 + 2
Essentially you're evaluating the left side of the equation, and within that left side, you're evaluating a left and a right. But you evaluate the left first, then the left first etc. etc. until you finally get a result and then evaluate the right, continuing until you have an answer:
left right
left right
value
value right
value
value right
left right
value
left right
value
value value

Related

Gravityform easy calculation - but total is not beginning from 0

I have a pretty simple calculation in gravityform, but because I add +1 and +0.5 to what people are filling out in the input fields, then the total from the begining is showing a number instead of only 0.
Example:
Field A +1
Field B +0.5
Calculation Field A x B x 295. But because I add +1 and +0.5 to what people put in the input field, then the total from the beginning, shows 147,5. Because it calculate 1*.0.5*295 = 147,5.
But I want the total just to show 0 until people are filling out the input field.
How can I avoid this?
Your best bet for a code-based solution will probably be to use the gform_calculation_result filter and check a value of 1 or 0.5 and return 0 instead.
gform.addFilter( 'gform_calculation_result', function( result, formulaField, formId, calcObj ) {
if ( result == 1 || result == 0.5 ) {
result = 0;
}
return result;
} );
An alternate approach would be to use conditional statements right in the calculation formula, powered by our Gravity Forms Advanced Calculations plugin.
You could check if the field has a value and provide a formula for that and return 0 otherwise.
if ( F1 > 0 ):
F1 + 1
else:
0
endif;

R curly braces syntax [duplicate]

This question already has an answer here:
if {...} else {...} : Does the line break between "}" and "else" really matters?
(1 answer)
Closed 1 year ago.
It works, but I wonder why tis is correct
if (one_time_cost_year_zero != 0) { EIW_TPI_flag = 1
} else {EIW_TPI_flag = 0}
while this results in an error
if (one_time_cost_year_zero != 0) { EIW_TPI_flag = 1 }
else {EIW_TPI_flag = 0}
What's the logic behind that?
Because R would not know that your if -else statement is not finished yet (since only the if () line is also valid R...) compare
1 + 2
+ 3
vs
1 + 2 +
3
In R if we want to split a command over multiple lines we need to either leave a bracket open (as in the if -else example) or have a "hanging" operator at the end of the line (there are also "multiline" strings, but they are not really commands per se)....
Then, the error you are seeing results from the fact that we can't beginn a command with else (like we can't start a command with in, | etc.)
Accordingly, we could also write:
if (one_time_cost_year_zero != 0) { EIW_TPI_flag = 1 } else
{EIW_TPI_flag = 0}

Netsuite - Saved Search Formula(text) Case statement multiply 2 fields

I'm trying to get the product of 2 fields in the 'ELSE' portion of a CASE statement of a Formula(Text) row in a Netsuite saved search, but I keep getting 'ERROR: Invalid Expression' when I run the search. Current formula is:
CASE WHEN {binonhandcount} = 0 THEN '0' ELSE NVL({binonhandcount}, 0) * NVL({locationaveragecost}, 0) END
I've tried to simplify it by doing something like this:
CASE WHEN {binonhandcount} = 0 THEN '0' ELSE 1 + 1 END
But it still fails with an invalid expression error. All of the Googling I've done leads me to believe that this should work, but I can't seem to find my mistake. I'm hoping the extra eyes here can give me a kick in the right direction. Thank you.
The data type returned from the formula needs to match the Formula type selected. You can correct your formula by setting it to a Formula (Numeric) type and simply removing the quotes around the '0' after the first THEN:
CASE WHEN {binonhandcount} = 0 THEN 0 ELSE NVL({binonhandcount}, 0) * NVL({locationaveragecost}, 0) END
Or if you really want a text formula for some reason, you can wrap the ELSE statement in a TO_CHAR function:
CASE WHEN {binonhandcount} = 0 THEN '0' ELSE TO_CHAR(NVL({binonhandcount}, 0) * NVL({locationaveragecost}, 0)) END
In your NetSuite saved search replace Formula(text) to Formula(Numeric).
And your formula would be:
CASE WHEN {binonhandcount} = 0 THEN 0 ELSE NVL({binonhandcount}, 0) * NVL({locationaveragecost}, 0) END
Please remove the string from THEN '0'. You should be fine.

Trying to understand this simple recursion code

Please help me understand this simple recursion. I'm very new to programming, so I'm wondering how exactly this happens step by step.
I'm trying to learn recursion, but I'm stuck with the addition of "+"
function foo($bar) {
if ($bar == 1) return 1;
elseif ($bar == 0) return 0;
else return foo($bar - 1) + foo($bar - 2);
}
When trying to understand recursion I find it helps a lot to write down each individual case for a specific parameter and then build your understanding from there.
So let's take the example of foo(3)
foo(3) -> we don't hit either base case, so our function now wants to return
foo(2) + foo(1)
First we need to get foo(2)
foo(2) -> Again no base case, so we return
foo(1) + foo(0)
foo(1) = 1 and foo(0) = 0 (these are our base cases) so we see that
foo(2) = 1 + 0
Now our look at foo(3) is resolved to
foo(3) -> (1 + 0) + foo(1)
foo(1) = 1, so we can finally see that
foo(3) -> (1 + 0) + 1 = 2
You have to remember that recursion is basically building a "tree" of function calls - it's going to go as far down the tree as possible, and then come up one level and see what else it has to do to continue. I'm not sure how clear this is but hopefully it helps.
it's simple really (once you wrap your head around it). In the last line you are calling the function foo twice and adding their return values together.
here is a sample trace
call 1:
foo(3)
return foo(2) + foo(1)
call 2:
foo(2)
return foo(1) + foo(0)
call 3:
foo(1)
return 1
unrolls to call 2:
return 1 + foo(0)
call 4:
foo(0)
return 0
unrolls to call 2 again:
return 1 + 0
unrolls to call 1:
return 1 + foo(1)
call 5:
foo(1)
return 1
unrolls to call 1 again:
return 1 + 1
The first invocation of foo() ends up calling two additional invocation of foo(). Each of those two in turn calls two of their own, and so on.
First Iteration
foo()
Second Iteration
foo() foo()
Third Iteration
foo() foo() foo() foo()
etc.
So, if foo() does not hit one of the termination conditions, it always calls itself twice more.
It may be instructive to add a variable indicating the call depth and having foo() print out its arguments including the call depth argument.

Optimising R function that adds a new column to a data.frame

I have a function that at the moment programmed in a functional model and either want to speed it up and maybe solve the problem more in the spirit of R.
I have a data.frame and want to add a column based on information that's where every entry depends on two rows.
At the moment it looks like the following:
faultFinging <- function(heartData){
if(heartData$Pulse[[1]] == 0){
Group <- 0
}
else{
Group <- 1
}
for(i in seq(2, length(heartData$Pulse), 1)){
if(heartData$Pulse[[i-1]] != 0
&& heartData$Pulse[[i]] != 0
&& abs(heartData$Pulse[[i-1]] - heartData$Pulse[[i]])<20){
Group[[i]] <- 1
}
else{
if(heartData$Pulse[[i-1]] == 0 && heartData$Pulse[[i]] != 0){
Group[[i]] <- 1
}
else{
Group[[i]] <- 0
}
}
}
Pulse<-heartData$Pulse
Time<-heartData$Time
return(data.frame(Time,Pulse,Group))
}
I can't test this without sample data, but this is the general idea. You can avoid doing the for() loop entirely by using & and | which are vectorized versions of && and ||. Also, there's no need for an if-else statement if there's only one value (true or false).
faultFinging <- function(heartData){
Group <- as.numeric(c(heartData$Pulse[1] != 0,
(heartData$Pulse[-nrow(heartData)] != 0
& heartData$Pulse[-1] != 0
& abs(heartData$Pulse[-nrow(heartData)] - heartData$Pulse[-1])<20) |
(heartData$Pulse[-nrow(heartData)] == 0 & heartData$Pulse[-1] != 0)))
return(cbind(heartData, Group))
}
Putting as.numeric() around the index will set TRUE to 1 and FALSE to 0.
This can be done in a more vector way by separating your program into two parts: firstly a function which takes two time samples and determines if they meet your pulse specification:
isPulse <- function(previous, current)
{
(previous != 0 & current !=0 & (abs(previous-current) < 20)) |
(previous == 0 & current !=0)
}
Note the use of vector | instead of boolean ||.
And then invoke it, supplying the two vector streams 'previous' and 'current' offset by a suitable delay, in your case, 1:
delay <- 1
samples = length(heartData$pulse)
isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])
Let's try this on some made-up data:
sampleData = c(1,0,1,1,4,25,2,0,25,0)
heartData = data.frame(pulse=sampleData)
result = isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])
Note that the code heartData$pulse[-(samples-(1:delay))] trims delay samples from the end, for the previous stream, and heartData$pulse[-(1:delay)] trims delay samples from the start, for the current stream.
Doing it manually, the results should be (using F for false and T for true)
F,T,T,T,F,F,F,T,F
and by running it, we find that they are!:
> print(result)
FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE
success!
Since you want to bind these back as a column into your original dataset, you should note that the new array is delay elements shorter than your original data, so you need to pad it at the start with delay FALSE elements. You may also want to convert it into 0,1 as per your data:
resultPadded <- c(rep(FALSE,delay), result)
heartData$result = ifelse(resultPadded, 1, 0)
which gives
> heartData
pulse result
1 1 0
2 0 0
3 1 1
4 1 1
5 4 1
6 25 0
7 2 0
8 0 0
9 25 1
10 0 0

Resources