So now we have the code better engineered for refactoring. It is time to start breaking down the code we have into functions. Before we start, I can already read the hate mail. Yes, we will get to object oriented programming. We are just going small bits at a time so everyone has time to let the stuff they learned sink it. Without further nonsense, lets dig into Noob to Pro Functions.
Lets talk about functions in the context of Noob to Pro series.
Because we are trying to take the next step up on the programming skills hierarchy, we need to get the repetition out of this code. When analyzing this code, we are looking for things that repeat. If it feels like you should cut and paste for you to code that same solution that is a pretty good candidate to look into turning it into a function. Lets see where we can do that in the code.
using System; using System.Windows.Forms; namespace NoobToPro { public partial class FormCalc : Form { string value1 = ""; string value2 = "" ; string results = "" ; string sign = ""; bool isValue2 = false; public FormCalc() { InitializeComponent(); } private void btn7_Click(object sender, EventArgs e) { if(!isValue2) { value1 += "7"; results = ""; txtInput.Text = value1; } else { value2 += "7"; txtInput.Text = value2; } } private void btn8_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "8"; results = ""; txtInput.Text = value1; } else { value2 += "8"; txtInput.Text = value2; } } private void btn9_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "9"; results = ""; txtInput.Text = value1; } else { value2 += "9"; txtInput.Text = value2; } } private void btn4_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "4"; results = ""; txtInput.Text = value1; } else { value2 += "4"; txtInput.Text = value2; } } private void btn5_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "5"; results = ""; txtInput.Text = value1; } else { value2 += "5"; txtInput.Text = value2; } } private void btn6_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "6"; results = ""; txtInput.Text = value1; } else { value2 += "6"; txtInput.Text = value2; } } private void btn1_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "1"; results = ""; txtInput.Text = value1; } else { value2 += "1"; txtInput.Text = value2; } } private void btn2_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "2"; results = ""; txtInput.Text = value1; } else { value2 += "2"; txtInput.Text = value2; } } private void btn3_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "3"; results = ""; txtInput.Text = value1; } else { value2 += "3"; txtInput.Text = value2; } } private void btn0_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "0"; results = ""; txtInput.Text = value1; } else { value2 += "0"; txtInput.Text = value2; } } private void btnPeriod_Click(object sender, EventArgs e) { if (!isValue2) { value1 += "."; results = value1; txtInput.Text = value1; } else { value2 += "."; txtInput.Text = value2; } } private void btnDivide_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "/"; } private void btnMultiply_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "*"; } private void btnSubtract_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "-"; } private void btnAdd_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "+"; } private void btnEquals_Click(object sender, EventArgs e) { switch (sign) { case "+": results = (Decimal.Parse(value1) + Decimal.Parse(value2)).ToString(); break; case "-": results = (Decimal.Parse(value1) - Decimal.Parse(value2)).ToString(); break; case "*": results = (Decimal.Parse(value1) * Decimal.Parse(value2)).ToString(); break; case "/": results = (Decimal.Parse(value1) / Decimal.Parse(value2)).ToString(); break; } value1 = ""; value2 = ""; txtInput.Text = value1; isValue2 = false; lblResult.Text = results; } private void FormCalc_Load(object sender, EventArgs e) { lblResult.Text = ""; } } }
Take a moment and look at the code. Do you see something that was likely created using copy and paste?
If not, I promise you it is there. If you still cannot get it don’t worry that is what this post is trying to teach.
Where’s Wal….I mean, Functionable code?
If you notice that in each button we have a pattern. An if statement checking if it is value 1 or 2. Then logic for value 1 setting that involves appending the value. Resetting the results to empty string and displaying the new value in the textbox. Then we have similar logic setting value 2. We could totally take that pattern, factor out the differences between the code block and create a function.
We are about to really shrink the size of this program.
First create a bs function with no return. We don’t want to worry about anything other then setting up the pattern. We will clean it up in a second. After your create your bs function, I called mine bob. Copy and past button 7 code into it.
private void bob() { if (!isValue2) { value1 += "7"; results = ""; txtInput.Text = value1; } else { value2 += "7"; txtInput.Text = value2; } }
Here is are new function. Now we need to factor out the differences. These differences are tied to the number 7 string. So lets move it to the parameter list and call it number.
Now the function has been generalized so we want to give it a name to describe what it is doing. How about setValueAndUpdateDisplay.
private void setValueAndUpdateDisplay(string number) { if (!isValue2) { value1 += number; results = ""; txtInput.Text = value1; } else { value2 += number; txtInput.Text = value2; } }
Implementing the new functions
With our function done, lets pull out the duplicate code and replace it with out function and the parameter that will represent the number of the button.
Now when we continue making edits to the code, that part of the code is located in only one place. Before a single change to that block of code would require 10 separate changes with 10 chances of introducing errors. We eliminated that with the new function. Our exposure is know only 1 place to introduce potential errors.
using System; using System.Windows.Forms; namespace NoobToPro { public partial class FormCalc : Form { string value1 = ""; string value2 = "" ; string results = "" ; string sign = ""; bool isValue2 = false; public FormCalc() { InitializeComponent(); } private void setValueAndUpdateDisplay(string number) { if (!isValue2) { value1 += number; results = ""; txtInput.Text = value1; } else { value2 += number; txtInput.Text = value2; } } private void btn7_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("7"); } private void btn8_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("8"); } private void btn9_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("9"); } private void btn4_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("4"); } private void btn5_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("5"); } private void btn6_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("6"); } private void btn1_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("1"); } private void btn2_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("2"); } private void btn3_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("3"); } private void btn0_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("0"); } private void btnPeriod_Click(object sender, EventArgs e) { setValueAndUpdateDisplay("."); } private void btnDivide_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "/"; } private void btnMultiply_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "*"; } private void btnSubtract_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "-"; } private void btnAdd_Click(object sender, EventArgs e) { txtInput.Text = ""; isValue2 = true; sign = "+"; } private void btnEquals_Click(object sender, EventArgs e) { switch (sign) { case "+": results = (Decimal.Parse(value1) + Decimal.Parse(value2)).ToString(); break; case "-": results = (Decimal.Parse(value1) - Decimal.Parse(value2)).ToString(); break; case "*": results = (Decimal.Parse(value1) * Decimal.Parse(value2)).ToString(); break; case "/": results = (Decimal.Parse(value1) / Decimal.Parse(value2)).ToString(); break; } value1 = ""; value2 = ""; txtInput.Text = value1; isValue2 = false; lblResult.Text = results; } private void FormCalc_Load(object sender, EventArgs e) { lblResult.Text = ""; } } }
So that was fun. I will tell you what. There is another place here that could use a function. Why don’t you give it a go and try to replicate what we did. Worse comes to worse, you can always get the results in the next post.
Before you shoot of your mail saying I did this wrong. Just remember, I am taking it step by step. The concept of a function doing one thing can wait for another day.