How do I display each number with corresponding value? - c#

I have an assignment where I need to calculate the amount of money for 2 people where we have 2 different interest rates. I need to display the amount of money that they would have at each of the given age. The issue is that it only prints the final amount which is 60 years old, how do I print the correct amount at the correct age? Here is the code
Console.WriteLine("*************************Investing vs.Savings ************************* \n");
Console.WriteLine("{0,-25} {1,-30} {2,-30}","Age", "Linda's Account", "John's Account");
Console.Write("-----------------------------------------------------------------------\n");
for(int age=20;age<=60;age+=10)
{
double Linda = 1000;
double John = 1000;
for (int year=1;year<=40;year++)
{
double retLin = 0.06;
double retJon = 0.015;
Linda += Linda * retLin;
John += John * retJon;
}
Console.WriteLine("{0,-25}{1,-30:0.00} {2,-35:0.00}", age, Linda, John);
}
Console.Read();

If I figured it right, your desired response is a line of output for each person's balance on each deacde. To do this you only need one iteration in wich balances are increased based on each person's interest rate.
But to calculate the interest rate correctly, it should be added to the balance on every year. So a fixed inner loop of 10 iterations is needed for each decade.
The code is:
double Linda = 1000;
double John = 1000;
double retLin = 0.06;
double retJon = 0.015;
for (int age = 30; age <= 60; age += 10)
{
for (int i = 0; i < 10; i++)
{
Linda += Linda * retLin;
John += John * retJon;
}
Console.WriteLine("{0,-25}{1,-30:0.00} {2,-35:0.00}", age, Linda, John);
}
Note that this will not print tha balance on the starting decade (you can simply print the starting values before the loop operations).

I think this is what you need (comments in code):
Console.WriteLine("*************************Investing vs.Savings ************************* \n");
Console.WriteLine("{0,-25} {1,-30} {2,-30}", "Age", "Linda's Account", "John's Account");
Console.Write("-----------------------------------------------------------------------\n");
// It always is good idea to store info in variables, to give
// them meaning and easily parametrize the code.
var baseAge = 20;
var ageStep = 10;
var finalAge = 60;
// Of course, it would not make sense if you'd have just simple loop
// i = 0, i < limit, i++.
for (int age = baseAge; age <= finalAge; age += ageStep)
{
double Linda = 1000;
double John = 1000;
// Here you missed starting point, as it always calculated
// as if we were in first loop - we need account for that.
for (int year = age; year <= 40; year++)
{
double retLin = 0.06;
double retJon = 0.015;
Linda += Linda * retLin;
John += John * retJon;
}
Console.WriteLine("{0,-25}{1,-30:0.00} {2,-35:0.00}", age, Linda, John);
}
Console.Read();

Related

Convert money input into coins

ive just started some classes on c# and have been given an assignment with the following rules:
Prompt the user to enter an amount of dollars and cents. For example 1.18
- Display the number of quarters, dimes, nickels, and pennies to make that amount
Example If they entered 2.16 it should say:
8 quarters, 1 dimes, 1 nickels, 1 pennies
the problem that i run into is that this only seems to work if they type the money value as a whole. so if they wanted to type $1.18 they would type 118 and it would work just fine, but as soon as they type 1.18 it crashes. another example would be if they were to type 765 for $7.65 it would work fine, however if they type it correctly as 7.65 it would fail. sorry for the lame question, im super new, thanks for the help!
int totalCash;
Console.WriteLine("input money");
string moneyString = Console.ReadLine();
totalCash = int.Parse(moneyString);
int quarter = totalCash / 25;
totalCash %= 25;
int dime = totalCash / 10;
totalCash %= 10;
int nickel = totalCash / 5;
totalCash %= 5;
int penny = totalCash / 1;
totalCash %= 1;
Console.WriteLine("{0} quarters, {1} dimes, {2} nickels, {3} pennies", quarter, dime, nickel, penny);
```
There are lots of ways get the result but this the best approach I ever tried :
public static string ConvertMoneyIntoCoins(double money)
{
int cents = (int)(Math.Round(money, 2) * 100);
var coins = new[] {
new { Name = "Quarters", Value = 25 }, new { Name = "Dimes", Value = 10 },
new { Name = "Nickels", Value = 5 }, new { Name = "Pennies", Value = 1 }
};
var changes = coins.Select(coin => new { Amt = Math.DivRem(cents, coin.Value, out cents), Coin = coin }).Where(x => x.Amt != 0).ToList();
var strBld = new StringBuilder();
foreach (var change in changes)
{
strBld.Append(change.Amt + " " + change.Coin.Name + ", ");
}
return strBld.ToString();
}
It's working when you enter whole number should be the clue you pay attention to. If you assume the whole number is dollars, you can not mod by a whole number. All of your divisors are a factor of 100 too big. When you do that, you'll notice that you have the wrong data type as well. Note that i disagree with using tryparse when debugging as it eats errors. You should be running it in debug mode and then you would get an actual stack trace and a line it crashes at.

Interest On Balance Calculation Repayments

I am trying to design some code that will calculate a repayment plan for a loan, given a principle amount, term period (12 months) and and interest rate. I want the payments each month to be the same value (the last can differ slightly to account for remainders), and the interest is calculated from the remaining loan balance.
The basic rules are
Interest is dependant on the loan balance.
Loan balance is dependant on the total monthly repayment value.
Capital repayment is dependant on total monthly repayment value and interest.
The total monthly repayment amount can vary but must be the same each month (except the last one which can be different).
Here is the code I currently have, it does continous iterations until it finds the correct total monthly repayment value. This does work sort of but seems very inefficient and it takes the balance horribly into negative when it shouldnt . I'm wondering if anyone knows of a better way of doing this?
static void calcRepaymentPlan()
{
decimal loanAmount = 100000; //100,000
decimal ir = 0.10m;
//day counts
int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//get month/days
int dayCount = days.Sum();
int months = days.Length;
//get interest values
decimal interestdaily = ir / dayCount;
//total each month
decimal ideal_total_repayment = (loanAmount / months); //random number but seems like the best place to start
//some arrays to store balances
decimal[] balances = null;
decimal[] interest = null;
decimal[] capitalrepayment = null;
decimal totalRepaymentsValue = 0;
while (totalRepaymentsValue != loanAmount)
{
//array for balance each month
balances = new decimal[months];
for (int i = 0; i < months; i++)
{
balances[i] = loanAmount - ((i+1) * ideal_total_repayment);
}
//array for interest each month
interest = new decimal[months];
for (int i = 0; i < months; i++)
{
interest[i] = (interestdaily * balances[i]) * days[i];
}
//array for capital each month
capitalrepayment = new decimal[months];
for (int i = 0; i < months; i++)
{
capitalrepayment[i] = ideal_total_repayment - interest[i];
}
//how much of the loan are we paying back?
totalRepaymentsValue = capitalrepayment.Sum();
//how much difference between the loan amount and the total we have got now?
decimal difference = loanAmount - totalRepaymentsValue;
//how much to increment
decimal incr = 1;
//are we within 100? if so make the increment finer
if (difference < 100)
incr = 0.1m;
//if the difference is less than 1, then just add/subtract it from the last repayment
if (difference < 1)
{
capitalrepayment[months - 1] += difference;
balances[months - 1] += difference;
//this should now be the
totalRepaymentsValue = capitalrepayment.Sum();
continue;
}
//change the ideal total repayment
ideal_total_repayment += totalRepaymentsValue < loanAmount ? incr : -incr;
}
Console.WriteLine("--------------------------------------------------------------------------------------");
Console.WriteLine(" Balance Capital Interest Total Repayment");
for (int i = 0; i < months; i++)
{
string balanceStr = balances[i].ToString("#,##0.00");
string capitalStr = capitalrepayment[i].ToString("#,##0.00");
string interestStr = interest[i].ToString("#,##0.00");
string totalStr = (capitalrepayment[i] + interest[i]).ToString("#,##0.00");
Console.WriteLine("{0}). {1} {2} {3} {4}", (i + 1),
balanceStr, capitalStr, interestStr, totalStr);
}
Console.WriteLine("Ideal Total Repayment Value : {0}", ideal_total_repayment);
Console.WriteLine("Total Repaying : {0}", totalRepaymentsValue);
Console.WriteLine("-------------------------------------------------------------------------------------");
}

Bank interest calculator

I'm trying to make a calculator for interest in bank, like how many years would it take for 1$ to turn into 15$ with 4% interest, but all i get is the same number over and over, but i need it to go higher each year, like 1st year: 1$ * 4%interest, and 2nd year: 4% interest * 1st year interest, and 3rd year: 4% interest* 2nd year interest, and so on until it hits 15$
private void btreikna_Click(object sender, RoutedEventArgs e)
{
double vextir4 = 0.04;
double vextir8 = 0.08;
double vextir12 = 0.12;
double vextir16 = 0.16;
double vextir20 = 0.2;
double startvextir = Convert.ToDouble(byrjunisk.Text);
double artal = Convert.ToDouble(tbartal.Text);
double plusplus = vextir4 * startvextir;
double count = artal;
List<int> listfullofints = new List<int>();
for (int i = 0; i < artal; i++)
{
int[i]utkoma = plusplus * artal;
}
Your code is not very clear, but what you probably want is something like this:
decimal target = 15;
decimal start = 1;
decimal interest = 0.04M;
decimal currentCapital = start;
var numOfYears = 0;
while (currentCapital < target)
{
currentCapital = currentCapital + currentCapital*interest;
numOfYears++;
}
Console.WriteLine(currentCapital + " in " + numOfYears);
Few notes about that code and your attempt. It is advised to use decimal for precise calculations (and you want to be precise with money :) ) In your code you are not updating your plusplus variable - it is always the very first interest. And the last note - you cant use for loop as you dont know ahead of time the number of executions.
The classical formula for compound interest is:
V = (1 + r) ^ t
Where V is future value (or final number/original number), r is interest rate, and t is time.
Thus, in your case: V = 15 (from 15/1), r = 0.04, find t. Or, in other words:
t = log (V) / log (1 + r)
I recommend you to use Math.Log method.
double t = Math.Log(15D) / Math.Log(1.04D);
To get the time t you look for (without for loop). You may also be interested to look at the link JleruOHeP provides for interest calculation.

Progressive loop calculations

Ok. So I'm trying to have a program.. where the user enters his salary and then the program will calculate his salary for the next four years with a raise of 2.5% each year.
I feel like I have done this completely wrong, because my loop is only calculating one time.. its not even showing four salary's.. not to mention having them each raised 2.5% each time.
private void btnDisplay_Click(object sender, EventArgs e)
{
int count;
for (count = 1; count <= 4; count++)
{
decimal Raise;
decimal Salary;
decimal Sum;
decimal Total;
Raise = Convert.ToDecimal(0.025);
Salary = Convert.ToDecimal(txtSalary.Text);
Sum = Salary * Raise;
Total = Salary + Sum;
label2.Text = Total.ToString("c");
}
txtSalary is whatever the user entered salary is.
label2 is the display of the calculation.
---------------- UPDATE: I have updated the code with the final product. Thanks to everyone for helping out especially Patrick Hofman! You are the best.. I couldn't have done it without you. ------------------------
private void btnDisplay_Click(object sender, EventArgs e)
{
decimal salary = Convert.ToDecimal(txtSalary.Text);
decimal raise = 0.025m;
decimal previous = salary;
for (decimal year = 1; year <= 4; year++)
{
decimal sum = previous * (1 + raise);
previous = sum;
listBox1.Items.Add(sum.ToString("c"));
}
I think you should have something like this:
private void btnDisplay_Click(object sender, EventArgs e)
{
decimal salary = Convert.ToDecimal(txtSalary.Text);
decimal raise = 0.025m;
decimal total = 0;
decimal previous = salary;
listBox1.Items.Add("Start: {0:N2}", salary);
for (int year = 1; year <= 4; year++)
{
decimal sum = previous * (1 + raise);
previous = sum;
total += sum;
listBox1.Items.Add("Year {0}: {1:N2}", year, sum);
}
listBox1.Items.Add("Total: {0:N2}", total);
}
Note I made some changes to the variables. Some were moved to keep them over the for loop.
The steps:
Start with setting the start point (previous) to the salary.
For each year, multiply the previous year's salary with the raise percentage +1.
Set the previous and add that year's salary to the total.
Show the total in the label.
int count;
Salary = Convert.ToDecimal(txtSalary.Text);
for (count = 1; count <= 4; count++)
{
Salary *= 1.025m;
}
label2.Text = Salary.ToString("c");
You need to make sure you're retrieve the salary once at teh beginning and don't overwrite it till the end.
Problem 1: You are declaring the variables inside the forloop.so each time they are initialised with their default values.
Solution 1: inorder to retain their last assigned values you need to move the declaration of the variables outside the loop.
Problem 2: you are not able to see the results/changes as you are updating the label inside the for loop without any delay.so evatually you can only see the last calculated result.
Solution2: You need to either create 4 different labels to show the 4 different results or you need to wait for some time for updating the label results in each iteration by using timer functionality.
Try This: using LabelArray
Label[] lblSalaries = new Label[4];
private void CreateControls()
{
int x = 0, y = 10;
for (int i = 0; i < lblSalaries.Length;i++ )
{
lblSalaries[i] = new Label();
x += 60;
lblSalaries[i].Size = new System.Drawing.Size(50, 30);
lblSalaries[i].Location = new System.Drawing.Point(x,y);
Controls.Add(lblSalaries[i]);
}
}
private void btnDisplay_Click(object sender, EventArgs e)
{
int count;
decimal Raise;
decimal Salary;
decimal Sum;
decimal Total;
CreateControls();
for (count = 1; count <= 4; count++)
{
Raise = Convert.ToDecimal(0.025);
Salary = Convert.ToDecimal(txtSalary.Text);
Sum = Salary * Raise;
Total = Salary + Sum;
lblSalaries[count-1].Text = Total.ToString("c");
}
}

How to convert a number to a range of prices

I want to calculate the amount to charge my customers, when they buy licenses of my product.
I sell it in ranges of licenses:
1-10 : $50/user
11-20 : $40/user
21-30 : $30/user
31-50 : $20/user
So when someone purchases 136 licenses, I will charge him:
50 x 2 x $20 = $2000
30 x 1 x $30 = $900
6 x $50 = $300
I'm looking for an algorithm on how to process the given number and break it into number of occurrences in a range..
How can I do this in plain C# or LINQ?
------------ EDIT ----------------------------
I started a less confusing question (Algorithm for Fogbugz pricing scheme) and I got the answer I've been looking for.
Thank you all..
If presented with this price structure I would think that it is in the customer's best interest to minimize the cost by buying the package that best suits their need. The following algorithm uses dynamic programming to calculate the minimal possible price to exactly buy a certain number of licenses (you can save money by buying more than you need, although I haven't implemented that):
int getPrice(int n)
{
if (n >= 1 && n <= 10) return 50 * n;
if (n >= 11 && n <= 20) return 40 * n;
if (n >= 21 && n <= 30) return 30 * n;
if (n >= 31 && n <= 50) return 20 * n;
throw new Exception("Impossible");
}
int minimizePrice(int n)
{
int[] minimumPrice = new int[n + 1];
for (int i = 1; i <= n; ++i)
{
minimumPrice[i] = int.MaxValue;
for (int j = Math.Max(0, i - 50); j < i; ++j)
{
minimumPrice[i] = Math.Min(minimumPrice[i],
minimumPrice[j] + getPrice(i - j));
}
}
return minimumPrice[n];
}
For 70 licenses the minimal price is $1400 which can be obtained by buying 2 blocks of 35 licenses. You are suggesting a greedy algorithm. This will confuse your customers. A clever customer will place two orders instead of one large order and save $400.
I'd suggest changing your prices so that there is no upper limit to the number of licenses you can buy at $20 each.
This looks like it would be very similar to algorithms that make change for purchases (which coins to choose). The only difference is that you're comparing against a range instead of a single number.
The code could look something like this:
var val = 136;
var price = 0;
while (val > 0)
{
var range = FindMatchingRange(val); // Use a dictionary, list, or array.
var number = Math.Min(val, range.Max);
price += range.CostPerUser * number;
val -= number;
}
If I were a person who needed 10 licenses, under your suggested pricing plan why would I ever buy just 10 licenses?
10 licenses * $50/license = $500
11 licenses * $40/license = $440
What you would want is plan that lowers the cost for the most recently purchased licenses. So that for person wanting 11 licenses they would pay:
(10 licenses * $50/license) + (1 license * $40/license) = $540
A possible plan would look like this:
first 10 licenses (1-10): $50/user
next 10 licenses (11-20): $40/user
next 10 licenses (21-30): $30/user
all licenses after that (31+) : $20/user
Writing code to compute final cost for any number of users is a simple exercise. The calculation for someone purchasing 136 licenses would look like this:
(10 licenses * $50/license) + (10 licenses * $40/license) + (10 licenses * $30/license) + (106 licenses * $20/license) = $500 + $400 + $300 + $2120 = $3,220.
The original pricing plan is wacky, in my opinion. Take the customer who purchased 130 licenses last year who comes back and wants 10 more. What justification is there for charging them the highest rate? They are a high volume customer, you want to sell them (and they justifiably expect to receive) additional licenses at the lowest "marginal" price.
I made a calculation class for you... just more customer-orientated.
It calculates the cheapest price possible with your defined priceranges.
Example: 136 Licenses
50 Licenses 20$ each ( because: 31-50 : $20/user )
50 Licenses 20$ each ( because: 31-50 : $20/user )
36 Licenses 20$ each ( because: 31-50 : $20/user )
TOTAL: 1720
Example 130 Licenses
50 Licenses 20$ each
50 Licenses 20$ each
30 Licenses 30$ each
TOTAL: 1900
Code for the class:
public class PriceCalculator
{
public List<OrderPackage> CalculateCheapestPrice(Int32 AmountOfLicenses,
List<PriceRange> PriceRanges, out Double Total)
{
List<OrderPackage> result = new List<OrderPackage>();
Total = 0;
Int32 AmountsOfLicensesleft = AmountOfLicenses;
PriceRanges.Sort(ComparePrice);
for (int i = 0; i < PriceRanges.Count; i++)
{
for (int j = PriceRanges[i].MaxAmount; j >= PriceRanges[i].MinAmount; j--)
{
if (j <= AmountsOfLicensesleft)
{
OrderPackage Order = new OrderPackage();
Int32 AmountOfThisPackage = AmountsOfLicensesleft / j;
//Int32 AmountForThisPrice = Convert.ToInt32(Math.Floor(tmp));
Order.PriceRange = PriceRanges[i];
Order.AmountOfLicenses = j;
Total += Order.AmountOfLicenses * Order.PriceRange.PricePerLicense;
for (int k = 0; k < AmountOfThisPackage; k++)
{
result.Add(Order);
}
AmountsOfLicensesleft = AmountsOfLicensesleft - (AmountOfThisPackage * j);
}
}
}
return result;
}
private static int ComparePrice(PriceRange x, PriceRange y)
{
if (x.PricePerLicense == y.PricePerLicense)
return 0;
if (x.PricePerLicense > y.PricePerLicense)
return 1;
if (x.PricePerLicense < y.PricePerLicense)
return -1;
return 0;
}
public class OrderPackage
{
public PriceRange PriceRange { get; set; }
public Int32 AmountOfLicenses { get; set; }
}
public class PriceRange
{
public int MinAmount { get; set; }
public int MaxAmount { get; set; }
public Double PricePerLicense { get; set; }
}
}
Usage example:
private void button1_Click(object sender, EventArgs e)
{
// Preparing PriceRangeDefinitions
List<PriceCalculator.PriceRange> PriceRangeDefinitions = new List<PriceCalculator.PriceRange>();
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 1, MaxAmount = 10, PricePerLicense = 50 });
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 11, MaxAmount = 20, PricePerLicense = 40 });
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 21, MaxAmount = 30, PricePerLicense = 30 });
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 31, MaxAmount = 50, PricePerLicense = 20 });
// Start the Calculation
PriceCalculator calculator = new PriceCalculator();
Double Total;
List<PriceCalculator.OrderPackage> Packages =
calculator.CalculateCheapestPrice(130, PriceRangeDefinitions, out Total);
// Show Proof of Concept
String ProofOfConcept = String.Empty;
for (int i = 0; i < Packages.Count; i++)
{
ProofOfConcept += Packages[i].AmountOfLicenses.ToString() + " Licenses " +
Packages[i].PriceRange.PricePerLicense.ToString() + "$ each" + Environment.NewLine;
}
ProofOfConcept += Environment.NewLine + "TOTAL: " + Total.ToString();
MessageBox.Show(ProofOfConcept);
}
A KeyValuePair collection or dictionary maybe?

Categories