When I run the code, it doesn't calculate and it doesn't show the calculations.
Wondering if my variables or something else is wrong or maybe in the wrong place.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Question_3_Retail_Price_Calculator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
decimal costPrice = 0;
decimal markUpRateA = 0.19m;
decimal markUpRateB = 0.14m;
decimal markUpRateC = 0.12m;
decimal markUpRate = 0m;
decimal markUpTotal = 0;
decimal totalCost = 0;
// Add the items to ListBox 1
listBox1.Items.Add("Markup Rate =");
listBox1.Items.Add("Markup Total =");
listBox1.Items.Add("Total Cost =");
try
{
// Read the cost price from the user
costPrice = decimal.Parse(textBox1.Text);
}
catch (System.Exception excep )
{
MessageBox.Show(excep.Message);
}
if (costPrice <= 50)
{
// Calculate the value of the product
costPrice = (costPrice / 100) * markUpRateA;
}
else if (costPrice >= 50 && costPrice < 100)
{
// Calculate the value of the product
costPrice = (costPrice / 100) * markUpRateB;
}
else if (costPrice < 100)
{
// Calculate the value of the product
costPrice = (costPrice / 100) * markUpRateC;
}
else if (markUpRate == markUpTotal)
{
// Calculate the total monetary amount
markUpTotal = costPrice * markUpRate;
}
else
{
// Calculate the Total Cost of the product
totalCost = costPrice + markUpTotal;
}
// Output the total Cost
MessageBox.Show("Total Cost is: €" + totalCost);
}
}
}
Need some help figuring this out! Thanks in advance!
You're setting your total cost in the last else condition which will be executed only if all the other if-else conditions are not executed. That is why this code isn't working as you expect.
Even if you enter a value >100, your result is never assigned to totalCost. Because execution enters this part of your code
else if (markUpRate == markUpTotal)
{
// Calculate the total monetary amount
markUpTotal = costPrice * markUpRate;
}
and then jumps directly to the Message.Show(..) line.
There is a lot of crossover in you if else statements. If costPrice is 50, do you want to run rate A, rate B, or rate C (I think you have put your > sign the wrong way with markup rate C).
Also, why is it in a try loop? You are basically saying: "If there are no problems, assign costPrice to whatever the user entered, then skip the rest. And if there is a problem, do the rest but the costPrice will be the default value I assigned it to at the start (0)."
Basically, all the rest of the stuff should be in the try loop, not the catch loop.
Oh and read Xaero's answer as well, I have to wite this here though because i'm not allowed not comment yet :(.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace IndividualAssignmentLoan {
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
jmToday.Caption = Format(Now, "DDDD, D/MMMM/YYYY")
}
protected void btnCalculate_Click(object sender, EventArgs e)
{
double amount = double.Parse(jmLoanAmount.Text);
double downPay = double.Parse(jmDownPayment.Text);
double interest = double.Parse(jmInterestRate.Text);
int period = int.Parse(jmLoanPeriod.Text);
Double monthlyPay;
Double loanCost;
monthlyPay = ((amount * interest) / 1) - (Math.Pow(1/(1 + interest), period));
loanCost = monthlyPay * (period * 12);
jmMonthlyPayment.Text = monthlyPay.ToString();
jmTotalLoanCost.Text = loanCost.ToString();
}
}
}
Hi, I've written to the point where I do not understand where I am going wrong with my loan calculator. I've input my formula to get the loan amount as...
monthlyPay = ((amount * interest) / 1) - (Math.Pow(1/(1 + interest), period));
I've tried other ways of getting the correct amount, but nothing seems to give me the monthly amount I need. Can someone help me with the formula. Oh an my clock I have on top lol...
jmToday.Caption = Format(Now, "DDDD, D/MMMM/YYYY")
I hate it when teachers teach students to use double for money-related operations. Always use decimal, kids! 128-bit non-floating point goodness (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/decimal)
Anyway, I think I deciphered what your teacher intended with the formula (your comment was ambiguous to say the least). I think you want:
double actualAmountToPay = amount - downPay;
double monthlyPay = actualAmountToPay * interest / (1 - 1 / Math.Pow((1 + interest), period));
double totalCost = monthlyPay * (period * 12);
Leave btnClick handling parsing and move monthly payment calculation to a separate method:
double CalculateMonthlyPayment(double amount, double downPayment, int termInYears, double interestRate)
{
int paymentsCount = MonthsPerYear * termInYears;
double principal = amount - downPayment;
if (interestRate == 0)
{
return principal / paymentsCount;
}
double monthlyRate = interestRate / MonthsPerYear;
double coefficient = Math.Pow(1 + monthlyRate, paymentsCount);
double monthlyPayment = principal * (monthlyRate * coefficient) / (coefficient - 1);
return monthlyPayment;
}
MonthsPerYear is a constant with an obvious value.
TotalPayment will be paymentsCount * MonthlyPayment
Keep in mind that you need to handle exception cases: amount <= 0, downPayment < 0, amount <= downPayment, termInMonths < 1. Also decide if you allow negative interest rate.
My goal is to make this program to take a number of pizzas and types of pizzas and count how much they cost. I decided to go with an object solution. The problem is it doesn't calculate it and it lets the program run even when The fields are empty. I literally have no idea why it doesn't calculate it. I'm also new to objects so there may be some logical mistakes.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Assignment_2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void OrderButton_Click(object sender, EventArgs e)
{
double withTax = 0;
double tax = 0;
double subTotal = 0;
var pizzas = new Pizza[3];
if(ValidateAndDeclareQuantities())
{
pizzas = Declare();
subTotal = CalcSubTotal(pizzas);
tax = CalcTax(pizzas);
withTax = CalcWithTax(pizzas);
}
}
bool ValidateAndDeclareQuantities()
{
var combolist = new List<ComboBox>();
combolist.Add(comboBox1);
combolist.Add(comboBox2);
combolist.Add(comboBox3);
var textboxlist = new List<TextBox>();
textboxlist.Add(Quantity1);
textboxlist.Add(Quantity2);
textboxlist.Add(Quantity3);
for (int i = 0; i < 3; i++)
{
if (combolist[i].Text == "Cheese" || combolist[i].Text == "Vegetable" || combolist[i].Text == "Meat")
{ }
else combolist[i].Text = "Wrong input";
}
int[] Quantities = new int[3];
for (int i = 0; i < 3; i++)
{
if (int.TryParse(textboxlist[i].Text, out Quantities[i])&&textboxlist[i].Text!=null)
{ }
else { textboxlist[i].Text = "Wrong input"; }
}
return true;
}
Pizza[] Declare()
{
var pizzas = new Pizza[3];
string type;
int price;
type = comboBox1.Text;
price = int.Parse(Quantity1.Text);
Pizza pizza1 = new Pizza(type, price);
pizzas[0] = pizza1;
type = comboBox2.Text;
price = int.Parse(Quantity2.Text);
Pizza pizza2 = new Pizza(type, price);
pizzas[1] = pizza2;
type = comboBox3.Text;
price = int.Parse(Quantity3.Text);
Pizza pizza3 = new Pizza(type, price);
pizzas[2] = pizza3;
return pizzas;
}
double CalcSubTotal(Pizza[] pizzas)
{
double subTotal = 0;
for (int i = 0; i < 3; i++)
{
subTotal += pizzas[i].Price;
}
return subTotal;
}
double CalcTax(Pizza[] pizzas)
{
double tax = 0;
for (int i = 0; i < 3; i++)
{
tax += pizzas[i].Tax;
}
return tax;
}
double CalcWithTax(Pizza[] pizzas)
{
double withTax = 0;
for (int i = 0; i < 3; i++)
{
withTax += pizzas[i].WithTax;
}
return withTax;
}
void WriteOut(double subTotal, double tax, double withTax)
{
lblSubTotal.Text = "" + subTotal;
lblTax.Text = "" + tax;
lblTotal.Text = "" + withTax;
}
}
}
And the class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_2
{
class Pizza
{
string type;
int quantity;
public double Price;
public double SubTotal;
public double Tax;
public double WithTax;
public Pizza(string type, int quantity)
{
this.type = type;
this.quantity = quantity;
FindPrice();
CalcSubTotal();
CalcTax();
CalcWithTax();
}
private void FindPrice()
{
switch (type)
{
case "Cheese":
Price = 9.95;
break;
case "Vegetables":
Price = 10.95;
break;
case "Meat":
Price = 11.95;
break;
}
}
private void CalcSubTotal()
{
SubTotal = Price * quantity;
}
private void CalcTax()
{
Tax = SubTotal * 0.13;
}
private void CalcWithTax()
{
WithTax = SubTotal + Tax;
}
}
}
Solution form
The quick answers:
ValidateAndDeclareQuantities never returns false. It should (probably) return false when you set "Wrong Input".
(Minor) int[] Quantities = new int[3]; is never used, aside from writing to it.
(Minor) var pizzas = new Pizza[3]; is also never used. It just gets overwritten by Declare a few lines later. Pizza[] pizzas=null; or just Pizza[] pizzas; is a better alternative. Not the greatest structure here though.
(Minor) Your variable called price in Declare is poorly named as it appears to actually be quantity. Things like this easily throw people off.
WriteOut is never called. withTax, tax and subTotal in OrderButton_Click are probably being computed correctly, but the values aren't being outputted.
The longer answer
It's a bit on the messy side! I appreciate that it's just a learning thing - we've all been there - but good code hygiene is just as important (if not more important) than the structure of the language.
UX: Don't overwrite what the user entered - specifically, don't replace the textbox input with "wrong input"; That's better off going on some other label. I would imagine you've already felt how weird this kind of experience is whilst testing the code.
Named things that don't need a specific class: Like a cheese pizza and a ham one. Enums are your friend! Use them instead of strings like "Cheese":
public enum PizzaType{
Cheese,
Tomato
}
Using enums in this way helps avoid the wonderful world of pain that is unexpected capitalisation and it's considerably faster too. CheEse pizza anyone?
Repetition: Large portions of your code are repetitive too; You'll want to practice avoiding it as much as you can. ('DRY'/ 'Don't Repeat Yourself'). A little forward planning helps massively. Everybody has preferences on code structure; mine here would be a separate "Pizza displayer" class which holds a quantity input box and does the validation too.
Junk: Slightly related to the above, you're creating a bunch of Lists and arrays which get created each time the function is called and then are just chucked out. Create a single array of some more abstract type (like an array of "Pizza displayers") and keep that array as a property on the Form. It's minor here, but being more aware of how much trash your program creates helps make your code go faster.
Notes on floats: You should never, ever use float/ double for money. Use decimal instead, or just do everything in pennies. Floating points aren't precise and you'll hit a rounding issue sooner or later.
I am stuck with this for quite a while. What I want my program to do :
I will have two lists. One of quantity and one of price. I want to multiply two according to their serial(example : quantity[i] * price[i]) and add the multiplication result together and get a specific number lets say I add them and I get 100 but I want 101.123 and the way I want to achieve is adding 0.001 to the first price number (I cant touch the quantity number) and check if it matches the answer I wanted. I cant add more than 5 so if it fails to get the number from the first number I want to move to the second one and leave the first one as it was before. Any one? Here's where i have gotten.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ultimateproject_beginner_ {
class Program {
static List<decimal> QuantityList() {
Console.WriteLine("Quantity");
Console.WriteLine();
List<decimal> quantityList = new List<decimal>();
for (;;) {
string stringQuantityNumber = Console.ReadLine();
decimal quantityNumber = 0M;
if (stringQuantityNumber == "done") {
break;
} else {
if (decimal.TryParse(stringQuantityNumber, out quantityNumber)) {
quantityList.Add(quantityNumber);
}
}
}//end of for loop
return quantityList;
}
static List<decimal> PriceList() {
Console.WriteLine("Price");
List<decimal> priceList = new List<decimal>();
for (;;) {
string stringPriceNumber = Console.ReadLine();
decimal priceNumber = 0M;
if (stringPriceNumber == "done") {
break;
} else {
if (decimal.TryParse(stringPriceNumber, out priceNumber)) {
priceList.Add(priceNumber);
}
}
}//end of for loop
return priceList;
}
static void Main(string[] args) {
List<decimal> quantityList = QuantityList();
List<decimal> priceList = PriceList();
decimal destination = 101.123M;
decimal sum = 0M;
for (int i = 0; i < quantityList.Count; i++) {
decimal product = priceList[i] * quantityList[i];
sum = sum + product;
}
Console.ReadKey(true);
}
}
}
I have tried to make it work with some nested for loops but I get stuck where I have to multiply the new value with all other ones.
What I get: 100, What I want : 101.123 How: by adding 0.001 to priceList and check if the sum is 101.123
One approach to dealing with this is to compute the total on first path, then figure out how many additions you would need, and then perform the adjustments. Note that it is possible that you wouldn't be able to reach the desired target, because the max value that you can add is limited by $0.05 times the total quantity of all items ordered. If the sum is $100, you need $101.23, but the order has only ten items in all, the highest you can get with $0.04 per item is $100.50.
You can compute the total using LINQ:
var total = quantityList.Zip(priceList, (q, p) => q*p).Sum();
Compute the value remaining to be assigned, and go through the individual rows, and do the adjustment until remaining drops to zero:
var remaining = destination - total;
for (int i = 0; remaining > 0 && i < quantityList.Count; i++) {
var quantity = quantityList[i];
// Avoid crashes on zero quantity
if (quantity == 0) {
continue;
}
// We cannot assign more than quantity * 0.05
var toAssign = Math.Min(remaining, quantity * 0.05);
remaining -= toAssign;
// Split the amount being assigned among the items
priceList[i] += toAssign / quantity;
}
if (remaining > 0) {
Console.WriteLine("Unable to distribute {0:C}", remaining);
}
Note: Ideally, you should consider creating a class representing quantity/price pairs, rather than using parallel lists.
After sum is calculated, compare it to destination. If sum < destination, then calculate number of 0.001 increments needed as count = (destination - sum) / 0.001. If this is less than 5, then add this many to the first price, otherwise add five of them (0.005), and then subtract 5 from count. If count > 0 then repeat the process for the second price, etc. If count is greater than pricelist.Count * 5, you can't reach the destination price.
I was able to write this tiny segment of this program to display the numbers in Ascending order but i still cant get it to display it in Descending order.
Basics of what this program should do is takes in two number values from the user in the form of "From" and "To" and displays it as a list in the listbox. The users choice of either ascending or descending order depends on which of the two Radio buttons he has selected.
private void btnCalc_Click(object sender, EventArgs e)
{
double fromNum, toNum, total = 0;
fromNum = double.Parse(txtFrom.Text);
toNum = double.Parse(txtTo.Text);
lstResult.Items.Clear();
lblResult.Text = "";
if (radAsc.Checked)
{
while (fromNum <= toNum)
{
lstResult.Items.Add(fromNum);
total = total + fromNum;
fromNum++;
}
}
else
{
while (fromNum >= toNum)
{
lstResult.Items.Add(fromNum);
total = total + toNum;
toNum--;
}
}
lblResult.Text = total.ToString();
}
Here's an image to what the program looks like.
http://imgur.com/SVwN3Tx
Note:- I am completely new to C# and I've just started taking it in College.
I suggest using for loop instead of while which makes the code easy to implement:
if (radAsc.Checked)
{
// num += 1: - I've seen odds/even switch on the screenshot
// so you may want to change/add num += 1 into num += 2
for (double num = fromNum; num <= toNum; num += 1) {
lstResult.Items.Add(num);
total = total + num;
}
}
else
{
// Descending order:
// - start from the bottom (toNum)
// - loop until the top (fromNum)
// - descend by 1 (num -= 1)
for (double num = toNum; num >= fromNum; num -= 1) {
lstResult.Items.Add(num);
total = total + num;
}
}
You're decrementing the wrong value
while (fromNum >= toNum)
{
lstResult.Items.Add(fromNum);
total = total + toNum;
toNum--;
}
So, here's what you're doing:
Say fromNum is 10, and toNum is 1.
After your first iteration, fromNum is still 10 but toNum is 0. Decrement the fromNum instead of toNum and it should work accordingly.
EDIT
Couple things to take note. If total is collecting the sum of all numbers, a neat way to write:
total = total + value;
is
total += value;.
You should also verify that the numbers will actually work before going into your logic. So if the radio button is selected for Ascending order, you want to make sure fromNum is less than toNum, and maybe throw up a message box if they're not:
if(fromNum < toNum)
{ run logic .... }
else
{ alert user ... }
I am relatively new to C# and am experiencing a problem. My program keeps throwing an error per my try catch. I have looked over everything and changed things, but nothing seems to work. Could it be the reading of the text file? or the array? or the transfer into the listbox? I really need some help with this. It has become nothing but a headache.
............................................................................................................................................................................................................................................................................................................................................................................................................................................................................
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Total_Sales_BBrantley
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnCalc_Click(object sender, EventArgs e)
{
try
{
// Declare variable to hold the amount of sales
// Declare variable to act as the accumulator
const int SIZE = 100;
double[] allSales = new double[SIZE];
double total = 0.0;
double average;
double highest = allSales[0];
double lowest = allSales[2000];
int count = 0;
// Declare a StreamReader variable.
StreamReader readFile;
// Open the file and get a StreamReader object using a relative path
readFile = File.OpenText("Sales.txt");
while (!readFile.EndOfStream && count < allSales.Length)
{
allSales[count] = int.Parse(readFile.ReadLine());
// Increment count
count++;
}
// Close the file
readFile.Close();
lstSales.Items.Add("The file contains " + count + " items:");
for (int index = 0; index < count; index++)
{
lstSales.Items.Add(allSales[index]);
}
// Display the total
double sum = allSales.Sum();
lblTotal.Text = sum.ToString();
total += sum;
average = total / allSales.Length;
lblAverage.Text = average.ToString();
for (int index = 1; index < allSales.Length; index++)
{
if (allSales[index] > highest)
{
highest = allSales[index];
}
lblHighest.Text = highest.ToString();
}
for (int index = 1; index < allSales.Length; index++)
{
if (allSales[index] < lowest)
{
lowest = allSales[index];
}
lblLowest.Text = lowest.ToString();
}
}
catch (Exception)
{
// Display an error message on bad input from file
MessageBox.Show("Error calculating the sales.");
}
}
private void btnExit_Click(object sender, EventArgs e)
{
//Closes the application
this.Close();
}
}
}
I didn't read all your code, but there's an error just at the start:
const int SIZE = 100;
double[] allSales = new double[SIZE];
<snip>
double lowest = allSales[2000];
You've declared the array to have 100 elements, but you're trying to access the 2,000th. Your array isn't that big, so you'll get an IndexOutOfRangeException on that line.
Arrays have fixed sizes in C# once declared. If you need the size to change, use the generic List class.
Bulding on martin_costello's answer, perhaps you could initialize lowest and highest like this:
double highest = double.MinValue;
double lowest = double.MaxValue;
Or at the very least, initialize these values after you have loaded your data!
Also, a tip for debugging: if you're getting an error, either display the error returned by the catch or comment out the try/catch so that you can see the error.
An example of the former:
catch (Exception ex)
{
// Display an error message on bad input from file
MessageBox.Show(string.Concat("Error calculating the sales: ", ex.Message, "\r\n", ex.StackTrace));
}