I am getting string out of bounds error for substr for the below. How can i get over this?
SEL DRAWING_NUMBER
,CASE
WHEN SUBSTR(DRAWING_NUMBER,1,1) ='Y' THEN SUBSTR(DRAWING_NUMBER ,1,(INDEX(DRAWING_NUMBER , '.')-1))
ELSE DRAWING_NUMBER
END AS DERIVED_DRAWING
FROM GEEDW_D_PLP_BULK_V.CDR_DOCUMENTUM_TRSMTL
Most likely some values for DRAWING_NUMBER that start with 'Y', do not contain '.' characher.
In those cases INDEX(DRAWING_NUMBER, '.') will return 0. In that case, your SUBSTR(DRAWING_NUMBER ,1,(INDEX(DRAWING_NUMBER , '.')-1) will evaluate to SUBSTR(DRAWING_NUMBER, 1, -1), which is out of bounds by definition of SUBSTR function.
What you are probably trying to accomplish is:
SEL
DRAWING_NUMBER
,CASE
WHEN (SUBSTR(DRAWING_NUMBER, 1, 1) ='Y') AND (INDEX(DRAWING_NUMBER , '.') > 0)
THEN SUBSTR(DRAWING_NUMBER, 1, (INDEX(DRAWING_NUMBER , '.') - 1))
ELSE DRAWING_NUMBER
END AS DERIVED_DRAWING
FROM GEEDW_D_PLP_BULK_V.CDR_DOCUMENTUM_TRSMTL;
You might rewrite that using a LIKE instead:
CASE WHEN DRAWING_NUMBER LIKE 'Y%.%'
THEN SUBSTR(DRAWING_NUMBER ,1,(INDEX(DRAWING_NUMBER , '.')-1))
ELSE DRAWING_NUMBER
END
And you might switch to Standard SQL, too:
CASE WHEN DRAWING_NUMBER LIKE 'Y%.%'
THEN SUBSTRING(DRAWING_NUMBER FROM 1 FOR POSITION('.' IN DRAWING_NUMBER) -1)
ELSE DRAWING_NUMBER
END
Related
I am trying to create a code which identifies if the elements in an array are monotonic or not.
I wrote the below code and got the error -
function isMonotonic(array)
if length(array) <= 2
return true
end
check_up = []
check_down = []
for i in range(2, length(array))
if array[i] <= array[i-1]
append!(check_up, 1)
end
if array[i] >= array[i - 1]
append!(check_down, 1)
end
end
if sum(check_up) == length(array) - 1 || sum(check_down) == length(array) - 1
return true
else
return false
end
end
isMonotonic([1, 2, 3, 4, 5, 6 , 7])
I am getting the below error
Error: Methoderror: no method matching zero(::Type{Any})
I think it is because I am trying to sum up the empth array, I want to understand how to overcome this problem in general, I have a solution for the above code, but in genral I want to know the reason and how to use it. I do not want to first check if the array is empty or not and then do the sum.
If you wanted to save yourself lots of effort, the simplest solution would just be:
my_ismonotonic(x) = issorted(x) || issorted(x ; rev=true)
This will return true if x is sorted either forwards, or in reverse, and false otherwise.
We could maybe make it a little more efficient using a check so we only need a single call to issorted.
function my_ismonotonic(x)
length(x) <= 2 && return true
for n = 2:length(x)
if x[n] > x[1]
return issorted(x)
elseif x[n] < x[1]
return issorted(x ; rev=true)
end
end
return true
end
# Alternatively, a neater version using findfirst
function my_ismonotonic(x)
length(x) <= 2 && return true
ii = findfirst(a -> a != x[1], x)
isnothing(ii) && return true # All elements in x are equal
if x[ii] > x[1]
return issorted(x)
else
return issorted(x ; rev=true)
end
end
The loop detects the first occurrence of an element greater than or less than the first element and then calls the appropriate issorted as soon as this occurs. If all elements in the array are equal then the loop runs over the whole array and returns true.
There are a few problems of efficiency in your approach, but the reason you are getting an actual error message is because given the input, either this expression sum(check_up) or this expression sum(check_down) will effectively result in the following call:
sum(Any[])
There is no obvious return value for this since the array could have any type, so instead you get an error. If you had used the following earlier in your function:
check_up = Int[]
check_down = Int[]
then you shouldn't have the same problem, because:
julia> sum(Int[])
0
Note also that append! is usually for appending a vector to a vector. If you just want to add a single element to a vector use push!.
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.
How to have multiple OR operators in a single if statement? I tried this way but there's an error of:
Incompatible data types in expression or assignment.
I looked at documentation of length function and it is LENGTH ( {string | raw-expression | blob-field } [ , type ] )?
Here's the code:
DEFINE VARIABLE cMonth AS CHARACTER.
DEFINE VARIABLE cDay AS CHARACTER.
DEFINE VARIABLE cYear AS CHARACTER.
UPDATE cDateFromUser.
cDay = (SUBSTRING(cDateFromUser,1,2)).
cMonth = (SUBSTRING(cDateFromUser,3,2)).
cYear = (SUBSTRING(cDateFromUser,5,4)).
IF (LENGTH(cDay <> 2)) OR (LENGTH(cMonth <> 2)) OR (LENGTH(cYear <> 4)) THEN DO:
/*Code*/
END.
ELSE DO:
/*Code*/
END.
The syntax is not right here. Use the following IF:
IF (LENGTH(cDay) <> 2) OR (LENGTH(cMonth) <> 2) OR (LENGTH(cYear) <> 4) THEN DO:
Can someone help me with what is wrong with this expression
case When ({item.locationquantitybackordered} > 0 AND {quantitycommitted} > 0)
Then ({item.locationquantitybackordered}+{quantitycommitted})
Else
when {item.locationquantitybackordered} > 0
Then {quantitycommitted} = 0
Else {item.locationquantitybackordered} = 0
{item.locationquantitybackordered}+{quantitycommitted}
End
End
It looks like there are a few things I would fix on this.
First, you don't need ELSE before WHEN. There should only be one WHEN, at the end of the CASE statement as the last condition.
Second, you have two END statements, which isn't necessary - only one is needed per CASE statement. You might need one if you had a nested CASE statement, but you don't so it is unnecessary.
Finally, your ELSE actually doesn't make much sense - you have two statements in there, {item.locationquantitybackordered} = 0 (which is a test, not a value) and {item.locationquantitybackordered} + {quantitycommitted}, which is a proper value, and it is the same as your first case above.
I'd rewrite your statement as:
CASE
WHEN ({item.locationquantitybackordered} > 0 AND {quantitycommitted} > 0) THEN ({item.locationquantitybackordered} + {quantitycommitted})
WHEN {item.locationquantitybackordered} > 0 THEN 0
ELSE {item.locationquantitybackordered} + {quantitycommitted}
END
Is there a way to make certain functions such as isinteger() work with JuMPArrays?
I am using Julia/JuMP to solve an optimization problem, and after I get the solution, I want to check if the solution is integer. So here is what I wrote:
#defVar(m, 0<= x[1:3] <= 1)
...
xstar = getValue(x)
if isinteger(xstar)
...
end
And I get an error saying isinteger() has no method matching isinteger(::JuMPArray).
Thanks
So in general you can get an underlying array from a JuMPArray by using [:], e.g.
m = Model()
#variable(m, 0 <= x[1:3] <= 1)
#variable(m, 0 <= y[1:10, 1:10] <= 1)
solve(m)
xstar = getvalue(x)[:]
ystar = getvalue(y)[:,:]
Note that the reason for this is that JuMPArrays don't have to start with index 1, so the user needs to explicitly say they want a normal Julia array before doing things.
Regardless, you shouldn't use isinteger. Solvers don't always return very precise answers, e.g. they might say x[1] = 0.999996 but they really mean it is 1. You should do something like
for i in 1:3
if getvalue(x[i]) >= 0.999
println("x[$i] is 1!")
elseif getvalue(x[i]) <= 0.001
println("x[$i] is 0!")
end
end
to make sure you don't get any false negatives. If the variable is restricted to be integer or binary, use iround, e.g.
for i in 1:3
v = iround(getvalue(x[i]))
if v == 1
println("x[$i] is 1!")
elseif v == 0
println("x[$i] is 0!")
end
end
but it looks like in this case you are just seeing if the solution is naturally 0 or 1.