Calculator using recursion - c#

This is my code and i'm trying to do a basic calculator. Theres just one textbox where i'll be writing two numbers and adding them as well as getting the result in the same textbox like most calculators do.
my problem is that i get an error:
An unhandled exception of type 'System.StackOverflowException'
occurred in WindowsFormsApplication1.exe
after i press button + to write the next number.
public class calculator
{
int acum = 0;
int calcule(int option, int number)
{
switch (option)
{
case 3:
acum = acum + number;
break;
case 4:
acum = acum - number;
break;
case 5:
acum = acum * number;
break;
case 6:
acum = acum / number;
break;
default:
break;
}
if (number == 0)
{
return acum;
}
else
{
return calculate(option, number);
}
}
}
private void btnadd_Click(object sender, EventArgs e)
{
int numero1 = Convert.ToInt32(txtnumber.Text);
calculadora calcular = new calculadora();
txtnumber.Text = calculator.calculate(btnadd.TabIndex, number).ToString();
}
private void btnminus_Click(object sender, EventArgs e)
{
int numero1 = Convert.ToInt32(txtnumber.Text);
calculadora calcular = new calculadora();
txtnumber.Text = calculator.calculate(btnminus.TabIndex, number).ToString();
}
private void button1_Click(object sender, EventArgs e)
{
int number = Convert.ToInt32(txtnumber.Text);
calculadora calcular = new calculadora();
txtnumber.Text = calculator.calculate(button1.TabIndex, number).ToString();
}
private void button2_Click(object sender, EventArgs e)
{
int numero1 = Convert.ToInt32(txtnumber.Text);
calculadora calcular = new calculadora();
txtnumber.Text = calculator.calculate(button2.TabIndex, number).ToString();
}

First of all, there is many problems in your code:
acum is not static, each time you do Calculator calc = new Calculator(); the value is set to zero. So even if there was no error in your code, the result would be number.
The value of the arg number never changes in Calculate method so there is no way you can escape the recursive call once you enter the else here (=> StackOverflowException)
if (number == 0)
{
return acum;
}
else
{
return calculate(option, number);
}
And also Calculate(...) is private... you cannot access it outside the class Calculator
Try this :
enum OperationEnum
{
ADD=3,
SUB=4,
MUL=5,
DIV=6
}
public class Calculator
{
public double Calculate(OperationEnum operation, params int[] operands)
{
if (operands == null)
throw new InvalidOperationException();
if (operands.Length == 0)
return 0;
if (operands.Length == 1)
return operands[0];
switch (operation)
{
case OperationEnum.ADD:
return Add(operands);
case OperationEnum.SUB:
return Subtract(operands);
case OperationEnum.MUL:
return Multiply(operands);
case OperationEnum.DIV:
return Divide(operands);
default:
throw new ArgumentException("operation");
}
}
private double Divide(int[] operands)
{
if (operands.Length == 0)
return 0;
var result = operands[0];
for (int i = 1; i < operands.Length; i++)
{
double divider = operands[i];
if (divider == 0)
{
throw new DivideByZeroException();
}
result /= divider;
}
return result;
}
private double Multiply(int[] operands)
{
if (operands.Length == 0)
return 0;
double result = operands[0];
for (int i = 1; i < operands.Length; i++)
{
result *= operands[i];
}
return result;
}
private double Subtract(int[] operands)
{
if (operands.Length == 0)
return 0;
var result = operands[0];
for (int i = 1; i < operands.Length; i++)
{
result -= operands[i];
}
return result;
}
private int Add(int[] operands)
{
return operands.Sum();
}
}
private double _accumulator = 0;
private void btnadd_Click(object sender, EventArgs e)
{
int numero1 = Convert.ToInt32(txtnumber.Text);
Calculator calcular = new Calculator();
_accumulator = calcular.Calculate(OperationEnum.ADD,_accumulator, number);
txtnumber.Text = _accumulator.ToString()
}

Related

I can't get the textBox_name text and listBox_order items to display correctly in one line on another listbox

I have 3 list boxes, the listBox_menu is where the items are first displayed if buttons (entrees, drinks, and sides) are clicked, then to add the items to order you select your item from the listBox_menu and click add to order to have it appear in the listBox_order. From there once the customer order is ready to be made the submit button will print out the customers name (textBox_name) and all the items in the listBox_order, and display it all in one line.
I'm just having trouble figuring out how to do that, if anyone could please help.
First define two global variables, then use the CalculateTotalCost function (which I defined).
My answer has been updated.
Output (tested in Visual Studio 2017, .Net Framework 4.5.2):
These are my codes:
public Form1()
{
InitializeComponent();
listBox_menu.SelectionMode = SelectionMode.MultiExtended;
}
double Cost = 0;
string Order = null;
public double CalculateTotalCost(object input, bool Total)
{
if (Total == true)
{
switch (input)
{
case "Salad":
Cost += 2500;
break;
case "Rice":
Cost += 3000;
break;
case "non-alcoholic beer":
Cost += 1000;
break;
case "Water":
Cost += 200;
break;
case "Ex1":
Cost += 2200;
break;
default:
Cost += 2200;
break;
}
}
else
{
switch (input)
{
case "Salad":
Cost -= 2500;
break;
case "Rice":
Cost -= 3000;
break;
case "non-alcoholic beer":
Cost -= 1000;
break;
case "Water":
Cost -= 200;
break;
case "Ex1":
Cost -= 2200;
break;
default:
Cost -= 2200;
break;
}
}
return Cost;
}
private void Entrees_Click(object sender, EventArgs e)
{
listBox_menu.Items.Clear();
listBox_menu.Items.Add("Salad");
listBox_menu.Items.Add("Rice");
}
private void Drinks_Click(object sender, EventArgs e)
{
listBox_menu.Items.Clear();
listBox_menu.Items.Add("non-alcoholic beer");
listBox_menu.Items.Add("Water");
}
private void Sides_Click(object sender, EventArgs e)
{
listBox_menu.Items.Clear();
listBox_menu.Items.Add("Ex1");
listBox_menu.Items.Add("Ex2");
}
private void AddtoOrder_Click(object sender, EventArgs e)
{
if(listBox_menu.SelectedItems.Count>0)
{
for (int i = 0; i < listBox_menu.SelectedItems.Count; i++)
{
listBox_order.Items.Add(listBox_menu.SelectedItems[i].ToString());
lblTotalCost.Text = (CalculateTotalCost(listBox_menu.SelectedItems[i].ToString(),true)).ToString();
}
}
}
private void RemoveFromOrder_Click(object sender, EventArgs e)
{
if (listBox_order.SelectedItems.Count > 0)
{
listBox_order.Items.Remove(listBox_order.SelectedItem);
}
Order = null;
for (int i = 0; i < listBox_order.Items.Count; i++)
{
Order += listBox_order.Items[i].ToString() + " , ";
}
Cost = 0;
if (listBox_order.Items.Count > 0)
{
for (int i = 0; i < listBox_order.Items.Count; i++)
{
Cost = (CalculateTotalCost(listBox_order.Items[i], true));
}
}
lblTotalCost.Text = Cost.ToString();
}
private void Submit_Click(object sender, EventArgs e)
{
MessageBox.Show("Customer name: " + txtBoxCustomerName.Text + " Orders: " + Order + " Total cost: " + Cost);
}

How can i use the list in one function which has some data added in another function

So here is my first file QuizzyService:
List<Question> newQuestions = new List<Question>();
public static List<Question> QuizzyServiceQuestions()
{
using (Stream stream = File.Open("..\\Debug\\questions.bin", FileMode.Open))
{
var binaryFormatter = new BinaryFormatter();
return (List<Question>)binaryFormatter.Deserialize(stream);
}
}
int curQuestion = 0;
public Question NewGame(int questionCount)
{
Random r = new Random();
for(int i = 0; i < questionCount; i++)
{
Question x = QuizzyServiceQuestions()[r.Next(0, QuizzyServiceQuestions().Count)];
while (newQuestions.Contains(x))
{
x = QuizzyServiceQuestions()[r.Next(0, QuizzyServiceQuestions().Count)];
}
newQuestions.Add(x);
}
Console.WriteLine(newQuestions.Count);
return newQuestions[0];
}
public int CheckAnswer(int questionId, int answerId)
{
List<int> IdList = new List<int>();
for (int i = 0; i < QuizzyServiceQuestions().Count; i++)
{
IdList.Add(QuizzyServiceQuestions()[i].Id);
}
return IdList.Single(i => i == questionId);
}
public Question GetNextQuestion()
{
curQuestion += 1;
Console.WriteLine(newQuestions.Count);
//Console.WriteLine(curQuestion);
//Console.WriteLine(this.newQuestions.Count);
return newQuestions[curQuestion];
}
Here the relevant part of the xaml.cs file:
private int totalQuestionCount;
private int currentQuestionCount = 1;
private int correctAnswerCount;
Question newQuestion = new Question();
public MainWindow()
{
InitializeComponent();
}
private void btnNewGame_Click(object sender, RoutedEventArgs e)
{
if (!int.TryParse(tbQuestionCount.Text.Trim(), out totalQuestionCount))
{
tblStatus.Text = "Invalid question count!";
return;
}
correctAnswerCount = 0;
tblStatus.Text = string.Empty;
using(WpfQuizzyClient.QuizzyRef.QuizzyServiceClient client = new WpfQuizzyClient.QuizzyRef.QuizzyServiceClient("WSHttpBinding_IQuizzyService"))
{
newQuestion = client.NewGame(Convert.ToInt32(totalQuestionCount));
UpdateUserInterface(newQuestion);
}
}
private void btnAnswer_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
int answerId = -1;
switch (button.Name)
{
case "btnAnswerA": answerId = 0; break;
case "btnAnswerB": answerId = 1; break;
case "btnAnswerC": answerId = 2; break;
case "btnAnswerD": answerId = 3; break;
default:
// This should never happen
MessageBox.Show("Invalid button name detected - contact support!");
return;
}
using (WpfQuizzyClient.QuizzyRef.QuizzyServiceClient client = new WpfQuizzyClient.QuizzyRef.QuizzyServiceClient("WSHttpBinding_IQuizzyService"))
{
if (answerId == client.CheckAnswer(newQuestion.Id, answerId))
{
tblStatus.Text = string.Empty;
tblStatus.Text = "Correct! Total: " + currentQuestionCount + " / " + totalQuestionCount;
currentQuestionCount += 1;
UpdateUserInterface(client.GetNextQuestion());
}
else
{
tblStatus.Text = string.Empty;
UpdateUserInterface(client.GetNextQuestion());
}
}
My problem is that when i trigger btnAnswer_Click it doesnt have the list which has been created in NewGame but im not allowed to do something like NextQuestion(Question questionList)
If you need more info just tell me and i'll make sure to provide more as quickly as possible!
i found the fix ... i just had to remove both using and add the "WpfQuizzyClient.QuizzyRef.QuizzyServiceClient client = new WpfQuizzyClient.QuizzyRef.QuizzyServiceClient("WSHttpBinding_IQuizzyService")" before the MainWindow()

freezing form after clicking button

I have a problem regarding to payment button.
I don't encounter an error before building, but after building and clicking the payment button it hangs. I think its because of lblTotalPrice.text, but I don't know how to fix it.
public partial class Form1 : Form
{
int totalCost;
public double holDer;
public Form1()
{
InitializeComponent();
this.cbo1.Items.AddRange(new object[] { "Lechon Kawali - 200", "Bicol Express - 300"
,"Adobo - 350" });
}
private void btnAdd_Click(object sender, EventArgs e)
{
lb1.Items.Add(cbo1.SelectedItem);
lb1.SelectedIndex = lb1.SelectedIndex ;
int z = 0;
if (cbo1.SelectedIndex == 0)
{
z = z + 1;
}
if (cbo1.SelectedIndex == 1)
{
z = z + 2;
}
if (cbo1.SelectedIndex == 2)
{
z = z + 3;
}
switch(z)
{
case 1:
totalCost = totalCost + 200;
break;
case 2:
totalCost = totalCost + 300;
break;
case 3:
totalCost = totalCost + 350;
break;
}
lblSubTotalCost.Text = ("Php " + totalCost.ToString());
}
private void btnDelete_Click(object sender, EventArgs e)
{
int deleteCost = 0;
int itemCost = 0;
foreach (int selectedIndex in lb1.SelectedIndices)
{
itemCost = int.Parse(lb1.Items[selectedIndex].ToString().Split('-')[1]);
deleteCost += itemCost; lb1.Items.RemoveAt(selectedIndex);
}
totalCost = totalCost - deleteCost;
lblSubTotalCost.Text = ("Php " + totalCost.ToString());
lb1.Items.Remove(lb1.SelectedItem);
if (lb1.Items.Count > 0)
{
lb1.SelectedIndex = 0;
}
else
MessageBox.Show("No orders");
}
private void lblVAT_TextChanged(object sender, EventArgs e)
{
Add();
}
private void lblSubTotalCost_TextChanged(object sender, EventArgs e)
{
multiply();
Add();
}
public void multiply()
{
int a;
double b = 0.12;
bool Valid = int.TryParse(totalCost.ToString(), out a);
if (Valid)
lblVAT.Text = (a * b).ToString();
else
lblVAT.Text = "No VAT entered";
}
private void lbTotalPrice_TextChanged(object sender, EventArgs e)
{
Add();
}
public void Add()
{
int a;
int b;
bool AValid = int.TryParse(totalCost.ToString(), out a);
bool BValid = int.TryParse(lblVAT.Text, out b);
if (AValid && BValid)
{
lblTotalPrice.Text = ("Php " + (a + b).ToString());
}
}
private void btnPayment_Click(object sender, EventArgs e)
{
holDer = double.Parse(tbPayment.Text) - double.Parse(lblTotalPrice.Text);
MessageBox.Show("Change: " + holDer.ToString());
}
}
As you stated in your comments, your problem it is not that your application hangs, but the problem is that you are getting a Input string was not in a correct format Exception.
That it seems is from this block:
private void btnPayment_Click(object sender, EventArgs e)
{
holDer = double.Parse(tbPayment.Text) - double.Parse(lblTotalPrice.Text);
MessageBox.Show("Change: " + holDer.ToString());
}
As it is a not very complex code, your problem seems to be when you are casting your textboxes to Double. Be sure that you are using the correct separator for double values and that you not have any strange characters in tbPayment
Try using TryParse method:
double res;
if(double.TryParse(tbPayment.Text, out res))
{
holDer = res - double.Parse(lblTotalPrice.Text);
MessageBox.Show("Change: " + holDer.ToString());
}
else
{
MessageBox.Show("Input a correct format");
}
I suspect it's because the lblTotalPrice_TextChanged event-handler calls Add() which then changes the lblTotalPrice.Text property, causing the event to fire again, ad -infinitum?

Multiplication in C# WPF

I'm trying to make a program that generates 2 random numbers, then, after the user inputs the multiplication of those numbers, it will tell the user in a MessageBox whether or not the user was right or wrong. Sort of like an educational simulator.
I'm having problems with the end part. What I'm saying is; If the answer is the same as number1 and number2 multiplied, then it says; "Rétt!" and if not; "Rangt..."
Any ideas?
private void bt_end_Click(object sender, RoutedEventArgs e)
{
int number1 = 0;
int number2 = 0;
int answer = 0;
tbnumber1.Text = number1.ToString();
tbnumber2.Text = number2.ToString();
if (svar == (number1 * number2))
{
MessageBox.Show("Rétt!");
}
else
{
MessageBox.Show("Rangt...");
}
}
}
}
The full code.
public MainWindow()
{
InitializeComponent();
}
int tala1 = 0;
int tala2 = 0;
int svar = 0;
private void btstart_Click(object sender, RoutedEventArgs e)
{
tbtala1.Text = "";
tbtala2.Text = "";
tbsvar.Text = "";
Random random = new Random();
tala1 = random.Next(1, 11);
tala2 = random.Next(1, 11);
tbtala1.Text = tala1.ToString();
tbtala2.Text = tala2.ToString();
}
private void btend_Click(object sender, RoutedEventArgs e)
{
tbtala1.Text = tala1.ToString();
tbtala2.Text = tala2.ToString();
tbsvar.Text = svar.ToString();
if (svar == (tala1 * tala2).ToString())
{
MessageBox.Show("Rétt!");
}
else
{
MessageBox.Show("Rangt... :(");
}
}
}
}
SOLVED. Thank you to everyone who did/tried to help.
Final Version:
Final Version:
public MainWindow()
{
InitializeComponent();
}
int tala1 = 0;
int tala2 = 0;
int svar = 0;
private void btstart_Click(object sender, RoutedEventArgs e)
{
tbtala1.Text = "";
tbtala2.Text = "";
tbsvar.Text = "";
Random random = new Random();
tala1 = random.Next(1, 11);
tala2 = random.Next(1, 11);
tbtala1.Text = tala1.ToString();
tbtala2.Text = tala2.ToString();
}
private void btend_Click(object sender, RoutedEventArgs e)
{
tala1 = Convert.ToInt32(tbtala1.Text);
tala2 = Convert.ToInt32(tbtala2.Text);
svar = Convert.ToInt32(tbsvar.Text);
if (svar == (tala1 * tala2))
{
MessageBox.Show("Rétt!");
}
else
{
MessageBox.Show("Rangt... :(");
}
To do this in a safe manner, you should not only Parse the text inputs to numbers, but you should also ensure that the text does in fact contain numbers first. If your numbers are supposed to be integers then you could use this:
private void bt_end_Click(object sender, RoutedEventArgs e)
{
int number1 = 0;
int number2 = 0;
if (int.TryParse(tbnumber1.Text, out number1) ||
int.TryParse(tbnumber12.Text, out number2)) MessageBox.Show("Rangt...");
MessageBox.Show(svar == number1 * number2 ? "Rétt!" : "Rangt...");
}
You're putting the numbers in the textbox values. you have to convert textbox values to numbers.
private void btend_Click(object sender, RoutedEventArgs e)
{
try{
tala1 = Convert.ToInt32(tbtala1.Text);
tala2 = Convert.ToInt32(tbtala2.Text);
svar = Convert.ToInt32(tbsvar.Text);
if (svar == (tala1 * tala2))
{
MessageBox.Show("Rétt!");
}
else
{
MessageBox.Show("Rangt... :(");
}
}catch{
MessageBox.Show("Invalid input");
}
}
You never define svar. You probably meant something like this, assuming svar was set earlier and is the correct product of the random multiplication:
private void bt_end_Click(object sender, RoutedEventArgs e)
{
int number1 = 0;
int number2 = 0;
number1 = int.Parse(tbnumber1.Text);
number2 = int.Parse(tbnumber2.Text);
if (svar == (number1 * number2))
{
MessageBox.Show("Rétt!");
}
else
{
MessageBox.Show("Rangt...");
}
}
1.I observed that you have not initialized variable 'svar' anywhere.
Initialise your svar variable with proper value.
2.Replace This :
if (svar == (number1 * number2).ToString())
With Following :
if (svar == (number1 * number2))

How Do I make my ProgressBar work?

I'm making a Windows Form Application with VS 2010. I've added a ProgressBar to my form, and I change its value. However, the ProgressBar does not advance or change. I think one of the reasons is because the process is too fast, but I made it slow and it didn't work either.
Here's the code:
void pn_TenPercentProgressEvent(object sender, PrimeNumberEventArgs e)
{
probarPrimeNumber.Visible = true;
probarPrimeNumber.Value = (int)e.Percent * 100;
this.Refresh();
}
this is the class that event occurs:
public ulong[] Generate(int count)
{
ulong[] ulngaryResult = new ulong[count];
switch (count)
{
case 0:
{
throw new Exception("The Zero is NOT Permitted.");
}
case 1:
{
ulngaryResult[0] = 2;
break;
}
case 2:
{
ulngaryResult[1] = 3;
goto case 1;
}
default:
{
int intIndex = 0;
double dblPercent = 0.1;
for (ulong i = 2; i < ulong.MaxValue; i++)
{
if (this.IsPrime(i))
{
ulngaryResult[intIndex] = i;
intIndex++;
}
if (intIndex == (int)(dblPercent * count))
{
//Raise TenPercentProgressEvent
if (TenPercentProgressEvent != null) //Optional Event
{
TenPercentProgressEvent((object)this, new PrimeNumberEventArgs(intIndex, count, dblPercent));
}
dblPercent += 0.1;
}
if (intIndex == count)
{
//Raise FinishedProgressEvent
if (FinishedProgressEvent != null) //Optional Event
{
FinishedProgressEvent((object)this, new PrimeNumberEventArgs(intIndex, count, dblPercent));
}
break;
}
}
break;
}
}
return ulngaryResult;
}
Try (int)(e.Percent * 100). As it is, casting to int before multiplying by 100 rounds to either 0 or 1 - which then translates into either 0% or 100%, all the time, but never in between.

Categories

Resources