Better ways to get the data from csv file

I am learning powershell and wanted to do something basic like this. I bet there are more efficient ways to do this in powershell, any feedback regarding better ways to accomplish the samething (using powershell lol) would be greatly appreciated.

$monthCSV = Import-Csv 'C:\Users\Documents\September.csv'

$SpendingData = New-Object System.Collections.ArrayList

$SpendingAmounts = New-Object -TypeName psObject -Property @{
    Bills = 0
    Groceries = 0
    Gas = 0
    Shopping = 0
    Fast_Food = 0
    Convenient_Store = 0
    Pet = 0
    Eyecare = 0
    Gifts = 0
}

foreach ($purchase in $monthCSV) {

    if ($purchase.Category -eq "Bills & Utilities") {
        $SpendingAmounts.Bills += [int]$purchase.Amount
    }
    if ($purchase.Category -eq "Groceries") {
        $SpendingAmounts.Groceries += [int]$purchase.Amount
    }
    if ($purchase.Category -eq "Gas") {
        $SpendingAmounts.Gas += [int]$purchase.Amount
    }
    if ($purchase.Category -eq "Shopping") {
        $SpendingAmounts.Shopping += [int]$purchase.Amount
        }
    if ($purchase.Category -eq "Fast Food") {
        $SpendingAmounts.Fast_Food += [int]$purchase.Amount
        }
    if ($purchase.Category -eq "Convenient Store") {
        $SpendingAmounts.Convenient_Store += [int]$purchase.Amount
        }
    if ($purchase.Category -eq "Pet") {
        $SpendingAmounts.Pet += [int]$purchase.Amount
        }
    if ($purchase.Category -eq "Eyecare") {
        $SpendingAmounts.Eyecare += [int]$purchase.Amount
        }
    if ($purchase.Category -eq "Gifts") {
        $SpendingAmounts.Gifts += [int]$purchase.Amount
        }
}

$SpendingData.Add($SpendingAmounts) | Out-Null

$SpendingData

Hey there and welcome!

Do you have a particular thing you want to improve in the script? One general rule that I sort of live by is not to try to pre-optimize something that is already working and meeting my needs. Sure there might be things that could change but typically aren’t necessary. Just glancing I’m guessing this script does function and accomplishes the task you are wanting it to do.

One thing that you might consider instead of all the if statements is using a switch statement: [about Switch - PowerShell | Microsoft Learn](about Switch - PowerShell | Microsoft Learn

It might look something like this:

switch ($purchase.Category) {
'Gas' {$SpendingAmounts.Gas += [int]$purchase.Amount}
'Shopping' {$SpendingAmounts.Shopping += [int]$purchase.Amount}

I cut it short, but you probably get the idea. There might be other small things that others would suggest trying likely as there are other ways to do looping or to manipulate data. You could use ForEach-Object instead of the foreach keyword. You could initiate variables differently etc. It really depends on what’s important to you. The switch statement, should make your code more readable which is always a good thing.

1 Like

It does do what I want it. I like your rule, in the future I will adopt it, for now the type of feedback I am looking for is kind of like best practices maybe, or general advice from experienced users for inexperienced users. I would be ecstatic if an experienced user rewrote it the way they thought was best. So things like, if the PS custom object is the ideal object to store the data, or other ways of looping through the data like you said with less lines of code. Your feedback about using switch statement is exactly what I am looking for, so thank you for that! I will give that a try! I think I learn faster when I get advice from the pros if that makes sense.

Mashuuu,
Welcome to the forum. :wave:t3:

There you go:

That would be a lot of work with actually no benefit. I’d recommend just to keep coding. The improvement comes with time. And if you get stuck with some code and you ask in forums like this you will get some tips for improvement once in a while anyway.

1 Like

I think the biggest problem with your approach is that every time you add a category, you need to update your code. I would do something like this:

$monthCSV = Import-Csv -Path .\september.csv

$monthCSV | Group-Object -Property Category | 
    ForEach-Object {
        [PSCustomObject] @{
            Category    = $_.Name
            TotalAmount = ($_.Group | Measure-Object -Property Amount -Sum).Sum
        }
    }
2 Likes

Thank you for the Github link, I bookmarked it and will begin reading.

Olaf
That would be a lot of work with actually no benefit. I’d recommend just to keep coding. The improvement comes with time. And if you get stuck with some code and you ask in forums like this you will get some tips for improvement once in a while anyway.

Ok I will keep that in mind, and I actually forgot I could ask ChatGPT for ideas about best practices too and got a lot of great ideas from that as well. Thank you for your feedback!

matt-bloomfield

I think the biggest problem with your approach is that every time you add a category, you need to update your code. I would do something like this:

You are absolutely right, thank you for that suggestion. I am going to work on updating the script tonight with all the help you guys have given me.

Please keep in mind that ChatGPT or other AIs are not a reliable, trustworthy source for code! You will have to validate what you get out of them! :point_up:t3: