Thursday, August 18, 2011

Debugging and Trouble Shooting

Overview


There are three major types of errors that can occur in your program: First there are compile errors. These occur before you ever run the program. Typically they consist of mispelled key words or variables, missing semi-colons and curly braces. These must be corrected before you can run the program.

Next there are Run time errors. These are errors that occur when the program is running. Typically they consist of Data type conflicts, or objects that are called before they are initialized. These cause the code to break and go into debug mode.

The third kind of error is a logical error. Logical errors are errors in the logic of the program. They usually don't cause the program to fail or crash. Rather they cause the program to return the wrong answer or no answer at all. These are the hardest errors to track down and fix.



Compile Errors


The key with compile errors is to use the Visual Studio environnment.

Use the intellisense. The intellisense will show you all the objects defined by your program. It will show you all the relevant methods and properties. Using it can help cut down on mispellings and errors in capitalization.

Read the error messages. Actually read them. They don't always tell you exactly where the problem is, but they get you close.

Always work from the first error on down. Often fixing the first error will clear up most or all of the remaining errors. Errors tend to cascade through the program. One causes another which causes another, etc. If you work from the bottom of the list you will get frustrated, because you usually won't find anything wrong.

Pay attention to the color coding in the coding environment itself. A keyword should be blue--if it is not it may mean you mistyped it. A red underline signifies an error. A green underline is just a comment or possibly a warning.


Run time errors


Most runtime errors are caused by user input, Users don't always enter what we expect, so the program should be able to handle the unexpected input. Ideally, test all use input to see if it is in the correct form. Use TryParse() instead of Parse().

The other common cause of Runtime errors are objects that are not initialized properly. Make sure that you instantiate an object (make it new) before you call it.


Logical Errors


The key to finding logical errors is testing. Try the program with known values and a known output. If the output varies on the input, test a complete range of inputs to see if the proper outputs are returned.

One strategy is to put temporary outputs in your program that print out the state of certain variables at a given point in the process. You can check these against what the variable should be.

You can also use Visual Studios debugger. You can place breaks in the code and step through the part in question line by line, checking the values of the variables moment to moment.


General Suggestions


When writing a program, do one thing and then test it. If it works then when you add the next thing and the program fails you know it was in the new part.

The same goes when debugging and trouble shooting. Make one change and then test it. Never make a bunch of changes willy nilly. It makes it almost impossible to tell what is working and what isn't.

If you go over the code again and again and can't find a mistake in the logic, chances are good there isn't one. Look for syntax aand spelling errors instead. You often don't see these when looking at the logic.

If possible, have someone else look it over. Another person can often see what you don't.

If you spend hours on a thing and just can't get it to work. Walk away. Do something else entirely for a while. Often when you come back with fresh eyes, the problem that you were missing becomes obvious.

Repetition Structures

Programs often need to do the same commands several times in a row. Repitition structures, or loops, are designed to do this. There are several kinds of loops.

For loops


The first one we will look at is a for loop.

A for loop contains three elements, a variable with an intial value, a terminal condition, and an increment or decriment statement. Here is an example of a simple for loop that simply outputs the numbers 1 through 10.



for(int i=0;i<=10;i++)
{
Console.WriteLine(i);
}



You could also count backwards:



for(int i=10;i>0;i--)
{
Console.WriteLine(i);
}



The terminating condition can be a variable:



Console.WriteLine("How far do you want to count?");
int number=int.Parse(Console.ReadLine());

for(i=0;i<=number;i++)
{
Console.WriteLine(i);
}



While Loops


For loops are good when you have a specific number or repititions you want to do. While loops are good for when you have an indefinite number of repititions.
Here is an example of a while loop:



int grade=0;
while(grade != 999)
{
Console.WriteLine("Enter a grade. 999 to exit");
int grade = int.Parse(Console.Readline());

}



Do loops


Do loops are like while loops, but the condition is at the end of the loop. This has a subtle effect. A while loop might never execute. If the condition is met before the loop is encountered--if, for instance, grade equaled 999, the program would never execute the while loop. A do loop, on the other hand, always executes at least once.

Here is an example of a do loop:



int grade=0;

do
{
Console.WriteLine("Enter a grade. 999 to exit");
int grade = int.Parse(Console.Readline());

}while(grade != 999);



Infinite Loops


It is important that a loop have a termination point. If not you can create what is called an infinite loop. The only way out of an infinite loop is to stop the program.



for(int i=0;i>0;i++)
{
Console.WriteLine(i);
}



Embedded loops, break keyword


It is important to note that you can nest loops and selection structures as you need. You can have loops inside of loops and ifs inside of ifs. We will see some examples of this in later examples and lectures.

One additional Key words need mention: break. You can use break to exit from a loop before the terminal condition, Here is an example:



for(int i=1;i<1000;I++)
{
Console.WriteLine("enter a name--'exit' to quit");
string name=Console.ReadLine();
if (name.Equals("exit") || name.Equals("Exit"))
{
break;
}
}

Wednesday, August 17, 2011

Selection Statements

Programs often have to make choices about what to do with a value. If statements and switches are programming structures used to select what to do if a value falls into a certain range.

If statements


An if consists of the if keyword and a condition in parenthesis. The condition must evaluate to true or false (a bool). If there is only one statement after the if you don't have to use curly braces {}, though I would encourage you to use them just to be in the habit. If there are multiple statements dependent on the condition you do have to use curly braces.

Here is a method that shows an example of simple if statements




void SimpleIFStatement()
{
Console.WriteLine("Enter a number between 1 and 10");
int number = int.Parse(Console.ReadLine());


if (number <1 )
Console.WriteLine("the number is too small");


if (number > 10)
Console.WriteLine("The number is too Large");

}



The next example shows the use of the "else" clause in an if statement. The else clause handles any value not covered by the main if statement.




void IfElseStatement()
{
Console.WriteLine("Enter your age");
int age = int.Parse(Console.ReadLine());

if (age >= 18)
{
Console.WriteLine("You are old enough, Welcome");
}
else
{
//for anything less than 18
Console.WriteLine("Come back when your are older");
}
}



If you need to test for multiple possible conditions you can use the if, else if, else structure. It is important to note that sequence matters. The program stops at the first true statement. In the following example if I put the lowest temperature first, the program would always read "cool" for any temperature over 40, even if the temperature were 110.




void IFElseIFExample()
{
Console.WriteLine("Enter the day's high Temperature");
int temp = int.Parse(Console.ReadLine());

if (temp >= 90)
{
Console.WriteLine("Way too hot");
}
else
if(temp >= 80)
{
Console.WriteLine("A bit warm");
}
else
if (temp >= 70)
{
Console.WriteLine("Just right");
}
else
if (temp >= 60)
{
Console.WriteLine("Pleasant");
}
else
if (temp >= 40)
{
Console.WriteLine("cool");
}
else
{
Console.WriteLine("Cold");
}

}



Below is an if example used with the TryParse method. If you enter a bad value into the Parse method it crashes the program. With TryParse it doesn't. TryParse returns a boolean, True if the value actually parses into an int or double or whatever, false if it fails to parse. The try parse also requires an out parameter. If the values parses correctly it's value is assigned to the outside variable--in this case "number".
You can test the boolean variable with an if statement to determine if the parse worked or not.



void TryParseExample()
{
bool goodint;
int number;

Console.WriteLine("Enter an integer value");
goodint = int.TryParse(Console.ReadLine(), out number);

if (goodint == true)
{
Console.WriteLine("Your integer is {0}", number);
}
else
{
Console.WriteLine("Not an integer");
}
}



Finally here is an example of if statements with multiple conditions using and (&&) and or (||) to combine them.
In and conditions both sides of the statement must be true for the if to evaluate as true. For an or statement, if one or the other statement is true, then the whole statement is true.
Here is the example:



void ANDORExamples()
{
Console.WriteLine("Enter a number between 1 and 10");
int number = int.Parse(Console.ReadLine());

//and example both must be true
if (number > 1 && number < 10)
{
Console.WriteLine("Valid Entry");
}

//orExample
{
if (number < 1 || number > 10)
{
Console.WriteLine("Invalid Entry");
}
}
}


Switch


Switch is another way to select based on a set of values, but unlike the if else if structure it only matches exact values.




void SwitchExample()
{
Console.WriteLine("Enter a grade 1, 2, 3, or 4");
int grade = int.Parse(Console.ReadLine());

switch (grade)
{
case 1:
Console.WriteLine("D");
break;
case 2:
Console.WriteLine("c");
break;
case 3:
Console.WriteLine("B");
break;
case 4:
Console.WriteLine("A");
break;
default:
Console.WriteLine("Not a valid grade");
break;
}
}








Tuesday, August 16, 2011

Link to High Availability Presentation

Here is the link to the high Availability presentation"

http://www.seattlejungle.com/highavailability.htm

CLR Procedure

Here is the SQL for the CLR procedure:


Select LocationName as [Location],
Sum(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent)) as Subtotal,
Sum(Employee.GetTax(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent),TaxPercent))
as Tax,
sum(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent) +
Employee.GetTax(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent),TaxPercent))
as Total
From Employee.VehicleServiceDetail vsd
inner Join Employee.VehicleService vs
on vs.VehicleServiceID=vsd.VehicleServiceID
inner Join Customer.Location l
on l.LocationID=vs.LocationID
Group by LocationName



Here is the CLR code with the SQL embedded:


using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;


public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void usp_LocationSales()
{
// Put your code here
using (SqlConnection connect = new SqlConnection("context connection=true"))
{
connect.Open();
SqlCommand cmd = connect.CreateCommand();
cmd.CommandText = "Select LocationName as [Location], "
+ "Sum(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent)) as Subtotal, "
+ "Sum(Employee.GetTax(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent),TaxPercent)) "
+ " as Tax, "
+ " sum(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent) "
+ "+ Employee.GetTax(Employee.func_PriceWithDiscount(AutoServiceID,DiscountPercent),TaxPercent)) "
+ "as Total "
+ "From Employee.VehicleServiceDetail vsd "
+ "inner Join Employee.VehicleService vs "
+ "on vs.VehicleServiceID=vsd.VehicleServiceID "
+ "inner Join Customer.Location l "
+ "on l.LocationID=vs.LocationID "
+ "Group by LocationName ";

SqlContext.Pipe.ExecuteAndSend(cmd);
}
}
};

Monday, August 15, 2011

Windows Form:Tip Calculator



Here is all the auto generated code for the window:


#pragma once

namespace TipCalculator {

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;

///
/// Summary for Form1
///

public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}

protected:
///
/// Clean up any resources being used.
///

~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Panel^ panel1;
protected:
private: System::Windows::Forms::RadioButton^ rdoTwentyPercent;
private: System::Windows::Forms::RadioButton^ rdoFifteenPercent;
private: System::Windows::Forms::RadioButton^ rdoTenPercent;
private: System::Windows::Forms::TextBox^ txtAmount;
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Button^ button1;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::Label^ label3;
private: System::Windows::Forms::Label^ label4;
private: System::Windows::Forms::Label^ lblTax;
private: System::Windows::Forms::Label^ lblTip;
private: System::Windows::Forms::Label^ lblTotal;

private:
///
/// Required designer variable.
///

System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///

void InitializeComponent(void)
{
this->panel1 = (gcnew System::Windows::Forms::Panel());
this->rdoTenPercent = (gcnew System::Windows::Forms::RadioButton());
this->rdoFifteenPercent = (gcnew System::Windows::Forms::RadioButton());
this->rdoTwentyPercent = (gcnew System::Windows::Forms::RadioButton());
this->txtAmount = (gcnew System::Windows::Forms::TextBox());
this->label1 = (gcnew System::Windows::Forms::Label());
this->button1 = (gcnew System::Windows::Forms::Button());
this->label2 = (gcnew System::Windows::Forms::Label());
this->label3 = (gcnew System::Windows::Forms::Label());
this->label4 = (gcnew System::Windows::Forms::Label());
this->lblTax = (gcnew System::Windows::Forms::Label());
this->lblTip = (gcnew System::Windows::Forms::Label());
this->lblTotal = (gcnew System::Windows::Forms::Label());
this->panel1->SuspendLayout();
this->SuspendLayout();
//
// panel1
//
this->panel1->Controls->Add(this->rdoTwentyPercent);
this->panel1->Controls->Add(this->rdoFifteenPercent);
this->panel1->Controls->Add(this->rdoTenPercent);
this->panel1->Location = System::Drawing::Point(32, 56);
this->panel1->Name = L"panel1";
this->panel1->Size = System::Drawing::Size(280, 170);
this->panel1->TabIndex = 0;
//
// rdoTenPercent
//
this->rdoTenPercent->AutoSize = true;
this->rdoTenPercent->Location = System::Drawing::Point(58, 22);
this->rdoTenPercent->Name = L"rdoTenPercent";
this->rdoTenPercent->Size = System::Drawing::Size(77, 17);
this->rdoTenPercent->TabIndex = 0;
this->rdoTenPercent->TabStop = true;
this->rdoTenPercent->Text = L"10 Percent";
this->rdoTenPercent->UseVisualStyleBackColor = true;
//
// rdoFifteenPercent
//
this->rdoFifteenPercent->AutoSize = true;
this->rdoFifteenPercent->Location = System::Drawing::Point(58, 60);
this->rdoFifteenPercent->Name = L"rdoFifteenPercent";
this->rdoFifteenPercent->Size = System::Drawing::Size(77, 17);
this->rdoFifteenPercent->TabIndex = 1;
this->rdoFifteenPercent->TabStop = true;
this->rdoFifteenPercent->Text = L"15 Percent";
this->rdoFifteenPercent->UseVisualStyleBackColor = true;
//
// rdoTwentyPercent
//
this->rdoTwentyPercent->AutoSize = true;
this->rdoTwentyPercent->Location = System::Drawing::Point(58, 99);
this->rdoTwentyPercent->Name = L"rdoTwentyPercent";
this->rdoTwentyPercent->Size = System::Drawing::Size(96, 17);
this->rdoTwentyPercent->TabIndex = 2;
this->rdoTwentyPercent->TabStop = true;
this->rdoTwentyPercent->Text = L"twenty Percent";
this->rdoTwentyPercent->UseVisualStyleBackColor = true;
//
// txtAmount
//
this->txtAmount->Location = System::Drawing::Point(157, 257);
this->txtAmount->Name = L"txtAmount";
this->txtAmount->Size = System::Drawing::Size(100, 20);
this->txtAmount->TabIndex = 1;
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(32, 260);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(126, 13);
this->label1->TabIndex = 2;
this->label1->Text = L"Enter Amount Before Tax";
//
// button1
//
this->button1->Location = System::Drawing::Point(35, 305);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 3;
this->button1->Text = L"Calculate";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(334, 263);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(28, 13);
this->label2->TabIndex = 4;
this->label2->Text = L"Tax:";
//
// label3
//
this->label3->AutoSize = true;
this->label3->Location = System::Drawing::Point(337, 305);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(25, 13);
this->label3->TabIndex = 5;
this->label3->Text = L"Tip:";
//
// label4
//
this->label4->AutoSize = true;
this->label4->Location = System::Drawing::Point(337, 338);
this->label4->Name = L"label4";
this->label4->Size = System::Drawing::Size(34, 13);
this->label4->TabIndex = 6;
this->label4->Text = L"Total:";
//
// lblTax
//
this->lblTax->AutoSize = true;
this->lblTax->Location = System::Drawing::Point(437, 263);
this->lblTax->Name = L"lblTax";
this->lblTax->Size = System::Drawing::Size(0, 13);
this->lblTax->TabIndex = 7;
//
// lblTip
//
this->lblTip->AutoSize = true;
this->lblTip->Location = System::Drawing::Point(440, 304);
this->lblTip->Name = L"lblTip";
this->lblTip->Size = System::Drawing::Size(0, 13);
this->lblTip->TabIndex = 8;
//
// lblTotal
//
this->lblTotal->AutoSize = true;
this->lblTotal->Location = System::Drawing::Point(440, 338);
this->lblTotal->Name = L"lblTotal";
this->lblTotal->Size = System::Drawing::Size(0, 13);
this->lblTotal->TabIndex = 9;
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(192)), static_cast(static_cast(192)),
static_cast(static_cast(255)));
this->ClientSize = System::Drawing::Size(612, 446);
this->Controls->Add(this->lblTotal);
this->Controls->Add(this->lblTip);
this->Controls->Add(this->lblTax);
this->Controls->Add(this->label4);
this->Controls->Add(this->label3);
this->Controls->Add(this->label2);
this->Controls->Add(this->button1);
this->Controls->Add(this->label1);
this->Controls->Add(this->txtAmount);
this->Controls->Add(this->panel1);
this->Name = L"Form1";
this->Text = L"Tip Calculator";
this->panel1->ResumeLayout(false);
this->panel1->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();

}
#pragma endregion


And here, much shorter, is the piece of code we wrote in the button event handler:


private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {

double TAX = .095;
double mealAmount =double::Parse(txtAmount ->Text);
double taxAmount=(mealAmount * TAX);
lblTax->Text=taxAmount.ToString("c");
double percent=0;
if (rdoTenPercent->Checked)
{
percent=.1;
}
if (rdoFifteenPercent->Checked)
{
percent=.15;
}
if(rdoTwentyPercent->Checked)
{
percent=.2;
}

double tipAmount=(mealAmount * percent);
lblTip->Text=tipAmount.ToString("c");

lblTotal->Text=(mealAmount + taxAmount + tipAmount).ToString("c");
}