Group users by age for a range - c#

I have some data which i need to make some statistics. I need to group the users by age.
var byAge = displayResult.GroupBy(x => x.Age);
Which i can do as above. However, this gives me ages like 19, 20, 21 etc. what I want is grouping age by 10 years, such as
users between 10-20 yearsold, 20-30 years old, 30-40 years old etc.
How can i get that?

You can truncate the trailing digit by dividing by ten using integer division, and then multiplying back by ten.
var byAge = displayResult.GroupBy(x => 10*(x.Age/10));
Everyone between 0, inclusive, and 10, exclusive, will be in the bucket 0.
from 10 to 20 will be under the key 10, from 20 to 30 - under the key 20, and so on.

Related

Improve performance on List<byte[]>.Count by criteria

I have a List<byte[]> where I load information into that represents a matrix. Each byte in the array represents the segment it belongs in per criteria. So there can be multiple criteria's like Age, Income etc, and each criteria will be segmented.
An example of how this byte array might look in HEX is 0x0D1A0006
I represent the matrix on a form with Controls that is created depending on how many Criteria items there are, and how many Segments there are per Criteria, and each control knows in which criteria it belongs, and which segment of the criteria.
I loop through the controls then and use a lambda expression FilteredData.Count(x => x[curCriteria] == curSegment) to determine the count all the items in the list that correspond to the curCriteria and curSegment.
Is there a way to get the counts by not looping through the controls, but rather returns for me the count per segment in a specific criteria? Something like:
int[] = FilteredData.Count(x => x[curSegment]).ToArray<int>()
Here is some test data.
0x0E0C060E0003070C0203000A0B090B00
0x010C060E0004020C020309090B010B00
0x050C060E0001070C020500080B080B00
0x000C060E0004060C020D090C01040B00
0x070C080E0003040C0005010D0B0D0B00
0x050C060E0001050C020C090B0B030B00
0x0D0C060E0003080C0203030A0D080B00
0x030C060E0004040C02010008070A0B00
0x0A0C060E0004050C020C020B0B0C0B00
0x050C020E0001020C01050A060B020B00
0x050C060E0003080C020D000C08030B00
0x040C060E0000050C020D030C0B060000
0x000C030E0007040C070709050C090B00
My Matrix is basically 15 Criteria's and there layout is as follows:
Criteria 1, 15 Segments
Criteria 2, 13 Segments
Criteria 3, 10 Segments
Criteria 4, 15 Segments
Criteria 5, 9 Segments
Criteria 6, 8 Segments
Criteria 7, 10 Segments
Criteria 8, 14 Segments
Criteria 9, 15 Segments
Criteria 10, 15 Segments
Criteria 11, 11 Segments
Criteria 12, 15 Segments
Criteria 13, 14 Segments
Criteria 14, 15 Segments
Criteria 15, 13 Segments
There can be 30-40 Criteria's and maximum 64 Segments per criteria
Maybe it's a very simple solution, but you can store your items in separate lists along with the "all kind of item list", and then access Count property on separate lists to get the count of specific kind of item.
In other words: instead of querying the count by criteria, store your data by criteria.

how to calculate proportional ratio

First of all pardon me to raise this question here (not sure). Not good in maths so need help from others to understand how to calculate.
I have to calculate proportional ratio score. For doing that i am taking two input values
ValueA = 3
ValueB = 344.
To find the percentage of the proportional ratio ((ValueB-ValueA)/ValueA )*100)
that formula gives me the score 11366.6.
Now i have to match with proportional percentage against with following table,
no idea how to match with percentage
for example the score comes around 43.12 % then i will pick the value 5 (>40 -50)
% Ratio Score
0 0
≤10 1
>10 – 20 2
>20 – 30 3
>30 – 40 4
>40 – 50 5
>50 – 60 6
>60 – 70 7
>70 – 80 8
>80 – 90 9
>90 – 100 10
your formula is of (as you can see by the 11366.6 percentage) - it should be
100.0*(ValueB-ValueA)/(double)ValueB
this will give you values in between 0 and 100 percent if ValueB is always bigger than ValueA (if not use):
100.0*Math.Abs(ValueB - ValueA)/(double)Math.Max(ValueA, ValueB)
based on the table your score should than be simply:
var score = (int)Math.Ceiling(percentage / 10.0)
You should swap value a and value b of you get percentages bigger than 100. By the way, finding the proportional value is not unique and the formula you have provided is one way to do that. I guess Valuea/valueb is also a possibility for example.

X-axis scaling from number value to time in C#

I have a line graph where my x-axis shows ticks every 3000 data points. The frequency that I am working with is 10 Hz meaning 3000 data points translates to 3000/10 (300 seconds). Ultimately I would want to show it in minutes, so it should show 300/60 (5 minutes), 10, 15, 20, 25, and so on. Right now I am trying to find it on the properties of the chart but can't find it.
Do this:
var ticks = 3000;
var seconds = ticks / 10;
var minutes = TimeSpan.FromSeconds(seconds).TotalMinutes;

random at min&max values , enlight me

While i'm trying to code basic lottery app for myself ( note that i'm really beginner on programming especially c#), a guy on StackOverflow said to me
rnd.Next(1, 50 * 7) % 50 // Randoming like that will be increase to chance of getting 1 and 49
rnd.Next(1, 50 ) // instead of this
I am really wondering how can we test it ? Can we rely on this tests ? Please enlight me
The last example will get a uniform distribution between 1 and 49 (inclusive). That is, the same chance for any number between (and including) 1 and 49.
The first example is much more tricky. It will first create any number between 1 and 349. The modulo 50 maps the number onto the interval 0-49 (including 0 and 49).
We now introduce the possibility to get 0 - if the random number is 50, 100, 150, 200, 250 or 300.
We can also get number 1-49 through N+0, N+50, N+100, N+150, N+200, N+250, N+300
That is, 6 chances to get 0 and 7 to get any other number.
The conclusion is that the first example will give a random number betwen 0-49 (inclusive) with slightly less chance of 0 than for the other numbers.

Selecting random item from list having probability weighting using c#?

I have a scenario where i a was taking a list of users (20 users) from my database, where i was giving
weighting for users
first 5 users probability factor of 4
next 5 users probability factor of 3
next 5 users probability factor of 2
next 5 users probability factor of 1
So an user that occurs in the first 5 users is 4 times more
likely to occur than an user in the last 5.
So how can i select a random user from the list using probability in c#?
can anybody help me in doing this i am totally stuck up logically?
You could add the uses the number of probability times in the list. So the 5 first users are 4 times in the list, next 5 users 3 times and so on. Then just select one user from the complete list.
Create a list of partial sums of weights. In your example, it would be
[4, 8, 12, 16, 20, 23, ...]
The last element is the sum of all weights. Pick a random number between 0 and this sum (exclusive). Then your element is the first element with partial sum greater then the random number. So if you got 11, you need the third element, if you got 16, the fifth, etc.
I have a (bit hacky) solution for you:
Create a list containing the users, where each user is added as often as his weightage is. (e.g. User has a weightage of 5, add him 5 times to the list). Then us a Random to fetch a user from that list, that should solve your problem.
One solution would be to find the smallest common denominator of the weights (or just multiply them together) and create a new list that contains the keys of the first list, but multiple times, ie:
user1
user1
user2
user3
user3
user3
Then just to a newList.skip(Random.Next(newList.Count)).Take(1) and you are set!
You could apportion the probability range amongst the users using a dictionary. eg
User 1 has 1-4 (so max of 4)
User 2 has 5-8 (max of 8) etc etc...
Then after selecting the random number find which user within the dictionary it relates to. You can do this using Linq like so...
int iUser = users.Where(p => (choice <= p.Value)).First().Key;
..where users is a Dictionary<int,int> (Key = user number, Value = max value) and choice is the randomly generated value.
This is obviously more complex than the "multiple entries" method proposed by others but has its advantages if you
a) need a fractional weighting which makes the common denominator of your multiple entry method very small (resulting in many entries) or
b) need to weight heavily in favour of particular users (which would again have the effect of making the multiple entry method very large).
Working Example at ideone.

Categories

Resources