Storing old data in a list - c#

I've a method which gets some data (from a transmussion) and the method is called many times. I want to use data of the last transmission in this method. But
private List<byte> _dataOfLastMsg = new List<byte>();
internal List<msg> GetData (Imsgod msgod, List<Byte> data)
{
if (data == null || data.Count == 0)
return transmission;
// Call x
// USING _dataOfLastMsg
...
...
if (data.Count != 0)
_dataOfLastMsg = data;
}
Example:
Msg 1: 0 0 70 0 0
Msg 2: 0 0 0 0 0
Msg 3: 20 0 0 0 20
Call 1 of GetData: _dataOfLastMsg = 0 0 70 0 0
Call 2 of GetData: _dataOfLastMsg = 0 0 70 0 0
Call 3 of GetData: _dataOfLastMsg = 20 0 0 0 20
At call 3 the _dataOfLastMsg should be 0 0 70 0 0, because the call of _dataOfLastMsg is before this line: _dataOfLastMsg = data;
Whats wrong? Sorry for my bad english

About 90% of the code required to give you a sensible answer to this is missing, but here's something to think about.
Where are you calling this class?
Is an instance kept or is it recreated every time?
What is the actual output data and how are you calling it?
What is transmission and why are you returning it when data is empty?
What does //Call x mean?
Which data are you feeding into the program and how?
From what I can vaguely tell, on your third call your transmission is returned instead of _dataOfLastMsg, but the only way to tell is to slap down a breakpoint at the start of the method and hit debug to see the logical paths taken in your program and how the variables change.

Related

FlatBuffers: Encoding in C++ versus C#, decoding in C# end-to-end example

Imagine a schema:
namespace MyEvents;
table EventAddress
{
id:uint;
timestamp:ulong;
adress:string;
}
table EventSignalStrength
{
id:uint;
timestamp:ulong;
strength:float;
}
table EventStatus
{
status:string;
}
union Events {EventAddress, EventSignalStrength, EventStatus}
table EventHolder
{
theEvent:Events;
}
root_type EventHolder;
For status message "EXIT", in C++ I encode and send over the wire like:
std::string message("EXIT");
flatbuffers::FlatBufferBuilder builder;
auto messageString= builder.CreateString(message); // Message to send.
auto statusEvent= MyEvents::CreateEventStatus(builder, messageString);
auto eventHolder= MyEvents::CreateEventHolder(builder, MyEvents::Events_EventStatus, statusEvent.Union());
builder.Finish(eventHolder);
// Code to decode to check my work omitted, but the data decode properly in my real-world application.
ret= sendto(m_udpSocket, reinterpret_cast<const char*>(builder.GetBufferPointer()), static_cast<int>(builder.GetSize()), 0, reinterpret_cast<SOCKADDR *>(&m_destination), sizeof(m_destination));
For the same message, "EXIT", in C# I encode and send over the wire like:
string message= "EXIT";
FlatBufferBuilder builder = new FlatBufferBuilder(1);
StringOffset messageOffset = builder.CreateString(message);
EventStatus.StartEventStatus(builder);
EventStatus.AddStatus(builder, messageOffset);
Offset<EventStatus> eventStatusOffset = EventStatus.EndEventStatus(builder);
EventHolder.StartEventHolder(builder);
EventHolder.AddTheEventType(builder, Events.EventStatus);
EventHolder.AddTheEvent(builder, eventStatusOffset.Value);
Offset<EventHolder> eventHolderOffset = EventHolder.EndEventHolder(builder);
EventHolder.FinishEventHolderBuffer(builder, eventHolderOffset);
// Test the encoding by decoding:
EventHolder flatBuffer = EventHolder.GetRootAsEventHolder(builder.DataBuffer);
Events flatBufferType = flatBuffer.TheEventType; // Type looks good.
EventStatus decodedEvent= new EventStatus();
flatBuffer.GetDataObject<EventStatus>(decodedEvent); // decodedEvent.Status looks good.
// This code seems to send the correct data:
Byte[] sendSized = builder.SizedByteArray();
udpClient.Send(sendSized, sendSized.Length);
// This code does not seem to send the correct data:
//ByteBuffer sendByteBuffer = builder.DataBuffer;
//udpClient.Send(sendByteBuffer.Data, sendByteBuffer.Data.Length);
In my client application, written in C#, I decode as:
Byte[] receiveBytes = udpClient.Receive(ref m_remoteEndpoint);
ByteBuffer flatBufferBytes= new ByteBuffer(receiveBytes);
EventHolder flatBuffer = EventHolder.GetRootAsEventHolder(flatBufferBytes);
Events flatBufferType= flatBuffer.DataObjectType;
EventAddress eventAddress = null;
EventSignalStrength eventSignalStrength = null;
EventStatus eventStatus = null;
switch (flatBufferType)
{
case Events.EventAddress:
{
eventAddress = new EventAddress();
flatBuffer.GetDataObject<EventAddress>(eventAddress);
ProcessEventAddress(eventAddress);
break;
}
case Events.EventSignalStrength:
{
eventSignalStrength = new EventSignalStrength();
flatBuffer.GetDataObject<EventSignalStrength>(eventSignalStrength);
ProcessEventSignalStrength(eventSignalStrength);
break;
}
case Events.EventStatus:
{
eventStatus= new EventStatus();
flatBuffer.GetDataObject<EventStatus>(eventStatus);
Console.WriteLine("\nStatus Message: {0}", eventStatus.status);
break;
}
}
When I receive EventStatus messages from the C++ application, they decode properly.
When I receive EventStatus messages from the C# sending application, they decode properly.
When I dump the buffers sent from the applications, they are (in decimal):
C++ - 12 0 0 0 8 0 14 0 7 0 8 0 8 0 0 0 0 0 0 4 12 0 0 0 0 0 6 0 8 0 4 0 6 0 0 0 4 0 0 0 4 0 0 0 69 88 73 84 0 0 0 0
C# - 12 0 0 0 8 0 10 0 9 0 4 0 8 0 0 0 12 0 0 0 0 4 6 0 8 0 4 0 6 0 0 0 4 0 0 0 4 0 0 0 69 88 73 84 0 0 0 0
Originally, the messages from the C# sender were not decoding properly - now they are. I had made a change to the sender, so maybe had not rebuilt.
I am a little mystified that the received C++ buffer and the C# buffer are different, yet they decode properly to the same result.
My real-world schema is much more complex - am I following the proper procedure for decoding on the C# side?
Am I following the correct procedure for reducing the flatbuffer to Byte[] for sending over the wire in C#? It looks like I am, but it did not seem to work for awhile....
Any input appreciated.
The ByteBuffer contains the buffer, but not necessarily at offset 0, so yes, turning it into a byte array (or sending the bytebuffer contents from its starting offset) are the only correct ways of sending it.
The encoding may differ between languages, as implementations may serialize things in different orders. Here, the C++ implementation decides to write the union type field before the offset, which happens to be inefficient for alignment, so it is a bit bigger. C# does the opposite.

Matlab fwrite in C#

I have a piece of code that i am trying to implement in C#. The code writes a file using the frwite command using Matlab. I have tried looking at the documentation and doing some examples to understand how does frwite works.
I tried the following but no success.
Here is the code:
line_vectors = [5;10;15;20;25]
sampPeriod=100000;
[filename,permission,machineformat] = fopen(outputfile);
fwrite(outputfile,sampPeriod,'int32');
fwrite(outputfile,line_vectors(:),'float32');
Output using fread():
160
134
1
0
0
0
160
64
0
0
32
65
0
0
112
65
0
0
160
65
0
0
200
65
I tried to implement a similar code in C#:
using (BinaryWriter writer = new BinaryWriter(file))
{
writer.Write(100000);
writer.Write(5);
writer.Write(10);
writer.Write(15);
writer.Write(20);
}
Output using fread() in Matlab:
160
134
1
0
5
0
0
0
10
0
0
0
15
0
0
0
20
0
0
0
If anybody could help me in mapping the fwrite functionality in C#.
If you want all numbers after the 1st to be written as float32, you can indicate the value type for the other values, like this:
using (BinaryWriter writer = new BinaryWriter(file))
{
writer.Write(100000);
writer.Write(5.0f);
writer.Write(10.0f);
writer.Write(15.0f);
writer.Write(20.0f);
}
BinaryWriter.Write is an overloaded function, with many possible input types. Depending on the type passed as the input variable, the specific version of the function writes the bytes that represent the value as that type. Since your initial code provided no other information, the default is to assume int, and a 4 byte integer representation was used.

c# send int array via serial port to arduino

I'm trying to send an int array from C# to Arduino using the serial port. In C#, first I have the input string
input = "98;1;5;160;0;255;421;101";
then, I convert it to an int array
int [] sendint = input.Split(';').Select(n => Convert.ToInt32(n)).ToArray();
//this array is what I need to send to Arduino
then, I convert it to a byte array to send via the serial port
byte[] sendbytes = sendint.Select(x => (byte)x).ToArray();
// because Write() requires byte, not int
and finally, I send it
serialport.Write(sendbytes,0,sendbytes.Length);
// port is open, baudrate is OK, portname is OK
Then, it should be received by my Arduino
int recdata[10];
int bytes = 0;
if(Serial.available())
{
while(Serial.available())
{
recdata[bytes]=Serial.read();
bytes++;
}
checkdata(); //function which checks the received data
}
so recdata should be an int array
recdata = {98,1,5,160,0,255,421,101};
but it isn't. When I print it to another serial port to check..
for(int i = 0; i < 10; i++) //called befory checkdata() function in code above
{
Serial1.print(recdata[i] + " ");
}
I get 3 outputs, instead of 1, as if the serialport sends first one int, then second and then the rest.
98 0 0 0 0 0 0 0 0 0 1checkfail //1checkfail is from function checkdata()
1 0 0 0 0 0 0 0 0 0 1checkfail //and it's saying, that data
5 160 0 255 165 101 0 0 0 0 1checkfail//are wrong
98 1 5 160 0 255 421 101 0 0 1checkok //this is how it should like
//421 and 165 - i know, that i'm trying to save 421 in byte, which has a limit of 256, so this is another problem
Does anyone have a suggestion to this problem?
We should see what your checkdata() function does, but I'm prtty sure that you don't check the bytes variable.
What happens is that.... You are using a SERIAL communication. Which means that you don't get all your data at once, but instead you get it one byte at a time. If you send 8 bytes from the PC but check the Serial.available() function after two bytes have been received, you will get just 2 as an answer. I think that if you modify your code in this way
// Move these OUTSIDE the loop function
int recdata[10];
int bytes = 0;
// This is in the loop function
if(Serial.available())
{
while(Serial.available())
{
recdata[bytes]=Serial.read();
bytes++;
}
if (bytes >= 8)
{
checkdata(); //function which checks the received data
bytes = 0;
}
}
it will work properly...
Otherwise... Write your checkdata function and we'll see.
By the way... I'll put a check in the reading part, like
while(Serial.available())
{
if (bytes < 10)
{
recdata[bytes]=Serial.read();
bytes++;
}
}
So you can avoid memory corruption if you receive 12 bytes instead of 10...
The Arduino loop is catching up to the serial stream, so the loop is entered three times instead of just once.
You can use Serial.readBytes() instead of Serial.read(). It will keep filling your buffer until it times out. Use Serial.setTimeout() to choose a reasonable timeout instead of the default 1000 milliseconds.
char recdata[10];
int bytes = 0;
if(Serial.available())
{
bytes = Serial.readBytes(recdata, MAX_LENGTH);
checkdata(); //function which checks the received data
}
For the problem of converting ints to bytes, look at this question.

Linq To entites query returns wrong data(different than Management Studio Query)

like the title suggests my problem is that I have a query/Stored Procedure that selects a data from a view and its working just fine at the management studio, the problem is when I try to call this data from my application( using linq to entites) I get wrong data(wrong as in a single row is repeated 10 times when the query should return 5 different rows/records)
Here is my management studio Query :
select * from dbo.v_RouteCardDetails_SizeInfo
where Trans_TransactionHeader = 0
AND Direction = 0
AND RoutGroupID = 1
AND Degree = '1st'
Result Returned:
Size SizeQuantity Trans_TransactionHeader RoutGroupID Direction Degree
XS 10 0 1 0 1st
S 2 0 1 0 1st
M 0 0 1 0 1st
L 5 0 1 0 1st
XXL 2 0 1 0 1st
and here is my Linq Query:
(from x in context.v_RouteCardDetails_SizeInfo
where x.Trans_TransactionHeader == 0
&& x.Direction == 0
&& x.RoutGroupID == 1
&& x.Degree.ToLower() == "1st"
select x).ToList<_Model.v_RouteCardDetails_SizeInfo>();
And the result returned is :
Size SizeQuantity Trans_TransactionHeader RoutGroupID Direction Degree
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
XS 10 0 1 0 1st
for 2 days I've been trying to fix this, will appreciate your help
Thanks
Undoubtedly the fields that Entity Framework has guessed as primary key of the view are not unique in the view. Try to add fields to the PK in the edmx designer (or code-first mapping) until you've really got a unique combination.
EF just materializes identical rows for each identical key value it finds in the result set from the SQL query.
Because it is not possible to have sme enviroment as your I suggest you do following things:
Check in debbuger what exactly is in list. The printed result suggest that you somehow display data returned form database and in this code could be an error.
Preview LINQ query. You can use LinqPad for this.

Specific Combinations in C#, unable to grasp it

I've been looking into combinations lately, I've tried various 3rd party solutions, and tried to get my head around it myself. Without success I might add.
I need to generate a 13 length string with all possible combinations of say.. int 0-2, I.E
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 2
0 0 0 0 0 0 0 0 0 0 0 1 0
...
2 2 2 2 2 2 2 2 2 2 2 2 2
You probably get the drill, I'm aware I could just wrap this up in loops if I wanted a dirty solution. Any guidance or pointers are appreciated.
I'd be happy to write the code for you, but it seems like you are looking for intuition into the problem. So maybe this feels more like a "teach a man to fish" moment.
So let me ask you a few questions:
Let's generalize the problem to strings of length N. What does the N=1 case look like? It's
0
1
2
And what does the N=2 case look like? It's
00
01
02
10
11
12
20
21
22
I wonder if you can see how, given the N=1 case, we can easily derive (aka generate) the N=2 case in a very mechanical fashion. Now if you see the pattern for this specific case, can you say what the pattern is for the general case? i.e. If you happened to already have in your hand the answer for strings of length N, and I asked you to provide me with the answer for strings of length N+1 could you do so? If so you have the very definition of a recursive algorithm.
PS I think I'd call these combinations rather than permutations.
I can't help thinking of this as just adding number in a N-based numeric system (in your example a 3-base system).
I would write one method (if not already there in the framework or a library) that would allow you to switch bases. I.E:
String transformNumberFrom10BaseToXBase(int number, int base)
then just write a for loop (sorry, pseudo-c-like-code :) ):
for (int i = 0; i < base ^ 13; i++) {
print transformNumberFrom10BaseToXBase(i, base)
}
Ok, hope that helps or give you an idea on how to solve it :)
I've written quickly function that returns list of permutations, so if you have not time to write your own method, you can use it. length is permutation length, max is maximum number (in your case, it would be 2)
static List<int[]> getPermutationList(int length, int max)
{
List<int[]> perm_list = new List<int[]>();
int[] perm = new int[length];
for (int i = 0; i < length; ++i)
perm[i] = 0;
while(true)
{
for (int i = length - 1; ; --i)
{
if (i == -1)
return perm_list;
if (perm[i] < max)
{
perm[i]++;
for (int j = i + 1; j < length; ++j)
perm[j] = 0;
break;
}
}
int[] perm_copy = new int[length];
for (int i = 0; i < length; ++i)
{
perm_copy[i] = perm[i];
}
perm_list.Add(perm_copy);
}
return perm_list;
}

Categories

Resources