How to initialize a multidimensional array in VB.NET - vb.net

I am trying to initialize a multidimensional array. Here is my syntax; this does not create errors but it does not store all values either. Although it correctly prints out all records in this snippet,
dFirstWeek = CDate(FirstWeek)
dFirstWeek = DateAdd(DateInterval.WeekOfYear, -1, dFirstWeek)
Dim dFirstDay As Date
Dim arrWeekYear(5000, 1) As Date
Dim i As Integer = 0
Dim j As Integer = 0
dFirstDay = dFirstDay.AddDays(1)
While dFirstWeek <= dLastWeek
dFirstDay = dFirstWeek
dFirstWeek = dFirstWeek.AddDays(7)
While dFirstDay < dFirstWeek
arrWeekYear(i, j) = (dFirstWeek)
arrWeekYear(i, j + 1) = (dFirstDay)
Response.Write(arrWeekYear(i, j).ToString("d"))
Response.Write(" ;")
Response.Write(arrWeekYear(i, j + 1).ToString("d"))
Response.Write("<br>")
dFirstDay = dFirstDay.AddDays(1)
j = 0
End While
i = i + 1
End While
later in this code, I try to reprint this array as follows:
i = 0
j = 0
Dim k As Integer = 0
'Response.Write(arrWeekYear.GetLength(0))
While k < arrWeekYear.GetLength(0) - 2
Response.Write(arrWeekYear(i, j).ToString("d"))
Response.Write(" ;")
Response.Write(arrWeekYear(i, j + 1).ToString("d"))
Response.Write("<br>")
j = 0
i = i + 1
k = k + 1
End While
but this time, only one "j" record appears per "i" record. Why is this? And then after these few records, many dates resembling null dates appear: "1/1/0001 "
So why do all records appear in upper section, but not from lower? Did I insert values wrongly into this array? And it does not have to have fixed number of rows, just a fixed number of columns.

Dim arrWeekYear(5000, 1) As Date
That’s a multi-dimensional array all right, but the second dimension only has a size of 2! And you access it via j, which is always 0 in your code. That makes no sense. Is that really what you want? I suggest you use a data structure inside your array instead of a multi-dimensional array.
In fact, you almost never want to use a multi-dimensional array. At all. Complex objects are almost always more appropriate. The only real exception is when you actually want to store a mathematical matrix.

Increment i inside the inner loop, rather than inside the outer loop.
And even simpler code (requires visual studio 2010):
Dim baseDate As Datetime = Convert.ToDatetime(FirstWeek).AddDays(-7)
For Each item In Enumerable.Range(0, (dLastWeek - baseDate).TotalDays / 7) _
.Select(Function(i) New DateTime() _
{baseDate.AddDays(i*7), baseDate.AddDays(i*7 + 7) })
Response.Write(string.Format("{0:d} ;{1:d}<br/>", item(0), item(1)))
Next item
And since Response.Write() is frowned upon in asp.net, you can take this a step further and assign the Enumerable.Range() call as the datasource for an asp:repeater control, if you're using webforms rather than mvc.

In the first piece you fill the array writing 7 times a value in the same array line.
In a test (from 01/01/2011 to 03/03/2011) the first 21 assignments are:
i | j | value | j+1 | value
0 | 0 | 01/01/2011 | 1 | 25/12/2010
0 | 0 | 01/01/2011 | 1 | 26/12/2010
0 | 0 | 01/01/2011 | 1 | 27/12/2010
0 | 0 | 01/01/2011 | 1 | 28/12/2010
0 | 0 | 01/01/2011 | 1 | 29/12/2010
0 | 0 | 01/01/2011 | 1 | 30/12/2010
0 | 0 | 01/01/2011 | 1 | 31/12/2010 final value in array (0,0) and (0,1)
1 | 0 | 08/01/2011 | 1 | 01/01/2011
1 | 0 | 08/01/2011 | 1 | 02/01/2011
1 | 0 | 08/01/2011 | 1 | 03/01/2011
1 | 0 | 08/01/2011 | 1 | 04/01/2011
1 | 0 | 08/01/2011 | 1 | 05/01/2011
1 | 0 | 08/01/2011 | 1 | 06/01/2011
1 | 0 | 08/01/2011 | 1 | 07/01/2011 final value in array (1,0) and 1,1)
2 | 0 | 15/01/2011 | 1 | 08/01/2011
2 | 0 | 15/01/2011 | 1 | 09/01/2011
2 | 0 | 15/01/2011 | 1 | 10/01/2011
2 | 0 | 15/01/2011 | 1 | 11/01/2011
2 | 0 | 15/01/2011 | 1 | 12/01/2011
2 | 0 | 15/01/2011 | 1 | 13/01/2011
2 | 0 | 15/01/2011 | 1 | 14/01/2011 final value in array (2,0) and (2,1)
etc.
In the 2nd part you get the values written :
i | j | value | j+1 | value
0 | 0 | 01/01/2011 | 1 | 31/12/2010
1 | 0 | 08/01/2011 | 1 | 07/01/2011
2 | 0 | 15/01/2011 | 1 | 14/01/2011
3 | 0 | 22/01/2011 | 1 | 21/01/2011
4 | 0 | 29/01/2011 | 1 | 28/01/2011
5 | 0 | 05/02/2011 | 1 | 04/02/2011
6 | 0 | 12/02/2011 | 1 | 11/02/2011
7 | 0 | 19/02/2011 | 1 | 18/02/2011
8 | 0 | 26/02/2011 | 1 | 25/02/2011
9 | 0 | 05/03/2011 | 1 | 04/03/2011
10 | 0 | 01/01/0001 | 1 | 01/01/0001
and this is the value in the rest of the array.
I think you forgot to increment some value in part 1?!?

Related

Comparison error when implementing a MUX gate in nand2tetris

I am trying to implement a MUX (Multiplexor) gate in the nand2tetris course. I first tried myself, and I got an error. But no matter what I changed I always got the error. So I tried checking some code online, and this is what most people use:
CHIP Mux {
IN a, b, sel;
OUT out;
PARTS:
Not(in=sel, out=nsel);
And(a=sel, b=b, out=c1);
And(a=nsel, b=a, out=c2);
Or(a=c1, b=c2, out=out);
}
But even when I try this code I still get the following error:
What I get as a truth table:
| a | b | sel | out |
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
What I should get:
| a | b | sel | out |
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 |
I have the newest software suite per 2020-01-13
From what can be seen your input pins are:
a = 0
b = 1
sel = 1
Your internal pins are:
nsel = 1
c1 = 1
c2 = 0
All as expected so far.
Expected out = 1 in this case and you get out = 0. Test script stops at this point because of failure.
Now there might be two reasons of that:
1) you didn't load correct Mux.hdl and because if you calculated Or(c1,c2) you would get 1 which is correct. If you placed And gate in place of Or it would explain failure
2) your implementation of Or.hdl is incorrect.Mux uses your version of Or gate if such file is present in the same directory.
So first verify your code in Hardware Simulator, then verify your implementation of Or.hdl. The latter you could do by removing temporarily Or.hdl from project directory. Hardware Simulator would load built-in version of Or gate.

SQL to group time series meeting a criteria, according to start and end time

I am analyzing power systems time series data, and I am trying to find the contiguous data points that meet a certain boolean flag.
I would like to query this table by returning the start and end time corresponding to the inflection points wherein the value changed from 1 to 0, and 0 to 1.
How should go about implementing the pseudo-sql code below?
SELECT Time
FROM InputTable
WHERE InputTable.Value = 1
INTO OutputTable??, TimeStart??, TimeEnd??;
Input:
+-------+---------+------+
| Index | Time | Value|
+-------+---------+------+
| 0 | 00:00:01| 1 |
| 1 | 00:00:02| 1 |
| 2 | 00:00:03| 1 |
| 3 | 00:00:04| 0 |
| 4 | 00:00:05| 1 |
| 5 | 00:00:06| 1 |
| 6 | 00:00:07| 0 |
| 7 | 00:00:08| 1 |
+-------+---------+------+
Output:
+-------+-----------+----------+
| Index | TimeStart | TimeEnd |
+-------+-----------+----------+
| 0 | 00:00:01 | 00:00:03 |
| 1 | 00:00:05 | 00:00:06 |
| 2 | 00:00:08 | 00:00:08 |
+-------+-----------+----------+
You need to group the values based on adjacent "1"s. This is tricky in MS Access. One method that can be used in Access is to count the number of "0"s (or non-"1" values) before each row.
select ind, min(time), max(time)
from (select t.*,
(select 1 + count(*)
from inputtable as t2
where t2.value = 0 and t2.time < t.time
) as ind
from inputtable as t
) as t
where value = 1
group by ind

SQL charge reversal data

I'm extracting financial information, but ran into charge reversal information. Basically if someone was charged for a service there would be a column with that charge. If the charge was later reversed there would be another row with the exact same data, but with a charge reversal flag on it. I want to only get charges that are were not reversed at all.
Below is an example of what i mean and need. As you can see the RVSLInd column has a 1 if the charge is a reversal. The 0 represents an initial charge
I couldn't do: select * from from table where rvslInd = 0. because this would get rid of the reversal row only.
RvslInd|ExtPriceAmt
-------| ----------|
0 | 155.70 |
0 | 1.50 |
0 | 239.00 |
0 | 1111.00 |
1 | -1111.00 |
0 | 217.00 |
0 | 1491.00 |
1 | -1491.00 |
0 | 388.00 |
0 | 72.00 |
This is what I want to be able to get back:
RvslInd|ExtPriceAmt
-------| ----------|
0 | 155.70 |
0 | 1.50 |
0 | 239.00 |
0 | 217.00 |
0 | 388.00 |
0 | 72.00 |
this would be my new table with a customer column added:
CustomerID|RvslInd|ExtPriceAmt
----------|-------| ----------|
1 | 0 | 155.70 |
1 | 0 | 1.50 |
1 | 0 | 239.00 |
2 | 0 | 217.00 |
2 | 0 | 388.00 |
2 | 0 | 72.00 |
Given your data, you cannot reliably do what you want. For the data you have shown, you could do:
select ExtPriceAmt
from t
where RvslInd = 0 and
not exists (select 1 from t t2 where t2.ExtPriceAmt = - t.ExtPriceAmt and t2.RvslInd = 1);
The problem is when the price is repeated. That gets in the way.
That said, all is not hopeless. You can get a list of the prices along with the number of non-reversed times:
select ExtPriceAmt,
sum(case when RvslInd = 0 then 1 when RvslInd = 1 then -1 end) as non_reversed_count
from t
group by ExtPriceAmt
having sum(case when RvslInd = 0 then 1 when RvslInd = 1 then -1 end) > 0;

SQL Server - Compare values from the same table

In SQL Server, I have one table with following data (tblUserSettings):
| CountryID | CityID | UserType | Value1 | Value2 | Value3 |
| 9 | 3 | 1 | 5 | 5 | 5 |
| 9 | 3 | 2 | NULL | NULL | NULL |
| 9 | 3 | 3 | 5 | 5 | 5 |
| 9 | 3 | 4 | 5 | 5 | 5 |
| 9 | 20 | 1 | 5 | 5 | 5 |
| 9 | 20 | 2 | NULL | NULL | NULL |
| 9 | 20 | 3 | 5 | 5 | 5 |
| 9 | 20 | 4 | 0 | 0 | 0 |
I need to compare all the values for all UserTypes from CityID = 20 with all the values for corresponding UserTypes from CityID = 3. The CountryID = 9. The columns to compare are: Value1, Value2, Value3.
I just need to know if all of them are matched to each other or not. I tried to do something as follows:
SELECT CASE WHEN ISNULL(t1.Value1, 0) = ISNULL(t2.Value1, 0) THEN 1 ELSE 0 END AS Match1,
CASE WHEN ISNULL(t1.Value2, 0) = ISNULL(t2.Value2, 0) THEN 1 ELSE 0 END AS Match2,
CASE WHEN ISNULL(t1.Value3, 0) = ISNULL(t2.Value3, 0) THEN 1 ELSE 0 END AS Match3
FROM tblUserSettings t1
INNER JOIN tblUserSettings t2 ON t1.CountryID = t2.CountryID
AND t1.UserType = t2.UserType
AND t1.CityID = 3
AND t2.CityID = 20
WHERE t1.CountryID = 9
And it gives me following result which I have to process further to define if everything matches or not.
| Match1 | Match2 | Match3 |
| 1 | 1 | 1 |
| 1 | 1 | 1 |
| 1 | 1 | 1 |
| 0 | 0 | 0 |
Can I do this in a way to have only one column and row in output - just receive either 1 for all the matches or 0 if at least one doesn't match?
If you are looking to get only one column with 1 when all the values match and 0 if atleast one doesn't, use,
SELECT
CASE WHEN ISNULL(t1.Value1, 0) = ISNULL(t2.Value1, 0)
AND ISNULL(t1.Value2, 0) = ISNULL(t2.Value2, 0)
AND ISNULL(t1.Value3, 0) = ISNULL(t2.Value3, 0)
THEN 1 ELSE 0 END AS Match
FROM tblUserSettings t1
INNER JOIN tblUserSettings t2 ON t1.CountryID = t2.CountryID
AND t1.UserType = t2.UserType
AND t1.CityID = 3
AND t2.CityID = 20
WHERE t1.CountryID = 9
If you are looking to compare all cities rather than just two you should be able to do this by grouping rather than joining.
Something like:
SELECT
CASE WHEN
max(Value1)-min(Value1) = 0
AND max(Value2)-min(Value2) = 0
AND max(Value3)-min(Value3) = 0
THEN 1 ELSE 0 AS Match
FROM tblUserSettings
GROUP BY CountryID,UserType

SQL Query to Count Number of Responses Matching Certain Criteria over a Date Range and Display as Grouped per Day

I have the following set of survey responses in a table.
It's not very clear but the numbers represent the 'satisfaction' level where:
0 = happy
1 = neutral
2 = sad
+----------+--------+-------+------+-----------+-------------------------+
| friendly | polite | clean | rate | recommend | booking_date |
+----------+--------+-------+------+-----------+-------------------------+
| 2 | 2 | 2 | 0 | 0 | 2014-02-03 00:00:00.000 |
| 1 | 2 | 0 | 0 | 2 | 2014-02-04 00:00:00.000 |
| 0 | 0 | 0 | 1 | 0 | 2014-02-04 00:00:00.000 |
| 1 | 1 | 2 | 0 | 2 | 2014-02-04 00:00:00.000 |
| 0 | 0 | 1 | 2 | 1 | 2014-02-04 00:00:00.000 |
| 2 | 2 | 0 | 2 | 0 | 2014-02-05 00:00:00.000 |
| 2 | 1 | 1 | 0 | 2 | 2014-02-05 00:00:00.000 |
| 1 | 0 | 1 | 2 | 0 | 2014-02-05 00:00:00.000 |
| 0 | 1 | 1 | 1 | 1 | 2014-02-05 00:00:00.000 |
| 1 | 0 | 2 | 2 | 0 | 2014-02-05 00:00:00.000 |
+----------+--------+-------+------+-----------+-------------------------+
For each day I need the totals of each of the columns matching each response option. This will answer the question: "How may people answered happy, neutral or sad for each of the available question options".
I would then require a recordset returned such as:
+------------+----------+------------+--------+----------+------------+--------+
| Date | FriHappy | FriNeutral | FriSad | PolHappy | PolNeutral | PolSad |
+------------+----------+------------+--------+----------+------------+--------+
| 2014-02-03 | 0 | 0 | 1 | 0 | 0 | 1 |
| 2014-02-04 | 2 | 2 | 0 | 2 | 1 | 1 |
| 2014-02-05 | 1 | 2 | 2 | 2 | 2 | 1 |
+------------+----------+------------+--------+----------+------------+--------+
This shows that on the 4th two responders answered "happy" for the "Polite?" question, one answered "Neutral" and one answered "sad".
On the 5th, one responder answered "happy" for the Friendly option, two choose "neutral" and two chose "sad".
I really wish to avoid doing this in code but my SQL isn't great. I did have a look around but couldn't find anything matching this specific requirement.
Obviously this is never going to work (nice if it did) but this may help explain:
SELECT cast(booking_date as date) [booking_date],
COUNT(friendly=0) [FriHappy],
COUNT(friendly=1) [FriNeutral],
COUNT(friendly=2) [FriSad]
FROM [u-rate-gatwick-qsm].[dbo].[Questions]
WHERE booking_date >= '2014-02-01'
AND booking_date <= '2014-03-01'
GROUP BY cast(booking_date as date)
Any pointers would be much appreciated.
Many thanks.
Here is a working version of your sample query:
SELECT cast(booking_date as date) as [booking_date],
sum(case when friendly = 0 then 1 else 0 end) as [FriHappy],
sum(case when friendly = 1 then 1 else 0 end) as [FriNeutral],
sum(case when friendly = 2 then 1 else 0 end) as [FriSad]
FROM [u-rate-gatwick-qsm].[dbo].[Questions]
WHERE booking_date >= '2014-02-01' AND booking_date <= '2014-03-01'
GROUP BY cast(booking_date as date)
ORDER BY min(booking_date);
Your expression count(friendly = 0) doesn't work in SQL Server. Even if it did, it would be the same as count(friendly) -- that is, the number of non-NULL values in the column. Remember what count() does. It counts the number of non-NULL values.
The above logic says: add 1 when there is a match to the appropriate friendly value.
By the way, SQL Server doesn't guarantee the ordering of results from an aggregation, so I also added an order by clause. The min(booking_date) is just an easy way of ordering by the date.
And, I didn't make the change, but I think the second condition in the where should be < rather than <= so you don't include bookings on March 1st (even one at exactly midnight).