Problem Definition
Classes:
A Class describes the characteristics of some real objects/events that occurs in the real word. The class specifies the characteristics of class as the properties and behavior and operations on those attributes as the methods. Example: Person is a class
Objects:
Objects are instance of classes. Example: John is a person
Data Abstraction:
Data abstraction is used to hide complex internal details from the external user. It is based on the idea that to consider only important details and ignoring other details.
Data Encapsulation:
Data Encapsulation involves hiding the data from the external world. The hidden data are accessed by the external world using accessors and mutators.
Inheritance:
Inheritance is used to reuse the existing functionality of the classes in the new class. Inheritance improves the readability of the code and ensures code re-usability.
Polymorphism:
Polymorphism means the ability to take many forms. Polymorphism enables the function and operator to perform more than one task under the same name with different number of parameters, different data type or different return type.
- Advantages of Object Oriented Programming (OOP) Principles:
Some of the advantages of using OOP principle while developing the application includes:
- Code Reusability
- Easy code maintenance
- Provides security to the data stored in the class
- It is easy to write large programs, by writing them in small chunks and then combining them into one.
Solution:
Objects Identification:
To develop the application that calculates the cost of carpeting rooms, it requires the objects of carpet that is used and the object of the room which needs to be carpeted.
Classes Identification:
To develop the application that calculates the cost of carpeting rooms, it requires the classes for RoomDimension and RoomCarpet.
Required Data Identification:
RoomDimension class stores the properties of the room which includes the length and width of the room.
RoomCarpet class stores the dimension of the room to be carpeted and the cost of carpet per square meter
Methods Identification:
The RoomDimension class in addition to the constructor of the class, it contains the function named areaOfRoom() which determines the area of the rectangular room by multiplying the room length with the room width.
The RoomCarpet class in addition to the constructor of the class, it contains the function named costOfCarpeting() which determines the cost of carpeting the given room. This is done by multiplying the room area with the cost of the carpet.
The structure of the CarpetCostCalculator application is given below.
The RoomCarpet.cs file contains the RoomCarpet Class
The RoomDimension.cs file contains the RoomDimension Class
The file Form1.cs stores the GUI of the Carpet Cost calculator application
The Program.cs stores the main program of the application.
The user interface of CarpetCostCalculator application is given below.
Initially the user is required to enter the number of rooms. After entering the number of rooms, the Get Room Dimension button is enabled. On clicking the Get Room Dimension button, it requests user to enter the length and width of specified number of rooms. After entering the room dimension, the text box to enter the carpet cost is enabled. After entering the cost of the carpet, the Calculate button is enabled. On clicking the Calculate button the total cost of carpeting the specified number of rooms is displayed to the user. On clicking the clear button, all the entries are deleted, and the state goes back to the initial state. On clicking the exit button, the application exits.
Object-Oriented Programming Principles
Solution:
To develop the application that calculates the cost of carpeting rooms, it requires two classes namely the RoomDimension and RoomCarpet.
The RoomDimension class stores the length and width of the room. The RoomDimesion class contains a constructor that is used to initialize the RoomDimension object with the length and width of the room. The class contains the areaOfRoom() function, it calculates the area of the room by multiplying the room length with its width and return its area.
The RoomCarpet class stores the cost of the carpet per square meter and the dimension of the room to be carpeted. The RoomCarpet class contains a constructor that is used to initialize the RoomCarpet object with the room dimension and the cost of the carpet. The class contains the costOfCarpeting() function, it calculates the cost of carpeting the room of specified size. Tjos is done by multiplying the are of the room with the carpet cost.
An Association relationship exist between the RoomDimension and RoomCarpet class.
The use case diagram of the Carpet CostCalculator application is given below.
On executing an application, a form is displayed, which request to enter the number of rooms Initially a form is displayed to user requesting to enter the number of room. The user then enters the length and width of the room. The user also enters the carpet cost. Finally, the user clicks the button to request the application system to determine the total cost of carpeting all the rooms.
Now the application system determines the area of each room then determines the cost of carpeting each room. Finally, the total cost is found, and the result is displayed to the user.
Solution:
RoomDimension.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarpetCostCalculator
{
class RoomDimension
{
private int roomLength;
private int roomWidth;
public RoomDimension(int length, int width)
{
roomLength = length;
roomWidth = width;
}
public int areaOfRoom()
{
return roomLength * roomWidth;
}
}
}
RoomCarpet.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarpetCostCalculator
{
class RoomCarpet
{
RoomDimension dimensionOfRoom;
int carpetCost;
public RoomCarpet(RoomDimension dimension, int cost)
{
this.dimensionOfRoom = dimension;
this.carpetCost = cost;
}
public int costOfCarpeting()
{
return carpetCost* dimensionOfRoom.areaOfRoom();
}
}
}
Solution:
An association relationship between exist between the Room Dimension and the RoomCarpet class. This because the dimension of the room is associated with the room carpet class. This is notified via the RoomDimension object acts as the attribute of the RoomCarpet class.
Solution:
There have been no changes made to the initial design document. Control structures like if and for loop are used while implementing the CarpetCostCalculator application. “If” control structure is used to test whether the data is valid. “while” control structure is used to perform continuously until the correct data is entered.
Solution:
The GUI coding of main form is given below:
Form1.Designer.cs:
namespace CarpetCostCalculator
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name=”disposing”>true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
Advantages of OOP Principles
/// Required method for Designer support – do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.noOfRoomsTxtBx = new System.Windows.Forms.TextBox();
this.carpetCostTxtBx = new System.Windows.Forms.TextBox();
this.getRoomDimensionButton = new System.Windows.Forms.Button();
this.clearButton = new System.Windows.Forms.Button();
this.calculateButton = new System.Windows.Forms.Button();
this.exitButton = new System.Windows.Forms.Button();
this.costLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font(“Microsoft Sans Serif”, 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(172, 9);
this.label1.Name = “label1”;
this.label1.Size = new System.Drawing.Size(187, 25);
this.label1.TabIndex = 0;
this.label1.Text = “Carpet Company”;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(22, 59);
this.label2.Name = “label2”;
this.label2.Size = new System.Drawing.Size(95, 13);
this.label2.TabIndex = 1;
this.label2.Text = “Number of Rooms:”;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(22, 120);
this.label3.Name = “label3”;
this.label3.Size = new System.Drawing.Size(65, 13);
this.label3.TabIndex = 2;
this.label3.Text = “Carpet Cost:”;
//
// noOfRoomsTxtBx
//
this.noOfRoomsTxtBx.Location = new System.Drawing.Point(143, 56);
this.noOfRoomsTxtBx.Name = “noOfRoomsTxtBx”;
this.noOfRoomsTxtBx.Size = new System.Drawing.Size(100, 20);
this.noOfRoomsTxtBx.TabIndex = 3;
this.noOfRoomsTxtBx.TextChanged += new System.EventHandler(this.noOfRoomsTxtBx_TextChanged);
//
// carpetCostTxtBx
//
this.carpetCostTxtBx.Location = new System.Drawing.Point(143, 113);
this.carpetCostTxtBx.Name = “carpetCostTxtBx”;
this.carpetCostTxtBx.Size = new System.Drawing.Size(100, 20);
this.carpetCostTxtBx.TabIndex = 4;
this.carpetCostTxtBx.TextChanged += new System.EventHandler(this.carpetCostTxtBx_TextChanged);
//
// getRoomDimensionButton
//
this.getRoomDimensionButton.Location = new System.Drawing.Point(298, 53);
this.getRoomDimensionButton.Name = “getRoomDimensionButton”;
this.getRoomDimensionButton.Size = new System.Drawing.Size(125, 23);
this.getRoomDimensionButton.TabIndex = 5;
this.getRoomDimensionButton.Text = “Get Room Dimension”;
this.getRoomDimensionButton.UseVisualStyleBackColor = true;
this.getRoomDimensionButton.Click += new System.EventHandler(this.getRoomDimension_Click);
//
// clearButton
//
this.clearButton.Location = new System.Drawing.Point(177, 189);
this.clearButton.Name = “clearButton”;
this.clearButton.Size = new System.Drawing.Size(91, 23);
this.clearButton.TabIndex = 6;
this.clearButton.Text = “Clear”;
this.clearButton.UseVisualStyleBackColor = true;
this.clearButton.Click += new System.EventHandler(this.clearButton_Click);
//
// calculateButton
//
this.calculateButton.Location = new System.Drawing.Point(38, 189);
this.calculateButton.Name = “calculateButton”;
this.calculateButton.Size = new System.Drawing.Size(94, 23);
this.calculateButton.TabIndex = 7;
this.calculateButton.Text = “Calculate”;
this.calculateButton.UseVisualStyleBackColor = true;
this.calculateButton.Click += new System.EventHandler(this.calculateButton_Click);
//
// exitButton
//
this.exitButton.Location = new System.Drawing.Point(298, 189);
this.exitButton.Name = “exitButton”;
this.exitButton.Size = new System.Drawing.Size(91, 23);
this.exitButton.TabIndex = 8;
this.exitButton.Text = “Exit”;
this.exitButton.UseVisualStyleBackColor = true;
this.exitButton.Click += new System.EventHandler(this.exitButton_Click);
//
// costLabel
//
this.costLabel.AutoSize = true;
this.costLabel.ForeColor = System.Drawing.Color.Red;
this.costLabel.Location = new System.Drawing.Point(111, 153);
this.costLabel.Name = “costLabel”;
this.costLabel.Size = new System.Drawing.Size(0, 13);
this.costLabel.TabIndex = 9;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(432, 249);
this.Controls.Add(this.costLabel);
this.Controls.Add(this.exitButton);
this.Controls.Add(this.calculateButton);
this.Controls.Add(this.clearButton);
this.Controls.Add(this.getRoomDimensionButton);
this.Controls.Add(this.carpetCostTxtBx);
this.Controls.Add(this.noOfRoomsTxtBx);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = “Form1”;
this.Text = “Carpet Cost Calculator”;
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox noOfRoomsTxtBx;
private System.Windows.Forms.TextBox carpetCostTxtBx;
private System.Windows.Forms.Button getRoomDimensionButton;
private System.Windows.Forms.Button clearButton;
private System.Windows.Forms.Button calculateButton;
private System.Windows.Forms.Button exitButton;
private System.Windows.Forms.Label costLabel;
}
}
Form1.cs:
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 CarpetCostCalculator
{
public partial class Form1 : Form
{
RoomDimension[] roomsDimensions;
public Form1()
{
InitializeComponent();
carpetCostTxtBx.Enabled = false;
calculateButton.Enabled = false;
getRoomDimensionButton.Enabled = false;
}
private void clearButton_Click(object sender, EventArgs e)
{
noOfRoomsTxtBx.Text = “”;
carpetCostTxtBx.Text = “”;
costLabel.Text = “”;
carpetCostTxtBx.Enabled = false;
calculateButton.Enabled = false;
getRoomDimensionButton.Enabled = false;
}
private void getRoomDimension_Click(object sender, EventArgs e)
{
int roomCount = 0;
string lengthOfRoom = “”;
string widthOfRoom = “”;
int roomLength = 0;
int roomWidth = 0;
if (int.TryParse(noOfRoomsTxtBx.Text, out roomCount))
{
roomsDimensions = new RoomDimension[roomCount];
for (int i = 0; i < roomCount; i++)
{
Boolean valid = false;
while (!valid)
{
lengthOfRoom =
Microsoft.VisualBasic.Interaction.InputBox(
“Enter the length of Room” + (i + 1),
“Input Room Dimension”, “0”, 0, 0);
if (int.TryParse(lengthOfRoom, out roomLength))
valid = true;
else
MessageBox.Show(“The length of the room is not valid”);
}
valid = false;
Designing Object-Oriented Solution
while (!valid)
{
widthOfRoom =
Microsoft.VisualBasic.Interaction.InputBox(
“Enter the width of Room” + (i + 1),
“Input Room Dimension”, “0”, 0, 0);
if (int.TryParse(widthOfRoom, out roomWidth))
valid = true;
else
MessageBox.Show(“The width of the room is not valid”);
}
roomsDimensions[i] = new RoomDimension(roomLength, roomWidth);
}
carpetCostTxtBx.Enabled = true;
}
else
{
MessageBox.Show(“Enter the valid number of rooms”);
}
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Dispose();
}
private void carpetCostTxtBx_TextChanged(object sender, EventArgs e)
{
int cost;
if (int.TryParse(carpetCostTxtBx.Text, out cost))
calculateButton.Enabled = true;
else
calculateButton.Enabled = false;
}
private void calculateButton_Click(object sender, EventArgs e)
{
int totalCost = 0;
for (int i = 0; i < roomsDimensions.Length; i++)
{
RoomCarpet roomCarpet = new RoomCarpet(roomsDimensions[i], int.Parse(carpetCostTxtBx.Text));
totalCost += roomCarpet.costOfCarpeting();
}
costLabel.Text = “The cost of carpetting the room is $” + totalCost;
}
private void noOfRoomsTxtBx_TextChanged(object sender, EventArgs e)
{
carpetCostTxtBx.Enabled = false;
calculateButton.Enabled = false;
int roomCount;
if (int.TryParse(noOfRoomsTxtBx.Text, out roomCount))
getRoomDimensionButton.Enabled = true;
else
getRoomDimensionButton.Enabled = false;
}
}
}
Application Demonstration:
On executing the CarpetCostCalculator application the following window is displayed to the user:
On entering the valid number of rooms, the Get Room dimension button is enabled as given below.
On clicking the get room dimension button, a dialog is displayed to enter the length and width of each room as shown below.
After entering the dimension of the room, the carpet cost text field is enabled. On entering the valid cost of the carpet, the calculate button is enabled as given below.
On clicking the calculate button, the cost of carpeting all the rooms is displayed to user
Testing:
The CarpetCostCalculator application when executed produces the following window to the user:
The Get Room dimension button is enabled, on entering the valid number of rooms. This example is given as shown below.
On clicking the get room dimension button, a dialog is displayed to enter the length and width of each room as shown below.
The carpet cost text field is enabled only after entering the dimension of all the rooms. The calculate button is enabled, on entering the valid cost of the carpet.
The cost of carpeting all the rooms is displayed to user, on clicking the calculate button.
Solution:
Testing Analysis:
Testing Condition |
Expected Output |
Actual Output |
Number of Rooms: 2 |
Get Room Dimension Button must be enabled |
|
Number of Rooms: 2c |
Get Room Dimension Button must be disabled as the number of rooms is not valid |
|
Length of Room: 12 |
It must try to get the width of the room |
|
Length of Room: 12e |
Displays the error message as the length of the room is not valid |
|
Width of Room: 13 |
It must try to get the length of the next room/ return to the main form |
|
Width of Room: 13s |
Displays the error message as the width of the room is not valid |
|
Carpet Cost: 20 |
The calculate button must be enabled |
|
Carpet Cost: 20e |
The calculate button must be disabled |
|
Number of Room: 2 Length of Room1: 12 Width of Room1: 13 Length of Room2: 14 Width of Room2: 15 Carpet Cost: 20 |
The Cost of carpeting the room is $7320 |
Improvements:
Based on the feedback received from users, some of the suggestions for the improvement of the application is provided below.
- Help menu must be added to the application. It should describe how to use the application effectively.
- The application should display a hint message stating the type of data to be entered
- The application should display the error message regarding the type of the invalid data
- The application should contain more GUI interface to make application pleasing to use.
- The application should request carpet cost for each room as sometime, a different carpet may be laid for each room.
- The application should contain the field that receives the labor cost of carpeting the room.
Solution:
Onscreen help menu is added to the CarpetCostCalculator application as shown in the figure below.
The revised program after adding the Help information is given below.
Form1.cs:
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 CarpetCostCalculator
{
public partial class Form1 : Form
{
RoomDimension[] roomsDimensions;
public Form1()
{
InitializeComponent();
carpetCostTxtBx.Enabled = false;
calculateButton.Enabled = false;
getRoomDimensionButton.Enabled = false;
}
private void clearButton_Click(object sender, EventArgs e)
{
noOfRoomsTxtBx.Text = “”;
carpetCostTxtBx.Text = “”;
costLabel.Text = “”;
carpetCostTxtBx.Enabled = false;
calculateButton.Enabled = false;
getRoomDimensionButton.Enabled = false;
}
private void getRoomDimension_Click(object sender, EventArgs e)
{
int roomCount = 0;
string lengthOfRoom = “”;
string widthOfRoom = “”;
int roomLength = 0;
int roomWidth = 0;
if (int.TryParse(noOfRoomsTxtBx.Text, out roomCount))
{
roomsDimensions = new RoomDimension[roomCount];
for (int i = 0; i < roomCount; i++)
{
Boolean valid = false;
while (!valid)
{
lengthOfRoom =
Microsoft.VisualBasic.Interaction.InputBox(
“Enter the length of Room” + (i + 1),
“Input Room Dimension”, “0”, 0, 0);
if (int.TryParse(lengthOfRoom, out roomLength))
valid = true;
else
MessageBox.Show(“The length of the room is not valid”);
}
valid = false;
while (!valid)
{
widthOfRoom =
Microsoft.VisualBasic.Interaction.InputBox(
“Enter the width of Room” + (i + 1),
“Input Room Dimension”, “0”, 0, 0);
if (int.TryParse(widthOfRoom, out roomWidth))
valid = true;
else
MessageBox.Show(“The width of the room is not valid”);
}
roomsDimensions[i] = new RoomDimension(roomLength, roomWidth);
}
carpetCostTxtBx.Enabled = true;
}
else
{
MessageBox.Show(“Enter the valid number of rooms”);
}
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Dispose();
}
private void carpetCostTxtBx_TextChanged(object sender, EventArgs e)
{
int cost;
if (int.TryParse(carpetCostTxtBx.Text, out cost))
calculateButton.Enabled = true;
else
calculateButton.Enabled = false;
}
private void calculateButton_Click(object sender, EventArgs e)
{
int totalCost = 0;
for (int i = 0; i < roomsDimensions.Length; i++)
{
RoomCarpet roomCarpet = new RoomCarpet(roomsDimensions[i], int.Parse(carpetCostTxtBx.Text));
totalCost += roomCarpet.costOfCarpeting();
}
costLabel.Text = “The cost of carpetting the room is $” + totalCost;
}
private void noOfRoomsTxtBx_TextChanged(object sender, EventArgs e)
{
carpetCostTxtBx.Enabled = false;
calculateButton.Enabled = false;
int roomCount;
if (int.TryParse(noOfRoomsTxtBx.Text, out roomCount))
getRoomDimensionButton.Enabled = true;
else
getRoomDimensionButton.Enabled = false;
}
private void helpToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show(“1) Enter the valid number of rooms n” +
“2) Click the Get Dimension Button n” +
“3) Enter the length and width of each room n”+
“4) Enter the cost of the carpet n” +
“5) Click the Calculate Button to determine the cost” +
“6) Click the Clear button to clear the text fields n”+
“7) Click the Exit button to exit the application”,”Information”);
}
}
}
4.5 Solution:
Support Documentation:
The steps to be followed by the user to use the CarpetCostCalculator application is given below
- Enter the valid number of rooms
- Click the Get Dimension Button
- Enter the length and width of each room
- Enter the cost of the carpet
- Click the Calculate Button to determine the cost
- Click the Clear button to clear the text fields
- Click the Exit button to exit the application
Maintenance Documentation:
- cs file contains the Room Dimension class which stores the details about the length and width of the room
- cs file contains Room Carpet class which stores the dimension of the room to be carpeted and the cost of the carpet
- The Form1.cs file provides the GUI interface of the CarpetCostCalculator application.
References:
- Pressman, R. & Maxim, R. (1982). Software Engineering: A Practitioner’s Approach. MC-Graw Hill Education.
- Wong S. & Nguyen, D. (2009).Principles of Object-Oriented Programming. Florida: University Press of Florida.
- Hejlsberg, A., Wiltamuth, S. & Golde P. (2006). The C# Programming Language. Addison-Wesley Publication
- Vystavel, R. (2017). C# Programming for Absolute Beginners. APress Publication
- Myers, J., Sandler, C. and Badgett, T.(2011). The Art of Software Testing. J Wiley Publication
- Ammann, P. & Offutt, J. (2016). Introduction to Software Testing. Cambridge University Press.