IF OR Statements which always evaluate to TRUE - vb.net

Recently I found an error which was due to the way I constructed an IF OR statement.
The original statement:
If a = 1 OR 2 OR 3 Then
`Execute code 1`
`Else if a = 4 OR 5 OR 6 Then`
`Execute code 2`
`Else`
`Do nothing`
The corrected code:
If a = 1 OR a = 2 OR a = 3 Then
`Execute code 1`
`Else if a = 4 OR a = 5 OR a = 6 Then`
`Execute code 2`
`Else`
`Do nothing`
So, the issue was the first part of the IF statement would always evaluate true regardless of the value of a, because it also evaluates the boolean value of the number 2, which is true. So simply spelling out that each number should be compared to the value of a fixes that issue.
My questions are:
1. When using an if statement and you have a comparative operation ( if a =1) followed by "OR 2", in what situation would you actually want to look at the boolean value of the number versus comparing the number against the value of the previously referenced variable?
Is there a way to identify if statements present in the code which will logically ALWAYS be true (and probably have a error)?
Edit: the_lotus pointed out that the boolean value of each number was not being evaluated but bitwise operations were performed between all the values and then a boolean evaluation was performed on the result. In this particular case it may be possible for it to evaluate either true or false depending on the value of a, though I am still interested in identifying if statements which always evaluate true.

As per your Edit, since you want to check if the value of A falls within a range, what you could do is store the ranges as an array and perform IndexOf to see if the value of A is in the collection.
Here is a quick example:
Dim a As Integer = 4
Dim collection1() As Integer = {1, 2, 3}
Dim collection2() As Integer = {4, 5, 6}
If Array.IndexOf(collection1, a) > -1 Then
Console.WriteLine("a = 1, 2, or 3")
ElseIf Array.IndexOf(collection2, a) > -1 Then
Console.WriteLine("a = 4, 5, or 6")
Else
Console.WriteLine("a is not a value between 1-6")
End If
Fiddle: Live Demo

Related

How do I return the sum of array with exceptions by using a while loop in a function?

Python beginner here.
I already have the solution to the question but I'm not understanding why the "add" variable in the solution plays a role of creating exceptions to remove numbers between 6 and 9. I already tried Python Tutor but still not understanding. Many thanks in advance!
QUESTION: Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 9 (every 6 will be followed by at least one 9). Return 0 for no numbers.
Sample Solution code
def summer_69(arr):
total = 0
add = True
for num in arr:
while add:
if num != 6:
total += num
break
else:
add = False
while not add:
if num != 9:
break
else:
add = True
break
return total
Sample answers:
summer_69([1, 3, 5]) --> 9
summer_69([4, 5, 6, 7, 8, 9]) --> 9
summer_69([2, 1, 6, 9, 11]) --> 14
You can think of the variable "add" as a flag. I think that might be a better name for this variable in this instance.
It is only being used to tell if you have run into a 6 within the sequence of numbers in the array, then once it has been set it goes through an arbitrary amount of numbers in the array until it gets a 9 and then it resets the flag.
It may help to rename the variable "add" as "flag". Have your new variable "flag" default to False and then if you run into a 6 set "flag" to true. Once the flag is on do not add any trailing numbers in the sequence until you run into the number 9 then reset to false.
Perhaps that will help the readability. Naming variables is the hardest part of programming.

Lookupset with duplicate records SUM not working SSRS 2008

I have the below data in a dataset called Questions and all IDs in another dataset called Dataset1
ID Answer
1 Yes
2 Yes
2 No
2 Yes
3 No
My expected output should be as below
ID Yes No
1 1 0
2 2 1
3 0 1
I am trying to match the ids from Dataset1 and get the Answer from Questions dataset.
If I just use Lookup, it is just checking the first match and ignoring the second record. For eg, in the above data, for ID-2, it is checking the first record with id 2 and counting 'Yes' and ignoring the other 'No' and 'Yes'
=Sum(iif(Lookup(Fields!ID.Value, Fields!ID.Value, Fields!answer.Value, "Questions") = "Yes", 1, 0))
I want to count all Yes and No like shown in the expected output above
I have tried using Lookupset but I couldn't get it working. Is there any easier way without using custom code. If custom code is necessary, could you please advise on how to achieve this.
Thank you in advance.
Why do you need a second dataset?
Have a matrix on the questions dataset, row grouped by ID then use a sum in each column as follows:
=SUM(IIF(Fields!answer.Value="Yes",1,0))
=SUM(IIF(Fields!answer.Value="No",1,0))
You can count the output from a lookupset by using the following custom code:
Function CountAnswers(ByVal AnswerArray As Object(), Answer As string) As Object
If AnswerArray Is Nothing Then Return cint(0)
If Answer Is Nothing Then Return "Nothing"
Dim TotalCount As Decimal = New Decimal()
Dim AnswerPosition As Decimal = New Decimal()
TotalCount = 0
For AnswerPosition = 0 to AnswerArray.GetUpperBound(0)
TotalCount = Switch(IsNothing(AnswerArray(AnswerPosition)),TotalCount, cstr(AnswerArray(AnswerPosition))=Answer,TotalCount + 1, TRUE,TotalCount)
Next
return TotalCount
End Function
Then enter the following under "Yes" and "No" on a matrix on Dataset1:
Code.CountAnswers(Lookupset(Fields!ID.Value, Fields!ID.Value, Fields!answer.Value,"Questions"),"Yes")
Code.CountAnswers(Lookupset(Fields!ID.Value, Fields!ID.Value, Fields!answer.Value,"Questions"),"No")

Report Builder 3.0 How to filter on different columns

I have a parameter in my report (Report Builder 3.0) called REPORT_FILTER. This parameter has 4 available values. The labels are (1) Home Group, (2) Home Branch, (3) Other Group, and (4) Other Branch. The corresponding values are 1, 2, 3, and 4.
The SQL used to run this report adds "1" to the "Filter1" column for the Home Group and "2" to the "Filter1" column for the Other Group.
The SQL used to run this report adds "1" to the "Filter2" column for the Home Branch and "2" to the "Filter2" column for the Other Branch.
When the SQL runs, I get 1 or 2 in the "Filter 1" and "Filter 2" columns. This data is just what I expect.
What I would like to do is add a filter to the report so the user only gets the records they want. What I'm struggling with is that the filter(s) will have to use 2 columns and I'm not sure how to do that.
For example, if the user selects, Home Group (value = 1), the report should only return those records that have a 1 in the Filter1 column
If the user selects, Other Branch (value = 4), the report should only return those records that have a 2 in the Filter2 column
This report already takes a while to run several minutes, so (I think) I would prefer to filter the results in Report Builder instead of with the SQL. If I could do it with SQL, that would be acceptable. I've tried to write SQL to do this but haven't been able to succeed as well.
Any suggestions would be appreciated. Thanks for the help.
Pretty easy to do in SQL, just add this WHERE condition:
WHERE
CASE
WHEN
#REPORT_FILTER = 4 and Filter2 = 2 then 1
WHEN
#REPORT_FILTER = 3 and Filter2 = 1 then 1
WHEN
#REPORT_FILTER = 2 and Filter1 = 2 then 1
WHEN
#REPORT_FILTER = 1 and Filter1 = 1 then 1
ELSE 0
END = 1
And similarly in SSRS, just use a Filters expression of
(Parameters!REPORT_FILTER.Value = 4 And Fields!Filter2.Value = 2)
OR
(Parameters!REPORT_FILTER.Value = 3 And Fields!Filter2.Value = 1)
OR
(Parameters!REPORT_FILTER.Value = 2 And Fields!Filter1.Value = 2)
OR
(Parameters!REPORT_FILTER.Value = 1 And Fields!Filter1.Value = 1)
Set the expression type to Boolean and set the comparison value to True.

Search array with logical condition

I have integer array for which I have to check whether items meet the logical condition.
For example:
array: [1, 4, 17, 22, 45]
condition: 1 AND 17 AND (22 OR 49)
How to check that elements of array fulfill the condition.
I have elements of array stored in DB as rows with common identifier:
ID_1 | 1
ID_1 | 4
ID_1 | 17
ID_1 | 22
ID_1 | 45
If someone has any idea how to check that those values meet condition through SQL or search across array I would be grateful.
Maybe something like this:
Module StartupModule
Sub Main()
Dim nums() As Integer = {1, 4, 17, 22, 45}
Dim hasNumbers As Func(Of Integer(), Boolean) = Function(arr)
Return arr.Contains(1) AndAlso arr.Contains(17) AndAlso (arr.Contains(22) OrElse arr.Contains(49))
End Function
Dim result As Boolean = hasNumbers(nums)
Console.WriteLine(result)
Console.ReadLine()
End Sub
End Module
EDIT
It won't do as just now read that condition would be anything. So I would use expression trees.
I assume that you want to find invoices containing item id 1 AND 17 AND (22 OR 49). Then you can do
SELECT invoice_id
FROM items
WHERE item_id IN (1, 17, 22)
GROUP BY invoice_id
HAVING COUNT(*) = 3
UNION
SELECT invoice_id
FROM items
WHERE item_id IN (1, 17, 49)
GROUP BY invoice_id
HAVING COUNT(*) = 3
This works only if the item_ids are unique per invoice.
I found a solution in the reverse logic. For each element in a condition that represents an item (not braces or logical operand, so integer) I checked whether it is element of array. If it is then it's replaced with true, otherwise with fasle.
So I get something like this:
array: [1, 4, 17, 22, 45]
original conditions
condition A: 1 AND 17 AND (22 OR 49)
condition B: 17 AND 45
will turn into
condition A: true AND true AND (true OR false)
condition B: true AND true
Then I just need to make function that will evaluate string with boolean expression into true or false.
Here is example how to evaluate logical expression.
So I didnt test array with condition then check if items in condition exist or not in array and replace them with true/false. With that I got a logical expression that should be evaluated.

Octave keyboard input function to filter concatenated string and integer?

if we write 12wkd3, how to choose/filter 123 as integer in octave?
example in octave:
A = input("A?\n")
A?
12wkd3
A = 123
while 12wkd3 is user keyboard input and A = 123 is the expected answer.
assuming that the general form you're looking for is taking an arbitrary string from the user input, removing anything non-numeric, and storing the result it as an integer:
A = input("A? /n",'s');
A = int32(str2num(A(isdigit(A))));
example output:
A?
324bhtk.p89u34
A = 3248934
to clarify what's written above:
in the input statement, the 's' argument causes the answer to get stored as a string, otherwise it's evaluated by Octave first. most inputs would produce errors, others may be interpreted as functions or variables.
isdigit(A) produces a logical array of values for A with a 1 for any character that is a 0-9 number, and 0 otherwise.
isdigit('a1 3 b.') = [0 1 0 1 0 0 0]
A(isdigit(A)) will produce a substring from A using only those values corresponding to a 1 in the logical array above.
A(isdigit(A)) = 13
that still returns a string, so you need to convert it into a number using str2num(). that, however, outputs a double precision number. so finally to get it to be an integer you can use int32()