Reputation: 13
I'm creating a little program that takes user inputs (string and decimal) and will print them back out to the user when they choose the "View Summary" option from the menu.
The menus cycle through based on user inputs and the account name/account balances will print immediately after they are requested/inputted, but I can't get them to save and print once option 3 is selected. Despite any inputs, the "View Summary" says assets are 0 and debts are 0 every time.
The Account class has a string name and decimal balance, and I only want it to save until the user is done. (No database. Just trying to get concepts for now)
My main questions:
is this because of the loops/should the list be outside of them to capture data?
would a dictionary be a better idea, and can I start with an empty collection?
static void Main(string[] args)
{
string menuChoice;
string response;
do
{
// Welcome/Menu screen
Console.WriteLine("\nWelcome to your Net Worth Calculator.\n \n MENU:\n 1. Add Asset\n 2. Add Debt\n 3. View Summary");
Console.WriteLine(" ");
Console.WriteLine("What would you like to do?\nPlease make a selection: ");
menuChoice = Console.ReadLine();
Account asset = new Account();
var accountList = new List<Account>();
if (menuChoice == "1")
{
do
{ //D1
Console.WriteLine("\nGreat! Let's add an account.");
Console.WriteLine("Account name:");
asset.name = Console.ReadLine();
Console.WriteLine("Your account name is: " + asset.name);
Console.WriteLine("\nWhat is your current account balance with " + asset.name + "?");
Console.WriteLine("Balance:");
asset.balance = Decimal.Parse(Console.ReadLine());
accountList.Add(asset);
Console.WriteLine("Your balance with " + asset.name + " is currently $" + asset.balance + ".");
Console.WriteLine("\n\nWould you like to add another account? y/n");
response = Console.ReadLine();
} while (response != "n");
}
if (menuChoice == "3")
{
//D3
Console.WriteLine("Let's take a look at the accounts and balances that you've added so far:");
Console.WriteLine($"{asset.balance} is your asset, and {debt.balance} is your debt.");
decimal netWorth = asset.balance - debt.balance;
Console.WriteLine(netWorth);
Console.WriteLine($"{ asset.balance}");
Console.WriteLine("\n\nWould you like to add another account? y/n");
response = Console.ReadLine();
}
Upvotes: 1
Views: 121
Reputation: 8194
One issue is exactly as you've described, because you create a new instance of accountList
on each iteration of the loop it loses the information from last time. Move it outside the loop as shown below.
I suppose you could use a Dictionary<string, decimal>
if you wanted. The advantage is that it doesn't allow duplicate keys and allows you to access values by key. If you need neither of these things then a List<T>
is fine as you have it now.
There were some other issues so I've taken some liberties with your code but I believe the below does what you want:
void Main()
{
string menuChoice;
string response;
var accountList = new List<Account>();
var debtList = new List<Debt>();
do
{
response = "";
Console.WriteLine("\nWelcome to your Net Worth Calculator.\n \n MENU:\n 1. Add Asset\n 2. Add Debt\n 3. View Summary\n 4. Quit");
Console.WriteLine(" ");
Console.WriteLine("What would you like to do?\nPlease make a selection: ");
menuChoice = Console.ReadLine();
if (menuChoice == "1")
{
do
{
Account asset = new Account();
Console.WriteLine("\nGreat! Let's add an account.");
Console.WriteLine("Account name:");
asset.name = Console.ReadLine();
Console.WriteLine("Your account name is: " + asset.name);
Console.WriteLine("\nWhat is your current account balance with " + asset.name + "?");
Console.WriteLine("Balance:");
asset.balance = Decimal.Parse(Console.ReadLine());
accountList.Add(asset);
Console.WriteLine("Your balance with " + asset.name + " is currently $" + asset.balance + ".");
Console.WriteLine("\n\nWould you like to add another account? y/n");
response = Console.ReadLine();
} while (response != "n");
}
if (menuChoice == "2")
{
do
{
Debt debt = new Debt();
Console.WriteLine("\nGreat! Let's add a debt.");
Console.WriteLine("Debt name:");
debt.name = Console.ReadLine();
Console.WriteLine("Your debt name is: " + debt.name);
Console.WriteLine("\nWhat is your current debt balance with " + debt.name + "?");
Console.WriteLine("Balance:");
debt.balance = Decimal.Parse(Console.ReadLine());
debtList.Add(debt);
Console.WriteLine("Your balance with " + debt.name + " is currently $" + debt.balance + ".");
Console.WriteLine("\n\nWould you like to add another debt? y/n");
response = Console.ReadLine();
} while (response != "n");
}
if (menuChoice == "3")
{
var totalAsset = accountList.Sum(x => x.balance);
var totalDebt = debtList.Sum(x => x.balance);
Console.WriteLine("Let's take a look at the accounts and balances that you've added so far:");
Console.WriteLine($"{totalAsset} is your asset, and {totalDebt} is your debt.");
decimal netWorth = totalAsset - totalDebt;
Console.WriteLine($"Net worth: {netWorth}");
Console.WriteLine("\n\nPress any key to return to the menu");
Console.ReadLine();
}
} while (menuChoice != "4");
}
public class Account
{
public string name {get;set;}
public decimal balance {get;set;}
}
public class Debt
{
public string name {get;set;}
public decimal balance {get;set;}
}
Summary:
accountList
outside of the loop so it doesn't get erased on the next iteration debtList
to track debt (assume you had this but didn't show it?) Depending on what account/debt share in common you may just be able to have one class instead of two.
Upvotes: 0
Reputation: 14477
do { // ... Account asset = new Account(); var accountList = new List<Account>(); // ... if (menuChoice == "3") { Console.WriteLine($"{asset.balance} is your asset, and {debt.balance} is your debt."); } } while (/* ... */);
You are declaring a new assset
object and the accountList
on each menu loop. Of course, assset.balance
would be zero when you print, since it will always be a fresh new object when you choose menu option #3.
You should move the list outside of the menu loop:
static void Main(string[] args)
{
string menuChoice;
string response;
var accountList = new List<Account>();
do { // ...
And, create a new instance of Account
inside menu option #1:
if (menuChoice == "1")
{
do
{ //D1
var asset = new Account();
// ... rest of your code
} while (response != "n");
}
As for calculating the assets and debts, you need to find all account with positive numbers or negative numbers, respectively:
var assets = accountList.Where(x => x.balance > 0).Sum(x => x.balance);
// assuming that you used negative value for debt
var debts = accountList.Where(x => x.balance < 0).Sum(x => x.balance);
Ideally, you would want two different type of Account
for less messy code:
public abstract class Account
{
public string Name { get; set; }
public decimal Balance { get; set; }
}
public class Asset : Account { }
public class Debt : Account { }
// in option #3
accountList.OfType<Asset>().Sum(x => x.Balance);
Upvotes: 0
Reputation: 662
accountList must be outside the input loop, so that no matter which option is selected, you are able to access it (read or write).
Something like this:
static void Main(string[] args)
{
string menuChoice;
string response;
var accountList = new List<Account>();
// Welcome/Menu screen
Console.WriteLine("\nWelcome to your Net Worth Calculator.\n \n MENU:\n 1. Add Asset\n 2. Add Debt\n 3. View Summary");
do
{
Console.WriteLine(" ");
Console.WriteLine("What would you like to do?\nPlease make a selection: ");
menuChoice = Console.ReadLine();
if (menuChoice == "1")
{
do
{ //D1
Account asset = new Account();
Console.WriteLine("\nGreat! Let's add an account.");
Console.WriteLine("Account name:");
asset.name = Console.ReadLine();
Console.WriteLine("Your account name is: " + asset.name);
Console.WriteLine("\nWhat is your current account balance with " + asset.name + "?");
Console.WriteLine("Balance:");
asset.balance = Decimal.Parse(Console.ReadLine());
accountList.Add(asset);
Console.WriteLine("Your balance with " + asset.name + " is currently $" + asset.balance + ".");
Console.WriteLine("\n\nWould you like to add another account? y/n");
response = Console.ReadLine();
} while (response != "n");
}
if (menuChoice == "3")
{
//D3
Console.WriteLine("Let's take a look at the accounts and balances that you've added so far:");
Console.WriteLine($"{asset.balance} is your asset, and {debt.balance} is your debt.");
decimal netWorth = asset.balance - debt.balance;
Console.WriteLine(netWorth);
Console.WriteLine($"{ asset.balance}");
Console.WriteLine("\n\nWould you like to add another account? y/n");
response = Console.ReadLine();
}
Upvotes: 1