Fill a list with objects depending on eachothers attributes - c#

I have a List where I want to use the latest object created in the List to calculate the next objects attributes. I'm not sure how to write the loop doing that. Can you help me with that?
public ActionResult ShowDetail(DateTime startdate, double PresentValue, double InterestRate, double FutureValue, int PaymentPeriods)
{
List<Calculation> cList = new List<Calculation>();
Calculation calc = new Calculation();
calc.Date = startdate.ToShortDateString();
calc.InvoiceAmount = 2000;
calc.InterestRate = InterestRate;
calc.InterestAmount = (PresentValue * InterestRate / 360 * 30);
calc.Amortization = (2000 - (PresentValue * InterestRate / 360 * 30));
calc.PresentValue = PresentValue;
cList.Add(calc);
for (int i = 0; i < PaymentPeriods; i++)
{
cList.Add(new Calculation()
{
var calcBefore = cList.GetLastObject //Some how I want to take the object before the one i want to create
cList.Add(new Calculation()
{
Date = calcBefore.Date.Add(1).Month() //something like this
InvoiceAmount = calcBefore.InvoiceAmount
InterestRate = calcBefore.InterestRate
InterestAmount = (calcBefore.PresentValue * InterestRate / 360 * 30) //I want to take the presentvalue from the object before in the List and use that to calculate the the next InterestAmount
//And so on
}
});
}
return PartialView("ShowDetail", cList);
}
Calculation:
public partial class Calculation
{
public string Date { get; set; }
public double InvoiceAmount { get; set; }
public double InterestRate { get; set; }
public double InterestAmount { get; set; }
public double Amortization { get; set; }
public double PresentValue { get; set; }
}

You can use the index of the list to access the last inserted:
var calcBefore = cList[cList.Count - 1];
another way which does the same: Enumerable.Last:
var calcBefore = cList.Last();
Since you have added one before the loop the list is not empty and this is safe.
Here is the complete loop:
for (int i = 0; i < PaymentPeriods; i++)
{
calc = new Calculation();
Calculation calcBefore = cList[cList.Count - 1];
calc.Date = DateTime.Parse(calcBefore.Date).AddMonths(1).ToString();
calc.InvoiceAmount = calcBefore.InvoiceAmount;
calc.InterestRate = calcBefore.InterestRate;
calc.InterestAmount = (calcBefore.PresentValue * InterestRate / 360 * 30);//I want to take the presentvalue from the object before in the List and use that to calculate the the next InterestAmount
cList.Add(calc);
}
According to the Date, i assume you want to add one month, use DateTime.AddMonths:
Date = DateTime.Parse(calcBefore.Date).AddMonths(1).ToString();
However, i wouldn't use a String for a DateTime at all.

do not think you would use a loop,
All you would have to do is have a constructor take an Calculation object as a parameter.
Then you would do something like
public partial class Calculation
{
public string Date { get; set; }
public double InvoiceAmount { get; set; }
public double InterestRate { get; set; }
public double InterestAmount { get; set; }
public double Amortization { get; set; }
public double PresentValue { get; set; }
public Calculation (Calculation as calculation(
{
.. set you prop
}
}
then when you call a new object, you pass in the last object in the current list
var newObj = new Calculation(cList[cList.Length -1]);

Related

C# methood to scrape a line into an array - does not pass the array on return

i am quite new to C# and i have been doing my progress via projects with goals i`m trying to achieve.
i am stuck in something rather general and simple, and it will assist me to understand and move forward.
public Array ExtractRakeFromHand(string theline)
{
int rri = 0;
var rakeandpot = theline.Split().Where(x => x.StartsWith("("))
.Select(x => x.Replace("(", string.Empty).Replace(")", string.Empty))
.ToList();
var playerssplit = theline.Substring(theline.IndexOf("ers ("));
var pbreakdown = playerssplit.Substring(theline.IndexOf("("));
pbreakdown = pbreakdown.Remove(pbreakdown.Length - 1, 1);
var numofplayers = pbreakdown.Split(',');
(string player, double player_portion, double potsize, double rakesize, string hand)[] myar = new (string player, double player_portion, double potsize, double rakesize, string hand)[numofplayers.Length];
for (int iii = 0; iii < myar.Length; iii++)
{
myar[iii].rakesize = Double.Parse(rakeandpot[0]);
myar[iii].potsize = Double.Parse(rakeandpot[1]);
}
var values = pbreakdown.Split(',');
(string name, double value)[] result = new (string, double)[values.Length];
for (int ii = 0; ii < values.Length; ii++)
{
var splittedValue = values[ii].Split(':');
result[ii] = (splittedValue[0], Double.Parse(splittedValue[1], CultureInfo.InvariantCulture));
myar[rri].player = result[rri].name;
var ppot = (result[rri].value / myar[rri].potsize);
var ppotr = ppot * myar[rri].rakesize;
myar[rri].player_portion = ppotr;
rri++;
}
return myar;
}
i call this method via var thedata = ExtractRakeFromHand(d);
the return is an object that does not contain the "Name" and "Rake" fields.
how can i make it return the array in the same way it was created ?
I tried to add this class:
public class RakeHandParse
{
public string player { get; set; }
public double player_portion { get; set; }
public double potsize { get; set; }
public double rakesize { get; set; }
public string hand { get; set; }
}
but i`m not sure how to use it inside the code to get back the full details.
thanks so much !
replace public Array ExtractRakeFromHand(string theline)
with public (string player, double player_portion, double potsize, double rakesize, string hand)[] ExtractRakeFromHand(string theline)
and call like:
(string player, double player_portion, double potsize, double rakesize, string hand)[] myar = ExtractRakeFromHand(d);

Increment through property names in object

I have the following object:
namespace BluetoothExample
{
public class Assay
{
public double Band_1 //Vis450
{
get;
set;
}
public double Band_2 //Vis500
{
get;
set;
}
public double Band_3 //Vis550
{
get;
set;
}
public double Band_4 //Vis570
{
get;
set;
}
}
}
I want to populate the 4 bands in my object. Which I currently do in the following way:
public Populate()
{
int _i = 0;
double[] nirData = new double[4];
MyDevice.Characteristic.ValueUpdated += (sender, e) =>
{
nirData[_i] = BitConverter.ToDouble(e.Characteristic.Value, 0);
_i++;
};
Assay assay = new Assay();
assay.Band_1 = nirData[0];
assay.Band_2 = nirData[1];
assay.Band_3 = nirData[2];
assay.Band_4 = nirData[3];
}
I was wondering if it was possible to do the entire thing inside the MyDevice.Characteristic.ValueUpdate method instead? My thought is that it should be possible to increment and populate the properties of my object like so:
string name = "assay.Band_" + _i;
name = BitConverter.ToDouble(e.Characteristic.Value, 0);
This is obviously wrong, but it sort of demonstrates my idea.
Just make your band an Array, or List:
public class Assay
{
public double[] Band
{
get;
set;
}
}
And then you can simply assign it like:
public Populate()
{
int _i = 0;
double[] nirData = new double[4];
MyDevice.Characteristic.ValueUpdated += (sender, e) =>
{
nirData[_i] = BitConverter.ToDouble(e.Characteristic.Value, 0);
_i++;
};
Assay assay = new Assay();
assay.Band = nirData;
}

Why is my Output rounding up my decimal number? Should I be using Decimal or something else?

C# Amateur here;
I'm creating a basic 'Quote Calculator', ItemQuantity * ItemCost.
I want the quantity to be whole numbers (1,2,3,4,5, etc), and cost can be either whole numbers or have decimal places (1, 2, 3.45, 6.2).
Everything is working in my WPF application, however, the TextBlock I am using to output the sum of itemQuantity * itemCost is showing a rounded integer.
Obviously, I'd like it to be accurate to two decimal places, but currently it rounds the figure up. What am I doing incorrectly?
List<Items> quoteList = new List<Items>();
public void button_itemadd_Click(object sender, RoutedEventArgs e)
{
quoteList.Add(new Items()
{
itemName = input_itemdesc.Text,
itemQuantity = Convert.ToInt32(input_itemquantity.Text),
itemCost = Convert.ToDecimal(input_itemcost.Text)
});
dataGridView1.ItemsSource = "";
dataGridView1.ItemsSource = quoteList;
updateQuote();
}
public void updateQuote()
{
decimal costTotal = 0;
for (int i = 0; i < quoteList.Count; i++)
{
costTotal += (Convert.ToInt32(quoteList[i].itemCost) * Convert.ToDecimal(quoteList[i].itemQuantity));
}
// output_quotecost is the TextBlock
output_quotecost.Text = costTotal.ToString();
}
}
class Items
{
public string itemName { get; set; }
public int itemQuantity { get; set; }
public decimal itemCost { get; set; }
}
It looks like you mixed up the Convert methods on:
costTotal += (Convert.ToInt32(quoteList[i].itemCost) *
Convert.ToDecimal(quoteList[i].itemQuantity));
Instead, it should be:
costTotal += (Convert.ToDecimal(quoteList[i].itemCost) *
Convert.ToInt32(quoteList[i].itemQuantity));
You have to replace .ToInt32 with .ToDeciaml in order to get the right output.

C# cannot convert Int to Double

I get the error converting Int to Double, my next line Average[y] = Average[y] + Students[i].Marks; is not working either. So how can convert int[] to double[]?
public static double[] Averages(StudentMarks[] Students, int amount, string[] DifferentGroups, int GroupAmount, out double[] Average)
{
Average = new double[Max];
int y = 0;
int CountGroups = 0;
//int sum = 0;
for (int i = 0; i < amount; i++)
{
if (Students[i].Group == DifferentGroups[y])
{
Convert.ToDouble(Students[i].Marks);
//Average[y] = Average[y] + Students[i].Marks;
}
}
return Average;
}
The main:
static void Main(string[] args)
{
int amount;
StudentMarks[] Students;
string[] DifferentGroups;
int GroupAmount;
double[] Average;
ReadData(out Students, out amount);
DifferentGroups = FindDifferentGroups(Students, amount, out DifferentGroups, out GroupAmount);
Average = Averages(Students, amount, DifferentGroups, GroupAmount, out Average);
Class:
public const int Max = 50;
public string Surname { get; set; }
public string Name { get; set; }
public string Group { get; set; }
public int AmountOfMarks { get; set; }
public int[] Marks { get; set; }
So Student[i].Marks is Array.
Convert.ToDouble returns a double - it does not make an integer property or variable a double.
I think you want:
if (Students[i].Group == DifferentGroups[y])
{
double mark = Convert.ToDouble(Students[i].Marks);
Average[y] = Average[y] + mark;
}
or just:
if (Students[i].Group == DifferentGroups[y])
{
Average[y] = Average[y] + Convert.ToDouble(Students[i].Marks);
}
All Convert.ToXXX functions return the new value. Therefore, you should be expecting that and assigning the return value to a local variable.
Something like:
double YourMark = Convert.ToDouble(Students[i].Marks);
So how can convert int[] to double[]?
By programming. You write code to do it.
var d = new double[Students[i].Marks.Length];
for (int j = 0; j < Students[i].Marks.Length; ++j)
{
d[j] = Convert.ToDouble(Students[i].Marks[j]);
}
Or use LINQ:
var d = Students[i].Marks.Select(n => Convert.ToDouble(n)).ToArray();
Next time a method call won't compile or doesn't work the way you hoped it might, a good first step would be to check the documentation.

count grade while looping by using answer in streamwriter?

Can someone look at my code? How do I count the grade while looping, or can I take the line from StreamWriter and put substring?
I keep making it more and more messy... and I need to display it like
Student that score A got how many?
Student that got B got how many?>
student that got C how many>
student that got d ... f...
using (StreamReader reader = new StreamReader("Student.txt"))
{
StreamWriter output = new StreamWriter("Result.txt");
String line;
line = reader.ReadLine();
while (line != null)
{
String name = line.Substring(0, 9);
String Asg1 = line.Substring(10, 3);
String Asg2 = line.Substring(16, 3);
String Test = line.Substring(22, 3);
String Quiz = line.Substring(28, 3);
String Exam = line.Substring(34, 3);
int intAsg1 = int.Parse(Asg1);
int intAsg2 = int.Parse(Asg2);
int intTest = int.Parse(Test);
int intQuiz = int.Parse(Quiz);
int intExam = int.Parse(Exam);
int percentAsg1 = (intAsg1 * 25) / 100;
int percentAsg2 = (intAsg2 * 25) / 100;
int percentTest = (intTest * 10) / 100;
int percentQuiz = (intQuiz * 10) / 100;
int percentExam = (intExam * 30) / 100;
// this part i dont get it~
**String Grade;
if (overallScore >= 70)
{
Grade = "A";
}
else if (overallScore >= 60)
{
Grade = "B";
}
else if (overallScore >= 50)
{
Grade = "C";
}
else if (overallScore >= 40)
{
Grade = "D";
}
else
{
Grade = "F";
}
}
}
It's not looping.
while !reader.EndOfStream
{
/*now check each Readline.
parse each line and create a new grade object for
each iteration and add to collection*/
}
A custom class to store the data for each student:
public class grade
{
public int asg1{ get; set; }
public int asg2{ get; set; }
public int test{ get; set; }
public int quiz{ get; set; }
public int exam{ get; set; }
//whatever else you need
}
A collection of Grades:
var grades = New List<grade>
I think you are looking for a class to hold the results in addition to correcting the readline loop.
public class Student
{
public string Name { get; set; }
public List<Grade> Grades { get; set; }
}
Then create a list before you start the loop
var students = new List<Student>();
Then add to the list in each iteration

Categories