C# WinAppCalculator to WebAppCalculator - c#

Hi I am pretty new to coding especially in c# and have a problem with my project. I am looking to make a calculator online using c# and upload it to a database and host in azure. Here is my question:
I am having a problem with my c# code in Visual Studio using web forms. It is simply not working, It can input numbers and operations however does not get the correct result e.g. 3 + 3 = 33. This is a conversion from WinApp, so it may be from there? But I re-created the UI and repurposed the code to fit a online app. After I get this to work I plan on uploading it to azure. Is there any reason why this is not working? My WinApp in .NET has a very similar code and works so is it a .NET/ASP.net issue? Any help is appreciated!
Here is the .aspx.cs file:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class WebForm1 : Page
{
protected void Page_Load(object sender, EventArgs e)
{
ViewState["operationPerf"] = "false";
ViewState["operation"] = string.Empty;
ViewState["answer"] = "0";
}
protected void NumbEvent(object sender, EventArgs e)
{
if (textbox.Text == "0" || bool.Parse(ViewState["operationPerf"].ToString()) == true)
textbox.Text = string.Empty;
Button butt = (Button)sender;
textbox.Text += butt.Text;
ViewState["operationPerf"] = false;
label.Text = label.Text + " " + textbox.Text;
}
protected void OperandEvent(object sender, EventArgs e)
{
ViewState["operationPerf"] = true;
Button butt = (Button)sender;
string newOperand = butt.Text;
label.Text = label.Text + " " + newOperand;
switch (ViewState["operation"])
{
case "+":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(Double.Parse(Convert.ToString(ViewState["answer"])), Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
ViewState["answer"] = textbox.Text;
ViewState["operation"] = newOperand;
}
protected void Bequal_Click(object sender, EventArgs e)
{
ViewState["operationPerf"] = true;
switch (ViewState["operation"])
{
case "+":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(Double.Parse(Convert.ToString(ViewState["answer"])), Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
label.Text = label.Text + " = " + textbox.Text;
label.Text = "";
ViewState["answer"] = textbox.Text;
textbox.Text = ViewState["answer"].ToString();
ViewState["answer"] = 0;
ViewState["operation"] = "";
}
protected void BC_Click(object sender, EventArgs e)
{
textbox.Text = "0";
label.Text = "";
ViewState["answer"] = 0;
ViewState["operation"] = "";
}
}
This is my original code before attempting to fix the issue:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication2
{
public partial class WebForm1 : Page
{
bool operationPerf = false;
string operation = "";
double answer = 0;
protected void NumbEvent(object sender, EventArgs e)
{
if (textbox.Text == "0" || operationPerf)
textbox.Text = string.Empty;
Button butt = (Button)sender;
textbox.Text += butt.Text;
operationPerf = false;
label.Text = label.Text + " " + textbox.Text;
}
protected void OperandEvent(object sender, EventArgs e)
{
operationPerf = true;
Button butt = (Button)sender;
string newOperand = butt.Text;
label.Text = label.Text + " " + newOperand;
switch (operation)
{
case "+":
textbox.Text = (answer + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (answer - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (answer * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (answer / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(answer, Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
answer = Double.Parse(textbox.Text);
operation = newOperand;
}
protected void Bequal_Click(object sender, EventArgs e)
{
operationPerf = true;
switch (operation)
{
case "+":
textbox.Text = (answer + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (answer - Double.Parse(textbox.Text)).ToString();
break;
case "*":
textbox.Text = (answer * Double.Parse(textbox.Text)).ToString();
break;
case "/":
textbox.Text = (answer / Double.Parse(textbox.Text)).ToString();
break;
case "^":
textbox.Text = (Math.Pow(answer, Double.Parse(textbox.Text))).ToString();
break;
case "√":
textbox.Text = (Math.Sqrt(Double.Parse(textbox.Text))).ToString();
break;
default:
break;
}
label.Text = label.Text + " = " + textbox.Text;
label.Text = "";
answer = Double.Parse(textbox.Text);
textbox.Text = answer.ToString();
answer = 0;
operation = "";
}
protected void BC_Click(object sender, EventArgs e)
{
textbox.Text = "0";
label.Text = "";
answer = 0;
operation = "";
}
}
}

If you're getting 33 as the result of 3 + 3 then that suggests to me that you're using the + operator on two strings (or maybe a string and a number) rather than two numbers, i.e. the + operator is doing string concatenation rather than addition.
If you use the + operator on two numbers (types such as int, float, double, decimal) then it adds the two numbers together as you'd expect.
However, if you use the + operator on
two strings, or
a string and an instance of something which has an implementation of the ToString method (which means pretty much anything which isn't a struct, because all classes in .net are derived from object, which has a ToString method)
then it concatenates the two strings, or the string and the return value of the other object's ToString method. (* see footnote)
I can't see in the code where this is happening, but I'd suggest a bit of refactoring which would make it easier to track down.
This switch block has quite a lot of repetition:
switch (ViewState["operation"])
{
case "+":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) + Double.Parse(textbox.Text)).ToString();
break;
case "-":
textbox.Text = (Double.Parse(Convert.ToString(ViewState["answer"])) - Double.Parse(textbox.Text)).ToString();
break;
All those calls to Double.Parse are going to return the same two values, regardless of which one is executed, so only make the calls once and cache the result, e.g.
var answer = Double.Parse(Convert.ToString(ViewState["answer"]));
var textboxValue = Double.Parse(textbox.Text);
switch (ViewState["operation"])
{
case "+":
textbox.Text = (answer + textboxValue).ToString();
break;
case "-":
textbox.Text = (answer - textboxValue).ToString();
break;
This gives you shorter lines, easier to read, easier to spot any mistakes, and importantly there are fewer nested brackets. Transposing a bracket and a comma in a long and complex line of code, in the best case scenario causes a compiler error, but if it doesn't then it can cost hours of investigating why the application is misbehaving.
I also notice that this entire switch block appears to be repeated in both the OperandEvent and Bequal_Click methods. Do you need it in both? I can't tell from looking at the posted code, but it's something I'd suggest you think about. If you do need it in both, and it needs to behave identically in both, then move it into its own private method, and call that method from the OperandEvent and Bequal_Click methods.
May I draw your attention to the Don't Repeat Yourself principle of software development?
OF ALL THE PRINCIPLES OF PROGRAMMING, Don’t Repeat Yourself (DRY) is perhaps one of the most fundamental. The principle was formulated by Andy Hunt and Dave Thomas in The Pragmatic Programmer, and underlies many other well-known software development best practices and design patterns. The developer who learns to recognize duplication, and understands how to eliminate it through appropriate practice and proper abstraction, can produce much cleaner code than one who continuously infects the application with unnecessary repetition.
Duplication Is Waste
Every line of code that goes into an application must be maintained, and is a potential source of future bugs. Duplication needlessly bloats the codebase, resulting in more opportunities for bugs and adding accidental complexity to the system. The bloat that duplication adds to the system also makes it more difficult for developers working with the system to fully understand the entire system, or to be certain that changes made in one location do not also need to be made in other places that duplicate the logic they are working on. DRY requires that “every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”
Any time you find yourself writing more or less the same block of code more than once, you should ask yourself, "can I refactor this code into a new, shorter line, a new reusable method, or maybe even a new class?"
I hope you find this answer helpful, and wish you the best of luck in your studies.
Footnote
What I said about the behaviour of the + operator isn't the whole truth, because a class can explicitly define how the + and other operators behave when applied to an instance of that class (this is known as operator overloading). But you say you're new to programming, and this detail isn't really relevant to this question, so don't worry about it for now.

Related

C# Calculator, Equal button won't perform operation on second click

I'm building calculator (similar to win10 standard calculator), and problem is when you click equal button twice or more. I'm getting second argument from textBox and every time you click equal button it changes it's text value.
e.g when you type 10 + 5 = 15 and then you press button again it shows 25 instead of 20 and so on.
private void buttonEqual(object sender, EventArgs e)
{
secondArg = Convert.ToDouble(textBox1.Text);
switch (oper) {
case "+":
result = firstArg + Convert.ToDouble(label7.Text);
textBox1.Text = result.ToString();
label3.Text = firstArg.ToString();
break;
case "-":
result = firstArg - secondArg;
textBox1.Text = result.ToString();
label3.Text = result.ToString();
break;
case "*":
result = firstArg * secondArg;
textBox1.Text = result.ToString();
label3.Text = result.ToString();
break;
case "/":
result = firstArg / secondArg;
textBox1.Text = result.ToString();
label3.Text = result.ToString();
break;
case "^":
result = Math.Pow(firstArg, secondArg);
textBox1.Text = result.ToString();
break;
In your + case, you set label3.Text = firstArg.ToString();. In all the other cases shown you set it equal to result. Set label3.Text = result.ToString(); to fix.
You also don't use secondArg in the + case, this might be contributing to your issue as well.

Switch statement using text box within forms

I am building a form that takes an input number from a text box and then will take the number that was input, and display the roman numeral equivalent in another text box.
My Form:
private void convertButton_Click(object sender, EventArgs e)
{
int numberInput;
switch (numberInput)
This is where I keep getting an error code. The "switch (numberInput)" is seen as and unassigned local variable. How do I assign it so that it will be able to access all of the case integers?
{
case 1:
outputTextBox.Text = "I";
break;
case 2:
outputTextBox.Text = "II";
break;
case 3:
outputTextBox.Text = "III";
break;
case 4:
outputTextBox.Text = "IV";
break;
case 5:
outputTextBox.Text = "V";
break;
case 6:
outputTextBox.Text = "VI";
break;
case 7:
outputTextBox.Text = "VII";
break;
case 8:
outputTextBox.Text = "VIII";
break;
case 9:
outputTextBox.Text = "IX";
break;
case 10:
outputTextBox.Text = "X";
break;
default:
MessageBox.Show("Please enter and number between 1 and 10. Thank you!");
break;
}
Cause your variable is not assigned yet int numberInput; and so the error. You said input is coming from a TextBox, in that case do like below assuming textbox1 is your TextBox control instance name
int numberInput = Convert.ToInt32(this.textbox1.Text.Trim());
Convert.ToInt32 may throw an exception if the parsing is unsuccessful. Another method is to Int.Parse:
int numberInput = int.Parse(textbox1.Text.Trim());
or better yet
int numberInput;
if(int.TryParse(textbox1.Text.Trim(), out numberInput))
{
switch (numberInput)
...
}

How can I find the last character of a textbox text?

I am a beginner in C#. I am making a web calculator like Microsoft Desktop calculator with the help of asp.net. But I'm stuck at one place. My code for Plus, minus, multiply or div is like:
protected void btnPlus_Click(object sender, EventArgs e)
{
if (txtBox1.Text.EndsWith("+"))
{
txtBox1.Text = txtBox1.Text;
}
else
{
txtBox1.Text = txtBox1.Text + "+";
ViewState["Operation"] = "+";
}
}
But I want to check this condition for all operations like minus, multiply and divide. I don't want Plus, Minus, Multiply or Div signs appear in the textbox.
You can store all your operators in a string constant and check if the last character is contained in that string:
private const string OPERATORS = "+-/*";
protected void btnPlus_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtBox1.Text) || // check if string is empty
OPERATORS.Contains(txtBox1.Text.Last())) // or if last character is a operator
{
txtBox1.Text = txtBox1.Text;
}
else
{
txtBox1.Text = txtBox1.Text + "+";
ViewState["Operation"] = "+";
}
}
You can do something like the following:
Extract last character
Based on the character assign operator to the view state
If it is any operator then remove them from the textbox
Finally do the operation
if (txtBox1.Text != "")
{
char last_char = txtBox1.Text[txtBox1.Text.Length - 1];
switch (last_char)
{
case '+':
ViewState["Operation"] = "+";
txtBox1.Text.Remove(txtBox1.Text.Length - 1);
break;
case '-':
ViewState["Operation"] = "-";
txtBox1.Text.Remove(txtBox1.Text.Length - 1);
break;
// do the same for all operators
default:
break;
}
}

Cannot calculate decimals in my calculator

So, I have made a calculator in C# but it cannot calculate decimal numbers.
It works perfectly fine when clicking on for example the buttons: 6 then . (this is a dot) then 5. But as soon as I click on the "+"-button (or any other operator) afterwards in the form, the program stops and I get a message saying that
"An unhandled exception of type 'System.FormatException' occured in
mscorlib.dll. The input string was not in a correct format".
I don't know exactly how to solve this. Is there anyone that knows how to solve this problem?
Here is my code:
namespace Kalkylator{
public partial class Form1 : Form{
String operation = ""; //the operation we will use
Double resultat = 0; //the result we will get
bool finished = false; //if false, we have not pressed the "=" button yet
public Form1(){
InitializeComponent();
}
//
private void button_click(object sender, EventArgs e){
if (finished == true){ //if we press any operator, clear the textbox-window so new numbers can be entered
textBoxFonster.Clear();
}
finished = false; //we are not done with the calculation
Button b = (Button)sender;
if (b.Text == "."){
if (!textBoxFonster.Text.Contains(".")){
textBoxFonster.Text = textBoxFonster.Text + b.Text;
}
}
else{
textBoxFonster.Text = textBoxFonster.Text + b.Text; //writes the number in the textBox
}
}
private void operator_click(object sender, EventArgs e)
{
Button b = (Button)sender;
operation = b.Text; //the operation we will perform is the operatorButton we will press
resultat = Double.Parse(textBoxFonster.Text); //HERE IS WHERE THE PROGRAM GIVES ME THE ERROR.
finished = true; //we are done with the calculation
}
private void clear_click(object sender, EventArgs e)
{
textBoxFonster.Text = ""; //clear the window from all text
resultat = 0; //clear the value of resultat and set it to 0
}
private void LikaMed_click(object sender, EventArgs e)
{
switch(operation){
case "+": //add the result with the text in the textBox
textBoxFonster.Text = (resultat + Double.Parse(textBoxFonster.Text)).ToString();
break;
case "-":
textBoxFonster.Text = (resultat - Double.Parse(textBoxFonster.Text)).ToString();
break;
case "*":
textBoxFonster.Text = (resultat * Double.Parse(textBoxFonster.Text)).ToString();
break;
case "%":
textBoxFonster.Text = (resultat / Double.Parse(textBoxFonster.Text) * (resultat/100)).ToString();
break;
case "^":
textBoxFonster.Text = (Math.Pow(resultat, Double.Parse(textBoxFonster.Text))).ToString();
break;
case "Log": //takes the 10th log of resultat
textBoxFonster.Text = (Math.Log10(resultat)).ToString();
break;
case "Sqrt":
textBoxFonster.Text = (Math.Sqrt(resultat)).ToString();
break;
case "/": //divide the result with the text in the textBox if that text is not 0. If so, show an error message
if ((Double.Parse(textBoxFonster.Text)) != 0){
textBoxFonster.Text = (resultat / Double.Parse(textBoxFonster.Text)).ToString();
}
else{ //show error in MessageBox
MessageBox.Show("Cannot divide by 0!");
}
break;
default:
break;
}
finished = true; //this will clear the result textbox when clicking another number after the equal sign has been clicked
}
}
}
Don't use Double.Parse without specifying the Culture.
Change:
switch(operation){
case "+": //add the result with the text in the textBox
textBoxFonster.Text = (resultat + Double.Parse(textBoxFonster.Text)).ToString();
break;
case "-":
textBoxFonster.Text = (resultat - Double.Parse(textBoxFonster.Text)).ToString();
break;
to:
Double operand1=resultat;
Double operand2=0;
Double.TryParse(textBoxFonster.Text,NumberStyles.Float,CultureInfo.InvariantCulture,out operand2);
switch(operation){
case "+": //add the result with the text in the textBox
textBoxFonster.Text = (operand1 + operand2).ToString();
break;
case "-":
textBoxFonster.Text = (operand1 - operand2).ToString();
break;
Alternatively, you could actually support multiple cultures, and change this code:
if (b.Text == "."){
if (!textBoxFonster.Text.Contains(".")){
textBoxFonster.Text = textBoxFonster.Text + b.Text;
}
}
to this:
if (b.Text == System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator){
if (!textBoxFonster.Text.Contains(System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)){
textBoxFonster.Text = textBoxFonster.Text + b.Text;
}
}

Listbox unassigned variable

Full disclosure here, I am a student doing homework. I have 2 listboxes with items that can be selected. What is said in them is not needed to be extracted. I wrote the code out and everything works except I get an error saying "use of unassigned variable" on 3 variables at the end of the code. They are locFees, days, and registration. Can anyone tell me what I am doing wrong that is causing the variables to not have a value?
private void btnCalc_Click(object sender, EventArgs e)
{
double registration, lodging, total, days, locFees;
int workshopIndex, locationIndex;
if (lbWorkshop.SelectedIndex != -1)
{
workshopIndex = lbWorkshop.SelectedIndex;
switch (workshopIndex)
{
case 0:
days = 3;
registration = 1000;
break;
case 1:
days = 3;
registration = 800;
break;
case 2:
days = 3;
registration = 1500;
break;
case 3:
days = 5;
registration = 1300;
break;
case 4:
days = 1;
registration = 500;
break;
}
}
else
{
MessageBox.Show("You didn't select a workshop.");
}
if (lbLocation.SelectedIndex != -1)
{
locationIndex = lbLocation.SelectedIndex;
switch (locationIndex)
{
case 0:
locFees = 150;
break;
case 1:
locFees = 225;
break;
case 2:
locFees = 175;
break;
case 3:
locFees = 300;
break;
case 4:
locFees = 175;
break;
case 5:
locFees = 150;
break;
}
}
else
{
MessageBox.Show("You didn't select a city.");
}
lodging = locFees * days;
total = registration + lodging;
}
Can anyone tell me what I am doing wrong that is causing the variables to not have a value?
Sure - you're ignoring the possibility that workshopIndex isn't 0, 1, 2, 3 or 4.
If you believe that should never happen, just add:
default:
throw new InvalidOperationException("Invalid selected index " + workshopIndex);
Or if you just want to use some defaults, do something like:
default:
days = 1;
registration = 100;
break;
That's the first way you can end up with days and registration unassigned.
Next, there's the fact that you only go into the switch block at all if lbWorkshop.SelectedIndex != -1. Your else block is just:
else
{
MessageBox.Show("You didn't select a workshop.");
}
... so after that else block, you're going to continue. You probably want:
else
{
MessageBox.Show("You didn't select a workshop.");
return;
}
You've then got the same problem for locFees, in terms of both the switch statement and the else block.
One thing to learn from this: be grateful that the compiler spotted these for you. It's stopped you from running code which definitely had bugs in. That's always a good thing.

Categories