C
C#•2w ago
a

Need help with text files

There is a text file with numbers. First number means category and five others are points. I need to sum the points but have trouble doing it. Also there may be several categories with same number. If there are, they need to be showed as one same category and their points need to be summed.
182 Replies
canton7
canton7•2w ago
What have you tried, and why didn't it work?
a
aOP•2w ago
I was able to output first number of every line - categories but dont know how to sum five following numbers of every line string filepath = @"C:\Users\Vartotojas\Desktop\task.txt"; var lines = new List<string>(); lines = File.ReadAllLines(filepath).ToList(); var category = new List<string>(); var points = new List<string>(); foreach (string line in lines) { category.Add(line.Split(' ')[0]); } foreach(string k in category) { Console.WriteLine(k); } heres what I got working so far
Pobiega
Pobiega•2w ago
okay, the basics are there, but there are some problems here You've correctly identified that you need to use Split to separate your string, but you are not storing the result, instead only getting the first numbers and ignoring everything else Your points is also not connected to a category, meaning you would lose that connection after parsing So instead of List<string> to store your data in, can you think of a more suitable type?
a
aOP•2w ago
honestly I cant lol array? I thought list is the best
Pobiega
Pobiega•2w ago
do you know the difference between an array and a list?
a
aOP•2w ago
yeah but still you think I need to use array?
Pobiega
Pobiega•2w ago
To be fair, neither is what I had in mind here
a
aOP•2w ago
whoah
Pobiega
Pobiega•2w ago
There are a few options - the goal is to sum each "category", so we could skip directly to that and just store the sum as we go alternatively, we create one list per category, add all the points, then sum them at the end which do you think sounds better/easier to understand?
a
aOP•2w ago
this one
Pobiega
Pobiega•2w ago
okay
a
aOP•2w ago
buuut then every category would be in different list correct?
Pobiega
Pobiega•2w ago
we need a way to associate a key (the category id) with a list of values (the "points") correct we need to keep them apart
a
aOP•2w ago
would it later be possible to sort and compare them?
Pobiega
Pobiega•2w ago
probably, but depends on what exactly you mena by "them" :p the categories, or the points
a
aOP•2w ago
if there are multiple categories with same numbers (like in my given file) I need to make them into one category categories 1 15 20 22 5 9 and 1 9 6 8 7 12 so there should be 1 113 if im correct sum all 10 numbers
Pobiega
Pobiega•2w ago
right, so their total sum for category 1
a
aOP•2w ago
yeah I was thinnking about this points.Add(line.Split(' ')[1]); but idk didnt work for me
Pobiega
Pobiega•2w ago
well ofc not points isnt associated with any category first, lets clean up a bit
var lines = new List<string>();
lines = File.ReadAllLines(filepath).ToList();
var lines = new List<string>();
lines = File.ReadAllLines(filepath).ToList();
thats a lot of noise. just var lines = File.ReadAllLines(filepath); is perfectly fine after that, we cant use two lists like that. as said, we need to associate the points with the category luckily, there is a datatype that helps us do a Key-Value store: the Dictionary<TKey, TValue> now, what would be your suggested types for TKey and TValue respectively?
a
aOP•2w ago
I dont think I've ever seen this Dictionary<TKey, TValue> damn my suggested types for them are int? or wdym by type
Pobiega
Pobiega•2w ago
yeah int would work as the key but if you use it as value, you would associate an int with another int... that works fine if we just store the sum but you wanted to store the individual points
a
aOP•2w ago
then what do you suggest😭 string/char?
Pobiega
Pobiega•2w ago
how about List<int>? each category (int) stores the points ( List<int>)
a
aOP•2w ago
so this would put every category number in one list?
Pobiega
Pobiega•2w ago
no a Dictionary<int, List<int>> would be a collection of key value pairs
a
aOP•2w ago
ahh
Pobiega
Pobiega•2w ago
where each pair has a single key (an int), and a value (a list of ints) makes sense?
a
aOP•2w ago
yeah
Pobiega
Pobiega•2w ago
okay, so first we need to make one of those dictionaries
a
aOP•2w ago
Dictionary<int, int> key = new Dictionary<int, int>(); like this?
Pobiega
Pobiega•2w ago
almost check what types you used
a
aOP•2w ago
ints ahh wait xdf
Pobiega
Pobiega•2w ago
yeah, and what did we say about <int, int>?
a
aOP•2w ago
Dictionary<int, List<int>> key = new Dictionary<int, List<int>>();
Pobiega
Pobiega•2w ago
sure that works, I'd personally prefer var categories = new Dictionary<int, List<int>>();
a
aOP•2w ago
oh nah, you too smart xd but now do I need this var category = new List<string>();?
Pobiega
Pobiega•2w ago
nope
a
aOP•2w ago
kk
Pobiega
Pobiega•2w ago
we can safely throw that ok, now to start parsing the lines
a
aOP•2w ago
I dont need that split command too right? category.Add(line.Split(' ')[0]);
Pobiega
Pobiega•2w ago
not as such, but we will need to use split
a
aOP•2w ago
oh right
Pobiega
Pobiega•2w ago
okay, so how do we parse our lines? whats step 1
a
aOP•2w ago
categories.Add(int.Parse(line)); something like this lmao
Pobiega
Pobiega•2w ago
nawww for one, it wont work, and two, its a bit too much
a
aOP•2w ago
nah wait gimme a min minute
Pobiega
Pobiega•2w ago
sure
a
aOP•2w ago
categories.Add(line, points); I give up
Pobiega
Pobiega•2w ago
wellll we need to do something with the string like... turn it into a sequence of numbers, perhaps
a
aOP•2w ago
with loop?
Pobiega
Pobiega•2w ago
probably yeah I don't think you'll be happy with me if I write a linq-oneliner for this 😄 but im tempted to try...
a
aOP•2w ago
wait what wdym by that go ahead
Pobiega
Pobiega•2w ago
var categories = lines
.Select(l => l.Split(" ").Select(int.Parse).ToArray())
.ToDictionary(x => x[0], x => x.Skip(1).ToArray());
var categories = lines
.Select(l => l.Split(" ").Select(int.Parse).ToArray())
.ToDictionary(x => x[0], x => x.Skip(1).ToArray());
tada... I don't think this is very helpful thou 😛 it also has a bit of a bug so dont worry about it
a
aOP•2w ago
I think I saw something very similar when looking for help with my problem on google
Pobiega
Pobiega•2w ago
its not what we want to do
a
aOP•2w ago
aight
Pobiega
Pobiega•2w ago
so
var categories = new Dictionary<int, List<int>>();

foreach (var line in lines)
{
// we are here.
}
var categories = new Dictionary<int, List<int>>();

foreach (var line in lines)
{
// we are here.
}
what do we need to do at "we are here"?
a
aOP•2w ago
categories.Add(lines, ); is this even a good start or nah
Pobiega
Pobiega•2w ago
no
a
aOP•2w ago
rip no add function?
Pobiega
Pobiega•2w ago
what would you add?
a
aOP•2w ago
categories and points
Pobiega
Pobiega•2w ago
points doesnt exist and categories is... the thing you are adding to
a
aOP•2w ago
dude let me be real, I have no idea it shouldnt even start with "categories"?
Pobiega
Pobiega•2w ago
no we need to do something to the text the variable line contains the current string we are working on that represents a single category and its items do you remember .Split?
a
aOP•2w ago
ofc use it now?
Pobiega
Pobiega•2w ago
yeah but lets keep the result for now ie, dont throw it away we might also want to turn those strings into numbers at the same time if you are comfortable with that
a
aOP•2w ago
I am
Pobiega
Pobiega•2w ago
ok, give me your best shot
a
aOP•2w ago
int.Parse(line.Split(' ')[0]) something like this in a middle
Pobiega
Pobiega•2w ago
close, but not quite int.Parse handles a single number and we wanna parse all the numbers so I present you...
var numbers = line.Split(" ").Select(int.Parse).ToArray();
var numbers = line.Split(" ").Select(int.Parse).ToArray();
this I gotta go for ~10 min try to understand this line of code while Ima wayh
a
aOP•2w ago
no way I could have had that right😭 kkkk
Pobiega
Pobiega•2w ago
You see there are three parts to that line ye? Is it obvious what each part does?
a
aOP•2w ago
I think I understand this var numbers is an array now yeah? oh wait, one question line.Split(" ") what exactly does it split? every element divided by comma? nah, not comma, space
Pobiega
Pobiega•2w ago
exactly it divides the string into many strings, each divided by a space then, each item in that array (the array of split strings), is transformed with the .Select method select applies another method to each thing in its sequence in this case, it turns a string into an int and finally we .ToArray the sequence so we get an array
a
aOP•2w ago
how nice now I need to turn first number of array into category? or var numbers already dont contain category numbers nah, it contains
Pobiega
Pobiega•2w ago
It has all the numbers So can you divide it into two variables, called key and points?
a
aOP•2w ago
with another split?
Pobiega
Pobiega•2w ago
Split is a method for strings You now have an int array
a
aOP•2w ago
var key = numbers.Take(0).ToArray();
Pobiega
Pobiega•2w ago
Close numbers[0] is better We just want the first, and we dont want it as an array But how do we get the rest..?
a
aOP•2w ago
my original idea was to add five items to list one by one with add() or use getrange
Pobiega
Pobiega•2w ago
we could do something like that, but I'd like to separate out the points first
var key = numbers[0];
var points = numbers[1..];
var key = numbers[0];
var points = numbers[1..];
is the best way, if you ask me
a
aOP•2w ago
those two dots at the end are good or do I need to continue with that line?
Pobiega
Pobiega•2w ago
haha, no they are good it means "from 1, all the way to the end"
a
aOP•2w ago
wtf I actually lack this much knowledge💀
Pobiega
Pobiega•2w ago
well, Im not showing you the simplest most basic way to do things im showing you modern syntax
a
aOP•2w ago
points.Sum(); would this work? int sum = points.Sum(); Console.WriteLine(sum);
Pobiega
Pobiega•2w ago
Yeah it would, but its too early Remember category 1?
a
aOP•2w ago
yeah ok Im lost a bit var key does it mean categories?
Pobiega
Pobiega•2w ago
no well yes it means the category id for this line you could call it categoryId if you want you still there?
a
aOP•2w ago
yeah xd tryna do something
Pobiega
Pobiega•2w ago
show me
a
aOP•2w ago
right now nothing works but im trying to implement this if (testArray.Length != testArray.Distinct().Count()) { Console.WriteLine("Contains duplicates"); } to check for same categories
Pobiega
Pobiega•2w ago
uh thats... not what it does
a
aOP•2w ago
rip then
Pobiega
Pobiega•2w ago
it checks for duplicate entries, not same category ie x 5 5 dont worry about duplicates yet we'll handle that
a
aOP•2w ago
then what do I need to do rn? I thought only about duplicates
Pobiega
Pobiega•2w ago
show me what you got
a
aOP•2w ago
string filepath = @"C:\Users\Vartotojas\Desktop\task.txt"; var lines = File.ReadAllLines(filepath); var categories = new Dictionary<int, List<int>>(); foreach (string line in lines) { var numbers = line.Split(" ").Select(int.Parse).ToArray();
var key = numbers[0]; var points = numbers[1..]; int sum = points.Sum();
Console.WriteLine(key+" "+sum); }
Pobiega
Pobiega•2w ago
eight right*
a
aOP•2w ago
also, how do you make ur code darker in chat?
Pobiega
Pobiega•2w ago
$codegif
a
aOP•2w ago
thx
Pobiega
Pobiega•2w ago
but notice how we are not interacting with categories at all inside the loop? we are not done
a
aOP•2w ago
yeah I was wondering about that xd
Pobiega
Pobiega•2w ago
all we've done is process the individual line into its two parts, the category id and the points the next part is getting the associated List<int> for the given category now, there are two cases that are possible in this scenario 1. this is the first time we see this category 2. this is not the first time we see this category
a
aOP•2w ago
before this, do I need to add key and points to categories?
Pobiega
Pobiega•2w ago
no thats what we are working on right now we cant add now, because we dont know what to do if we blindly try to add, what if the dictionary already contains the category (like 1)? you need to think like a computer
a
aOP•2w ago
so I need to check before adding?
Pobiega
Pobiega•2w ago
thats one way alternatively we handle that in a... more graceful manner
a
aOP•2w ago
teach me your ways
Pobiega
Pobiega•2w ago
okay, so there is a method all dictionaries have that is called... GetValueOrDefault it takes in a key, and gives you either the value assocaited with that key, or the default value for that type this method is incredibly useful because we want access to the list for a given category, or a blank list if there is no list already associated how can we do that?
a
aOP•2w ago
CAN WE??? ofc
Pobiega
Pobiega•2w ago
?
a
aOP•2w ago
oh ok, I read it wrong💀 how shamefull
categories.GetValueOrDefault(key,points);
categories.GetValueOrDefault(key,points);
with something like this
Pobiega
Pobiega•2w ago
ooo, spicy and not too far off either
a
aOP•2w ago
categories.GetValueOrDefault(key);
Pobiega
Pobiega•2w ago
yep so that will give you back the value, or default for List<int> which is.... null Lists default to null so we combine that with a fancy operator called ?? and presto var values = categories.GetValueOrDefault(key) ?? []; now this might be a lot to unpack, so lets go over exactly what it does we get the value in the dictionary, or null then ?? checks if the left operand is null... if it is, it assigns the right operand if it wasnt, it does nothing so value is either the list we had, or a blank new list []
a
aOP•2w ago
holy shit alright then but doesnt this need IF statement?
Pobiega
Pobiega•2w ago
this is the same as writing...
var values = categories.GetValueOrDefault(key);
if (values == null)
{
values = new List<int>();
}
var values = categories.GetValueOrDefault(key);
if (values == null)
{
values = new List<int>();
}
nope thats why its so beautiful
a
aOP•2w ago
for real
Pobiega
Pobiega•2w ago
but yeah, there is a conditional in there, its just not an if regardless we now have a list now we can add values to it suggestions?
a
aOP•2w ago
we add key to values💀
Pobiega
Pobiega•2w ago
naww not key key is the category
a
aOP•2w ago
so points?
Pobiega
Pobiega•2w ago
yep
a
aOP•2w ago
should I add sum()?
Pobiega
Pobiega•2w ago
no again, you chose NOT to work that way and you are not sure if this is the last time you see this category so its too early to sum anything
a
aOP•2w ago
alright but those
values
values
mean they are whole
categories
categories
? I might be slow on this one
Pobiega
Pobiega•2w ago
they are not entire categories yet they are categories in progress they MIGHT be full, or they might not be we simply dont know
a
aOP•2w ago
but then again, this line is to check which category has same numbers right?
Pobiega
Pobiega•2w ago
yeah
a
aOP•2w ago
kk
Pobiega
Pobiega•2w ago
if we already have a list, we get that, instead of starting on a new list
a
aOP•2w ago
values.Add(points[1..]);
values.Add(points[1..]);
lmao im stuck again
Pobiega
Pobiega•2w ago
close but why are you skipping the first point? and what does .Add expect?
a
aOP•2w ago
now that I think about it, I forgot what
[1..]
[1..]
meant. my mistake could it be it expects only one item? soooo whole array doesnt work
Pobiega
Pobiega•2w ago
correct. is there perhaps another method that expects more?
a
aOP•2w ago
values.ForEach(x => {points[x]++;}); this thing
Pobiega
Pobiega•2w ago
naw values.AddRange
a
aOP•2w ago
xd oh ofc values.AddRange(points); correct?
Pobiega
Pobiega•2w ago
yep
a
aOP•2w ago
this might sound dumb, but at this point, program doesnt know which category has duplicates right?
Pobiega
Pobiega•2w ago
it doesnt know and it doesnt care it handles them nicely for example, these two lines
1 15 20 22 5 9
1 9 6 8 7 12
1 15 20 22 5 9
1 9 6 8 7 12
it will essentially see as 1 15 20 22 5 9 9 6 8 7 12 and I can prove it to you
a
aOP•2w ago
because of this line right?
Pobiega
Pobiega•2w ago
yea well, we are actually not quite done yet we have 1 more thing to do we need to update the dictionarys reference for the key because we might have created a new list so lets slap a categories[key] = values; down there
a
aOP•2w ago
alright
Pobiega
Pobiega•2w ago
now, the code should look like...
var categories = new Dictionary<int, List<int>>();

foreach (var line in lines)
{
var numbers = line.Split(" ").Select(int.Parse).ToArray();
var key = numbers[0];
var points = numbers[1..];
var values = categories.GetValueOrDefault(key) ?? [];
values.AddRange(points);
categories[key] = values;
}

foreach (var kvp in categories)
{
Console.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value)}");
}
var categories = new Dictionary<int, List<int>>();

foreach (var line in lines)
{
var numbers = line.Split(" ").Select(int.Parse).ToArray();
var key = numbers[0];
var points = numbers[1..];
var values = categories.GetValueOrDefault(key) ?? [];
values.AddRange(points);
categories[key] = values;
}

foreach (var kvp in categories)
{
Console.WriteLine($"{kvp.Key}: {string.Join(", ", kvp.Value)}");
}
that last part just prints the stuff inside the dictionary prints this for me:
1: 15, 20, 22, 5, 9, 9, 6, 8, 7, 12
5: 0, 6, 12, 14, 5
2: 12, 12, 5, 14, 13, 11, 12, 11, 14, 9
7: 1, 1, 9, 6, 7
8: 11, 17, 15, 13, 9
10: 12, 20, 13, 14, 16
4: 12, 16, 14, 12, 16
9: 11, 12, 11, 15, 16
1: 15, 20, 22, 5, 9, 9, 6, 8, 7, 12
5: 0, 6, 12, 14, 5
2: 12, 12, 5, 14, 13, 11, 12, 11, 14, 9
7: 1, 1, 9, 6, 7
8: 11, 17, 15, 13, 9
10: 12, 20, 13, 14, 16
4: 12, 16, 14, 12, 16
9: 11, 12, 11, 15, 16
a
aOP•2w ago
and I just put Sum() at the end xd
Pobiega
Pobiega•2w ago
yep
a
aOP•2w ago
one last thing sorting from smallest to biggest category
categories[key].Sort();
categories[key].Sort();
but idk
Pobiega
Pobiega•2w ago
nah so, what do you mean by smallest category? the category id itself, or the summed values?
a
aOP•2w ago
by var key if I understand
Pobiega
Pobiega•2w ago
.Sort() doesnt work on dictionaries, they are unsortable because of how they work. You can however "sort" them when you iterate over their content...
foreach (var kvp in categories.OrderBy(x => x.Key))
{
Console.WriteLine($"{kvp.Key}: {kvp.Value.Sum()}");
}
foreach (var kvp in categories.OrderBy(x => x.Key))
{
Console.WriteLine($"{kvp.Key}: {kvp.Value.Sum()}");
}
1: 113
2: 113
4: 70
5: 37
7: 24
8: 65
9: 65
10: 75
1: 113
2: 113
4: 70
5: 37
7: 24
8: 65
9: 65
10: 75
a
aOP•2w ago
this is second foreach loop right?
Pobiega
Pobiega•2w ago
yes
a
aOP•2w ago
console is empty for me somehow ooh my mistake fixed well what can I say thank you sooooo much my master for putting up with me today xd
Pobiega
Pobiega•2w ago
gonna give you a fair warning if you turn this in to a teacher as "your code" they will know you did not write this yourself
a
aOP•2w ago
nahh, this isnt my homework
Pobiega
Pobiega•2w ago
good
a
aOP•2w ago
one question tho - how would you rate this task
Pobiega
Pobiega•2w ago
because while it isnt a masterpiece, its using some fancy stuff, like ?? and GetValueOrDefault, and [], and .Select...
a
aOP•2w ago
how hard is it fomr 1 to 10
Pobiega
Pobiega•2w ago
the task? its good well whats a 10? nasa level orbital calculations?
a
aOP•2w ago
10 is like, you spend week doing it and 1 is 5 mins of work
Pobiega
Pobiega•2w ago
hm okay a 3?
a
aOP•2w ago
damn xd
Pobiega
Pobiega•2w ago
I could have done this in 30-40 seconds probably
a
aOP•2w ago
I need to get better
Pobiega
Pobiega•2w ago
but I'm not new
a
aOP•2w ago
ok another question, how long have you been programming?
Pobiega
Pobiega•2w ago
Ive written C# for over 20 years
a
aOP•2w ago
ohhhhhhh
Pobiega
Pobiega•2w ago
and programming in total for... almost 30
a
aOP•2w ago
explains a lot
Pobiega
Pobiega•2w ago
yeah 🙂
a
aOP•2w ago
damn how wonderful well thx again
Pobiega
Pobiega•2w ago
do you understand this code now? or is anything unclear in how it works
a
aOP•2w ago
looks like everythings clear but to make it perfectly clear, I'll need to work with it
Pobiega
Pobiega•2w ago
thats fine
Want results from more Discord servers?
Add your server