Table of Contents
- Thinking In OOP
- OOP As A Foundation
- Expressions, Math, Exceptions, If-Else, and Case
- Adding Complexity + Looping
- OOP - Getting Real
- Appendix
- Notes
Who is this book for?
To-Do:
- Talk about the intended audience (first-term programming students)
- What are LOGs
- Instructor’s Guide (a future book)
The ABCs of Programming with Objects
An “Objects-First” Introduction to Programming
Learning how to program is a journey into thinking about things and how to manipulate them. For a long time, most instructors and teachers who’ve taken up the challenge of teaching programming have done so with a focus on the manipulations and less concern with the things the program represents. This procedural mindset has been the way many of us (myself included) learned programming in the first place. The problem with this mindset, however, is that “real” programs haven’t been written that way for decades now.
Object-Oriented Programming (OOP) has been around for a long time, but it can be hard to adjust one’s approach from a procedural mindset to become comfortable with OOP. This book aims at offering a way to teach programming starting with OOP, rather than tacking it on at the end. Through simple examples, and a focus on the things first, this book will guide the student (and the teacher) through numerous examples that introduce all the concepts needed to get started in programming with Objects.
The essence of this OOP-First approach are seen in what I call the “ABCs of Classes and Objects”. From these first three topics I move to the “traditional” concerns of programming, all the while placing them within their most natural context: Objects.
Topic A
This topic is the first of a three-part introduction to object-oriented programming. The focus of this first part is to introduce classes and methods. This topic does not go beyond the use of static methods in a class.
Introduction
The purpose of this topic is to introduce the class as the central piece of modern computer programs. A computer program is “a set of instructions for manipulating information.” Notice the two key elements of a computer program: Instructions and Information. A class is a kind of template that groups together data (information) and instructions for manipulating that data.
Manipulating information is done through something called “methods”. A method is basically a set of instructions that has an overall name (method name). Methods cannot exist on their own; methods must exist in a “context”, and the context for all methods is the class. Methods are where programmers tell a computer “what to do.”
Every computer program has one important method that is the entry point or starting point for running the program: main. The main method must be publicly available in order for the operating system to be able to run the program.
Topic B
The focus of this second part is to show how classes act as templates for creating objects. This topic limits itself to showing a) how to create (instantiate) objects using classes and b) how classes can be used to describe what an object “looks like”.
Introduction
The purpose of this topic is to show how classes don’t just “contain” methods: Classes act as templates for defining complex types of information (objects). In fact, a class can almost be thought of as a “mini-program”, because a class brings together the two key elements of every program: Instructions and Information. With classes, we can create objects that do what we want them to.
The class is the basic building block for creating objects. As a template, a class describes
a) What an object “looks like” (that is, what information is inside the object), and
b) How an object “works” (that is, what instructions an object can perform on data).
This topic focuses on the first part – describing what an object “looks like” – by introducing fields and exploring the idea of object state.
Topic C
The focus of this third part is to show the concepts of encapsulation and information hiding as well as good object design by creating private fields and introducing public getters/setters and constructors.
Introduction
The purpose of this topic is to highlight how a major responsibility of every class is to “protect” the data within the class. This is done by designing classes that only use private fields and that “expose” access to the values of those fields through getter and setter methods. Getters and setters provide a way for the programmer to control access to fields in an object and to ensure that the fields are “used correctly”.
(Note: Later topics will address how to write code that tests the values coming through the setters’ parameters to ensure that only “acceptable” values are allowed into an object’s fields.)
This topic also covers the important role of constructors in ensuring that objects have a “stable state” at the moment that they are created. In other words, constructors are responsible to ensure that all of the fields in an object are filled with “meaningful” values. A constructor also forces other code to supply required information when creating (instantiating) an object based on that class. Constructors are the “first line of defense” for ensuring that objects are created properly.
Thinking In OOP
What is a Computer Program
Introduction
What is a computer program? A computer program is basically a set of instructions for manipulating information. To be of any value, the information used by a computer program must have a way to get into the program (input) and get out of the program (output). That may sound too simplistic, but ultimately it is entirely accurate; even the most sophisticated computer program can do nothing more than process information (albeit, in a very fast and efficient way), and no matter how cool the program looks, if there is no way to put information into it and get information out of it then it’s not of much use to anyone.
The most familiar kind of input and output (or I/O) in a computer program comes from the user. Textual information is entered (input) from the user via the keyboard and displayed (output) to the user via the monitor. Other means of user I/O can include computer mice, microphones, speakers, printers, fax machines, Braille readers, touch screens, stylus, etc.
Besides handling user I/O, computer programs can also do file or database I/O. Computer files and databases allow information to be persistent. Information is said to be persistent when it can be stored outside of the computer program and later retrieved for further processing. The combination of a) user I/O, b) fast and accurate processing, and c) persistent information storage is what makes computer programs so useful.
Variables, Values and Data Types
”… manipulating information.”
At the heart of all computer programs is the idea of information or data. This is especially true in Object-Oriented Programming languages. With information being such a critical component of computer programs, it’s important to understand what we mean by information.
It’s All About Information
Since computer programs are all about handling information, it is important to understand something about the different kinds of information programs deal with. Essentially, most information falls into one of the following categories:
- Numeric information (e.g.: a person’s age or the price of a vehicle)
- Textual information (e.g.: the title of a book)
- Conceptual information (e.g.: truth - whether a statement is considered true or false)
These different kinds of information can be said to be primitive. They represent the most basic kind of data that today’s computer programs have to deal with. These three kinds of information can be further subdivided into fundamental data types:
Category of Information | Basic Data Types |
---|---|
Numeric | Integer - whole numbers |
Real - numbers with fractional components | |
Currency - numbers representing monetary values | |
Textual | Character - a single letter or symbol |
String - a set of characters (with or without spaces) | |
Conceptual | Boolean - true/false, yes/no, on/off |
Any meaningful handling of information requires the understanding of three related (but distinct) concepts: variables, values, and data types.
In order for a computer program to manipulate information, it needs a way to hold or refer to information. This is the concept of a variable. A variable is a name or identifier used to refer to a single piece of information. It acts like a container that allows a program to refer to a piece of information indirectly, without being dependent on the exact content of that information. One analogy is that a variable is like a cup: a cup can be used to hold different kinds of liquids (water, juice, or even motor oil). The cup is independent of the liquid (the cup can even be empty), but it provides an effective way of working with a liquid (for example, measuring the amount of water used in a recipe).
Besides the idea of a variable that can hold information, there is the concept of a value. Unlike a variable (which is only used to refer to a piece of information), a value is the specific information contained in a variable. Returning to the previous analogy of a cup, a value is like the specific liquid inside the cup (variable). What does a particular cup hold? Is it water or motor oil? The cup is not what’s really important; what’s important is what is in the cup (especially if you are making a recipe!).
The final concept is one that has already been alluded to: the idea of a data type. A data type refers to the kind of information that a variable can hold. For example, the kind of material that a cup is designed to hold is a liquid. The description “liquid” is a description of the type of content that the cup can hold. A plate, on the other hand, is designed to hold a different kind of material - something that is solid (such as a steak or chicken cordon bleu). More specifically, the “data type” that a plate is intended to hold is “food” and steak would qualify as a type of food while motor oil would not. Notice that the concept of data type (e.g.: “food”) can be applied to both the variable (plate) and the value (steak).
This brings up an important consideration: The data type of a variable should be appropriate for the kind of information the variable is intended to hold. There is a close relationship between variables, values and data types, even though those three ideas refer to different things. Cups are used to hold liquids; plates are used to hold food; and a balloon is used to hold a gas. It would be entirely inappropriate (if not impossible) to use a balloon to hold a piece of cake! Using these analogies, the concepts of variable, value and data type can be clearly distinguished:
Variable | Value | Data Type |
---|---|---|
Cup | Orange Juice | Liquid |
Plate | Black Forest Cake | Food |
Balloon | Helium | Gas |
Returning to the way these concepts are used in a computer program, the following table gives some examples of variables and values for the data types fundamental to most high-level programming languages.
Variable | Value | Data Type |
---|---|---|
Age | 25 | Integer |
PI | 3.14159 | Real |
Cost | $4.95 | Currency |
Gender | ‘M’ | Character |
Title | “Computer Basics 101” | String |
Success | True | Boolean |
Rules About Variables, Values and Data Types
It has been stated that while variables, values and data types are distinct concepts, they are closely related. This close association between these concepts allows us to work with and manipulate information. Before we can begin working with these concepts in a simple program, however, we need to establish some basic rules about how to work with variables, values and data types.
The first rule has already been alluded to in the previous section: The data type of a value must match the data type of the variable that stores the value. This rule is closely related to a second rule: A variable and its data type must be declared before the variable can be used. Whenever a variable name is first identified in a computer program, the data type of the variable must be declared. Stating, or declaring, what the data type of a variable is will allow a computer program to know two things:
- How much computer memory must be set aside for the variable’s value.
- How to interpret a value stored in a variable.
A variable cannot be used until it is declared, and once a variable’s data type has been identified it can only hold values that match that data type. For example, if a variable called Status has been declared as a character, then it can only hold a character value (such as ‘T’ or ‘5’). Any attempt to store a value of a different type (such as “Temporary”) in Status would produce an error in the computer program.
A third rule that is related to the second is that once a variable’s data type has been declared, its data type cannot be changed.1 This is because a variable’s data type tells the computer how to interpret the variable’s value (e.g.: is it a character or a number?), and any attempt to change the data type would result in a misinterpretation of the previously stored value.
Another rule is that each primitive variable in a computer program can only hold a single value at any given moment in time. The reason for this rule is so that the computer knows what value to supply when a variable is used in the program. In fact, when a primitive variable’s data type is declared, the computer sets aside enough memory to store only one value - no more! If a new value is stored in the variable, then any previously stored value is lost. This also gives an advantage to the programmer - it is easier to plan for and test a computer program if you can predict what value will be stored in the variable. Since a variable can only hold one value at a time, it is not unusual for a computer program to use many variables.
Notice that this last rule applies to variables with primitive data types. Often, computer programs allow the creation of more complex data types, such as classes and arrays. The rule of a variable storing only one value changes slightly for these complex types. In the case of classes, one variable whose type is based on a class can only store one object (even though the object might be complex and hold many values). Likewise, a variable that refers to an array can only refer to one array (even though arrays can hold many values). These complex data types will be discussed in a later lesson.
Lastly, in order for a computer program to distinguish one variable from another, each variable (in a given scope) must have a distinct name. If two variables were given identical names, then the computer would not be able to tell which variable to use in a given calculation. By giving each variable a different name, it is easier for both the computer and the programmer to keep track of which ones to use.
Notice, however, the qualification to this rule: in a given scope. In general, scope refers to the context in which a variable is used. If two variables are used in two different contexts, then it is permissible to use the same variable name because the computer uses the different contexts to tell them apart (similar to how two people can have the same first name but be distinguished from each other if they have different last names). An obvious (and trivial) example of this is if a variable called Age is used in two different computer programs, then the computer can tell which variable to use because it knows which program it is currently running. Usually, the term scope is used to refer to distinctly different contexts within the same computer program. The idea of scope will be discussed in more detail later. To begin with, most of the programs will be fairly simple and will only have one scope, so it is fair to simplify this rule as each variable must have a distinct name.
In summary, the basic rules for variables, values and data types are:
- Any value stored in a variable must be of the same data type as the variable.
- Variables must be declared before they can be used.
- A variable’s data type can only be declared once.
- Each primitive variable can only hold one value at a given time.
- Each variable must have a distinct name.
Programming Languages and Coding Instructions
”… a set of instructions …”
What Programmers Write
Programmers write code in plain-text files known as source files. The language that a programmer use to write code is called a programming language. Just as with human languages, there are many different programming languages. Some examples of modern programming languages are C# (the language used in this book), Java, Visual Basic .Net, SQL, and JavaScript. In addition, many other programming languages have been developed over the years such as Python, Lisp, Fortran, Cobol, Haskell, C, C++, and many more.
Each programming language defines their own words (called keywords), punctuation and grammar rules (or syntax). And like human languages, programming languages typically promote certain “world-views” or perspectives on how code should be written. Some languages emphasize the steps involved in manipulating information (a Procedural perspective). Others put the emphasis on the information itself (as in most Object-Oriented programming languages).
In all cases, programming languages allow us to write instructions that manipulate *data. Through variables, a computer program has the ability to manipulate the values stored in those variables. This manipulation of stored information is accomplished by giving the computer specific instructions on what manipulations to perform.
What Computers “See”
Programming languages allow programmers to give instructions to a computer in a form that is more familiar to and easier to use by the programmer. Today’s programming languages are known as high-level languages because they incorporate simple words with familiar meanings in English, such as if, else, while, do, and return. Low-level languages, such as Assembler, use more cryptic commands and are much closer to machine language, thereby making them harder for programmers to work with.
The exact form that the instructions will take depends on the programming language that is used. These instructions are then examined by a special program (a compiler, an assembler, or an interpreter) and translated into machine language. Machine language consists of a series of ones (1) and zeros (0) which act as on and off switches in the computer’s memory. These on and off switches change other information that is stored in memory, resulting in the manipulation of information.
The on and off switches in computer memory represent the flow of electricity through the computer. Millions and billions of these switches (also known as “gates” - no relation to Bill) are arranged on tiny computer chips in highly sophisticated patterns to allow for the organized flow of electricity. It is this organized flow of ones and zeros that allow us to use these machines for fast and efficient information processing.
Doing the Math
High-level programming languages (such as C++, C#, and Visual Basic) make it relatively easy to manipulate the values of variables. Assignment statements tell the computer to store specific values into specific variables. Assignment statements are often used with expressions, which are combinations of variables, values, and/or operators (such as Arithmetic operators). It is through expressions and assignment statements that the bulk of a computer’s work is done.
Expressions allow new values to be computed based on existing values. For example, if a variable called Cost has the value $5.95 and another variable called Markup has a value of 2.0, then a mathematical expression such as Cost * Markup can be used to create a new value - $11.90 (the Cost multiplied by the Markup value). Using this expression in an assignment statement, this resulting value of the expression can then be stored in another variable:
Price = Cost * Markup
All numeric information can be used with the common arithmetic operators of addition, subtraction, multiplication, and division. When combined to create complex expressions, the commonly accepted rules of mathematics are used to determine which operations should be used first (multiplication and division before addition and subtraction). The order of operations can be modified by using parentheses, as in regular mathematics.
Some arithmetic operations, such as calculating the remainder of a division operation, are only applicable to certain types of numeric information. Some languages supply a special symbol to represent these operations while other languages require the use of special library functions to perform the math. Complex arithmetic operations, such as calculating the sine of an angle, are typically done using library functions. Library functions are simply specialized routines or sets of instructions that can be called upon to do the required calculations.
The following chart summarizes key arithmetic operations and their corresponding symbols as used in the more common high-level programming languages. The chart also shows some of the more complex operations and the names of the library functions used to calculate them (for specific details on using functions, see the documentation for the corresponding language).
Arithmetic Operation | Symbols / Function Calls | ||||
C++ | C# | JavaScript | Visual Basic | SQL | |
Addition | + | + | + | + | + |
Subtraction | - | - | - | - | - |
Multiplication | * | * | * | * | * |
Division | / | / | / | / | / |
Remainder of Division | % | % | % | Mod | MOD(Division Expression) |
Square Root | sqrt( ) | Math.Sqrt( ) | Math.sqrt( ) | Sqr( ) | SQR( ) |
Exponential Notation (Power) | pow( ) | Math.Pow( ) | Math.pow( ) | ^ | POWER( ) |
Sine | sin( ) | Math.Sin( ) | Math.sin( ) | Sin( ) | SIN( ) |
Cosine | cos( ) | Math.Cos( ) | Math.cos( ) | Cos( ) | COS( ) |
Tangent | tan( ) | Math.Tan( ) | Math.tan( ) | Tan( ) | TAN( ) |
Parenthesis (affects order of operation) | ( ) | ( ) | ( ) | ( ) | ( ) |
The only “arithmetic” operation that is typically applied to string data types is addition. The addition of two strings is usually interpreted as the concatenation (joining together) of the two string values into a single string value.
Besides performing assignment statements and expressions, programming languages have instructions that allow the program to control which instructions to perform and which ones to skip over. These control statements allow for performing mutually exclusive instructions (this or that) and for performing certain instructions repeatedly. High level languages also incorporate mechanisms to identify sets of instructions as particular groups or functions as well as ways to call these program-defined functions whenever they are needed.
Summary
Information comes in various forms and programmers can create both simple and complex sets of instructions to manipulate that information. Successful computer programs combine the best techniques for user I/O, information processing, and persistent storage in order to meet the needs of individuals and businesses. Grasping the basic concepts of computer programs - variables, values, data types, I/O, assignments and expressions, and control statements - is fundamental to the efficient and effective development of computer software.
The C# Language
C# (pronounced ‘See-sharp’) is a programming language developed by Microsoft and rooted in the earlier languages of C and C++. It is an Object-Oriented programming language that has evolved quite a bit over time, with each released version adding new features and capabilities to the language. At present, C# is in version 6.0 and version 7.0 is under development. Like every programming language, however, it must allow us to hold information and provide sets of instructions to manipulate that information.
Data (information) is held inside of variables. The following keywords represent the commonly used built-in data types for the general categories of primitive information.
Category | C# Data Type |
---|---|
Whole numbers | int long short byte |
Real numbers | double single float |
Text | char string |
Conceptual | boolean |
Instructions are always placed inside of methods. In fact, a method can be defined as a named set of instructions. Methods can never exist all on their own; they have to be placed inside of some kind of context (or scope), and they are typically placed inside of classes. Classes, themselves, are one of the main means by which we can declare complex data types (which, in turn, can be used to declare objects designed to hold and process sets of data).
Where are variables placed in our program? Variables can appear inside of classes (where they are sometimes called member variables) and inside of methods (where they are called local variables). As we will learn later, the location of the variable defines its scope, and that scope will determine when and where the variable can be used.
If you are beginning to imagine a lego-like structure to the C# programming language, then you are on the right track! We can code classes that hold variables and methods. The classes themselves are new data types which can be used for for creating complex variables (objects). This characteristic of providing keywords for primitive data types along with a means to combine them into more complex data types is called type extensibility. You can think of it in this way: primitive data types are like chemical elements in the periodic table, while complex data types (which we design ourselves) are like molecules made by combining elements. While this analogy has its limits in describing the nature of C#, it does provide a good starting point in understanding how the language is designed.
The Main Method
Speaking of starting points, it’s important to note that every computer program needs a place to start. When we run a computer program, we are telling the operating system (OS) to start running the instructions in the program. That’s why every program needs a starting place - a place (method) where the computer can begin executing the program’s instructions. For C# (like many other languages), that entry point is traditionally called the Main()
method.
Let’s look at an example. The following code is a complete program that performs a simple task - displaying the text “Hello World” in a console window.
1
public
class
MyFirstProgram
2
{
3
public
static
void
Main
(
string
[]
args
)
4
{
5
System
.
Console
.
WriteLine
(
"Hello World"
);
6
}
7
}
The name of the class is MyFirstProgram
and it contains only one method - Main
- which is the starting point of the program. That method contains a single instruction telling the computer to display the text “Hello World” to the user.
Notice that besides the name of the class and the Main method, there are various keywords (in blue) and punctuation (such as curly braces { }
, parentheses ( )
, square brackets [ ]
, semicolons ;
and “dot operators” .
). All of these pieces have to be arranged according to the specific rules of the programming language. We call these rules the grammar and the arrangement of our code using the rules the syntax. You can learn more about some of the subtle distinctions between these two terms by searching online, but for now you can think of these words as being almost the same thing.
Syntax is the study of sentences and their structure, and the constructions within sentences. Syntax tells us what goes where in a sentence. Grammar is the general term referring to the set of rules in a given language including syntax , morphology, while syntax studies sentence structures. Apr 3, 2013 - by Googlebot
Order is important
The order in which we place our instructions within a method is important. All of the instructions are processed sequentially - one after the other. Look at this simple example:
1
public
class
PriceCalculation
2
{
3
public
static
void
Main
(
string
[]
args
)
4
{
5
double
price
=
12.95
,
total
;
6
total
=
price
*
10
;
7
System
.
Console
.
WriteLine
(
"The total price is "
+
total
);
8
}
9
}
In the main method are three lines of code (lines 5-7) which run sequentially. If I change the order of these instructions, then the program won’t run correctly. In fact, changing the order might even violate part of the C# grammer, creating what’s called a syntax error, and the computer won’t be able to run the program at all!
Understanding the Grammar of a programming language is fundamental to knowing how that language works. Without that knowledge, our attempts to write code will quickly be filled with frustration. The next chapter examines the grammar of C#.
Summary
We’ve covered a lot of ground so far, and all of it is fundamental to writing computer programs in C#. To recap, you should now know that
- Instructions are always placed inside methods (in fact, a method can be defined as a “set of instructions”).
- Methods always appear inside of classes or similar structures.
- C# provides keywords for primitive data types. We use these keywords to declare variables which hold values.
- C# is an extensible language - allowing one to define new complex data types with their own information (variables) and instructions (methods) for processing that information.
A Simplified C# Grammar
A language grammar is a set of small rules that can be combined to produce a syntax.
The many small rules in the C# programming language is its grammar. These rules specify the accepted way to write C# code. Individually, each rule in itself is not enough to produce complete working code. Instead, the rules are like building blocks, offering various ways to assemble or construct your code.
Take, for example, some of the grammar around variable declarations and program statements. A simplified grammar for declaring a variable in C# would look like this:
* dataType variableName*
We would have to supply both a data type and a variable name to declare a variable. Thus, if we wanted to store a whole number to represent a count, we could use the int
keyword and write the following:
int count
By itself, this variable declaration is not enough to produce a complete instruction in C#. We have to combine the variable declaration grammar with the grammar for a program statement in order to make a single instruction telling the computer to create the variable. In general, a program statement must be a statement that ends with a semicolon (;
). In other words, the program statement grammar requires the semicolon as “punctuation”, much in the same way that English sentences must end in a period. Thus, our completed syntax for creating a variable would be
int count;
The formal grammar for C# is actually quite large and complex. In fact, the grammars for most programming languages are so complex that they require another “language” to describe the grammar. An early and fairly standard language or means to express grammars is the Bakus-Naur Form, or BNF.
For our purposes, we will present a much more simplified grammar. The following sections express the bulk of the C# grammar used in this introduction to programming fundamentals in C#.
Common Grammar Elements
Most of the grammar rules in C# are quite short, defining the order of keywords, identifiers and symbols. In the following grammars, the use of square brackets ([]
) indicate an optional part of the syntax for the grammar rule; those square brackets are not actual symbols in the final syntax of the grammar. With each of the rules is a very brief explanation. Later chapters will go into more depth and provide examples of how to use these grammars.
Program Statements and Statement blocks
Individual instructions are known as Program Statements. The instructions can be short and simple, or they can be long an complex. In either case, the program statement must end in a semicolon (;). These individual instructions run sequentially, one after the other, so the order of individual instructions is important.
Besides individual instructions, we can group individual statements into Statement Blocks. A statement block is a set of zero or more program statements that are enclosed in a set of curly braces ({ }
). Statement blocks are frequently used with Flow Control Statements (such as the if
and for
statements).
Variable Declarations
Before a variable can be used, it must be declared. Declaring a variable tells the compiler to
- set aside room in memory to store information,
- treat that data as a specific data type, and
- refer to that information by the variable name
The grammar for declaring variables is as follows.
1
dataType
variableName
[=
expression
]
[,
...]
- A Variable Declaration defines a new variable where
-
dataType
is any built-in or programmer-defined data type. -
variableName
is - an optional initial value may be assigned, as denoted by
[= expression]
, whereexpression
is any valid C# expression whose final data type matches the variable’s data type. When a variable is declared and initialized at the same time, it is called a Variable Initialization. - additional variable names (with or without initial values) can be declared using a comma-separated list. All variables are of the same data type as the first variable in the list.
Assignment Operation
1
variableName
assignmentOperator
expression
- Assignment Operations are operations where a value is assigned or stored in a variable.
-
variableName
is the name of the variable that will receive/store the value. -
assignmentOperator
is one of the following:=
Equals+=
Plus-Equals-=
Minus-Equals*=
Multiply-Equals/=
Divide-Equals%=
Modulus-Equals -
expression
is any valid C# expression whose final data type matches the variable’s data type. - An assignment operation is made into an assignment statement by adding a semicolon to the end of the operation. For example,
total = price * quantity;
Expressions
An Expression is any combination of literal values, variable names, operators (such as the arithmetic operators), and/or method calls (where the method returns a value). When an expression is processed by the computer, a single value is produced. This value can then be used in whatever operation the expressions occurs. For example, the value might be passed into a method as part of a method call, or it might be placed in a variable as part of an assignment statement.
Namespace Declaration and Using Statements
1
namespace
Name
2
{
3
// Classes, enumerations, or other programmer-defined data types
4
}
- A Namespace Declaration groups programmer-defined data types where
- The
Name
of the namespace can be one or more dot-separated names. For example, the following are all valid names for namespaces.System
System.Collections
MyGame
MyGame.GameRules
Namespaces are used to group classes and other programmer-defined data types into a single named group. The reason for grouping programmer-defined data types into namespaces is to prevent what are called “naming collisions”. A naming collision is where two or more classes or other programmer-defined data types are given the same name. In other words, you cannot have two classes named Circle
in the same namespace. However, if you place those two classes in different namespaces, then that is acceptable because the compiler will then be able to distinguish between the two classes based on the namespace they belong to.
Whenever a class or other data type is placed in a namespace, that namespace becomes part of the fully-qualified name of the data type. For example, if a class named Circle
is placed in a namespace called Geometry.Shapes
, then the fully qualified name of the class is Geometry.Shapes.Circle
.
Namespaces allow us to isolate our classes and other data types into groups. All of the classes/data types in a given namespace can automatically reference each other. To reference or use data types in other namespaces, we must either use their fully-qualified names or include them through the Using Statement.
1
using
NamespaceName
;
The using statement allows access to all the data types in referenced namespace. Using statements are typically placed at the beginning of a file. The NamespaceName
is simply the complete name of the namespace that contains the classes or data types that we want to access.
Classes and Class Members
As an object-oriented language, classes play a very prominent part of the code we write in C#. It is within classes, for example, that we place variables (also called fields) and methods (which are “named sets of instructions”). One of the first things that classes give us developers is a context or scope for the code that we write. Classes are also building blocks, acting as blueprints for new and complex data types that we as programmers can create as we develop richer and more complex computer programs. Classes permeate all the code that we write in C# and are so fundamental that you can’t even write a “Hello World” program without them.
Class Definition
1
[accessModifier]
class
ClassName
2
{
3
// FieldDeclarations
4
// PropertyDeclarations
5
// Constructors
6
// MethodDeclarations
7
}
- A Class Definition describes a new data type where
-
[accessModifier]
is eitherpublic
{format: csharp} orinternal
{format:csharp}. If no access modifier is provided, then the default modifier isinternal
{format:csharp}. -
ClassName
is the programmer-supplied name for the class (in TitleCase format) -
FieldDeclarations
,PropertyDeclarations
,Constructors
andMethodDeclarations
are all optional and can appear in any order.
See the related grammars below to see how they are defined.
Field Declarations
1
[accessModifier]
[
static
]
dataType
_FieldName
[=
constantExpression
];
- A Field Declaration identifies a static or instance member variable of the class where
-
[accessModifier]
is eitherpublic
{format: csharp},private
{format: csharp},protected
{format: csharp}, orinternal
{format:csharp}. If no access modifier is provided, then the default modifier isprivate
{format:csharp}. -
[static]
{format:csharp} is an optional keyword. If present, the field is shared among all instances of the class. If absent (which is the common case) then the field is an instance member and one is created every time an object based on the class is created. -
dataType
is any built-in data type or the name of a programmer-defined data type. -
_FieldName
is a the name you give to the member variable. By convention, private fields are given an underscore as a prefix to the name. -
constantExpression
is an optional expression that generates data whose value can be determined at compile time. Being a constant expression does not mean that the field is a constant, only that the initial value stored in the field is a constant and can be known at compile time before the program runs.
Property Declarations
Properties are a kind of cross between methods and fields. On one hand, they are used in the same way that fields are. When you want to assign (or set) a value to a property, you place the property on the left side of the assignment operator. When you want to use (or get) the properties value, you simply reference the property name just as you would a field name.
Internally, however, the get and set operations are like the bodies of a method, where you can place instructions to retrieve or change the data in the class or object.
Explicitly Implemented Property
Explicitly implemented properties are properties where the programmer supplies the getter and setter implementations. The bodies of the getter and setter may reference a field (known as a backing store) that holds the actual information. In these cases, the property is working to provide a controlled access to the underlying field’s data.
In other situations, a property may merely have a getter where the body of the getter derives or calculates a value to return from some other source, such as a calculation.
1
[accessModifier]
[
static
]
dataType
PropertyName
2
{
3
get
4
{
5
// Body of getter
6
}
7
set
8
{
9
// Body of setter
10
}
11
}
- A Property Declaration identifies a static or instance member of the class where
-
[accessModifier]
is eitherpublic
{format: csharp},private
{format: csharp},protected
{format: csharp}, orinternal
{format:csharp}. If no access modifier is provided, then the default modifier isprivate
{format:csharp}. -
[static]
{format:csharp} is an optional keyword. If present, the Property is shared among all instances of the class. If absent (which is the common case) then the Property is an instance member. -
dataType
is any built-in data type or the name of a programmer-defined data type. -
PropertyName
is a the name you give to the member property. -
Body of getter
is a set of instructions that must ultimately return a value of the same data type as the property. -
Body of the setter
is a set of instructions that can process incoming data that is in thevalue
{format:csharp} keyword. A typical implementation will store that data into the property’s backing store.
Autoimplemented Property
Autoimplemented properties are properties where the compiler takes care of the getter and setter implementations and also supplies a hidden field as the backing store for the property. The default get implementation is to retrieve the value from the backing store while the default set implementation is to place a value into the backing store.
1
[accessModifier]
[
static
]
dataType
PropertyName
{
get
;
set
;
}
- A Property Declaration identifies a static or instance member of the class where
-
[accessModifier]
is eitherpublic
{format: csharp},private
{format: csharp},protected
{format: csharp}, orinternal
{format:csharp}. If no access modifier is provided, then the default modifier isprivate
{format:csharp}. -
[static]
{format:csharp} is an optional keyword. If present, the Property is shared among all instances of the class. If absent (which is the common case) then the Property is an instance member. -
dataType
is any built-in data type or the name of a programmer-defined data type. -
PropertyName
is a the name you give to the member property.
Method Declarations
1
[accessModifier]
[
static
]
returnType
MethodName
(
ParameterList
)
2
{
3
// body of method
4
}
- A Method Declaration defines a named set of instructions.
-
[accessModifier]
is eitherpublic
{format: csharp},private
{format: csharp},protected
{format: csharp}, orinternal
{format:csharp}. If no access modifier is provided, then the default modifier isprivate
{format:csharp}. -
[static]
{format:csharp} is an optional keyword. If present, the method is shared among all instances of the class. If absent (which is the common case) then the method is an instance member. -
returnType
is any built-in data type or the name of a programmer-defined data type. The return type signifies the kind of information that the method will return. If the method does not return any information, then the keywordvoid
is used as the return type. -
MethodName
is a the name you give to the method. -
ParameterList
is a comma-separated list of individual variable declarations.
Constructors
1
[accessModifier]
ClassName
(
ParameterList
)
2
{
3
// body of constructor
4
}
- A Constructor is a set of instructions used when instantiating (creating) an object.
-
[accessModifier]
is eitherpublic
{format: csharp},private
{format: csharp},protected
{format: csharp}, orinternal
{format:csharp}. If no access modifier is provided, then the default modifier isprivate
{format:csharp}. -
ClassName
- All constructors use the name of the class to which they belong as the name of the constructor. -
ParameterList
is a comma-separated list of individual variable declarations. - Classes never return any information - they are simply blocks of instructions used to set up the initial state of the object.
Flow-Control Statements
- If-Else
- Case
- For and Foreach
- While and Do-While
Interlude 1 - Console Input/Output
TODO:
- Output
- Input
- Converting user input
The ABCs of Classes and Objects
A Tutorial and Walkthrough of coding Classes and Objects
The purpose of this tutorial is to give the student an opportunity to write code and to explore the fundamentals of Classes and Objects. Specifically, this tutorial demonstrates fields, properties, constructors, and methods in class declarations along with object instantiation and the use of the member access operator.
About Classes and Objects
A computer program is a set of instructions for manipulating information.
Information is central to the whole purpose of computer programs, and is the “thing” that has value in the eyes of the end-user. Information is often complex, being made up of many smaller pieces of related information. For example, the information could be the details of a bank account, the marks earned by a student, or information about a company or an employee. A key aspect of all of these is that the details of the information (First and Last name, for example) are bundled together and treated as a single unit - a composition of related information. In programming, those bundled sets of detailed information are known as objects.
Objects embody more than just information, however. A person can do things with objects. For example, if you imagine a Bank Account as an object, it can be made up of a bunch of information, such as Account Number, Balance and Overdraft Limit. Now imagine the things you can do with a bank account: you can Deposit or Withdraw money. These actions are tightly related to bank accounts, largely because they directly affect the information in the bank account. These actions are carried out as a set of instructions - known as methods - which are carried out in a prescribed way through a set of one or more program statements.
Two objects can have the same set of characteristics, but different information. For example, consider two Bank Account objects where one account has a balance of $4,500.00 and another has a balance of $125.00. The actual information is different, but the characteristics (what Bank Accounts “look like”) remain the same. The things you can do with the two bank accounts also remain the same: you can Deposit and Withdraw money. In programs, the characteristics of an object are defined in something called a Class. A class defines
- What an object “looks like” (information)
- How an object “behaves” (instructions to manipulate information)
For a computer program to be able to work with objects, it must first know the class definition of that object. Coding a class definition is like telling the computer about a new data type that you are defining. The name of the class is the name of the new data type. Once the data type is defined, then it can be used to create objects. A class definition (or “class” for short) acts as a blueprint for creating objects; from the blueprint, the computer is told what the object “looks like” and how it “behaves”. Every object is said to be an “instance” of a class, in the same way that a physical car would be an instance of the car’s blueprint. The term instantiation basically means “to instantiate”, and it refers to the act of creating objects in code. An object is said to be “based on” a class when that class is the data type from which an object has been instantiated (just as a physical car would be “based on” the car’s blueprint).
So, objects and classes are closely related, but not exactly the same. The relationship between objects and classes is pretty much the same as the relationship between ordinary values and data types.
Coding the Class Definition
A class definition can contain four parts: Fields, Properties, Constructors, and Methods. Fields and properties work together to describe what an object based on the class “looks like” (the object’s information). Constructors and Methods describe how the object “behaves” (what instructions an object performs to manipulate information).
- Fields
- Fields are variables that are shared by/accessible to all the other members of a class (properties, constructors, and methods).
- Fields are almost always declared as private (meaning that they are not directly accessible from outside the class).
- Although not commonly done, a field can be assigned an initial default value when it is declared.
- Properties
- Properties are used like ordinary fields or variables, but work internally as methods.
- Properties can have a Get method and/or a Set method.
- The Get method is used when attempting to retrieve a value from the property.
- The Set method is used when attempting to store a value in the property.
- Properties often (but not always) have a corresponding field that is used to hold or store the property’s value in the “background”; the field associated with a property is often referred to as the “backing store”.
- Properties that do not have a corresponding backing store will only have a Get method that calculates a value based on other values; there is no Set method because there is no single field in which to store a value for the property.
- Properties are usually declared as public (meaning that they can be accessed directly from outside the class).
- Constructors
- Constructors are called automatically whenever an object is created. Objects are created by the new keyword, whose general syntax is as follows:
new ClassName(ArgList)
- ArgList (or Argument List) is a comma-separated list of values that are sent to the constructor. The decision of which constructor can be called depends on the arguments (values) sent in when the new keyword is used; the compiler looks for a constructor with a parameter list that matches the argument list.
- Constructors have one purpose: to make sure that the fields in the object have meaningful values. This usually means that a constructor will need some parameters to get those values from the code that creates the object.
- Usually, constructors are made public.
- A class can define more than one constructor. If no constructor is defined for a class, then a “default constructor” is used, which simply sets all the fields to their default values.
- Constructors are called automatically whenever an object is created. Objects are created by the new keyword, whose general syntax is as follows:
- Methods
- A method is a set of instructions that are typically focused on manipulating or working with the fields and properties of an object.
- Methods are identified by a name (called the Method Name) and a parameter list; together the method name and parameter list make up what is called the Method Signature.
- If a method has a return type of void, then it is known as a Subroutine; subroutines do not return any information to the code that called it.
- If a method has any return type except void, then it is called a Function; functions can only return one item, and must do so using a return statement.
A Tutorial - OOP First in Three Parts
Practice makes better!
This three-part tutorial establishes the foundations of the key grammars around classes and objects. The first two work on a BankAccount and Bank class while the last part demonstrates the same concepts around the idea of rental cars and rental companies.
Part 1
This tutorial will walk you through the steps to create a class and an object based on the following design. This first program will demonstrate a BankAccount class and the transfer of money from one bank account to another.
![](/site_images/programming0101/3-BankAccount.png)
![](/site_images/programming0101/3-Bank.png)
- Open up Visual Studio and create a new C# Console Application project. In that project, create a folder called “Tutorial”.
![](/site_images/programming0101/3-Solution-Explorer.png)
- Right-click on the Tutorial folder, and create a class called “BankAccount”. Edit the BankAccount class so that it has the following code.
1
namespace
ObjectABCs.Tutorial
2
{
3
public
class
BankAccount
4
{
5
#region Fields (always private)
6
private
int
_AccountNumber
;
7
private
double
_Balance
;
8
#endregion
9
10
#region Properties
11
public
int
AccountNumber
12
{
13
get
{
return
_AccountNumber
;
}
14
private
set
{
_AccountNumber
=
value
;
}
15
}
16
17
public
double
Balance
18
{
19
get
{
return
_Balance
;
}
20
set
{
_Balance
=
value
;
}
21
}
22
#endregion
23
24
public
BankAccount
(
int
accountNumber
,
double
balance
)
25
{
26
AccountNumber
=
accountNumber
;
27
Balance
=
balance
;
28
}
29
30
public
void
Deposit
(
double
amount
)
31
{
32
Balance
=
Balance
+
amount
;
33
}
34
35
public
void
Withdraw
(
double
amount
)
36
{
37
Balance
=
Balance
-
amount
;
38
}
39
}
40
}
- Create another class inside the Tutorial folder, and name it “Bank”. Edit the class so that it has the following code.
1
namespace
ObjectABCs.Tutorial
2
{
3
public
class
Bank
4
{
5
public
static
void
Transfer
(
BankAccount
fromAccount
,
BankAccount
toAccou
\
6
nt
,
double
amount
)
7
{
8
fromAccount
.
Withdraw
(
amount
);
9
toAccount
.
Deposit
(
amount
);
10
}
11
}
12
}
- Create a driver class named “DemoDriver” and place it in the Tutorial folder. Edit the driver so that it has the following code.
1
using
System
;
2
3
namespace
ObjectABCs.Tutorial
4
{
5
public
class
DemoDriver
6
{
7
public
static
void
Start
()
8
{
9
BankAccount
myAccount
=
new
BankAccount
(
123546
,
250.00
);
10
BankAccount
storeAccount
=
new
BankAccount
(
987654
,
5473.28
);
11
12
DisplayAccount
(
myAccount
,
"My Account"
);
13
DisplayAccount
(
storeAccount
,
"Store Account"
);
14
15
Console
.
WriteLine
(
"I am purchasing an item for $12.95"
);
16
Bank
.
Transfer
(
myAccount
,
storeAccount
,
12.95
);
17
DisplayAccount
(
myAccount
,
"My Account"
);
18
DisplayAccount
(
storeAccount
,
"Store Account"
);
19
Console
.
WriteLine
(
"Purchase complete"
);
20
}
// end of Start() method
21
22
private
static
void
DisplayAccount
(
BankAccount
account
,
string
message
)
23
{
24
Console
.
WriteLine
(
message
);
25
Console
.
WriteLine
(
"-- Account Info --"
);
26
Console
.
WriteLine
(
"Acct. #: "
+
account
.
AccountNumber
);
27
Console
.
WriteLine
(
"Balance: $ "
+
account
.
Balance
);
28
Console
.
WriteLine
(
"-- ------------ --"
);
29
Console
.
WriteLine
();
30
}
// end of DisplayAccount() method
31
}
32
}
- Open the Program.cs file and edit the Main() method to call the demo driver class.
1
using
ObjectABCs.Tutorial
;
2
3
namespace
ObjectABCs
4
{
5
class
Program
6
{
7
static
void
Main
(
string
[]
args
)
8
{
9
DemoDriver
.
Start
();
10
}
11
}
12
}
When you run the program, you should see the result as shown in the following screen-shot.
![](/site_images/programming0101/3-Part-1-Output.png)
Part 2
A big aspect of developing computer programs is the work of modifying existing code that you or others have written. In this part of the tutorial, we’ll revisit the BankAccount and DemoDriver classes to add and take advantage of a new method on the BankAccount class: ToString().
![](/site_images/programming0101/3-BankAccount-2.png)
![](/site_images/programming0101/3-Part-2-Output.png)
- Open the BankAccount class and modify it by adding the following ToString() method in the body of the class.
1
public
override
string
ToString
()
2
{
3
string
accountInfo
=
"Balance (for account # "
4
+
AccountNumber
.
ToString
()
5
+
"): "
6
+
string
.
Format
(
"{0:C}"
,
Balance
);
7
8
return
accountInfo
;
9
}
- Open the DemoDriver class and modify the DisplayAccount() method to look like the following code.
1
private
static
void
DisplayAccount
(
BankAccount
account
,
string
message
)
2
{
3
Console
.
WriteLine
(
message
);
4
Console
.
WriteLine
(
"-- Account Info --"
);
5
Console
.
WriteLine
(
account
);
6
Console
.
WriteLine
(
"-- ------------ --"
);
7
Console
.
WriteLine
();
8
}
// end of DisplayAccount() method
Part 3
Many times, properties act to provide transparent access to fields. (All of the examples so far have used Properties in this simplest way.) In C# version 3.0, a new syntax was introduced called auto-implemented properties which reduces the amount of code required to get the same effect as these transparent properties.
Auto-implemented properties do not have a field as a “backing store” and do not have bodies for the get and set methods. For example, the following code demonstrates an auto-implemented property.
1
public
string
ClientName
{
get
;
private
set
;
}
This property has the exact same effect as the following, longer approach of using a property with a field in the background.
1
private
string
_ClientName
;
2
public
string
ClientName
3
{
4
get
{
return
_ClientName
;
}
5
private
set
{
_ClientName
=
value
;
}
6
}
In this part of the tutorial, you will create classes that use auto-implemented properties, as well as regular properties.
![](/site_images/programming0101/3-RentalCar.png)
![](/site_images/programming0101/3-RentalCompany.png)
- Open up Visual Studio and create a new C# Console Application project. In that project, create a folder called “Tutorial”.
![](/site_images/programming0101/3-Solution-Explorer.png)
- Create a new class in the Tutorial folder called RentalCar. Edit the class so that it matches the following code.
1
using
System
;
// needed for DateTime
2
namespace
ObjectABCs.Tutorial
3
{
4
public
class
RentalCar
5
{
6
public
string
VIN
{
get
;
private
set
;
}
7
public
string
ClientName
{
get
;
private
set
;
}
8
public
DateTime
DateTaken
{
get
;
private
set
;
}
9
public
int
DaysRental
{
get
;
set
;
}
10
public
DateTime
DateDue
11
{
12
get
13
{
14
return
DateTaken
.
AddDays
(
DaysRental
);
15
}
16
}
17
18
public
RentalCar
(
string
clientName
,
DateTime
dateTaken
,
int
days
)
19
{
20
ClientName
=
clientName
;
21
DateTaken
=
dateTaken
;
22
DaysRental
=
days
;
23
// figure out the remaining values
24
VIN
=
GetPretendVIN
();
25
}
26
27
private
static
string
_PretendVIN
=
"1ABC234DE567"
;
28
private
static
int
_Counter
=
10
;
29
private
static
string
GetPretendVIN
()
30
{
31
string
tempVIN
=
_PretendVIN
+
_Counter
.
ToString
();
32
_Counter
=
_Counter
+
1
;
33
return
tempVIN
;
34
}
35
36
public
override
string
ToString
()
37
{
38
return
VIN
;
39
}
40
}
41
}
- Create another class named RentalCompany. Edit the code to match the following.
1
using
System
;
// needed for DateTime
2
namespace
ObjectABCs.Tutorial
3
{
4
public
class
RentalCompany
5
{
6
public
int
CarCount
{
get
;
private
set
;
}
7
8
public
RentalCompany
(
int
carCount
)
9
{
10
CarCount
=
carCount
;
11
}
12
13
public
RentalCar
BookRental
(
string
name
,
int
days
)
14
{
15
RentalCar
car
;
16
car
=
new
RentalCar
(
name
,
DateTime
.
Today
,
days
);
17
CarCount
=
CarCount
-
1
;
18
return
car
;
19
}
20
21
public
override
string
ToString
()
22
{
23
return
CarCount
.
ToString
()
+
" cars available to rent."
;
24
}
25
}
26
}
- Create a final class named DemoRentals. This will be the driver to use RentalCompany and RentalCar objects. Edit DemoRentals to match the following.
1
using
System
;
2
3
namespace
ObjectABCs.Tutorial
4
{
5
public
class
DemoRentals
6
{
7
public
static
void
Start
()
8
{
9
string
name
;
10
int
daysToRent
;
11
12
name
=
PromptName
();
13
daysToRent
=
PromptRentalTime
();
14
15
RentalCar
rental
;
16
RentalCompany
budget
=
new
RentalCompany
(
5
);
17
18
rental
=
budget
.
BookRental
(
name
,
daysToRent
);
19
20
DisplayRentalInfo
(
rental
);
21
}
22
23
private
static
string
PromptName
()
24
{
25
Console
.
Write
(
"Enter name of person renting vehicle: "
);
26
string
name
=
Console
.
ReadLine
();
27
return
name
;
28
}
29
30
private
static
int
PromptRentalTime
()
31
{
32
Console
.
Write
(
"Enter number of days to rent: "
);
33
string
daysAsText
=
Console
.
ReadLine
();
34
int
days
=
Convert
.
ToInt32
(
daysAsText
);
35
return
days
;
36
}
37
38
private
static
void
DisplayRentalInfo
(
RentalCar
rental
)
39
{
40
Console
.
WriteLine
(
"Rental Info"
);
41
Console
.
WriteLine
(
"-----------"
);
42
Console
.
WriteLine
(
rental
);
43
Console
.
WriteLine
(
"Customer: "
+
rental
.
ClientName
);
44
Console
.
WriteLine
(
"Due Date: "
+
rental
.
DateDue
.
ToShortDateString
());
45
Console
.
WriteLine
();
46
}
47
}
48
}
- Lastly, modify the Main method in Program.cs to call the DemoRentals.Start() method.
1
using
ObjectABCs.Tutorial
;
2
3
namespace
ObjectABCs
4
{
5
class
Program
6
{
7
static
void
Main
(
string
[]
args
)
8
{
9
DemoRentals
.
Start
();
10
}
11
}
12
}
- Run the program. You should get results similar to the following screenshot.
![](/site_images/programming0101/3-Part-3-Output.png)
OOP As A Foundation
Topic A - Starting Classes
Overview
This topic introduces some of the basic syntax and grammar surrounding Object-Oriented Programming in C#. The following C# keywords are introduced.
- public
- class
- static
- string
- void
- return
- namespace
This topic will also introduce the following grammars, syntax and language constructs:
- Simple class declaration syntax (no members)
- Simple class declaration syntax (with static methods)
- Method overloading
- Method declaration syntax (class methods, with the static keyword)
- Parameter declaration (variable declaration) syntax
- Class (static) method call syntax (with and without arguments)
- main function (entry point of program)
- Console output
- Simple string concatenation
- C# as a case-sensitive language
- Single-line, multi-line and XML comments
LOGs
At the end of this topic, you should be able to …
OOP Basics
- Define the term “class” as used in OOP
- Explain the purpose of classes in computer programs
- Describe the primary keywords used in declaring a class
- Define the term “method” and give an example
- Create simple classes with methods only
- Explain what is meant by “overloading”
- Describe the syntax of a method declaration (aka, method implementation)
- Explain how classes with identical names can be distinguished from each other
General Programming Concepts and Terms
- Define the term “keyword” as it applies to programming languages
- Define the term “identifier” as it applies to programming languages
- Define the term “program statement” and identify how the computer recognizes a program statement
- Define the term “syntax” as it applies to programming languages
- Identify the entry point for every computer program
- Perform simple output to the console using System.Console
- Identify the basic structure of a simple C# program
- Explain what is meant by a “driver”
- Explain what is meant by a “case-sensitive” programming language
- Explain what is meant by a “strongly-typed” programming language
- Explain what “string concatenation” is and how it works
- Define and distinguish the terms “argument” and “parameter”
- Use single-line, multi-line and XML comments as a means of documenting code
- List the four pieces of information to include in comments at the top of every source file
Intro to IDEs
- Define the term “IDE” as it relates to software development tools
- Define the terms “project” and “solution”
- Identify the various parts of the IDE (Integrated Development Environment) used in this course
- Create a new project in the IDE for this course
- Create new source files in the IDE for this course
- Add existing files to a project
Code Samples
The following examples are used to illustrate this topic.
- Nothingness - This class represents the absolute minimum code required to code a class. Even though it’s not a very “useful” class, it does provide and introduction to the ideas of classes, keywords and identifiers.
- HelloWorld - This adaptation of the classic “Hello World” program illustrates static methods. This example includes and introduces the concept of a “driver”.
- Comments - This class is not really “functional”, but is intended to illustrate the basic types of comments allowed in the programming language.
Nothingness
This class represents the absolute minimum code required to code a class. Even though it’s not a very “useful” class, it does provide and introduction to the ideas of classes, keywords and identifiers.
1
namespace
Topic.A.Examples
2
{
3
public
class
Nothingness
4
{
5
6
}
7
}
HelloWorld
This adaptation of the classic “Hello World” program illustrates static methods. This example includes and introduces the concept of a “driver”.
1
namespace
Topic.A.Examples
2
{
3
public
class
Salutation
// Define a class called "Salutation"
4
{
5
public
static
string
Greeting
()
6
{
7
return
"Hello World!"
;
8
}
// end of Greeting()
9
10
public
static
string
Greeting
(
string
name
)
11
{
12
return
"Hello "
+
name
;
13
}
// end of Greeting(string)
14
15
public
static
string
Farewell
()
16
{
17
return
"So long!"
;
18
}
// end of Farewell()
19
}
// end of Salutation class
20
}
1
namespace
Topic.A.Examples
2
{
3
public
class
HelloWorld_Driver
4
{
5
public
static
void
Main
(
string
[]
args
)
6
{
7
System
.
Console
.
WriteLine
(
Salutation
.
Greeting
());
8
System
.
Console
.
WriteLine
(
Salutation
.
Greeting
(
"Bob"
));
9
System
.
Console
.
WriteLine
();
// print a blank line
10
System
.
Console
.
WriteLine
(
Salutation
.
Farewell
());
11
}
12
}
13
}
Comments
This class is not really “functional”, but is intended to illustrate the basic types of comments allowed in the programming language.
1
/*
2
* File: Comments.cs
3
* Author: Dan Gilleland
4
* Date: 2010
5
* Purpose: To illustrate multi-line, single-line, and XML comments.
6
* This is a multi-line comment.
7
*/
8
namespace
Topic.A.Examples
9
{
10
/// <summary>
11
/// Comments illustrates multi-line, single-line, and XML comments.
12
/// </summary>
13
/// <remarks>
14
/// This class is a stand-alone class used to illustrate comments.
15
/// This particular XML comment is "attached" to the class as
16
/// a whole, while other XML comments are for fields or methods
17
/// in the class (a few methods and fields have been included for
18
/// illustration purposes).
19
/// [Author: Dan Gilleland]
20
/// </remarks>
21
public
class
Comments
22
{
23
/// <summary>
24
/// This is a method of <see cref="Comments"/>
25
/// </summary>
26
/// <returns>This method returns a string.</returns>
27
public
static
string
SimpleMethod
()
28
{
29
return
"Hello World!"
;
// "Hello World!" is a literal string value
30
}
// end of SimpleMethod()
31
32
/// <summary>
33
/// This is a one-sentence description of the method.
34
/// </summary>
35
/// <param name="name">This is where I describe the purpose of this para\
36
meter
</
param
>
37
/// <returns>Here I describe what information is returned from this meth\
38
od
.</
returns
>
39
/// <remarks>
40
/// This method has a single parameter.
41
/// </remarks>
42
public
static
int
MethodWithParameter
(
string
name
)
43
{
44
return
name
.
Length
;
// This is a single-line comment (must be end of\
45
physical
line
)
46
}
// end of MethodWithParameter(string)
47
}
// end of Comments class
48
}
Practice Exercises
- OuterSpace – This class is the simplest possible class (and, coincidentally, one of the most useless).
- AnsweringMachine – The AnsweringMachine class provides a method to give an answer to an incoming phone call.
Driver – This class is the driver for the AnsweringMachine class. - Salutation – This is the Salutation class that was previously demonstrated.
HelloWorld_Driver – This class is the driver for the Salutation class.
OuterSpace
This class is the simplest possible class (and, coincidentally, one of the most useless).
Problem Statement:
Create a class called OuterSpace. This class has no members at all (it is empty, like outer space). Add a multi-line comment at the beginning that should include your full name as the author of the class. Also make an XML comment for the class as a whole.
AnsweringMachine
The AnsweringMachine class provides a method to give an answer to an incoming phone call.
Problem Statement:
Create the AnsweringMachine class so that it can provide a default answer for an incoming phone call as well as a customizable answer. The methods should be named answer and they should return a String. There should be two methods in total, and both of them should be declared as static. The actual content of the default message can be whatever you choose, while the customizable method will receive a single String argument that has the name of the person receiving the message. Also create a driver that demonstrates the AnsweringMachine in a Console environment.
Use the following details to guide your solution.
Method Detail
-
public static string Answer()
Provides a standard default message for the answering machine.Returns:
A String that instructs the caller to leave a message. -
public static string Answer(string name)
Provides a customizable message for the answering machine.To use this method, supply a person’s name, and this name will be incorporated into the message that is returned. For example,
System.Console.WriteLine(AnsweringMachine.Answer("Bob");
Parameters:
name
- A String that is the name of the person being called.
Returns:
A String that instructs the caller to leave a message for the person with the supplied name.
Salutation and HelloWorld_Driver
In each of the single-line comments above a line of code, enter a phrase or sentence in English that describes what is done in that line of code.
Salutation
1
// Instructions: Enter comments in each blank to describe the following code
2
// _____________________________________________________
3
namespace
Topic.A.Exercises
4
{
5
6
// _____________________________________________________________________
7
public
class
Salutation
8
{
9
// _________________________________________________________________
10
public
static
string
Greeting
()
11
{
12
// _____________________________________________________________
13
return
"Hello World!"
;
14
}
// end of Greeting()
15
16
// _________________________________________________________________
17
public
static
string
Greeting
(
string
name
)
18
{
19
// _____________________________________________________________
20
return
"Hello "
+
name
;
21
}
// end of Greeting(string)
22
23
// _________________________________________________________________
24
public
static
string
Farewell
()
25
{
26
// _____________________________________________________________
27
return
"So long!"
;
28
}
// end of Farewell()
29
}
// end of Salutation class
30
}
HelloWorld_Driver
1
// Instructions: Enter comments in each blank to describe the following code
2
// _____________________________________________________
3
namespace
Topic.A.Exercises
4
{
5
// _____________________________________________________
6
public
class
HelloWorld_Driver
7
{
8
// __________________________________________________________________
9
public
static
void
main
(
string
[]
args
)
10
{
11
// ______________________________________________________________
12
System
.
Console
.
WriteLine
(
Salutation
.
Greeting
());
13
// ______________________________________________________________
14
System
.
Console
.
WriteLine
(
Salutation
.
Greeting
(
"Bob"
));
15
// ______________________________________________________________
16
System
.
Console
.
WriteLine
();
// print a blank line
17
// ______________________________________________________________
18
System
.
Console
.
WriteLine
(
Salutation
.
Farewell
());
19
}
20
}
21
}
Topic B – Starting Classes
Overview
This topic introduces some of the basic syntax and grammar surrounding Object-Oriented Programming in Java. The following keywords are introduced. (Note that additional keywords from previous topics may also be present.)
- new
- char
- int
- double
This topic will also introduce the following grammars, syntax and language constructs. (Note that additional concepts from previous topics may also be present.)
- Method declaration syntax (instance methods)
- Object instantiation
- Instance method call syntax (with and without arguments)
- Class Field declaration syntax (member variables)
- Assignment statement syntax
- Accessing public fields in objects (storing & retrieving values)
Note that this package introduces the distinction between static and non-static methods. Static methods, also known as “class methods”, are identified by the keyword static and must be qualified by the class name; for example, in the following method call Salutation is the name of the class and Greeting is a static method of that class.Salutation.Greeting()
Non-static methods, also known as “instance methods”, are identified by the absence of the static keyword and must be called by using an instance of the class (that is, an object). An example of calling an instance method would beapp.Greeting()
where the app is an instance of the Salutation class.
LOGs
At the end of this topic, you should be able to …
OOP Basics
- Define the term “object” as used in OOP
- Describe the syntax of static and non-static method declarations
- Compare and contrast the syntax for method declarations (implementations) vs. method calls (for both static and non-static methods)
- Define the term “field” as used in OOP and give an example
- Compare and contrast instance and class members, for both methods and fields
- Identify the “member access operator” and explain it’s purpose
- Create (instantiate) objects
- Distinguish between classes and objects in OOP
- Explain what is meant by the phrase “type extensibility” and how classes represent “complex” data types in OOP
General Programming Concepts and Terms
- List the three categories of simple information
- Define the term “intrinsic data type”
- Explain what an assignment statement is and how it works
- Compare and contrast the three categories of simple information with the complex types of information which classes represent
- Explain the advantages of using classes and objects instead of only using intrinsic data types
Code Samples
The following examples are used to illustrate this topic.
- Salutation - This adaptation of the classic “Hello World” program illustrates instance methods. This example includes and introduces the concept of a “driver” and the idea of creating (instantiating) an object based on a class.
- Person - This simple class illustrates and introduces the idea of fields (member variables) of a class. This example includes and introduces the idea of a driver. The driver also illustrates how a single class can be used to instantiate multiple, distinct objects.
- Account - This simple class also illustrates fields. This example includes a driver.
- Comments - This class continues the illustration of the kinds of comments allowed in the programming language. This class builds on the previous example by showing comments for fields as well as methods.
- Student - This class introduces a slightly more complex class by offering more fields. This example includes two drivers. By using two drivers, this illustrates that separate “programs” can share/use the same class definition.
- The first driver is a simple “test driver” to ensure that the class is “working”. This introduces the student to the idea that it is necessary to “test” or prove that the code we are creating is valid.
- The second driver illustrates how the a single class can act as the basis for creating many distinct objects.
- Employee + Company - These are other classes similar to the Person and Student classes. These classes, however, “share” a driver, illustrating the fact that any given “program” typically uses more than one class. In addition, this driver introduces the ToString() and Parse() methods of the DateTime class.
Salutation & Driver
This adaptation of the classic “Hello World” program illustrates instance methods. This example includes and introduces the concept of a “driver” and the idea of creating (instantiating) an object based on a class.
1
/*
2
* Purpose: To illustrate
3
* - Keywords: public, class, return
4
* - Grammar: method declaration, parameter declaration, single line co\
5
mments
6
* - Other:
7
* - string data type
8
* - method overloading
9
* - Instance members
10
*/
11
namespace
Topic.B.Examples
12
{
13
public
class
Salutation
14
{
15
public
string
Greeting
()
16
{
17
return
"Hello World!"
;
18
}
19
20
public
string
Greeting
(
string
name
)
21
{
22
return
"Hello "
+
name
;
23
}
24
}
25
}
1
/*
2
* Purpose: To illustrate
3
* - Keywords: public, class, static, void, new
4
* - Grammar: variable (object) declaration, object instantiation, meth\
5
od declaration, method call, multi-line comments
6
* - Other:
7
* - main - the entry level of every program
8
* - console output (println)
9
* - Instance vs. Class methods
10
* - instance method call
11
* - instance method call with argument
12
* - (optional) array declaration - string[]
13
*/
14
namespace
Topic.B.Examples
15
{
16
17
public
class
HelloWorld_Driver
18
{
19
public
static
void
Main
(
string
[]
args
)
20
{
21
Salutation
app
=
new
Salutation
();
22
23
System
.
Console
.
WriteLine
(
app
.
Greeting
());
24
System
.
Console
.
WriteLine
(
app
.
Greeting
(
"Bob"
));
25
}
26
}
27
}
Person
This simple class illustrates and introduces the idea of fields (member variables) of a class. This example includes and introduces the idea of a driver. The driver also illustrates how a single class can be used to instantiate multiple, distinct objects.
- Data Attributes of the Person class:
- FirstName : String
- LastName : String
- Age : Integer
1
namespace
Topic.B.Examples
2
{
3
public
class
Person
4
{
5
/// <summary>This is the first name of the person</summary>
6
public
string
FirstName
;
7
/// <summary>This is the last name of the person</summary>
8
public
string
LastName
;
9
/// <summary>This is the person's age</summary>
10
public
int
Age
;
11
}
12
}
1
namespace
Topic.B.Examples
2
{
3
public
class
DemoPerson
4
{
5
public
static
void
Main
(
string
[]
args
)
6
{
7
Person
someGuy
;
8
someGuy
=
new
Person
();
9
someGuy
.
FirstName
=
"Harry"
;
10
someGuy
.
LastName
=
"Burns"
;
11
someGuy
.
Age
=
25
;
12
13
Person
someGirl
;
14
someGirl
=
new
Person
();
15
someGirl
.
FirstName
=
"Sally"
;
16
someGirl
.
LastName
=
"Albright"
;
17
someGirl
.
Age
=
25
;
18
19
string
fullName
;
20
21
fullName
=
someGuy
.
FirstName
+
" "
+
someGuy
.
LastName
;
22
System
.
Console
.
WriteLine
(
"Hi. My name is "
+
fullName
);
23
24
fullName
=
someGirl
.
FirstName
+
" "
+
someGirl
.
LastName
;
25
System
.
Console
.
WriteLine
(
"Hi"
+
someGuy
.
FirstName
+
26
". My name is "
+
fullName
);
27
}
28
}
29
}
Account
This simple class also illustrates fields. This example includes a driver.
* Data Attributes of the Account class:
* AccountNumber : Integer
* Balance : Real
* OverdraftLimit : Double
1
namespace
Topic.B.Examples
2
{
3
public
class
Account
4
{
5
public
int
AccountNumber
;
6
public
double
Balance
;
7
public
double
OverdraftLimit
;
8
}
9
}
1
namespace
Topic.B.Examples
2
{
3
public
class
DemoAccountDriver
4
{
5
public
static
void
Main
(
string
[]
args
)
6
{
7
Account
myAccount
;
// declares a reference variable to an Account ob\
8
ject
9
myAccount
=
new
Account
();
// creates the Account object.
10
11
myAccount
.
Balance
=
500000.00
;
12
myAccount
.
OverdraftLimit
=
1000000.00
;
13
myAccount
.
AccountNumber
=
123456
;
14
}
15
}
16
}
Comments
This class continues the illustration of the kinds of comments allowed in the programming language. This class builds on the previous example by showing comments for fields as well as methods.
1
/*
2
* File: Comments.cs
3
* Author: Dan Gilleland
4
* Date: 2010
5
* Purpose: To illustrate multi-line, single-line, and XML comments.
6
* This is a multi-line comment.
7
*/
8
namespace
Topic.B.Examples
9
{
10
/// <summary>
11
/// Comments illustrates multi-line, single-line, and XML comments.
12
/// </summary>
13
/// <remarks>
14
/// This class is a stand-alone class used to illustrate comments.
15
/// This particular XML comment is "attached" to the class as
16
/// a whole, while other XML comments are for fields or methods
17
/// in the class (a few methods and fields have been included for
18
/// illustration purposes).
19
/// </remarks>
20
public
class
Comments
21
{
22
/// <summary>
23
/// Here is a simple integer variable that is pre-set to the value 5.
24
/// </summary>
25
/// <remarks>
26
/// This is an instance member (non-static) of the class.
27
/// </remarks>
28
private
int
_five
=
5
;
29
30
/// <summary>
31
/// Here is a whole number that is pre-set to the value 0.
32
/// </summary>
33
/// <remarks>
34
/// This field is a static member of the class.
35
/// </remarks>
36
private
static
int
_instanceCounter
=
0
;
37
38
/// <summary>
39
/// Here is a real number that is pre-set to the value 3.14159.
40
/// </summary>
41
/// <remarks>
42
/// This field is a constant member of the class.
43
/// </remarks>
44
private
const
double
_PI
=
3.14159
;
45
46
/* ****************** Methods ******************** */
47
/// <summary>
48
/// This is a method of <see cref="Comments"/>
49
/// </summary>
50
/// <returns>This method returns a string.</returns>
51
public
static
string
SimpleMethod
()
52
{
53
return
"Hello World!"
;
54
}
// end of SimpleMethod()
55
56
/// <summary>
57
/// This is a one-sentence description of the method.
58
/// </summary>
59
/// <param name="name">This is where I describe the purpose of this para\
60
meter
</
param
>
61
/// <returns>Here I describe what information is returned from this meth\
62
od
.</
returns
>
63
/// <remarks>
64
/// This method has a single parameter.
65
/// </remarks>
66
public
static
int
MethodWithParameter
(
string
name
)
67
{
68
return
name
.
Length
;
69
}
// end of MethodWithParameter(string)
70
}
// end of Comments class
71
}
Student
The Student class introduces a slightly more complex example by offering more fields.
- Data Attributes of the Student class:
- Name : String
- Gender : Character
- StudentId : Integer
- Program : String
- GradePointAverage : Double
- FullTime : Boolean
This example also includes two drivers. By using two drivers, this illustrates that separate “programs” can share/use the same class definition.
The first driver is a simple “test driver” to ensure that the class is “working”. This introduces the student to the idea that it is necessary to “test” or prove that the code we are creating is valid.
The second driver illustrates how the a single class can act as the basis for creating many distinct objects.
1
/**
2
* Purpose: To illustrate
3
* Highlights:
4
* - Keywords: char, int, double
5
* - Grammar: variable declaration (fields)
6
* - Other:
7
* - Instance members
8
*/
9
namespace
Topic.B.Examples
10
{
11
public
class
Student
12
{
13
public
string
Name
;
// The full name of the student
14
public
char
Gender
;
// Gender can be 'M' or 'F'
15
public
int
StudentId
;
// The school-provided student ID
16
public
string
Program
;
// The course program; e.g.: "CST"
17
public
double
GradePointAverage
;
// GPA is from 1.0 to 9.0
18
public
bool
FullTime
;
// If the student is enrolled full-t\
19
ime
20
}
21
}
1
/**
2
* Purpose: To illustrate
3
* Highlights:
4
* - Keywords: public, class, static, void, new
5
* - Grammar:
6
*/
7
namespace
Topic.B.Examples
8
{
9
public
class
DemoStudentDriver
10
{
11
public
static
void
Main
(
string
[]
args
)
12
{
13
Student
bob
,
mary
,
joe
,
susan
,
frank
;
14
bob
=
new
Student
();
15
mary
=
new
Student
();
16
joe
=
new
Student
();
17
susan
=
new
Student
();
18
frank
=
new
Student
();
19
20
bob
.
Name
=
"Bob McNalley"
;
21
bob
.
Gender
=
'M'
;
22
bob
.
Program
=
"CST"
;
23
bob
.
StudentId
=
200765789
;
24
bob
.
GradePointAverage
=
6.76
;
25
26
mary
.
Name
=
"Mary McTavishski"
;
27
mary
.
Gender
=
'F'
;
28
mary
.
Program
=
"CST"
;
29
mary
.
StudentId
=
200765790
;
30
mary
.
GradePointAverage
=
5.76
;
31
32
joe
.
Name
=
"Joe Jetson"
;
33
joe
.
Gender
=
'M'
;
34
joe
.
Program
=
"CST"
;
35
joe
.
StudentId
=
200765792
;
36
joe
.
GradePointAverage
=
4.66
;
37
38
susan
.
Name
=
"Susan Orlando"
;
39
susan
.
Gender
=
'F'
;
40
susan
.
Program
=
"CST"
;
41
susan
.
StudentId
=
200765795
;
42
susan
.
GradePointAverage
=
8.54
;
43
44
frank
.
Name
=
"Frank Smith"
;
45
frank
.
Gender
=
'M'
;
46
frank
.
Program
=
"CST"
;
47
frank
.
StudentId
=
200765797
;
48
frank
.
GradePointAverage
=
8.52
;
49
50
displayStudentInformation
(
bob
);
51
}
52
53
public
static
void
displayStudentInformation
(
Student
someStudent
)
54
{
55
System
.
Console
.
WriteLine
(
someStudent
.
Name
);
56
System
.
Console
.
WriteLine
(
someStudent
.
Gender
);
57
System
.
Console
.
WriteLine
(
someStudent
.
Program
);
58
System
.
Console
.
WriteLine
(
someStudent
.
StudentId
);
59
System
.
Console
.
WriteLine
(
someStudent
.
GradePointAverage
);
60
}
61
}
62
}
Employee & Company
The Employee and Company classes are similar to the Person and Student classes.
- Data Attributes of the Employee class:
- FirstName : String
- LastName : String
- SocialInsuranceNumber : Integer
- YearlySalary : Real
- EmploymentStartDate : Date
- Gender : Character
1
using
System
;
2
namespace
Topic.B.Examples
3
{
4
public
class
Employee
5
{
6
public
string
FirstName
;
7
public
string
LastName
;
8
public
int
SocialInsuranceNumber
;
9
public
double
YearlySalary
;
10
public
DateTime
EmploymentStartDate
;
11
public
char
Gender
;
12
}
13
}
- Data Attributes of the Company class:
- Name : String
- City : String
- IsIncorporated : Boolean
- BusinessStartDate : Date
- NumberOfEmployees : Integer
- GrossIncomeToDate : Real
1
using
System
;
2
namespace
Topic.B.Examples
3
{
4
public
class
Company
5
{
6
public
string
Name
;
7
public
string
City
;
8
public
bool
IsIncorporated
;
9
public
DateTime
BusinessStartDate
;
10
public
int
NumberOfEmployess
;
11
public
double
GrossIncomeToDate
;
12
}
13
}
In the following driver, the Employee and Company classes are both being used, illustrating the fact that any given “program” typically uses more than one class. In addition, this driver introduces the overloaded ToString() method in the DateTime class to improve the output of displaying dates and the Parse() method to convert a string representation of a date to an actual DateTime instance.
1
using
System
;
2
namespace
Topic.B.Examples
3
{
4
public
class
DemoCompanyAndEmployee
5
{
6
public
static
void
Main
(
string
[]
args
)
7
{
8
Company
Acme
=
new
Company
();
9
Employee
Salesman
=
new
Employee
();
10
Employee
Shipper
=
new
Employee
();
11
12
// Set the company's information
13
Acme
.
Name
=
"Acme International"
;
14
Acme
.
City
=
"Edmonton"
;
15
Acme
.
BusinessStartDate
=
new
DateTime
();
// new Date() defaults to t\
16
he
current
date
17
Acme
.
IsIncorporated
=
false
;
18
Acme
.
NumberOfEmployess
=
2
;
19
Acme
.
GrossIncomeToDate
=
2152368.52
;
// $ 2 million, plus change
20
21
// Set the salesman's information
22
Salesman
.
FirstName
=
"Wiley"
;
23
Salesman
.
LastName
=
"Coyote"
;
24
Salesman
.
Gender
=
'M'
;
25
Salesman
.
SocialInsuranceNumber
=
123456789
;
26
Salesman
.
EmploymentStartDate
=
DateTime
.
Today
;
27
Salesman
.
YearlySalary
=
45250.00
;
28
29
// Set the shipper's information
30
Shipper
.
FirstName
=
"Road"
;
31
Shipper
.
LastName
=
"Runner"
;
32
Shipper
.
Gender
=
'F'
;
33
Shipper
.
SocialInsuranceNumber
=
7777777
;
34
Shipper
.
EmploymentStartDate
=
DateTime
.
Parse
(
"June 1, 2008"
);
35
Shipper
.
YearlySalary
=
54520.00
;
36
37
38
// Show the information
39
System
.
Console
.
WriteLine
(
"The information for the company:"
);
40
System
.
Console
.
WriteLine
(
Acme
.
Name
);
41
System
.
Console
.
WriteLine
(
Acme
.
City
);
42
System
.
Console
.
WriteLine
(
Acme
.
BusinessStartDate
);
43
System
.
Console
.
WriteLine
(
Acme
.
IsIncorporated
);
44
System
.
Console
.
WriteLine
(
Acme
.
NumberOfEmployess
);
45
System
.
Console
.
WriteLine
(
Acme
.
GrossIncomeToDate
);
46
47
System
.
Console
.
WriteLine
(
"The employee information: Salesman"
);
48
System
.
Console
.
WriteLine
(
Salesman
.
FirstName
);
49
System
.
Console
.
WriteLine
(
Salesman
.
LastName
);
50
System
.
Console
.
WriteLine
(
Salesman
.
Gender
);
51
System
.
Console
.
WriteLine
(
Salesman
.
SocialInsuranceNumber
);
52
System
.
Console
.
WriteLine
(
Salesman
.
EmploymentStartDate
);
53
System
.
Console
.
WriteLine
(
Salesman
.
YearlySalary
);
54
55
System
.
Console
.
WriteLine
(
"The employee information: Shipper"
);
56
System
.
Console
.
WriteLine
(
Shipper
.
FirstName
);
57
System
.
Console
.
WriteLine
(
Shipper
.
LastName
);
58
System
.
Console
.
WriteLine
(
Shipper
.
Gender
);
59
System
.
Console
.
WriteLine
(
Shipper
.
SocialInsuranceNumber
);
60
System
.
Console
.
WriteLine
(
Shipper
.
EmploymentStartDate
.
ToString
(
"MMMM \
61
d
,
yyyy
"));
62
System
.
Console
.
WriteLine
(
Shipper
.
YearlySalary
);
63
}
64
}
65
}
Practice Exercises
- AnsweringMachine - Create the AnsweringMachine class so that it can provide a default answer for an incoming phone call as well as a customizable answer.
- Account - Extend the Account class from the example to include more information. Specifically, include an AccountType:String, BankName:String, BranchNumber:Integer, and InstitutionNumber:Integer.
- CanadianAddress - Create the CanadianAddress class so that it can represent the majority of possible addresses that some place may have in Canada.
- Course - Create the Course class so that it represents a post-secondary course.
- ExamResult - Create the ExamResult class so that it represents the results of an exam written by a student.
- LabResult - Create the labResult class so that it represents the results of a lab submitted by a student.
AnsweringMachine
The AnsweringMachine class provides a method to give an answer to an incoming phone call.
Problem Statement:
Create the AnsweringMachine class so that it can provide a default answer for an incoming phone call as well as a customizable answer. The methods should be named answer and they should return a String. There should be two methods in total, and both of them should be declared as instance members (non-static). The actual content of the default message can be whatever you choose, while the customizable method will receive a single String argument that has the name of the person receiving the message.
Also create a driver that demonstrates the AnsweringMachine in a Console environment
Create a driver for the AnsweringMachine class that creates an instance of the class and displays the results of calling the answer methods.
Account
Extend the Account class from the example to include more information.
Problem Statement:
Extend the Account class from the example to include more information. Specifically, include an AccountType:String, BankName:String, BranchNumber:Integer, and InstitutionNumber:Integer.
Also modify the driver to make use of the added information.
Notes
The branch number and the institution number together make up the Transit Number for a bank. “The bank transit number is 8 digits long. This is divided into a 5 digit branch number and 3 digit institution code, for example 10000-200.” (See http://en.wikipedia.org/wikiSort_code)
For more information on bank accounts and transit numbers in Canada, see http://en.wikipedia.org/wiki/Routing_transit_number#Canadian_transit_number.
CanadianAddress
This class represents an address for some place in Canada.
Problem Statement:
Create the CanadianAddress class so that it can represent the majority of possible addresses that some place may have in Canada. Design the class to have only public fields, as specified in this document.
- Data Attributes of the CanadianAddress class:
- Street : String
- Unit : String
- City : String
- Province : String
- PostalCode : String
- RuralRoute : String
- BoxNumber : String
Also create a driver for testing this class; you may use any name for the driver as long as it is not already mentioned in this package. In the driver, create instances of the CanadianAddress class that represent your current address as well as the address of your school (use hard-coded data).
Course
This class represents a post-secondary course with a theory (exam) and a lab portion.
Problem Statement:
Create the Course class so that it represents a post-secondary course. Design the class to have only public fields, as specified in this document.
- Data Attributes of the Course class:
- CourseName : String
- CourseNumber : String
- ExamCount : Integer
- LabCount : Integer
- ClassHours : Integer
Also create a driver for testing this class; you may use any name for your driver as long as it is not already mentioned in this package. In the driver, instantiate all of the first term classes you are taking and populate those objects with data (use hard-coded data).
ExamResult
This class represents the results of an exam for a student.
Problem Statement:
Create the ExamResult class so that it represents the results of an exam written by a student. Design the class to have only public fields, as specified in this document.
- Data Attributes of the ExamResult class:
- Name : String
- TotalMarks : Integer
- MarksEarned : Real
- ExamWeight : Integer
- StudentId : Integer
Also create a driver for testing this class; you may use any name for the driver as long as it is not already mentioned in this package. In the driver, instantiate all of the exams you have taken to date in this course and populate those objects with data (use hard-coded data).
LabResult
This class represents the results of an lab for a student.
Problem Statement:
Create the labResult class so that it represents the results of a lab submitted by a student. Design the class to have only public fields, as specified in this document.
- Data Attributes of the LabResult class:
- LabNumber : Integer
- TotalMarks : Integer
- MarksEarned : Real
- LabWeight : Integer
- StudentId : Integer
Also create a driver for testing this class; you may use any name for the driver as long as it is not already mentioned in this package. In the driver, instantiate all of the labs you have submitted to date in this course and populate those objects with data (use hard-coded data).
Topic C – Starting Classes
Overview
This topic introduces some of the basic syntax and grammar surrounding Object-Oriented Programming in C#. The following keywords are introduced. (Note that additional keywords from previous topics may also be present.)
• private
• this
• bool
• true
• false
• DateTime
This topic will also introduce the following grammars, syntax and language constructs. (Note that additional concepts from previous topics may also be present.)
• Private fields (encapsulation)
• Public properties (encapsulation)
• Constructor syntax
• Object instantiation with parameterized constructors
• Overriding the Object’s ToString() method
Daily LOGs
The following daily LOGs are covered in this package.
OOP Basics
• Define the term “encapsulation” as used in OOP
• Explain why encapsulation is a good design principle
• Define the term “access specifier” and identify where it occurs in the code for a class
• List the two access specifiers that are used in this course
• Describe the difference between “private” and “public” members of a class
• Describe the concepts of “properties” as used in OOP
• Define the term “backing store” as it applies to properties and fields
• Describe and explain the purpose and function of a constructor for a class
• Describe the syntax of a class constructor
• Identify when a class constructor is “called”
• Define the term “class scope” as used in OOP
• Define the term “local scope” as used in OOP
• Define the term “state” as applied to objects used in OOP
• Define the term “override” as used in OOP
• Explain the purpose and function of the ToString() method and why we sometimes want to change its default behaviour when we create classes
• Create simple class diagrams to represent classes
General Programming Concepts and Terms
• List three levels of scope
Code Samples
The following examples are used to illustrate this topic.
- Person - This simple class illustrates and introduces the idea of encapsulation (private fields with public properties). This example does not have a constructor. This example includes a driver. The driver is also used to illustrate how, with only fields & getter/setter methods, an object can be in an “unknown” (and invalid) state as soon as it is created; this idea is introduced to show the need for a constructor, and opens the discussion of the idea of a “default constructor”.
- Account - This simple class also illustrates encapsulation, but with some of the fields being read-only. This necessitates the presence of a constructor. This example includes a driver which shows that a class is in a “known state” as soon as it is created.
- Student - This class reinforces the idea of encapsulation and constructors. It also introduces the idea of overloading the default toString() method that every class inherits from the Object class. This example includes a driver with multiple objects, showing how the use of constructors makes it easier to create many objects in a few lines of code.
- Employee + Company - These are other classes similar to the Person and Student classes, but the Employee class uses Auto-Implemented properties (new since C# 3.0). Lastly, these classes “share” a driver, illustrating the fact that any given “program” typically uses more than one class.
The following class diagrams detail the design of these examples.
Person
This simple class illustrates and introduces the idea of encapsulation (private fields with public properties). This example does not have a constructor. This example includes a driver. The driver is also used to illustrate how, with only fields & getter/setter methods, an object can be in an “unknown” (and invalid) state as soon as it is created; this idea is introduced to show the need for a constructor, and opens the discussion of the idea of a “default constructor”.
![Person Class Diagram](/site_images/programming0101/C-Person.png)
Account
This simple class also illustrates encapsulation, but with some of the fields being read-only. This necessitates the presence of a constructor. This example includes a driver which shows that a class is in a “known state” as soon as it is created.
![Account Class Diagram](/site_images/programming0101/C-Account.png)
Student
This class reinforces the idea of encapsulation and constructors. It also introduces the idea of overloading the default ToString() method that every class inherits from the Object class. This example includes a driver with multiple objects, showing how the use of constructors makes it easier to create many objects in a few lines of code.
![Student Class Diagram](/site_images/programming0101/C-Student.png)
Company and Employee
These are other classes similar to the Person and Student classes, but the Employee class uses Auto-Implemented properties (new since C# 3.0). Lastly, these classes “share” a driver, illustrating the fact that any given “program” typically uses more than one class.
![Company Class Diagram](/site_images/programming0101/C-Company.png)
![Employee Class Diagram](/site_images/programming0101/C-Employee.png)
Practice Exercises
- Person - Extend the Person class to include a constructor.
- Account – Extend the Account class from the example to include more information. Specifically, include an AccountType:String, BankName:String, BranchNumber:Integer, and InstitutionNumber:Integer.
- CanadianAddress - This class represents an address for some place in Canada.
- Course - This class represents a post-secondary course with a theory (exam) and a lab portion.
- ExamResult - This class represents the results of an exam for a student.
- LabResult - This class represents the results of an lab for a student.
Person
This simple class illustrates and introduces the idea of encapsulation (private fields with public properties). This example uses a constructor for ensuring the state of an object when it is instantiated (created).
Extend the Person class from the example to include a constructor that takes in a first and last name as well as an age in the parameter list.
![Person Class Diagram](/site_images/programming0101/C-Person-2.png)
Account
Extend the Account class from the example to include more information.
Problem Statement:
Extend the Account class from the example to include more information. Specifically, include an AccountType:String, BankName:String, BranchNumber:Integer, and InstitutionNumber:Integer. Base your solution on the following class diagram.
![Account Class Diagram](/site_images/programming0101/C-Account-2.png)
Also modify the driver to make use of the added information.
Notes
The branch number and the institution number together make up the Transit Number for a bank. “The bank transit number is 8 digits long. This is divided into a 5 digit branch number and 3 digit institution code, for example 10000-200.” (See http://en.wikipedia.org/wikiSort_code)
For more information on bank accounts and transit numbers in Canada, see http://en.wikipedia.org/wiki/Routing_transit_number#Canadian_transit_number.
CanadianAddress
This class represents an address for some place in Canada.
Problem Statement:
Create the CanadianAddress class so that it can represent the majority of possible addresses that some place may have in Canada. Design the class to use auto-implemented properties as specified in this class diagram. No constructor is required for this class.
![CanadianAddress Class Diagram](/site_images/programming0101/C-CanadianAddress.png)
Also create a driver for testing this class; you may use any name for the driver as long as it is not already mentioned in this namespace. In the driver, create two instances of the CanadianAddress class that represent your current address as well as the address of your school (use hard-coded data).
Course
This class represents a post-secondary course with a theory (exam) and a lab portion.
Problem Statement:
Create the Course class so that it represents a post-secondary course. Design the class to have auto-implemented properties and a constructor as specified in this class diagram. Note that the auto-implemented properties should have their “set” implementations marked as private.
![Course Class Diagram](/site_images/programming0101/C-Course.png)
Also create a driver for testing this class; you may use any name for your driver as long as it is not already mentioned in this namespace. In the driver, instantiate all of the first term classes you are taking and populate those objects with data (use hard-coded data).
LabResult
This class represents the results of a lab for a student.
Problem Statement:
Create the LabResult class so that it represents the results of a lab submitted by a student. Design the class to have the fields, properties, and constructor as specified in this document. Also create a ToString() method that describes the information in any given instance of this class.
Use an auto-implemented property for the MarksEarned; use fields as the “backing store” for all other properties.
Note that the following properties should not have “set” implementations: TotalMarks, LabNumber, LabWeight, and StudentId.
![LabResult Class Diagram](/site_images/programming0101/C-LabResult.png)
Here are some XML comments to describe the ToString( ) method.
1
/// <summary>
2
/// This method overrides the default ToString() method to display
3
/// more meaningful information about this object.
4
/// </summary>
5
/// <returns>A string displaying the StudentId, MarksEarned, and
6
/// TotalMarks.</returns>
7
/// <remarks>
8
/// A call to this method (such as <c>Lab4.ToString()</c>)
9
/// would produce the following result:
10
/// <code>The student (200702694) received 24.5/35 for this lab.</code>
11
/// </remarks>
Also create a driver for testing this class; you may use any name for the driver as long as it is not already mentioned in this namespace. In the driver, instantiate all of the labs you have submitted to date in any course and populate those objects with data (use hard-coded data); if you haven’t had any labs as of yet, then make up some data.
### ExamResult
This class represents the results of an exam for a student.
Problem Statement:
Create the ExamResult class so that it represents the results of an exam written by a student. Design the class to have the properties and constructors as specified in this document. (Note that there are two constructors for this class.) Also create a ToString( ) method that describes the information in any given instance of this class.
Use auto-implemented properties for the entire class. Note that only the following properties should have private “set” implementations: TotalMarks, ExamName, ExamWeight, and StudentId.
![ExamResult Class Diagram](/site_images/programming0101/C-ExamResult.png)
Also create a driver for testing this class; you may use any name for the driver as long as it is not already mentioned in this namespace. In the driver, instantiate all of the exams you have taken to date in this course and populate those objects with data (use hard-coded data); if you need to, you may create fake data for the driver.
Topic D – Testing and Debugging
Overview
This topic introduces the concepts of testing and verifying that code is running correctly. Two approaches will be presented and compared: Ad-hoc test drivers and Unit Tests.
Test drivers that rely on user input/output are the traditional means of verifying that code runs properly. The biggest benefit of test drivers is that they provide quick “ad-hoc” tests and are simple to produce on any IDE. However, test drivers have some major downfalls.
Current programming techniques make use of Unit Tests. A unit test is a simple, isolated test of some part of a class. Unit tests provide a way to clearly show the success or failure of a particular section of code. Unit tests are a key part of Test Driven Development (TDD).
Regardless of whether the developer uses test drivers or unit tests, it is important to remember that the developer is still responsible to make sure that the tests (and thus, the test results) are valid. Improper use of test drivers and unit tests can lead to
* “false positives” - indicating that something works when it really doesn’t, and
* “false negatives” - indicating that something is broken when it really isn’t
Note: For this course, students will be provided with unit tests and will not be expected to have to write their own unit tests. The unit tests supplied to students will use nUnit 2.5.7 which is already installed in the lab. To use these libraries at home, simply install nUnit 2.5.7 on your home computer.
LOGs
The following daily LOGs are covered in this package.
General Programming Concepts and Terms
- Explain the role of testing as it applies to software development
- Define and compare the terms “compile-time error” and “run-time error”
- Define the term “test driver”
- Create simple ad-hoc test drivers to test for run-time errors
- Define the term “TDD”
- Compare and contrast Test Drivers and Unit Tests
- Define the terms “false positive” and “false negative”
- List three downfalls of using Test Drivers
- Identify four benefits of using Unit Tests
- Add unit testing libraries and unit testing packages to existing programs
- Use unit tests to validate the requirements of a class’ design and behaviour
- Diagnose and correct software problems by using unit tests
Code Samples
The following examples are used to illustrate this topic.
- Person - This simple class was used to introduce the idea of encapsulation (private fields with public getters and setters). This example uses a constructor for ensuring the state of an object when it is instantiated (created). In this topic, it is used to demonstrate unit testing.
- Account - This simple class also illustrates encapsulation, but with some of the fields being read-only. This class uses a constructor (which is also necessary for getting state into fields which do not have corresponding setter methods).
- Student - This class reinforces the idea of encapsulation and constructors. It also demonstrates the idea of overloading the default ToString() method that every class inherits from the Object class.
- Employee – The Employee class represents basic information about an employee of a company.
- Company - These are other classes similar to the Person and Student classes. These classes, however, “share” a driver, illustrating the fact that any given “program” typically uses more than one class.
Test Drivers (Console I/O)
TBA
Unit Tests (nUnit)
The unit tests for these classes are included in the solution folder under the “Demos + Practice” folder. Simply double-click the NUnit Test Project (.nunit) and the tests will open in the NUnit GUI.
Person
This simple class was used to introduce the idea of encapsulation (private fields with public getters and setters). This example uses a constructor for ensuring the state of an object when it is instantiated (created). In this topic, it is used to demonstrate unit testing. The following diagram represents the last design for the Person class, as completed in the exercises portion of the previous topic.
![Previous Person Class Diagram](/site_images/programming0101/D-Person.png)
The supplied unit tests check all of this previously documented behaviour, but they also check to see if the Person class has overridden the ToString()
method. Because this requirement is new, and has not yet been implemented, the unit tests show this as a “failed test.” The following diagram is the design that the unit tests are evaluating.
![Person Class Diagram](/site_images/programming0101/D-Person-1.png)
Should…
* Instantiate (build) from constructor
* Get/Set First Name
* Get/Set Last Name
* Get/Set Age
* [NOT-YET-IMPLEMENTED] Override ToString() to get the person’s full name (as first name then last name)
The test for this method will report as “failed” because it has not yet been implemented.
Account
This simple class also illustrates encapsulation, but with some of the fields being read-only. This class uses a constructor (which is also necessary for getting state into fields which do not have corresponding setter methods).
![Account Class Diagram](/site_images/programming0101/D-Account.png)
Should…
* Get Bank Name
* Get Branch Number
* Get Institution Number
* Get Account Number
* Get Account Type
* Get/Set Balance
* Get/Set Overdraft Limit
Student
This class reinforces the idea of encapsulation and constructors. It also demonstrates the idea of overloading the default ToString() method that every class inherits from the Object class.
![Student Class Diagram](/site_images/programming0101/D-Student.png)
Should…
* Get/Set Name
* Get/Set Gender
* Get/Set Student Id
* Get/Set GPA
* Get/Set Program
* Get/Set Full-Time
* Override ToString() to get the student’s ID and name
Employee
![Employee Class Diagram](/site_images/programming0101/D-Employee.png)
Should…
* Get/Set First Name
* Get/Set Last Name
* Get/Set Gender
* Get/Set Employment Date
* Get/Set Salary
* Get Social Insurance Number
Company
![Company Class Diagram](/site_images/programming0101/D-Company.png)
Should…
* Get/Set Name
* Get/Set City
* Get/Set Incorporated
* Get/Set Number of Employees
* Get/Set Gross Income to Date
* Get Business Start Date
Practice Exercises
- Person - This simple class was used to introduce the idea of encapsulation (private fields with public properties). This example uses a constructor for ensuring the state of an object when it is instantiated (created). It also demonstrates the overriding of the ToString() method inherited from the Object method.
- CanadianAddress - This class represents an address for some place in Canada.
Update this class to now include a constructor and to override the ToString() method. - Course - This class represents a post-secondary course with a theory (exam) and a lab portion.
- ExamResult - This class represents the results of an exam for a student.
- LabResult - This class represents the results of a lab for a student.
For this exercise, take the code solutions you created in the previous topic and compare your results with the jUnit tests for these classes; check with your instructor to see where you can download the unit tests.
Person
This simple class was used to introduce the idea of encapsulation (private fields with public properties). This example uses a constructor for ensuring the state of an object when it is instantiated (created). It also demonstrates the overriding of the ToString() method inherited from the Object method.
![Person Class Diagram](/site_images/programming0101/D-Person-2.png)
Should…
* Instantiate (build) from constructor
* Get/Set First Name
* Get/Set Last Name
* Get/Set Age
* Override ToString() to get the person’s full name (as first name then last name)
CanadianAddress
![CanadianAddress Class Diagram](/site_images/programming0101/D-CanadianAddress.png)
Should…
* Instantiate (build) from Constructor
* Get/Set: Street, Unit, City, Province, Postal Code, Rural Route, Box Number
* Override ToString() to just show Street, City, Province, and Postal Code
Course
![Course Class Diagram](/site_images/programming0101/D-Course.png)
Should…
* Instantiate from Constructor
* Get: Course Name, Course Number, Exam Count, Lab Count, Class Hours
ExamResult
![ExamResult Class Diagram](/site_images/programming0101/D-ExamResult.png)
Should…
* Instantiate from Constructor
* Get/Set: Marks Earned
* Get: Name, Student Id, Total Marks, Exam Weight
* Override ToString() to show
“The student (studentId) received earnedMarks/totalMarks for this examName exam.”
LabResult
![LabResult Class Diagram](/site_images/programming0101/D-LabResult.png)
Should…
* Instantiate from Constructor
* Get/Set: Marks Earned
* Get: Lab Number, Student Id, Total Marks, Lab Weight
* Override ToString() to show
“The student (studentId) received earnedMarks/totalMarks for this lab.”
Expressions, Math, Exceptions, If-Else, and Case
Topic E – Expressions and Math
Overview
This topic introduces concepts surrounding the use of arithmetic expressions and common Math library routines.
This topic will introduce the following grammars, syntax and language constructs. (Note that additional concepts from previous topics may also be present.)
- Arithmetic expressions
- Assignment statements
- Automatic type conversion and casting
- Integer division
- String concatenation
- Math library routines and constants (such as Random, Square Root, and π)
This topic will also take a deeper look at the distinctive aspects of variables, values and data types as well as demonstrate the use of overloaded constructors. This is also the first foray into creating classes that actually “do something” – these classes not only maintain state but also provide methods to generate other information besides that which is stored in a class’ fields.
LOGs
OOP Basics
- Explain how method overloading is applied to constructors
General Programming Concepts and Terms
- Name at least three kinds of program statements commonly seen in all high-level programming languages
- Distinguish between Variables, Values and Data Types
- List the five basic rules governing variables, values and data types
- List the intrinsic (built-in) data types in C#
- Explain what is meant by the phrase “type extensibility”
- Define the terms Reference Type and Value Type as they apply to data types in C#
- Define the term Identifier
- Create and initialize variables in C#
- Explain what is meant by the terms “scope” and “lifetime” as they apply to variables
- Describe what is meant by the term “expression”
- Explain the difference between program statements and expressions as well as how the two relate to each other
- List the three general sets of operators in C#
- Describe the two basic rules of using arithmetic operators that every compiler must follow.
- Use the arithmetic operators to create arithmetic expressions
- Explain what is meant by “integer division” and how that can be useful in solving particular problems regarding numbers.
- Explain the purpose of the modulus (%) operator.
- List and describe how to use the various assignment operators in C#
- Explain the difference between binary and unary operators
- Demonstrate understanding of operator precedence and how to override the default precedence of the arithmetic operators
- Summarize and distinguish the rules for automatic type conversion involving arithmetic operators and the assignment operator
- Determine the final data type for expressions involving mixed data types and type conversion
- Describe “type casting” and explain how to use it appropriately.
- Compare and contrast the prefix and postfix behaviour of the unary arithmetic operators
- Identify and explain how to use the common Math library routines (for Power, Square Root, Absolute, random numbers, pi, trigonometry, and the various types of rounding)
- Use Math rounding methods with arithmetic expressions to round real numbers to a specific precision
- Create random whole number values within a specific range
- Use type casting appropriately in C#
- Create constants in C#
- Explain how arithmetic operations affect character values in C#
- List the most common math functions of the Math class
- Demonstrate how to use the various Math functions in simple programs
- List and describe the commonly used fields and methods of the String class
- Demonstrate how to use “String Arithmetic” (concatenation)
- List the equivalent “wrapper” classes for each of the primitive types.
Code Samples
The following examples are used to illustrate this topic.
- Calculator – This class introduces simple arithmetic operations, demonstrating simple addition and multiplication.
- Person - This adaptation of the person class changes the previous design by replacing the age field with a “read-only” field for the person’s birth date. The approximate age of the person is then calculated based on the current date and the birth date.
- Account - This class illustrates simple addition and calculation by allowing deposits and withdrawals. Note that changes to the balance can now only be made through deposits and withdrawals; the balance is now “read-only”.
- ElapsedTime – This class demonstrates overloaded constructors and introduces the concepts of operator precedence and integer division.
- ResolveExpressions – This class is used in conjuncture with several sample expressions that illustrate operator precedence and automatic type conversion.
- Circle - This class represents a simple circle of a specified diameter. The radius, area and circumference are calculated.
- Square - This class represents a simple square with a specified length for its side. The area and perimeter are calculated.
- Fraction - This class represents a fraction as a numerator and denominator. It provides the double equivalent of the fraction’s value as well as a string representation that uses the numerator and denominator. It demonstrates type casting and the integer division issue.
- Angle - This class represents an angle and provides the value in the following units: degrees, radians and grads. It also gives a simple example of unicode characters (for degrees).
- StockItem - This class represents an item that is part of an inventory. The item has an item name, a cost and a profit margin (which can be positive or negative). By using the profit margin, it can derive the price of the item. This example illustrates rounding.
- Die - This class represents a single six-sided die. This example is used to illustrate random number generation and casting.
- ParkingCounter - This class represents a simple counter to monitor whether a parking lot is full or not; it tracks vehicles entering and leaving the parking lot and allows the counter to be reset when the lot is full or empty. This class illustrates increment and decrement operators and/or the assignment increment or assignment decrement operators.
- QuadradicEquation - This class is used to solve for the two possible values of a quadratic formula where quadradic equals zero. This sample illustrates order of operations and parentheses.
Calculator
This class introduces simple arithmetic operations, demonstrating simple addition and multiplication.
Problem Statement
Write the code that will act as a calculator for doing math. This first version must be a working prototype; as a prototype, it does not have to support all of the features of the final product.
The solution must meet the following requirements:
- Should add two whole numbers.
- Should multiply two whole numbers.
Use the following class diagram when creating your solution. Since this class does not have properties or fields, make the methods static.
![Calculator Class Diagram](/site_images/programming0101/E-Calculator.png)
1
public
class
Calculator
2
{
3
public
static
int
Add
(
int
firstNumber
,
int
secondNumber
)
4
{
5
return
firstNumber
+
secondNumber
;
6
}
7
8
public
static
int
Multiply
(
int
firstNumber
,
int
secondNumber
)
9
{
10
return
firstNumber
*
secondNumber
;
11
}
12
}
Person
This adaptation of the person class changes the previous design by replacing the age field with a “read-only” field for the person’s birth date. The approximate age of the person is then calculated based on the current date and the birth date.
Problem Statement
Write the code that will represent a person with a first and last name and a date of birth.
The solution must meet the following requirements (new requirements are in bold):
* Should get and set the first and last name
* Should get the birth date
* Should get the person’s approximate age (which is the age that the person will turn to in the current year)
* Should get the person’s initials
* Should override ToString() to get the person’s full name (as first name then last name)
Use the following class diagram when creating your solution.
![Person Class Diagram](/site_images/programming0101/E-Person.png)
1
public
class
Person
2
{
3
public
string
FirstName
{
get
;
set
;
}
4
5
public
string
LastName
{
get
;
set
;
}
6
7
public
DateTime
BirthDate
{
get
;
private
set
;
}
8
9
public
int
Age
10
{
11
get
12
{
13
int
currentAge
=
0
;
14
currentAge
=
DateTime
.
Today
.
Year
-
BirthDate
.
Year
;
15
return
currentAge
;
16
}
17
}
18
public
Person
(
string
firstName
,
string
lastName
,
DateTime
birthDate
)
19
{
20
FirstName
=
firstName
;
21
LastName
=
lastName
;
22
BirthDate
=
birthDate
;
23
}
24
25
26
public
override
string
ToString
()
27
{
28
return
FirstName
+
" "
+
LastName
;
29
}
30
31
public
string
Initials
32
{
33
get
34
{
35
return
FirstName
[
0
]
+
"."
+
LastName
[
0
]
+
"."
;
36
}
37
}
38
}
Account
This class illustrates simple addition and calculation by allowing deposits and withdrawals. Note that changes to the balance can now only be made through deposits and withdrawals; the balance is now “read-only”.
Problem Statement
Write the code that will represent a simple bank account.
The solution must meet the following requirements (new requirements are in bold):
- Should get the bank name, branch number, institution number, account number, balance, overdraft limit, and account type
- Should allow the overdraft limit to be set
- Should support deposits and withdrawals
Use the following class diagram when creating your solution.
![Account Class Diagram](/site_images/programming0101/E-Account.png)
1
public
void
Withdraw
(
double
amount
)
2
{
3
Balance
-=
amount
;
4
}
5
6
public
void
Deposit
(
double
amount
)
7
{
8
Balance
+=
amount
;
9
}
ElapsedTime
This class demonstrates overloaded constructors and introduces the concepts of operator precedence and integer division.
Problem Statement
Write the code that will represent a period of elapsed time for a competitor in a marathon. It should be able to represent its information in two forms:
- Hours, minutes and seconds, and
- Total seconds.
The solution must meet the following requirements:
- Should calculate the hours, minutes and seconds given the total seconds
- Should calculate the total seconds given the hours, minutes and seconds
Use the following class diagram when creating your solution.
![ElapsedTime Class Diagram](/site_images/programming0101/E-ElapsedTime.png)
1
public
class
ElapsedTime
2
{
3
public
ElapsedTime
(
int
hours
,
int
minutes
,
int
seconds
)
4
{
5
TotalSeconds
=
hours
*
60
*
60
;
6
TotalSeconds
+=
minutes
*
60
;
7
TotalSeconds
+=
seconds
;
8
9
Hours
=
hours
;
10
Minutes
=
minutes
;
11
Seconds
=
seconds
;
12
}
13
14
public
ElapsedTime
(
int
totalSeconds
)
15
{
16
Hours
=
totalSeconds
/
(
60
*
60
);
17
Minutes
=
(
totalSeconds
-
Hours
*
60
*
60
)
/
60
;
18
Seconds
=
totalSeconds
-
Hours
*
60
*
60
-
Minutes
*
60
;
19
20
TotalSeconds
=
totalSeconds
;
21
}
22
23
public
int
Hours
{
get
;
private
set
;
}
24
25
public
int
Minutes
{
get
;
private
set
;
}
26
27
public
int
Seconds
{
get
;
private
set
;
}
28
29
public
int
TotalSeconds
{
get
;
private
set
;
}
30
}
ResolveExpressions
This class is used in conjuncture with several sample expressions that illustrate operator precedence and automatic type conversion.
Problem Statement
Write the code that will provide the final value for the expressions in the following exercise (as a solution for a student’s exercise).
Expressions Exercise
On a piece of paper, evaluate the following expressions to show the final value and the data type of the final value. Show the order in which the operations are evaluated.
- 10.0 + 15 / 2 + 4.3
- 8 / 5 + 1.25
- 10.0 + 15.0 / 2 + 4.3
- 3.0 * 4 / 6 + 6
- 3.0 * (4 % 6) + 6
- 3 * 4.0 / 6 + 6
- 20.0 - 2 / 6 + 3
- 10 + 17 % 3 + 4
- (10 + 17) % 3 +4.0
- 10 + 17 / 4.0 + 4
The solution for question 2 is provided as an example. Use the accompanying class diagram when creating your coded solution as proof of your final answers.
1
namespace
Topic.E.Examples
2
{
3
public
class
ResolveExpressions
4
{
5
public
static
double
Sample1
6
{
get
{
return
10.0
+
15
/
2
+
4.3
;
}
}
7
8
public
static
double
Sample3
9
{
get
{
return
10.0
+
15.0
/
2
+
4.3
;
}
}
10
11
public
static
double
Sample4
12
{
get
{
return
3.0
*
4
/
6
+
6
;
}
}
13
14
public
static
double
Sample5
15
{
get
{
return
3.0
*
(
4
%
6
)
+
6
;
}
}
16
17
public
static
double
Sample6
18
{
get
{
return
3
*
4.0
/
6
+
6
;
}
}
19
20
public
static
double
Sample7
21
{
get
{
return
20.0
-
2
/
6
+
3
;
}
}
22
23
public
static
int
Sample8
24
{
get
{
return
10
+
17
%
3
+
4
;
}
}
25
26
public
static
double
Sample9
27
{
get
{
return
(
10
+
17
)
%
3
+
4.0
;
}
}
28
29
public
static
double
Sample10
30
{
get
{
return
10
+
17
/
4.0
+
4
;
}
}
31
}
32
}
Circle
This class represents a simple circle of a specified diameter. The radius, area and circumference are calculated.
Problem Statement
Write the code for the Circle class. The solution must meet the following requirements:
- Should get and set the diameter
- Should calculate the area, radius, and circumference
Use the following class diagram when creating your solution.
![Circle Class Diagram](/site_images/programming0101/E-Circle.png)
1
using
System
;
2
namespace
Topic.E.Examples
3
{
4
public
class
Circle
5
{
6
public
Circle
(
double
diameter
)
7
{
8
this
.
Diameter
=
diameter
;
9
}
10
11
public
double
Diameter
{
get
;
set
;
}
12
13
public
double
Radius
14
{
get
{
return
Diameter
/
2
;
}
}
15
16
public
double
Circumference
17
{
get
{
return
Math
.
PI
*
Diameter
;
}
}
18
19
public
double
Area
20
{
get
{
return
Math
.
PI
*
Radius
*
Radius
;
}
}
21
}
22
}
Square
This class represents a simple square with a specified length for its side. The area and perimeter are calculated.
Problem Statement
Write the code for the Square class. The solution must meet the following requirements:
- Should get and set the length of the side of the square
- Should calculate the area and perimeter
Use the following class diagram when creating your solution.
![Square Class Diagram](/site_images/programming0101/E-Square.png)
1
namespace
Topic.E.Examples
2
{
3
public
class
Square
4
{
5
public
Square
(
double
side
)
6
{
7
this
.
Side
=
side
;
8
}
9
10
public
double
Side
{
get
;
set
;
}
11
12
public
double
Area
13
{
14
get
{
return
Side
*
Side
;
}
15
}
16
17
public
double
Perimeter
18
{
19
get
{
return
Side
*
4
;
}
20
}
21
}
22
}
Fraction
This class represents a fraction as a numerator and denominator. It provides the double equivalent of the fraction’s value as well as a string representation that uses the numerator and denominator. It demonstrates type casting and the integer division issue.
Problem Statement
Write the code for the Fraction class. The solution must meet the following requirements:
- Should get the string representation of the fraction, as “numerator/denominator”
- Should get the numeric value of the fraction (as a real number)
- Should get the reciprocal of the fraction
Use the following class diagram when creating your solution.
![Fraction Class Diagram](/site_images/programming0101/E-Fraction.png)
1
public
class
Fraction
2
{
3
public
int
Numerator
{
get
;
private
set
;
}
4
5
public
int
Denominator
{
get
;
private
set
;
}
6
7
public
Fraction
(
int
numerator
,
int
denominator
)
8
{
9
Numerator
=
numerator
;
10
Denominator
=
denominator
;
11
}
12
13
public
Fraction
Reciprocal
14
{
15
get
{
return
new
Fraction
(
Denominator
,
Numerator
);
}
16
}
17
18
public
override
string
ToString
()
19
{
20
string
stringValue
=
""
;
21
stringValue
+=
Numerator
+
"/"
+
Denominator
;
22
return
stringValue
;
23
}
24
25
public
double
ToDouble
()
26
{
27
// The casting of numerator to a double helps
28
// ensure that we don't lose any fractional
29
// portion due to integer division.
30
double
value
=
(
double
)(
Numerator
)
/
Denominator
;
31
return
value
;
32
}
33
}
Angle
This class represents an angle and provides the value in the following units: degrees, radians and grads. It also gives a simple example of unicode characters (for degrees).
Problem Statement
Write the code for the Angle class. The solution must meet the following requirements:
- Should get and set the angle’s value (in degrees)
- Should calculate the equivalent angle in Radians and Grads, using the following formulas:
- Radians = Degrees * (π / 180)
- Grads = Radians * (200 / π)
- Should override the ToString() method to return the angle in degrees, in the following format:
- degrees°
- The Unicode character for the degrees symbol (°) is ‘\u00B0’
Use the following class diagram when creating your solution.
![Angle Class Diagram](/site_images/programming0101/E-Angle.png)
1
using
System
;
2
namespace
Topic.E.Examples
3
{
4
public
class
Angle
5
{
6
public
Angle
(
double
degrees
)
7
{
8
this
.
Degrees
=
degrees
;
9
}
10
11
public
double
Degrees
{
get
;
set
;
}
12
13
public
double
Radians
14
{
15
get
16
{
17
double
radians
=
Degrees
*
(
Math
.
PI
/
180
);
18
return
radians
;
19
}
20
}
21
22
public
double
Grads
23
{
24
get
25
{
26
double
grads
=
Radians
*
(
200
/
Math
.
PI
);
27
return
grads
;
28
}
29
}
30
31
// http://unicode.org/notes/tn28/UTN28-PlainTextMath.pdf
32
// Page 40 of the above reference for the degree symbol
33
public
override
string
ToString
()
34
{
35
return
Degrees
.
ToString
()
+
'\
u00B0
'
;
36
}
37
}
38
}
StockItem
This class represents an item that is part of an inventory. The item has an item name, a cost and a profit margin (which can be positive or negative). By using the profit margin, it can derive the price of the item. This example illustrates rounding.
Problem Statement
Write the code for the StockItem class. The solution must meet the following requirements:
- Should get and set the name, cost and profit margin of the stock item
- Should represent the profit margin as a percent; a value of 45 means 45%
- Should calculate the price of the item, to the nearest cent
- Use the rounding where values under a half-cent are rounded down and values greater than or equal to a half-cent are rounded up
Use the following class diagram when creating your solution.
![StockItem Class Diagram](/site_images/programming0101/E-StockItem.png)
1
using
System
;
2
namespace
Topic.E.Examples
3
{
4
public
class
StockItem
5
{
6
public
double
Cost
{
get
;
set
;
}
7
8
public
double
ProfitMargin
{
get
;
set
;
}
9
10
public
StockItem
(
string
itemName
,
double
cost
,
double
profitMargin
)
11
{
12
this
.
ItemName
=
itemName
;
13
this
.
Cost
=
cost
;
14
this
.
ProfitMargin
=
profitMargin
;
15
}
16
17
public
string
ItemName
{
get
;
set
;
}
18
19
public
double
Price
20
{
21
get
22
{
23
// Round to the nearest cent
24
double
price
=
Cost
;
25
price
+=
Cost
*
(
ProfitMargin
/
100
);
26
return
Math
.
Round
(
price
*
100
)
/
100.0
;
27
}
28
}
29
}
30
}
Die
This class represents a single six-sided die. This example is used to illustrate random number generation and casting.
Problem Statement
Write the code for the Die class. The solution must meet the following requirements:
- Should generate a random value from 1 to 6, when initially created and when re-rolled
- Should get the face value of the die
Use the following class diagram when creating your solution. Note that this uses the Random class as a private static field.
![Die Class Diagram](/site_images/programming0101/E-Die.png)
1
using
System
;
2
namespace
Topic.E.Examples
3
{
4
public
class
Die
5
{
6
private
static
Random
rnd
=
new
Random
();
7
8
public
Die
()
9
{
10
Roll
();
11
}
12
13
public
int
FaceValue
{
get
;
private
set
;
}
14
15
public
void
Roll
()
16
{
17
FaceValue
=
rnd
.
Next
(
6000
)
%
6
+
1
;
18
}
19
}
20
}
ParkingCounter
This class represents a simple counter to monitor whether a parking lot is full or not; it tracks vehicles entering and leaving the parking lot and allows the counter to be reset when the lot is full or empty. This class illustrates increment and decrement operators and/or the assignment increment or assignment decrement operators.
Problem Statement
Write the code that will monitor vehicles entering and leaving a parking lot. The solution must meet the following requirements:
- Should track vehicles entering
- Should track vehicles leaving
- Should get total parking spots
- Should get open (empty) spots
- Should reset lot as full (that is, fill the parking lot)
- Should reset lot as empty (that is, clear all the parking spots of vehicles)
Use the following class diagram when creating your solution.
![ParkingCounter Class Diagram](/site_images/programming0101/E-ParkingCounter.png)
1
namespace
Topic.E.Examples
2
{
3
public
class
ParkingCounter
4
{
5
public
int
ParkingSpots
{
get
;
private
set
;
}
6
7
public
int
OpenSpots
{
get
;
private
set
;
}
8
9
public
ParkingCounter
(
int
parkingSpots
)
10
{
11
this
.
ParkingSpots
=
parkingSpots
;
12
this
.
OpenSpots
=
parkingSpots
;
13
}
14
15
public
ParkingCounter
(
int
parkingSpots
,
int
numberOfCars
)
16
{
17
this
.
ParkingSpots
=
parkingSpots
;
18
this
.
OpenSpots
=
this
.
ParkingSpots
-
numberOfCars
;
19
}
20
21
public
void
Leave
()
22
{
23
OpenSpots
++;
24
}
25
26
public
void
Enter
()
27
{
28
OpenSpots
--;
29
}
30
31
public
void
ResetLotAsEmpty
()
32
{
33
OpenSpots
=
ParkingSpots
;
34
}
35
36
public
void
ResetLotAsFull
()
37
{
38
OpenSpots
=
0
;
39
}
40
}
41
}
QuadradicEquation
This class is used to solve for the two possible values of a quadratic formula where quadratic equals zero. It is based off of the following formula.
![](/site_images/programming0101/E-QuadraticFormula.png)
This sample illustrates order of operations and parentheses.
Problem Statement
Write the code that will represent a quadratic equation that has a higher and lower root. It is to use the Quadratic formula, which states:
For ax^2 + bx + c = 0
$, the value of x is given by
![](/site_images/programming0101/E-QuadraticFormula.png)
More information on the quadratic formula can be found at http://www.purplemath.com/modules/quadform.htm.
The solution must meet the following requirements:
- Should get the lower root, using the quadratic formula
x=(-b-√(b^2-4ac))/2a
$ - Should get the higher root, using the quadratic formula
x=(-b+√(b^2-4ac))/2a
$ - Should overload the ToString() method to represent the quadratic formula showing the values for a, b and c in the following format:
a____x2 + ____b____x + ____c = 0
For example, given the values of 1, 3 and -4 for a, b and c respectively, the method should produce
1x2 + 3x + -4 = 0
Use the accompanying class diagram when creating your solution.
![QuadraticEquation Class Diagram](/site_images/programming0101/missing.png)
1
using
System
;
2
namespace
Topic.E.Examples
3
{
4
public
class
QuadraticEquation
5
{
6
private
int
a
;
7
private
int
b
;
8
private
int
c
;
9
10
public
QuadraticEquation
(
int
a
,
int
b
,
int
c
)
11
{
12
this
.
a
=
a
;
13
this
.
b
=
b
;
14
this
.
c
=
c
;
15
}
16
17
public
double
LowerRoot
18
{
19
get
20
{
21
double
value
;
22
value
=
(-
b
-
Math
.
Sqrt
(
b
*
b
-
4
*
a
*
c
))
/
(
2
*
a
);
23
return
value
;
24
}
25
}
26
27
public
double
HigherRoot
28
{
29
get
30
{
31
double
value
;
32
value
=
(-
b
+
Math
.
Sqrt
(
b
*
b
-
4
*
a
*
c
))
/
(
2
*
a
);
33
return
value
;
34
}
35
}
36
37
38
public
override
string
ToString
()
39
{
40
return
a
.
ToString
()
+
"x^2 + "
+
b
+
"x + "
+
c
+
" = 0"
;
41
}
42
}
43
}
Practice Exercises
- Calculator – This exercise expands on the original Calculator class to perform subtraction and division with integers.
- Fraction – This exercise expands on the original Fraction class to include methods that allow for adding, subtracting, multiplying, and dividing fractions.
- Square – This exercise expands on the original Square class to include a method that determines the diagonal of a square.
- Coordinate – Not Yet Implemented The Coordinate class represents a geographical co-ordinate for either longitude or latitude. A Coordinate’s value can be expressed either as a real number or as degrees, minutes and seconds. It makes use of integer division and overloaded constructors.
- PaintEstimator – The PaintEstimator class is used to estimate the number of paint cans needed for painting a simple room (with or without a window). It makes use of a constant and the Math library; it also uses overloaded constructors.
- BulkItem – The BulkItem class represents products that are available in bulk and shows the cost of individual items. It makes use of rounding (to two decimal places).
- Die - This exercise expands on the original Die class to allow for creating a die of any number of sides, with a default of six sides. This means that there is an overloaded constructor.
- RoundingCalculator – This exercise demonstrates rounding using separate methods for each level of rounding precision.
- GenericRoundingCalculator – This exercise demonstrates rounding to the nearest whole number of fractional number using a couple of “generic” methods.
- PeopleCounter – This simple class is used to count the number of people who have entered a store in a single day. It takes a simplistic approach, counting each person entering and leaving, estimating the number of people for the day by dividing the total count by two.
- ScoreCard – Not Yet Implemented This class represents a scorecard for tracking bowling scores frame by frame. It produces a final tally for the game, as well as the current score and the current frame.
- Cylinder – The Cylinder class represents a cylindrical object whose height and radius is known. The class provides methods to calculate the volume and surface area.
- Cone – The Cone class represents a conical object whose height and base radius is known. The class provides methods to determine the volume and surface area with this information.
- GravityCalculator – The GravityCalculator provides static methods for determining an object’s weight for the various planets in our solar system, given the equivalent weight as found on Earth.
- CurrencyCalculator – The CurrencyCalculator allows the conversion of US dollars to four other currencies, given the current exchange rate of those currencies.
For these exercises, compare your results with the unit tests for these classes.
Calculator
This exercise expands on the original Calculator class to perform subtraction and division with integers.
Problem Statement
Write the code that will act as a calculator for doing math. This version is a follow-up on the previous prototype; now it should support subtraction and division.
The solution must meet the following requirements:
- Should add two whole numbers.
- Should multiply two whole numbers.
- Should subtract two whole numbers.
- Should divide two whole numbers.
Use the following class diagram when creating your solution.
![Calculator Class Diagram](/site_images/programming0101/E-Calculator-2.png)
Fraction
This exercise expands on the original Fraction class to include methods that allow for adding, subtracting, multiplying, and dividing fractions.
Problem Statement
Write the code needed to expand the capabilities of the Fraction class. The class must now support the ability to add, subtract, multiply, and divide fractions as well as allow the individual numerator and denominator values to be seen. The solution must meet the following requirements:
- Should get the string representation of the fraction, as “numerator/denominator”
- Should get the numeric value of the fraction (as a real number)
- Should get the reciprocal of the fraction
- Should get the numerator and denominator
- Should add another fraction to its existing value
- Should subtract another fraction from its existing value
- Should multiply its existing value by another fraction
- Should divide its existing value by another fraction
As an assist, the following code can be used for the multiplication method.
1
public
void
multiplyBy
(
Fraction
otherFraction
)
2
{
3
this
.
numerator
=
this
.
numerator
*
otherFraction
.
numerator
;
4
this
.
denominator
=
this
.
denominator
*
otherFraction
.
denominator
;
5
}
Use the following class diagram when creating your solution.
![Fraction Class Diagram](/site_images/programming0101/E-Fraction-2.png)
Square
This exercise expands on the original Square class to include a method that determines the diagonal of a square.
Problem Statement
Write the code needed to add the ability for a Square to determine the length of its diagonal. The solution must meet the following requirements:
- Should get and set the length of the side of the square.
- Should calculate the area, perimeter, and diagonal of the square.
Use the following class diagram when creating your solution.
![Square Class Diagram](/site_images/programming0101/E-Square-2.png)
Coordinate
Not Yet Implemented The Coordinate class represents a geographical co-ordinate for either longitude or latitude. A Coordinate’s value can be expressed either as a real number or as degrees, minutes and seconds. It makes use of integer division and overloaded constructors.
Problem Statement
Write the code needed to represent a geographical co-ordinate for longitude and latitude. The solution must meet the following requirements:
- Should get the type of coordinate (such as “longitude” or “latitude”)
- Given the hours, minutes and seconds, it
- should calculate coordinate value as a real number
- should get hours, minutes, and seconds
- Given the coordinate value as a real number, it
- should calculate the hours, minutes and seconds
- should get the coordinate value as a real number
Use the following class diagram when creating your solution.
![Coordinate Class Diagram](/site_images/programming0101/E-Coordinate.png)
PaintEstimator
The PaintEstimator class is used to estimate the number of paint cans needed for painting a simple room (with or without a window). It makes use of a constant and the Math library; it also uses overloaded constructors.
Problem Statement
Write the code needed to help a painter to estimate the number of paint cans to paint simple rooms (with or without a window). The solution must meet the following requirements:
- Uses a constant value of 8.0 for the paint coverage. (8 square metres per can)
- Should get room height, width, and length
- Should get and set the window’s width and height
- Should calculate the number of paint cans for the room and the window
- Should calculate the surface area to be painted
- The room’s height, length and width should have a private set property.
Use the following class diagram when creating your solution.
![PaintEstimator Class Diagram](/site_images/programming0101/E-PaintEstimator.png)
BulkItem
The BulkItem class represents products that are available in bulk and shows the cost of individual items. It makes use of rounding (to two decimal places).
Problem Statement
Write the code for the BulkItem class. The solution must meet the following requirements:
- Should get and set the cost and quantity of the bulk item
- Should calculate the cost for each item in the bulk item
- Should properly round values for currency (either the US or Canadian dollar)
- The Quantity property’s set should be private.
Use the following class diagram when creating your solution.
Die
This exercise expands on the original Die class to allow for creating a die of any number of sides, with a default of six sides. This means that there is an overloaded constructor.
Problem Statement
Modify the Die class from the examples to support multi-sided die other than just the standard six sides. The solution must meet the following requirements (new requirements are in bold):
- The Sides and FaceValue properties’ set should be private.
- Should generate a six-sided die by default
- Should get the number of sides of the die
- Should randomly generate each side (if rolled enough); for example, if the die has ten sides, it should eventually roll a 1, 2, 3, 4, 5 6, 7, 8, 9, and 10
Use the following class diagram when creating your solution.
![Die Class Diagram](/site_images/programming0101/E-Die-2.png)
RoundingCalculator
This exercise demonstrates rounding using separate methods for each level of rounding precision.
Problem Statement
Write the code needed to provide rounding of various degrees of accuracy. The solution must meet the following requirements:
- All of the methods should be static.
- Should correctly round up to the nearest thousand
- Should correctly round down to the nearest thousand
- Should correctly round up to the nearest hundred
- Should correctly round down to the nearest hundred
- Should correctly round up to the nearest ten
- Should correctly round down to the nearest ten
- Should correctly round up to the nearest one
- Should correctly round down to the nearest one
- Should correctly round up to the nearest tenth
- Should correctly round down to the nearest tenth
- Should correctly round up to the nearest hundredth
- Should correctly round down to the nearest hundredth
Use the following class diagram when creating your solution.
![RoundingCalculator Class Diagram](/site_images/programming0101/E-RoundingCalculator.png)
GenericRoundingCalculator
This exercise demonstrates rounding to the nearest whole number of fractional number using a couple of “generic” methods.
Problem Statement
Write the code needed to perform rounding to either whole numbers or fractions at a specified level of precision. The solution must meet the following requirements:
- All of the methods should be static.
- Should correctly round up or down to the nearest whole number, such as
- the nearest thousand
- the nearest hundred
- the nearest ten
- the nearest one
- Should correctly round up or down to the nearest fractional value, such as
- the nearest tenth
- the nearest hundredth
Use the following class diagram when creating your solution.
![GenericRoundingCalculator Class Diagram](/site_images/programming0101/E-GenericRoundingCalculator.png)
PeopleCounter
This simple class is used to count the number of people who have entered a store in a single day. It takes a simplistic approach, counting each person entering and leaving, estimating the number of people for the day by dividing the total count by two.
Problem Statement
Write the code needed to track people entering and leaving a store. It must be able to estimate the number of people that have entered the store at the end of the day. The solution must meet the following requirements:
- The Count property should have a private set.
- Should default to having a count of zero people when first started up
- Should increment by one (that is, count a single person)
- Should increment by a specified quantity (for when a group of people enter)
- Should adequately estimate the number of people who entered the store, assuming that each person who enters also leaves the store
- Each estimate should be rounded down; for example, if 15 people are counted, then the estimate should be for only 7 (not 7.5 or 8)
Use the following class diagram when creating your solution.
![PeopleCounter Class Diagram](/site_images/programming0101/E-PeopleCounter.png)
ScoreCard
Not Yet Implemented This class represents a scorecard for tracking bowling scores frame by frame. It produces a final tally for the game, as well as the current score and the current frame.
Problem Statement
Write the code needed to.
The solution must meet the following requirements:
- Should
Use the following class diagram when creating your solution.
### Cylinder
The Cylinder class represents a cylindrical object whose height and radius is known. The class provides methods to calculate the volume and surface area.
Problem Statement
Write the code for the Cylinder class that meets the following requirements:
- The Radius and Height properties should have a private set.
- Should get the radius and the height
- Should calculate the volume and the surface area
-
Volume of a Cylinder = pi * r^2 * h
$ -
Surface Area of a Cylinder = 2 * pi * r^2 + 2 * pi * r * h
$
-
Use the following class diagram when creating your solution.
![Cylinder Class Diagram](/site_images/programming0101/E-Cylinder.png)
Cone
The Cone class represents a conical object whose height and base radius is known. The class provides methods to determine the volume and surface area with this information.
Problem Statement
Write the code for the Cone class that meets the following requirements:
- The Radius and Height properties should have a private set.
- Should get the radius and the height
- Should calculate the volume and the surface area
-
Volume of a Cone = 1/3 * pi * r^2 * h
$ -
Surface Area of a Cone = pi * r^2 + pi * r * sqrt(r^2 + h^2)
$
-
Note that the portion sqrt(r^2 + h^2)
$ is known as the slant height.
Use the following class diagram when creating your solution.
![Cone Class Diagram](/site_images/programming0101/E-Cone.png)
GravityCalculator
The GravityCalculator provides static methods for determining an object’s weight for the various planets in our solar system, given the equivalent weight as found on Earth.
Problem Statement
Write the code needed to convert Earth weights to their equivalent for the other planets in our solar system. The solution must meet the following requirements:
- All the methods should be static.
- Should convert a weight in Earth kilograms to their equivalent weight on
- Mercury
- Venus
- Mars
- Jupiter
- Saturn
- Uranus
- Neptune
- For information on equivalent weights among the planets, see these URLS.
- NinePlanets.org
- http://www.serve.com/chunter/index/info/aweigh.html
Use the following class diagram when creating your solution.
![GravityCalculator Class Diagram](/site_images/programming0101/E-GravityCalculator.png)
CurrencyCalculator
The CurrencyCalculator allows the conversion of US dollars to four other currencies, given the current exchange rate of those currencies.
Problem Statement
A currency exchange store at the international airport needs a program to convert from US dollars to four other currencies: Canadian dollar, Euro, Japanese Yen, and the Great Britain Pound. The store uses a set exchange rate for each currency as established at the start of the day. Write the code for a class called CurrencyCalculator to meet this need. The solution must meet the following requirements:
- Should correctly convert US dollars to the
- British Pound (GBP)
- Canadian Dollar (CAD)
- Euro (EUR)
- Japanese Yen (JPY)
- Should use the correct level of precision when making the exchange; each currency uses a different number of significant digits:
- CAD, GBP and EUR use two digits
- JPY uses three digits
To illustrate the possible exchange rates, please refer to the following images.
![Currency exchange rates sourced from http://www.x-rates.com](/site_images/programming0101/E-CurrencyExchange.png)
![](/site_images/programming0101/E-CurrencyAmericanDollar.png)
Use the following class diagram when creating your solution.
![CurrencyCalculator Class Diagram](/site_images/programming0101/E-CurrencyCalculator.png)
As a starter, you can use the following code to begin creating your class.
1
public
class
CurrencyCalculator
2
{
3
// The following are multipliers to convert the
4
// US dollar to different currencies.
5
/* The multiplier to convert US dollars to Canadian dollars. */
6
private
double
_ToCanadian
;
// CAD - Canadian Dollar
7
/* The multiplier to convert US dollars to the Euro. */
8
private
double
_ToEuro
;
// EUR - Euro
9
/* The multiplier to convert US dollars to the Japanese Yen. */
10
private
double
_ToYen
;
// JPY - Japanese Yen
11
/* The multiplier to convert US dollars to the British Pound. */
12
private
double
_ToPound
;
// GBP - Great Britain Pound
13
14
/* The number of significant digits for the Canadian dollar.
15
* The unit for portions of a dollar is the Cent. */
16
private
static
int
_CadDigits
=
2
;
// Cents
17
/* The number of significant digits for the Euro.
18
* The unit for portions of a dollar is the Cent. */
19
private
static
int
_EuroDigits
=
2
;
// Cents
20
/* The number of significant digits for the Japanese Yen.
21
* The unit for 1/100<sup>th</sup> portions of the Yen is the Sen,
22
* while each 1/1000<sup>th</sup> is known as a Rin. */
23
private
static
int
_YenDigits
=
3
;
// 1/100 is sen, 1/1000 is rin
24
/* The number of significant digits for the British Pound.
25
* The unit for portions of a Pound is the Pence (or P). */
26
private
static
int
_PoundDigits
=
2
;
// Pence (or p)
27
28
/*
29
* This constructor initializes a CurrencyCalculator object
30
* by taking the supplied parameter values and storing
31
* them in the fields of this instance of the class.
32
*/
33
public
CurrencyCalculator
(
double
toCanadian
,
double
toEuro
,
double
toYen
,
34
double
toPound
)
35
{
36
// Your code goes here...
37
}
38
39
/* ************** Methods **************** */
40
// Your code goes here...
41
}
Topic F – If-Else Structures
Overview
This topic introduces the if-else control flow statement and demonstrates both simple and complex conditional expressions. This topic will also introduce how to nest program statements.
LOGs
General Programming Concepts and Terms
- Describe and draw a diagram of the If-Then-Else logical structure
- Identify the programming statement that corresponds to the If-Then-Else logical structure
- Translate If-Then-Else structures into code
- Describe what is meant by a “conditional expression”
- List the operator precedence for mixing logical, arithmetic, and relational operations
- List the relational operators
- List the logical operators
- Use relational, logical, and arithmetic operators to construct conditional expressions
- Demonstrate an understanding of operator precedence in conditional expressions
- Use statement blocks to allow nesting program statements into control structures
- Define the term “boundary condition” as it relates to if-else statements and testing
- Identify the correct way to compare or check the contents of strings in conditional expressions
- List and describe the commonly used properties and methods of the String class that would be used in if-else statements
Code Samples
The following examples are used to illustrate this topic.
- StockItem - This class represents an item that is part of an inventory. The item has an item name, a cost and a profit margin (which can be positive or negative). By using the profit margin, it can derive the price of the item. The class can also report if the item is priced at or below cost.
- Account - This class illustrates simple if structure in handling withdrawals; withdrawals are only made when the amount does not exceed the balance and the overdraft. It also identifies if the account is overdrawn.
- Person - This adaptation of the person class checks the age of the person to see if the person’s life stage is infant, toddler, preschooler, school age, or adult.
- Fraction - This class now ensures that any negative denominators have their negative sign “moved” to the numerator. It also recognizes whether a fraction is proper (numerator less than denominator) or not and provides a method to express the fraction as a mixed number string.
- Angle - This version of the Angle class includes an attribute to identify the type of the angle as either acute, right, obtuse, straight, reflex, full rotation, or undefined.
- ParkingCounter - This class represents a simple counter to monitor whether a parking lot is full or not; it tracks vehicles entering and leaving the parking lot and allows the counter to be reset when the lot is full or empty. This class illustrates increment and decrement operators and/or the assignment increment or assignment decrement operators.
- MemoryAddress - This class represents a single memory address in both its base 10 and hexadecimal value.
- Color - This class represents a color as three base-10 RGB values and as a single hexadecimal value.
StockItem
This class represents an item that is part of an inventory. The item has an item name, a cost and a profit margin (which can be positive or negative). By using the profit margin, it can derive the price of the item. The class can also report if the item is priced at or below cost.
Problem Statement
Write the code for the StockItem class. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the name, cost and profit margin of the stock item
- Should represent the profit margin as a percent; a value of 45 means 45%
- Should calculate the price of the item, to the nearest cent
- Use the rounding where values under a half-cent are rounded down and values greater than or equal to a half-cent are rounded up
- Should recognize when the stock item is priced at cost (that is, the profit margin is zero)
- Should recognize when the stock item is priced below cost (that is, the profit margin is negative)
Use the following class diagram when creating your solution.
![StockItem Class Diagram](/site_images/programming0101/F-StockItem.png)
1
public
bool
IsPricedAtCost
2
{
3
get
4
{
5
bool
atCost
=
false
;
6
if
(
ProfitMargin
==
0
)
7
atCost
=
true
;
8
return
atCost
;
9
}
10
}
11
12
public
bool
IsPricedBelowCost
13
{
14
get
15
{
16
bool
belowCost
;
17
if
(
ProfitMargin
<
0
)
18
belowCost
=
true
;
19
else
20
belowCost
=
false
;
21
return
belowCost
;
22
}
23
}
Account
This class illustrates simple if structure in handling withdrawals; withdrawals are only made when the amount does not exceed the balance and the overdraft. It also identifies if the account is overdrawn.
Problem Statement
Write the code that will represent a simple bank account. The solution must meet the following requirements (new requirements are in bold):
- Should get the bank name, branch number, institution number, account number, balance, overdraft limit, and account type and allow the overdraft limit to be set
- Should support deposits
- Should only support withdrawals if the amount does not exceed the sum of the balance and the overdraft limit
- Should identify if the account is overdrawn
Use the following class diagram when creating your solution.
![Account Class Diagram](/site_images/programming0101/F-Account.png)
1
public
double
Withdraw
(
double
amount
)
2
{
3
if
(
amount
<=
Balance
+
OverdraftLimit
)
4
Balance
=
Balance
-
amount
;
5
else
6
amount
=
0
;
7
return
amount
;
8
}
9
10
public
bool
IsOverdrawn
11
{
12
get
13
{
14
bool
overdrawn
;
15
if
(
Balance
<
0
)
16
overdrawn
=
true
;
17
else
18
overdrawn
=
false
;
19
return
overdrawn
;
20
}
21
}
Person
This adaptation of the person class checks the age of the person to see if the person’s life stage is infant, toddler, preschooler, school age, or adult.
Problem Statement
Write the code that will represent a person with a first and last name and a date of birth. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the first and last name
- Should get the birth date
- Should get the person’s approximate age (which is the age that the person will turn to in the current year)
- Should override ToString() to get the person’s full name (as first name then last name)
- Should get the life stage, based on the following table
Age Range (Years) | Life Stage |
---|---|
0 | Infant |
< 3 | Toddler |
< 5 | Preschooler |
< 18 | School age |
>= 18 | Adult |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-Person.png)
1
public
string
LifeStage
2
{
3
get
{
4
string
stage
;
5
if
(
Age
==
0
)
6
stage
=
"infant"
;
7
else
if
(
Age
<
3
)
8
stage
=
"toddler"
;
9
else
if
(
Age
<
5
)
10
stage
=
"preschooler"
;
11
else
if
(
Age
<
18
)
12
stage
=
"school age"
;
13
else
14
stage
=
"adult"
;
15
return
stage
;
16
}
17
}
Fraction
This class now ensures that any negative denominators have their negative sign “moved” to the numerator. It also recognizes whether a fraction is proper (numerator less than denominator) or not and provides a method to express the fraction as a mixed number string.
Problem Statement
Write the code for the Fraction class. The solution must meet the following requirements (new requirements are in bold):
- Should get the string representation of the fraction, as “numerator/denominator”
- Should get the numeric value of the fraction (as a real number)
- Should get the reciprocal of the fraction
- Should get the numerator and denominator
- Should add another fraction to its existing value
- Should subtract another fraction from its existing value
- Should multiply its existing value by another fraction
- Should divide its existing value by another fraction
- Should affix the sign for negative fractions onto the numerator only
- Should identify if the fraction is a proper fraction
- Should express the fraction as a mixed number string
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-Fraction.png)
1
public
Fraction
(
int
numerator
,
int
denominator
)
2
{
3
Numerator
=
numerator
;
4
Denominator
=
denominator
;
5
FixSign
();
6
}
7
8
private
void
FixSign
()
9
{
10
if
(
Denominator
<
0
)
11
{
12
Denominator
*=
-
1
;
13
Numerator
*=
-
1
;
14
}
15
}
16
17
public
bool
IsProper
18
{
19
get
20
{
21
bool
proper
;
22
if
(
Numerator
<
Denominator
)
23
proper
=
true
;
24
else
25
proper
=
false
;
26
return
proper
;
27
}
28
}
29
30
public
override
string
ToString
()
31
{
32
string
stringValue
=
""
;
33
if
(
IsProper
)
34
stringValue
+=
(
Numerator
/
Denominator
)
+
" and "
35
+
(
Numerator
%
Denominator
)
+
"/"
+
Denominator
;
36
else
37
stringValue
+=
Numerator
+
"/"
+
Denominator
;
38
return
stringValue
;
39
}
Angle
This version of the Angle class includes an attribute to identify the type of the angle as either acute, right, obtuse, straight, reflex, full rotation, or undefined.
Problem Statement
Write the code for the Angle class. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the angle’s value (in degrees)
- Should calculate the equivalent angle in Radians and Grads, using the following formulas:
- Radians = Degrees * (π / 180)
- Grads = Radians * (200 / π)
- Should override the toString() method to return the angle in degrees, in the following format:
- degrees°
- The Unicode character for the degrees symbol (°) is ‘\u00B0’
- Should get the type of angle, based on the following table
Angle Range | Angle Type |
---|---|
< = 0 or > 360 | Undefined |
> 0 and < 90 | Acute |
= 90 | Right |
> 90 and < 180 | Obtuse |
= 180 | Straight |
> 180 and < 360 | Reflex |
= 360 | Full Rotation |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-Angle.png)
1
public
string
AngleType
2
{
3
get
4
{
5
string
angleType
;
6
if
(
Degrees
<=
0
)
7
angleType
=
"undefined"
;
8
else
if
(
Degrees
<
90
)
9
angleType
=
"acute"
;
10
else
if
(
Degrees
==
90
)
11
angleType
=
"right"
;
12
else
if
(
Degrees
<
180
)
13
angleType
=
"obtuse"
;
14
else
if
(
Degrees
==
180
)
15
angleType
=
"straight"
;
16
else
if
(
Degrees
<
360
)
17
angleType
=
"reflex"
;
18
else
if
(
Degrees
==
360
)
19
angleType
=
"full rotation"
;
20
else
21
angleType
=
"undefined"
;
22
return
angleType
;
23
}
24
}
ParkingCounter
This class represents a simple counter to monitor whether a parking lot is full or not; it tracks vehicles entering and leaving the parking lot and allows the counter to be reset when the lot is full or empty. This class illustrates increment and decrement operators and/or the assignment increment or assignment decrement operators.
Problem Statement
Write the code that will monitor vehicles entering and leaving a parking lot. The solution must meet the following requirements (new requirements are in bold):
- Should track vehicles entering
- Should track vehicles leaving
-
Should track the peak occupancy of the parking lot
- The peak occupancy represents the highest number of cars in the parking lot at any one time
- Should get total parking spots
- Should get open (empty) spots
- Should reset lot as full (that is, fill the parking lot)
- Should reset lot as empty (that is, clear all the parking spots of vehicles)
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-ParkingCounter.png)
1
public
int
PeakOccupancy
{
get
;
private
set
;
}
2
3
public
ParkingCounter
(
int
parkingSpots
)
4
{
5
this
.
ParkingSpots
=
parkingSpots
;
6
this
.
OpenSpots
=
parkingSpots
;
7
this
.
PeakOccupancy
=
0
;
8
}
9
10
public
ParkingCounter
(
int
parkingSpots
,
int
numberOfCars
)
11
{
12
this
.
ParkingSpots
=
parkingSpots
;
13
this
.
OpenSpots
=
this
.
ParkingSpots
-
numberOfCars
;
14
this
.
PeakOccupancy
=
numberOfCars
;
15
}
16
17
public
void
enter
()
18
{
19
OpenSpots
--;
20
int
numberOfCars
=
ParkingSpots
-
OpenSpots
;
21
if
(
numberOfCars
>
PeakOccupancy
)
22
PeakOccupancy
=
numberOfCars
;
23
}
MemoryAddress
This class represents a single memory address in both its base 10 and hexadecimal value.
Base ten is the common number system that we use in every day life. Base ten uses the digits 0-9 and the concept of the position of a digit occupying some multiple of ten. Thus, for the number 129 there is a hundreds-position (102), a tens-position (101) and a ones-position (10^0).
1
129 base 10
2
||\
3
|\ \_ 10^0 * 9 => 9
4
| \
5
\ \_ 10^2 * 2 => 20
6
\
7
\
8
\_ 10^3 * 1 => 100
9
====
10
129
Converting a value from one base to another (such as base-10 to base-16) involves thinking about the digit positions of the target base. Base 16 uses the digits 0-9 along with the letters A through F for the range of hex values zero to fifteen. Each digit position in a base-16 number can hold a value of 0 to F. Thus, a digit in the ones position is worth 1 times the digit. A two-digit hex value would have the sixteens-position (161) and a ones-position (160). A three-digit hex value would add onto that a two-hundred-and-fifty-sixth-position (16^2). For example, to convert the number 679 base 10 to a base 16, you would follow these steps.
- Divide the original number by the two-hundred-and-fifty-sixth-position (162). Then use the remainder in calculating the next position (161).
\include{longdiv} \longdiv{679}{256}
$ - Dividing the previous steps remainder (167) by 16 gives the result of 10, which is the hex-digit of
A
.\include{longdiv} \longdiv{167}{16}
$ - The remainder of that last step is the ones-position
- Thus, the base-10 value 679 is
2B9
in base-16.
1
2B9 base 16
2
||\
3
|\ \_ 16^0 * 9 => 9
4
| \
5
\ \_ 16^2 * 11 => 176
6
\
7
\
8
\_ 16^3 * 2 => 512
9
====
10
679 base 10
The following class demonstrates a small memory address (up to four hexadecimal digits) as a short
and a string representation of hexadecimal.
1
public
class
MemoryAddress
2
{
3
public
short
Base10Value
{
get
;
private
set
;
}
4
public
string
HexValue
5
{
6
get
7
{
8
string
hex
=
"0x"
;
9
// A short number in hexadecimal
10
// will be at most 4 digits
11
// FFFF
12
// ||||
13
// |||- 16^0 => 1
14
// ||-- 16^1 => 16
15
// |--- 16^2 => 256
16
// ---- 16^3 => 4096
17
int
value
=
Base10Value
;
18
int
portion
=
value
/
4096
;
19
hex
+=
ToHexDigit
(
portion
);
20
value
-=
portion
;
21
portion
=
value
/
256
;
22
hex
+=
ToHexDigit
(
portion
);
23
value
-=
portion
;
24
portion
=
value
/
16
;
25
hex
+=
ToHexDigit
(
portion
);
26
portion
=
value
%
16
;
27
hex
+=
ToHexDigit
(
portion
);
28
return
hex
;
29
}
30
}
31
32
public
MemoryAddress
(
short
address
)
33
{
34
Base10Value
=
address
;
35
}
36
37
private
static
string
ToHexDigit
(
int
number
)
38
{
39
string
result
;
40
if
(
number
<
10
)
41
result
=
number
.
ToString
();
42
else
if
(
number
==
10
)
43
result
=
"A"
;
44
else
if
(
number
==
11
)
45
result
=
"B"
;
46
else
if
(
number
==
12
)
47
result
=
"C"
;
48
else
if
(
number
==
13
)
49
result
=
"D"
;
50
else
if
(
number
==
14
)
51
result
=
"E"
;
52
else
if
(
number
==
15
)
53
result
=
"F"
;
54
else
// Should never happen...
55
result
=
""
;
56
57
return
result
;
58
}
59
}
Color
This class represents a color as three base-10 RGB values and as a single hexadecimal value.
Problem Statement
Create a data type to represent a color as both base-10 RBG values and as a hexadecimal value.
1
public
class
Color
2
{
3
public
byte
Red
{
get
;
private
set
;
}
4
public
byte
Blue
{
get
;
private
set
;
}
5
public
byte
Green
{
get
;
private
set
;
}
6
7
public
string
Hex
8
{
9
get
10
{
11
string
converted
=
"#"
;
12
converted
+=
ToHexDigit
((
byte
)(
Red
/
_Base16
))
13
+
ToHexDigit
((
byte
)(
Red
%
_Base16
));
14
converted
+=
ToHexDigit
((
byte
)(
Blue
/
_Base16
))
15
+
ToHexDigit
((
byte
)(
Blue
%
_Base16
));
16
converted
+=
ToHexDigit
((
byte
)(
Green
/
_Base16
))
17
+
ToHexDigit
((
byte
)(
Green
%
_Base16
));
18
return
converted
;
19
}
20
}
21
22
private
static
byte
_Base16
=
(
byte
)
16
;
23
private
static
string
ToHexDigit
(
byte
number
)
24
{
25
string
result
;
26
if
(
number
<
10
)
27
result
=
number
.
ToString
();
28
else
if
(
number
==
10
)
29
result
=
"A"
;
30
else
if
(
number
==
11
)
31
result
=
"B"
;
32
else
if
(
number
==
12
)
33
result
=
"C"
;
34
else
if
(
number
==
13
)
35
result
=
"D"
;
36
else
if
(
number
==
14
)
37
result
=
"E"
;
38
else
if
(
number
==
15
)
39
result
=
"F"
;
40
else
41
result
=
""
;
42
43
return
result
;
44
}
45
46
public
Color
(
byte
red
,
byte
blue
,
byte
green
)
47
{
48
Red
=
red
;
49
Blue
=
blue
;
50
Green
=
green
;
51
}
52
}
## Practice Excercises
- Rectangle – “All squares are rectangles, but not all rectangles are squares.” This class represents a simple rectangle with a height and width. From this information, the area, perimeter and diagonal can be obtained; it can also be determined if the rectangle is or is not square.
- HazardousMaterial – The HazardousMaterial class is a simple representation of the six main classes of hazardous materials (A through F). This class maps a classification code with a general description of the material’s classification:
- Class A – Compressed Gas
- Class B – Flammable and Combustible Material
- Class C – Oxidizing Material
- Class D – Poisonous and Infectious Material
- Class E – Corrosive Material
- Class F – Dangerously Reactive Material
- CurrencyCalculator – This exercise extends the previous CurrencyCalculator exercise by allowing the conversion from a foreign currency to US dollars.
- GravityCalculator – This exercise extends the previous GravityCalculator exercise by allowing the conversion to a weight on Earth from a weight on another planet in our solar system.
Rectangle
“All squares are rectangles, but not all rectangles are squares.” This class represents a simple rectangle with a height and width. From this information, the area, perimeter and diagonal can be obtained; it can also be determined if the rectangle is or is not square.
Problem Statement
Write the code for the Rectangle class. The solution must meet the following requirements:
- Should get and set the height and the width
- Should calculate the area, the perimeter and the diagonal
- The formula for the diagonal is √(〖width〗2 + 〖height〗2 )
- Should determine if the rectangle is a square
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-Rectangle.png)
HazardousMaterial
The HazardousMaterial class is a simple representation of the six main classes of hazardous materials (A through F). This class maps a classification code with a general description of the material’s classification:
- Class A – Compressed Gas
- Class B – Flammable and Combustible Material
- Class C – Oxidizing Material
- Class D – Poisonous and Infectious Material
- Class E – Corrosive Material
- Class F – Dangerously Reactive Material
Problem Statement
Write the code for the HazardousMaterial class. The solution must meet the following requirements:
- Should return the class code as the classification
- Should get the description for the class, based on the following table
Class Code | Description |
---|---|
A | Compressed Gas |
B | Flammable and Combustible Material |
C | Oxidizing Material |
D | Poisonous and Infectious Material |
E | Corrosive Material |
F | Dangerously Reactive Material |
- Should override the ToString() method to get the full description and class code in the following format:
- “Class ClassCode - Description”
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-HazardousMaterial.png)
CurrencyCalculator
This exercise extends the previous CurrencyCalculator exercise by allowing the conversion from a foreign currency to US dollars.
Problem Statement
A currency exchange store at the international airport needs a program to convert from US dollars to four other currencies: Canadian dollar, Euro, Japanese Yen, and the Great Britain Pound. The store uses a set exchange rate for each currency as established at the start of the day. Write the code for a class called CurrencyCalculator to meet this need. The solution must meet the following requirements (new requirements are in bold):
- Should correctly convert US dollars to the
- British Pound (GBP)
- Canadian Dollar (CAD)
- Euro (EUR)
- Japanese Yen (JPY)
- Should convert an amount to US dollars from any of the supported currencies (GBP, CAD, JPY, and EUR)
- Should use the correct level of precision when making the exchange; each currency uses a different number of significant digits:
- CAD, GBP and EUR use two digits
- JPY uses three digits
To illustrate the possible exchange rates, please refer to the following images.
![](/site_images/programming0101/F-CurrencyExchangeRates.png)
![](/site_images/programming0101/F-CurrencyAmericanDollar.png)
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-CurrencyCalculator.png)
GravityCalculator
This exercise extends the previous GravityCalculator exercise by allowing the conversion to a weight on Earth from a weight on another planet in our solar system.
Problem Statement
Write the code needed to convert Earth weights to their equivalent for the other planets in our solar system. The solution must meet the following requirements (new requirements are in bold):
- Should convert a weight in Earth kilograms to their equivalent weight on
- Mercury
- Venus
- Mars
- Jupiter
- Saturn
- Uranus
- Neptune
- Should convert a weight from a specific planet back to the equivalent weight on Earth
Use the following class diagram when creating your solution.
![](/site_images/programming0101/F-GravityCalculator.png)
Topic G – Raising Exceptions
Overview
This topic introduces the throw statement and exceptions. The following new keywords are introduced.
* throw
* throws
This topic will demonstrate objects that are capable of validating information supplied to them. This introduces the principle in object oriented design that well designed objects are capable of ensuring the validity of their internal state. When invalid information is supplied, either through the constructor or through other methods, objects can respond by raising exceptions.
LOGs
General Programming Concepts and Terms
- Describe how object-oriented programs run
- Describe what is meant by a “call stack”
- Define the term “Exception”
- Describe what is meant by the phrase “raising (or throwing) an exception”
- Describe the role that exceptions play in a computer program
- Identify the three most commonly used Exception types used in this course
OOP Basics
- Explain why methods (including constructors) should perform validation of their parameter values
- Explain the significance of raising an exception in the constructor
- Use exceptions as part of the validation of parameter values in methods and constructors
- Explain why property setters are a good place for throwing exceptions
- Identify when constructors should throw exceptions directly
Code Samples
- Fraction – The fraction class avoid the division by zero error by ensuring that the supplied denominator is not zero.
- Square – Only accepts positive, non-zero lengths for the side.
- Circle – Only accepts positive, non-zero diameters.
- Die – Only accepts from 4 to 20 sides for a die.
- Person – First and last names cannot be empty and the birth date cannot be in the future. This illustrates putting the validation on the setters and calling the setters from the constructor (to reduce the duplication of code).
- Student – Gender must be ‘M’ or ‘F’ (and will be converted to upper-case). The student name and program cannot be empty. The student ID must be 9 digits. The GPA must be between 0.0 and 9.0 (inclusive).
- ParkingCounter – Only accepts positive, non-zero counts for available parking spaces and number of cars. Also, the number of cars must not exceed the number of parking spaces. The rules for the number of cars must also apply for cars entering and leaving the parking lot.
- StockItem – Represents an inventory item that is kept in stock. The item’s description, cost and profit margin are all part of the class design. Empty descriptions and zero or negative costs, as well as profit margins less than -100, are not allowed.
- Account – The following account information is now verified when the class is created:
- Bank name and account type cannot be empty
- The opening balance must be greater than zero
- The overdraft limit cannot be negative
- The institution number must be 3 digits
- The branch number must be 6 digits
- Attempts to withdraw amounts beyond the overdraft limit should throw an “Insufficient Funds” exception
Fraction
The fraction class avoids the division by zero error by ensuring that the supplied denominator is not zero.
Problem Statement
Write the code for the Fraction class. The solution must meet the following requirements (new requirements are in bold):
* Should get the string representation of the fraction, as “numerator/denominator”
* Should get the numeric value of the fraction (as a real number)
* Should get the reciprocal of the fraction
* Should get the numerator and denominator
* Should add another fraction to its existing value
* Should subtract another fraction from its existing value
* Should multiply its existing value by another fraction
* Should divide its existing value by another fraction
* Should affix the sign for negative fractions onto the numerator only
* Should identify if the fraction is a proper fraction
* Should reject zero denominators
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Fraction.png)
1
public
Fraction
(
int
numerator
,
int
denominator
)
2
{
3
if
(
denominator
==
0
)
4
throw
new
System
.
Exception
(
"A fraction cannot have a denominator of \
5
zero
(
0
)
");
6
Numerator
=
numerator
;
7
Denominator
=
denominator
;
8
FixSign
();
9
}
Square
Only accepts positive, non-zero lengths for the side.
Problem Statement
Write the code needed to add the ability for a Square to determine the length of its diagonal. The solution must meet the following requirements (new requirements are in bold):
* Should get and set the length of the side of the square
* Should calculate the area, perimeter, and diagonal of the square
* Should only accept positive, non-zero lengths for the side
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Square.png)
1
private
double
_Side
;
2
public
double
Side
3
{
4
get
5
{
6
return
_Side
;
7
}
8
set
9
{
10
if
(
value
<=
0
)
11
throw
new
System
.
Exception
(
"A square must have a positive non-ze\
12
ro
length
for
its
side
");
13
_Side
=
value
;
14
}
15
}
Circle
Only accepts positive, non-zero diameters.
Problem Statement
Write the code for the Circle class. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the diameter
- Should calculate the area, radius, and circumference
- Should only accept positive, non-zero lengths for the diameter
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Circle.png)
1
private
double
_Diameter
;
2
public
double
Diameter
3
{
4
get
5
{
6
return
_Diameter
;
7
}
8
set
9
{
10
if
(
value
<=
0
)
11
throw
new
System
.
Exception
(
"Diameter must be a positive non-zero\
12
value
");
13
_Diameter
=
value
;
14
}
15
}
Die
Only accepts from 4 to 20 sides for a die. This class represents a single six-sided die. This example is used to illustrate random number generation and casting.
Problem Statement
Write the code for the Die class. The solution must meet the following requirements (new requirements are in bold):
- Should generate a random value from 1 to the number of sides on the die, when initially created and when re-rolled
- Should get the face value of the die
- Should get the number of sides of the die
- Should randomly generate each side (if rolled enough); for example, if the die has ten sides, it should eventually roll a 1, 2, 3, 4, 5 6, 7, 8, 9, and 10
- Should only accept 4 to 20 sides for the die
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Die.png)
1
public
Die
(
int
sides
)
2
{
3
if
(
sides
<
4
||
sides
>
20
)
4
throw
new
System
.
Exception
(
"A die can only have from 4 to 20 sides"
);
5
this
.
Sides
=
sides
;
6
Roll
();
7
}
Person
First and last names cannot be empty and the birth date cannot be in the future. This illustrates putting the validation on the setters and calling the setters from the constructor (to reduce the duplication of code).
This adaptation of the person class includes a check of the age of the person to see if the person’s life stage is infant, toddler, preschooler, school age, or adult.
Problem Statement
Write the code that will represent a person with a first and last name and a date of birth. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the first and last name
- Should get the birth date
- Should get the person’s approximate age (which is the age that the person will turn to in the current year)
- Should override toString() to get the person’s full name (as first name then last name)
- Should get the life stage, based on the following table
Age Range (Years) | Life Stage |
---|---|
0 | Infant |
< 3 | Toddler |
< 5 | Preschooler |
< 18 | School age |
>= 18 | Adult |
- Should ensure the first and last names are not empty (or null)
- Should trim leading and trailing spaces from the first and last names
- Should reject birthdates that are in the future
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Person.png)
1
private
string
_FirstName
;
2
public
string
FirstName
3
{
4
get
5
{
6
return
_FirstName
;
7
}
8
set
9
{
10
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
11
))
12
throw
new
Exception
(
"FirstName cannot be empty"
);
13
_FirstName
=
value
.
Trim
();
14
}
15
}
16
17
private
string
_LastName
;
18
public
string
LastName
19
{
20
get
21
{
22
return
_LastName
;
23
}
24
set
25
{
26
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
27
))
28
throw
new
Exception
(
"LastName cannot be empty"
);
29
_LastName
=
value
.
Trim
();
30
}
31
}
32
33
public
Person
(
string
firstName
,
string
lastName
,
DateTime
birthDate
)
34
{
35
if
(
birthDate
.
CompareTo
(
DateTime
.
Today
)
>
0
)
36
throw
new
System
.
Exception
(
"Birthdates in the future are not allowed\
37
");
38
FirstName
=
firstName
;
39
LastName
=
lastName
;
40
BirthDate
=
birthDate
;
41
}
Student
Gender must be ‘M’ or ‘F’ (and will be converted to upper-case). The student name and program cannot be empty. The student ID must be 9 digits. The GPA must be between 0.0 and 9.0 (inclusive).
Problem Statement
Write the code for the Student class. The class must now ensure that the supplied information is valid. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the student’s name, gender, GPA, program of studies, and whether or not the student is full-time.
- Should override the toString() method to get the student’s ID and name in this format:
(ID) Name - Should n * longer allow the student ID to be set (it’s only set through the constructor)
- Should reject empty text (and null values) for the student’s name and program of studies.
- Should trim the student’s name and the program name
- Should only accept ‘M’ and ‘F’ as valid genders
- Should set the gender to upper-case
- Should reject negative GPAs and GPAs over 9
- Should require a nine-digit student ID
This class reinforces the idea of encapsulation and constructors. It also demonstrates the idea of overloading the default ToString()
method that every class inherits from the Object class.
1
public
class
Student
2
{
3
#region Fields
4
private
string
_Name
;
5
private
char
_Gender
;
6
private
int
_StudentId
;
7
private
string
_Program
;
8
private
double
_GradePointAverage
;
9
private
bool
_IsFullTime
;
10
#endregion
11
12
#region Properties
13
public
string
Name
14
{
15
get
{
return
_Name
;
}
16
set
17
{
18
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
19
))
20
throw
new
System
.
Exception
(
"Name cannot be empty"
);
21
_Name
=
value
.
Trim
();
22
}
23
}
24
25
public
char
Gender
26
{
27
get
{
return
_Gender
;
}
28
set
29
{
30
value
=
char
.
ToUpper
(
value
);
31
if
(
value
!=
'M'
&&
value
!=
'F'
)
32
throw
new
Exception
(
"Gender must be M or F"
);
33
_Gender
=
value
;
34
}
35
}
36
37
public
int
StudentId
38
{
39
get
{
return
_StudentId
;
}
40
set
41
{
42
if
(
value
<
100000000
||
value
>
999999999
)
43
throw
new
Exception
(
"Student Ids must be 9 digits"
);
44
_StudentId
=
value
;
45
}
46
}
47
48
public
string
Program
49
{
50
get
{
return
_Program
;
}
51
set
52
{
53
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
54
))
55
throw
new
Exception
(
"Program cannot be empty"
);
56
_Program
=
value
.
Trim
();
57
}
58
}
59
60
public
double
GradePointAverage
61
{
62
get
{
return
_GradePointAverage
;
}
63
set
64
{
65
if
(
value
<
0
||
value
>
9
)
66
throw
new
System
.
Exception
(
"GPA must be between 0 and 9 inclusiv\
67
e
");
68
_GradePointAverage
=
value
;
69
}
70
}
71
72
public
bool
IsFullTime
73
{
74
get
{
return
_IsFullTime
;
}
75
set
{
_IsFullTime
=
value
;
}
76
}
77
#endregion
78
79
#region Constructors
80
public
Student
(
string
name
,
char
gender
,
int
studentId
,
string
program
,
doub
\
81
le
gradePointAverage
,
bool
isFullTime
)
82
{
83
if
(
studentId
<
100000000
||
studentId
>
999999999
)
84
throw
new
System
.
Exception
(
"Student Ids must be 9 digits"
);
85
this
.
Name
=
name
;
86
this
.
Gender
=
gender
;
87
this
.
StudentId
=
studentId
;
88
this
.
Program
=
program
;
89
this
.
GradePointAverage
=
gradePointAverage
;
90
this
.
IsFullTime
=
isFullTime
;
91
}
92
#endregion
93
94
#region Methods
95
public
override
string
ToString
()
96
{
97
return
"("
+
StudentId
+
") "
+
Name
;
98
}
99
#endregion
100
}
ParkingCounter
Only accepts positive, non-zero counts for available parking spaces and number of cars. Also, the number of cars must not exceed the number of parking spaces. The rules for the number of cars must also apply for cars entering and leaving the parking lot.
Problem Statement
Write the code that will monitor vehicles entering and leaving a parking lot. The solution must meet the following requirements (new requirements are in bold):
- Should track vehicles entering
- Should track vehicles leaving
- Should track the peak occupancy of the parking lot
- The peak occupancy represents the highest number of cars in the parking lot at any one time
- Should get total parking spots
- Should get open (empty) spots
- Should reset lot as full (that is, fill the parking lot)
- Should reset lot as empty (that is, clear all the parking spots of vehicles)
- Should only allow a positive (non-zero) number of parking spots
- Should not allow a negative number of cars (when using the overloaded constructor), and should not allow more cars than parking spots
-
Should not allow available (open) parking spots to go negative or to exceed the actual number of parking spots
- Should raise an error when trying to enter a full parking lot
- Should raise an error if trying to leave a parking lot that is already empty
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-ParkingCounter.png)
1
public
ParkingCounter
(
int
parkingSpots
)
2
{
3
if
(
parkingSpots
<=
0
)
4
throw
new
System
.
Exception
(
"Negative or zero parkingSpots not allowe\
5
d
");
6
this
.
ParkingSpots
=
parkingSpots
;
7
this
.
OpenSpots
=
parkingSpots
;
8
this
.
peak
=
0
;
9
}
10
11
public
ParkingCounter
(
int
parkingSpots
,
int
numberOfCars
)
12
{
13
if
(
parkingSpots
<=
0
)
14
throw
new
System
.
Exception
(
"Negative or zero parkingSpots not allowe\
15
d
");
16
if
(
numberOfCars
<
0
)
17
throw
new
System
.
Exception
(
"Negative numberOfCars not allowed"
);
18
if
(
numberOfCars
>
parkingSpots
)
19
throw
new
System
.
Exception
(
"The number of cars cannot exceed the num\
20
ber
of
parking
spots
");
21
this
.
ParkingSpots
=
parkingSpots
;
22
this
.
OpenSpots
=
this
.
ParkingSpots
-
numberOfCars
;
23
this
.
peak
=
numberOfCars
;
24
}
25
26
public
void
leave
()
27
{
28
if
(
OpenSpots
==
ParkingSpots
)
29
throw
new
System
.
Exception
(
"Parking lot is empty"
);
30
OpenSpots
++;
31
}
32
33
public
void
enter
()
34
{
35
if
(
OpenSpots
==
0
)
36
throw
new
System
.
Exception
(
"Parking lot is full"
);
37
OpenSpots
--;
38
int
numberOfCars
=
ParkingSpots
-
OpenSpots
;
39
if
(
numberOfCars
>
peak
)
40
peak
=
numberOfCars
;
41
}
StockItem
The StockItem class represents an inventory item that is kept in stock. The item’s description, cost and profit margin are all part of the class design. Empty descriptions and zero or negative costs, as well as profit margins less than -100, are not allowed.
Problem Statement
Write the code for adding validation to the StockItem class. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the name, cost and profit margin of the stock item
- Should represent the profit margin as a percent; a value of 45 means 45%
- Should calculate the price of the item, to the nearest cent
- Use the rounding where values under a half-cent are rounded down and values greater than or equal to a half-cent are rounded up
- Should recognize when the stock item is priced at cost (that is, the profit margin is zero)
- Should recognize when the stock item is priced below cost (that is, the profit margin is negative)
- Should reject an empty (or null) item name
- Should trim excess spaces from the ends of the item name
- Should require cost to be greater than zero
- Should only allow negative profit margins up to 100% (which is a full mark-down)
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-StockItem.png)
1
private
double
_Cost
;
2
public
double
Cost
3
{
4
get
5
{
6
return
_Cost
;
7
}
8
set
9
{
10
if
(
value
<=
0
)
11
throw
new
Exception
(
"Cost must be positive"
);
12
_Cost
=
value
;
13
}
14
}
15
16
private
double
_ProfitMargin
;
17
public
double
ProfitMargin
18
{
19
get
20
{
21
return
_ProfitMargin
;
22
}
23
set
24
{
25
if
(
value
<
-
100
)
26
throw
new
Exception
(
"A profit margin below 100% (more than the c\
27
ost
)
is
not
allowed
");
28
_ProfitMargin
=
value
;
29
}
30
}
31
32
private
string
_ItemName
;
33
public
string
ItemName
34
{
35
get
36
{
37
return
_ItemName
;
38
}
39
set
40
{
41
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
42
))
43
throw
new
Exception
(
"ItemName cannot be empty"
);
44
_ItemName
=
value
.
Trim
();
45
}
46
}
Account
The following account information is now verified when the class is created:
- Bank name and account type cannot be empty
- The opening balance must be greater than zero
- The overdraft limit cannot be negative
- The institution number must be 3 digits
- The branch number must be 6 digits
- Attempts to withdraw amounts beyond the overdraft limit should throw an “Insufficient Funds” exception
Problem Statement
Write the code that will add validation to the Account class. The solution must meet the following requirements (new requirements are in bold):
* Should get the bank name, branch number, institution number, account number, balance, overdraft limit, and account type and allow the overdraft limit to be set
* Should support deposits
* Should only support withdrawals if the amount does not exceed the sum of the balance and the overdraft limit, otherwise an exception stating “Insufficient Funds” should occur
* Should identify if the account is overdrawn
* Should require bank name and account type (that is, they cannot be empty or null)
* Should trim the bank name and account type
* Should verify that the branch number is six digits and the institution number is three digits
* Should require an opening balance
* Should not allow a negative overdraft limit
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Account.png)
1
public
double
Balance
2
{
3
get
{
return
_Balance
;
}
4
set
{
5
if
(
value
<
-
OverdraftLimit
)
6
throw
new
Exception
(
"Negative balances cannot exceed the Overdra\
7
ft
Limit
");
8
_Balance
=
value
;
9
}
10
}
11
12
public
double
OverdraftLimit
13
{
14
get
{
return
_OverdraftLimit
;
}
15
set
16
{
17
if
(
value
<
0
)
18
throw
new
Exception
(
"Negative overdraft limits not allowed"
);
19
_OverdraftLimit
=
value
;
20
}
21
}
22
23
public
int
BranchNumber
24
{
25
get
{
return
_BranchNumber
;
}
26
set
{
27
if
(
value
<
10000
||
value
>
99999
)
28
throw
new
Exception
(
"Branch number must be 5 digits"
);
29
_BranchNumber
=
value
;
30
}
31
}
32
33
public
int
InstitutionNumber
34
{
35
get
{
return
_InstitutionNumber
;
}
36
set
37
{
38
if
(
value
<
100
||
value
>
999
)
39
throw
new
Exception
(
"InstitutionNumber must be a three-digit val\
40
ue
");
41
_InstitutionNumber
=
value
;
42
}
43
}
44
45
public
string
AccountType
46
{
47
get
{
return
_AccountType
;
}
48
set
{
49
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
50
))
51
throw
new
Exception
(
"Account type cannot be empty"
);
52
_AccountType
=
value
.
Trim
();
53
}
54
}
55
56
public
string
BankName
57
{
58
get
{
return
_BankName
;
}
59
set
60
{
61
if
(
string
.
IsNullOrEmpty
(
value
)
||
string
.
IsNullOrEmpty
(
value
.
Trim
()
\
62
))
63
throw
new
Exception
(
"BankName is required"
);
64
_BankName
=
value
.
Trim
();
65
}
66
}
67
68
public
Account
(
string
bankName
,
int
branchNumber
,
int
institutionNumber
,
int
\
69
accountNumber
,
double
balance
,
double
overdraftLimit
,
string
accountType
)
70
{
71
if
(
balance
<=
0
)
72
throw
new
Exception
(
"Opening balance must be greater than zero"
);
73
if
(
balance
!=
Math
.
Round
(
balance
,
2
))
74
throw
new
Exception
(
"Opening balances cannot include a fraction of a\
75
penny
");
76
if
(
overdraftLimit
!=
Math
.
Round
(
overdraftLimit
,
2
))
77
throw
new
Exception
(
"Overdraft limit amounts cannot include a fracti\
78
on
of
a
penny
");
79
AccountNumber
=
accountNumber
;
80
Balance
=
balance
;
81
OverdraftLimit
=
overdraftLimit
;
82
BankName
=
bankName
;
83
BranchNumber
=
branchNumber
;
84
InstitutionNumber
=
institutionNumber
;
85
AccountType
=
accountType
;
86
}
87
88
public
double
Withdraw
(
double
amount
)
89
{
90
if
(
amount
!=
Math
.
Round
(
amount
,
2
))
91
throw
new
Exception
(
"Withdrawal amounts cannot include fractions of \
92
a
penny
");
93
if
(
amount
>
Balance
+
OverdraftLimit
)
94
throw
new
Exception
(
"Insufficient Funds"
);
95
if
(
amount
<=
Balance
+
OverdraftLimit
)
96
Balance
=
Math
.
Round
(
Balance
-
amount
,
2
);
97
else
98
amount
=
0
;
99
return
amount
;
100
}
101
102
public
void
Deposit
(
double
amount
)
103
{
104
if
(
amount
!=
Math
.
Round
(
amount
,
2
))
105
throw
new
Exception
(
"Deposit amounts cannot include fractions of a p\
106
enny
");
107
Balance
=
Math
.
Round
(
Balance
+
amount
,
2
);
108
}
Practice Exercises
- Account – Add one more point of validation to the Account class: Do not allow depositing or withdrawing non-positive amounts.
- Rectangle – The height and width of the rectangle must be greater than zero.
- Cone – The radius and height of the cone must be greater than zero.
- Course – The course name and number cannot be blank, and the exam and lab counts must be greater than zero. The class hours must also be greater than zero.
- Cylinder – The radius and height of the cylinder must be greater than zero.
- HazardousMaterial – The class code for the hazardous material can only be the letters ‘A’ through ‘F’, inclusive.
- ExamResult - Requires a positive, non-zero value for the total marks and weight. The weight cannot be over 50. The marks earned can be between zero and the total marks, inclusive. The student ID must be 9 digits, and the exam name cannot be an empty string.
- LabResult – Requires a positive, non-zero value for the lab number, total marks and weight. The weight cannot be over 50. The marks earned can be between zero and the total marks, inclusive. The student ID must be 9 digits.
- PeopleCounter – Does not allow adding a negative number of people to the counter.
- BulkItem – The description cannot be blank and the cost and quantity values must be greater than zero.
Account
Problem Statement
Write the code that will add another piece of validation to the Account class. The solution must meet the following requirements (new requirements are in bold):
- Should get the bank name, branch number, institution number, account number, balance, overdraft limit, and account type and allow the overdraft limit to be set
- Should support deposits
- Should only support withdrawals if the amount does not exceed the sum of the balance and the overdraft limit, otherwise an exception stating “Insufficient Funds” should occur
- Should identify if the account is overdrawn
- Should require bank name and account type (that is, they cannot be empty or null)
- Should trim the bank name and account type
- Should verify that the branch number is six digits and the institution number is three digits
- Should require an opening balance
- Should not allow a negative overdraft limit
- Should only allow positive, non-zero amounts when performing a deposit or withdrawal
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Account-2.png)
Rectangle
The height and width of the rectangle must be greater than zero.
Problem Statement
Write the code to provide validation for the Rectangle class. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the height and the width
- Should calculate the area, the perimeter and the diagonal
- The formula for the diagonal is √(〖width〗2 + 〖height〗2 )
- Should determine if the rectangle is a square
- Should require the height and width to be greater than zero
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Rectangle.png)
Cone
The radius and height of the cone must be greater than zero.
Problem Statement
Write the code to provide validation for the Cone class that meets the following requirements (new requirements are in bold):
- Should get the radius and the height
- Should calculate the volume and the surface area
- Should require the radius and height to be greater than zero
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Cone.png)
Course
The course name and number cannot be blank, and the exam and lab counts must be greater than zero. The class hours must also be greater than zero.
Problem Statement
Write the code to provide validation for the Course class. The solution must meet the following requirements (new requirements are in bold):
- Should get the course name and number, the number of exams and labs, and the class hours for the course.
- Should not allow empty course names or numbers
- Should trim spaces from the course name and number
- Should require class hours as well as lab and exam counts to be greater than zero
![](/site_images/programming0101/G-Course.png)
Cylinder
The radius and height of the cylinder must be greater than zero.
Problem Statement
Write the code to provide validation for the Cylinder class that meets the following requirements (new requirements are in bold):
- Should get the radius and the height
- Should calculate the volume and the surface area
- Should make sure the radius and height are greater than zero
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-Cylinder.png)
HazardousMaterial
The class code for the hazardous material can only be the letters ‘A’ through ‘F’, inclusive.
Problem Statement
Write the code to provide validation for the HazardousMaterial class. The solution must meet the following requirements (new requirements are in bold):
- Should return the class code as the classification
- Should make sure only class codes ‘A’ through ‘F’ are allowed (in either upper or lower case)
- Should make sure the classification is stored in upper case
- Should get the description for the class, based on the following table
Class Code | Description |
---|---|
A | Compressed Gas |
B | Flammable and Combustible Material |
C | Oxidizing Material |
D | Poisonous and Infectious Material |
E | Corrosive Material |
F | Dangerously Reactive Material |
- Should override the toString() method to get the full description and class code in the following format:
- “Class ClassCode - Description”
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-HazardousMaterial.png)
ExamResult
Requires a positive, non-zero value for the total marks and weight. The weight cannot be over 50. The marks earned can be between zero and the total marks, inclusive. The student ID must be 9 digits, and the exam name cannot be an empty string.
Problem Statement
Write the code to provide validation for the ExamResult class. The solution must meet the following requirements (new requirements are in bold):
- Should get the name, student Id, total marks, and exam weight
- Should get and set the marks earned
- Should override the toString() to show “The student (studentId) received earnedMarks/totalMarks for this examName exam.”
- Should require the total marks and weight to be a positive, non-zero value
- Should not allow a weight over 50
- The marks earned must be between zero and the total possible marks, inclusive
- The student ID must be nine digits
- The exam name cannot be an empty string (and must be trimmed)
![](/site_images/programming0101/G-ExamResult.png)
LabResult
Requires a positive, non-zero value for the lab number, total marks and weight. The weight cannot be over 50. The marks earned can be between zero and the total marks, inclusive. The student ID must be 9 digits.
Problem Statement
Write the code to provide validation for the LabResult class. The solution must meet the following requirements (new requirements are in bold):
- Should get the lab number, student Id, total marks, and lab weight
- Should get and set the marks earned
- Should override the toString() to show “The student (studentId) received earnedMarks/totalMarks for this lab.”
- Should require the total marks and weight to be a positive, non-zero value
- Should not allow a weight over 50
- The marks earned must be between zero and the total possible marks, inclusive
- The student ID must be nine digits
- The lab number must be a positive number
![](/site_images/programming0101/G-LabResult.png)
### PeopleCounter
Does not allow adding a negative number of people to the counter.
Problem Statement
Write the code needed to track people entering and leaving a store. It must be able to estimate the number of people that have entered the store at the end of the day. The solution must meet the following requirements (new requirements are in bold):
- Should default to having a count of zero people when first started up
- Should increment by one (that is, count a single person)
- Should increment by a specified quantity (for when a group of people enter)
- Should adequately estimate the number of people who entered the store, assuming that each person who enters also leaves the store
Each estimate should be rounded down; for example, if 15 people are counted, then the estimate should be for only 7 (not 7.5 or 8) - Should not allow a zero or negative quantity when adding to the counter
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-PeopleCounter.png)
BulkItem
The description cannot be blank and the cost and quantity values must be greater than zero.
Problem Statement
Write the code for the BulkItem class. The solution must meet the following requirements (new requirements are in bold):
- Should get and set the cost and quantity of the bulk item
- Should get and set the description
- Should ensure the description is not empty (and that it is trimmed)
- Should ensure the cost and quantity values are greater than zero
- Should calculate the cost for each item in the bulk item
- Should properly round values for currency (either the US or Canadian dollar)
Use the following class diagram when creating your solution.
![](/site_images/programming0101/G-BulkItem.png)
Topic H – Case Structures
Overview
This topic introduces the C# switch statement which is used to code case structures. The following new keywords are introduced.
* switch
* case
* default
* break
LOGs
General Programming Concepts and Terms
- Describe the syntax of the switch statement
- Discuss the limitations of the switch statement in C# and the available alternatives for the times that we can’t use a switch statement
Code Samples
- LetterGrade - Represents a letter grade as assigned in Quebec universities. Source: http://en.wikipedia.org/wiki/Letter_grade
- Rating – Represents a rating on a scale of 1 to 5, where 1 is “very bad”, 2 is “bad”, 3 is “average”, 4 is “good”, and 5 is “very good”.
LetterGrade
Problem Statement
Write the code for the LetterGrade class that represents a letter grade as assigned in Quebec universities (Source: http://en.wikipedia.org/wiki/Letter_grade). The solution must meet the following requirements (note – you do not need to perform validation for this sample):
- Should get and set the grade (as a single letter)
- Should ensure the grade is in upper-case
- Should get the appropriate descriptions for the grade, based on the following table:
Grade | Description |
---|---|
A | A - 80-100% - Greatly Above Standards |
B | B - 70-79% - Above Standards |
C | C - 60-69% - At Government Standards |
D | D - 50-60% - Lower Standards |
F | F - 0-49% - Failure |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/H-LetterGrade.png)
1
public
class
LetterGrade
2
{
3
private
char
_Grade
;
4
5
public
char
Grade
6
{
7
get
{
return
_Grade
;
}
8
set
{
this
.
_Grade
=
char
.
ToUpper
(
value
);
}
9
}
10
11
public
LetterGrade
(
char
grade
)
12
{
13
Grade
=
grade
;
14
}
15
16
17
public
override
string
ToString
()
18
{
19
string
description
;
20
switch
(
_Grade
)
21
{
22
case
'A'
:
23
description
=
"A - 80-100% - Greatly Above Standards"
;
24
break
;
25
case
'B'
:
26
description
=
"B - 70-79% - Above Standards"
;
27
break
;
28
case
'C'
:
29
description
=
"C - 60-69% - At Government Standards"
;
30
break
;
31
case
'D'
:
32
description
=
"D - 50-60% - Lower Standards"
;
33
break
;
34
case
'F'
:
35
description
=
"F - 0-49% - Failure"
;
36
break
;
37
default
:
38
description
=
"Invalid Letter Grade"
;
39
break
;
40
}
41
return
description
;
42
}
43
}
Rating
Problem Statement
Write the code for the Rating class that represents a rating on a survey where the rating is done using the values 1 through 5, inclusive. The solution must meet the following requirements (note – you do not need to perform validation for this sample):
- Should get and set the rating value
- Should get the appropriate string result when using the ToString() method, based on the following table:
Value | Description |
---|---|
1 | very bad |
2 | bad |
3 | average |
4 | good |
5 | very good |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/H-Rating.png)
1
public
class
Rating
2
{
3
public
int
Value
{
get
;
set
;
}
4
5
public
Rating
(
int
value
)
6
{
7
Value
=
value
;
8
}
9
10
11
public
override
string
ToString
()
12
{
13
string
rating
;
14
switch
(
Value
)
15
{
16
case
5
:
17
rating
=
"very good"
;
18
break
;
19
case
4
:
20
rating
=
"good"
;
21
break
;
22
case
3
:
23
rating
=
"average"
;
24
break
;
25
case
2
:
26
rating
=
"bad"
;
27
break
;
28
case
1
:
29
rating
=
"very bad"
;
30
break
;
31
default
:
32
rating
=
"Invalid Rating"
;
33
break
;
34
}
35
return
rating
;
36
}
37
}
Practice Exercises
- BahamaLetterGrade - Represents a letter grade as assigned in the Bahamas universities. Source: http://en.wikipedia.org/wiki/Letter_grade
- Feedback – Represents an opinion rating as feedback, where 1 is “no opinion”, 2 is “strongly disagree”, 3 is “disagree”, 4 is “agree, and 5 is “strongly agree”.
- HazardousMaterial – Represents the six hazardous material codes of ‘A’ through ‘F’.
BahamaLetterGrade
Problem Statement
Write the code for the BahamaLetterGrade class that represents a letter grade as assigned in the Bahamas universities (Source: http://en.wikipedia.org/wiki/Letter_grade). Each letter grade is also associated with a grade value. The solution must meet the following requirements (note – you do not need to perform validation for this exercise):
- Should get and set the grade (as a single letter)
- Should ensure the grade is in upper-case
- Should get the appropriate descriptions for the grade, based on the following table:
Grade | Grade Value | Description |
---|---|---|
A | 4 | A-4 - 90-100% |
B | 3 | B-3 - 71-89% |
C | 2 | C-2 - 56-70% |
D | 1 | D-1 - 46-55% |
F | 0 | F-0 - 0-45% |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/H-BahamaLetterGrade.png)
Feedback
Represents an opinion rating as feedback, where 1 is “no opinion”, 2 is “strongly disagree”, 3 is “disagree”, 4 is “agree, and 5 is “strongly agree”.
Problem Statement
Write the code for the Feedback class that represents a rating on a survey where the feedback is given using the values 1 through 5, inclusive. The solution must meet the following requirements (note – you do not need to perform validation for this sample):
- Should get and set the feedback value
- Should get the appropriate string result when using the ToString() method, based on the following table:
Value | Description |
---|---|
1 | no opinion |
2 | strongly disagree |
3 | disagree |
4 | agree |
5 | strongly agree |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/H-Feedback.png)
HazardousMaterial
The class code for the hazardous material can only be the letters ‘A’ through ‘F’, inclusive.
Problem Statement
Rewrite the code for the HazardousMaterial class to make use of the switch statement. The solution must meet the following requirements (new requirements are in bold):
- Should return the class code as the classification
- Should make sure only class codes ‘A’ through ‘F’ are allowed (in either upper or lower case)
- Should make sure the classification is stored in upper case
- Should get the description for the class, based on the following table
You must use a switch statement to get the results
Class Code | Description |
---|---|
A | Compressed Gas |
B | Flammable and Combustible Material |
C | Oxidizing Material |
D | Poisonous and Infectious Material |
E | Corrosive Material |
F | Dangerously Reactive Material |
- Should override the ToString() method to get the full description and class code in the following format:
- “Class ClassCode - Description”
Use the following class diagram when creating your solution.
![](/site_images/programming0101/H-HazardousMaterial.png)
Adding Complexity + Looping
Topic I –Enumerations and Composition
Overview
This topic introduces enumerations and composition. The following new keywords are introduced.
- enum
This topic will reveal how enumerations allow programmers to define new data types and values to represent conceptual information. This topic also discusses the concept of composition, describing how composition is simply the use of objects as fields in a class.
### LOGs
General Programming Concepts and Terms
- Define the term Enumeration
- List the benefits of using enumerations
- Describe where and when enumerations are used
- Compare and contrast enumerations and classes
- Use enumerations to define simple data types that are conceptual in nature and that have a limited set of possible “values”
OOP Basics
- Describe the idea of Composition
- List the benefits of Composition
Code Samples
Enumerations:
- Coin + CoinFace – The CoinFace enumeration helps to describe the tw * sides of a Coin, which can then be used in a tossing game.
- Account + AccountType – The Account’s account type is n * longer being represented as a string, but is its own enumeration: AccountType.
- LetterGrade + QuebecLetterGrade – The QuebecLetterGrade uses the simple LetterGrade enumeration and assigns specific ranges of percentage marks for the possible LetterGrade values.
Composition:
- Address + Student + GenderType – This revised version of the Student class now has an Address field. The address field is new; although similar to the CanadianAddress class, the Address class is simpler and more “generic” (having “State” instead of “Province” and “ZipCode” instead of “PostalCode”).
- ImproperFraction + MixedNumber + ProperFraction – In this sample, the idea of a Fraction class is made more specific by replacing it with three more specific types of numbers: MixedNumber, ProperFraction, and ImproperFraction. A MixedNumber is made up of a whole number and a ProperFraction. A MixedNumber can also be expressed as or derived from an ImproperFraction. The reciprocal of a ProperFraction is an ImproperFraction and the reciprocal of an ImproperFraction is a ProperFraction.
Coin + CoinFace
The CoinFace enumeration helps to describe the tw * sides of a Coin, which can then be used in a tossing game.
Problem Statement
Write the code needed to represent a coin that could be used in a coin-toss game. The solution must meet the following requirements.
- Should randomly generate the coin face that is showing when creating the coin
- Should get the side of the coin that is face showing
- Should allow the coin to be tossed to randomly generate a new coin face
- Should only support tw * sides for a coin’s face: Heads and Tails
Use the following diagram when creating your solution.
![](/site_images/programming0101/I-Coin.png)
1
public
class
Coin
2
{
3
public
enum
CoinFace
{
HEADS
,
TAILS
};
4
5
public
CoinFace
FaceShowing
{
get
;
private
set
;
}
6
7
public
Coin
()
8
{
9
Toss
();
10
}
11
12
public
void
Toss
()
13
{
14
if
(
Rnd
.
Next
(
2
)
==
0
)
15
FaceShowing
=
CoinFace
.
HEADS
;
16
else
17
FaceShowing
=
CoinFace
.
TAILS
;
18
}
19
}
Account + AccountType
The Account’s account type is n * longer being represented as a string, but is its own enumeration: AccountType.
![](/site_images/programming0101/I-AccountType.png)
Problem Statement
Write the code that will make the account type a type-safe value for the Account class. The solution must meet the following requirements (new requirements are in bold):
- Should get the bank name, branch number, institution number, account number, balance, overdraft limit, and account type and allow the overdraft limit to be set
- Should support deposits
- Should only support withdrawals if the amount does not exceed the sum of the balance and the overdraft limit, otherwise an exception stating “Insufficient Funds” should occur
- Should identify if the account is overdrawn
- Should require bank name and account type (that is, they cannot be empty or null)
- Should trim the bank name
- Should ensure that the Account Type is type-safe and that it is supplied when creating the account (that is, it cannot be null)
- Should support the following types of accounts: Chequing, Saving, Credit Card, and Line of Credit
- Should verify that the branch number is six digits and the institution number is three digits
- Should require an opening balance
- Should not allow a negative overdraft limit
Use the following class diagram when creating your solution.
![](/site_images/programming0101/I-Account.png)
1
public
class
Account
2
{
3
public
Account
(
string
bankName
,
int
branchNumber
,
int
institutionNumber
,
4
int
accountNumber
,
double
balance
,
double
overdraftLimit
,
5
AccountType
type
)
6
{
7
if
(
string
.
IsNullOrEmpty
(
bankName
)
||
8
string
.
IsNullOrEmpty
(
bankName
.
Trim
()))
9
throw
new
System
.
Exception
(
"Bank name cannot be empty"
);
10
if
(
branchNumber
<
10000
||
branchNumber
>
99999
)
11
throw
new
System
.
Exception
(
"Branch number must be 5 digits"
);
12
if
(
institutionNumber
<
100
||
institutionNumber
>
999
)
13
throw
new
System
.
Exception
(
"Institution number must be 3 digits"
);
14
if
(
balance
<=
0
)
15
throw
new
System
.
Exception
(
"Opening balance must be greater than zer\
16
o
");
17
OverdraftLimit
=
overdraftLimit
;
18
this
.
BankName
=
bankName
;
19
this
.
BranchNumber
=
branchNumber
;
20
this
.
InstitutionNumber
=
institutionNumber
;
21
this
.
AccountNumber
=
accountNumber
;
22
this
.
Balance
=
balance
;
23
this
.
Type
=
type
;
24
}
25
26
private
double
_overdraftLimit
;
27
28
public
double
Balance
{
get
;
private
set
;
}
29
public
string
BankName
{
get
;
private
set
;
}
30
public
int
BranchNumber
{
get
;
private
set
;
}
31
public
int
InstitutionNumber
{
get
;
private
set
;
}
32
public
int
AccountNumber
{
get
;
private
set
;
}
33
public
AccountType
Type
{
get
;
private
set
;
}
34
35
public
double
OverdraftLimit
36
{
37
get
38
{
return
_overdraftLimit
;
}
39
set
40
{
41
if
(
value
<
0
)
42
throw
new
System
.
Exception
(
"Negative overdraft limits not allowe\
43
d
");
44
this
.
_overdraftLimit
=
value
;
45
}
46
}
47
48
public
bool
IsOverdrawn
()
49
{
50
return
Balance
<
0.0
;
51
}
52
53
public
void
Deposit
(
double
amount
)
54
{
55
Balance
+=
amount
;
56
}
57
58
public
double
Withdraw
(
double
amount
)
59
{
60
if
(
amount
>
Balance
+
_overdraftLimit
)
61
throw
new
System
.
Exception
(
"Insufficient Funds"
);
62
Balance
-=
amount
;
63
return
amount
;
64
}
65
}
LetterGrade + QuebecLetterGrade
The QuebecLetterGrade uses the simple LetterGrade enumeration and assigns specific ranges of percentage marks for the possible LetterGrade values.
Problem Statement
Write the code for the LetterGrade class that represents a letter grade as assigned in Quebec universities (Source: http://en.wikipedia.org/wiki/Letter_grade). The solution must meet the following requirements (new requirements are in bold):
- Should get and set the grade as a type-safe value
- Should get the appropriate descriptions for the grade, based on the following table:
Grade | Description |
A | A - 80-100% - Greatly Above Standards |
B | B - 70-79% - Above Standards |
C | C - 60-69% - At Government Standards |
D | D - 50-60% - Lower Standards |
F | F - 0-49% - Failure |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/I-QuebecLetterGrade.png)
![](/site_images/programming0101/I-LetterGrade.png)
1
public
enum
LetterGrade
2
{
3
A
,
B
,
C
,
D
,
F
4
}
5
6
public
class
QuebecLetterGrade
7
{
8
public
LetterGrade
Grade
{
get
;
set
;
}
9
10
public
QuebecLetterGrade
(
LetterGrade
grade
)
11
{
12
this
.
Grade
=
grade
;
13
}
14
15
public
override
string
ToString
()
16
{
17
string
description
;
18
switch
(
Grade
)
19
{
20
case
LetterGrade
.
A
:
21
description
=
"A - 80-100% - Greatly Above Standards"
;
22
break
;
23
case
LetterGrade
.
B
:
24
description
=
"B - 70-79% - Above Standards"
;
25
break
;
26
case
LetterGrade
.
C
:
27
description
=
"C - 60-69% - At Government Standards"
;
28
break
;
29
case
LetterGrade
.
D
:
30
description
=
"D - 50-60% - Lower Standards"
;
31
break
;
32
case
LetterGrade
.
F
:
33
description
=
"F - 0-49% - Failure"
;
34
break
;
35
default
:
36
description
=
"Invalid Letter Grade"
;
37
break
;
38
}
39
return
description
;
40
}
41
}
Address + Student + GenderType
This revised version of the Student class now has an Address field. The address field is new; although similar to the CanadianAddress class, the Address class is simpler and more “generic” (having “State” instead of “Province” and “ZipCode” instead of “PostalCode”).
![](/site_images/programming0101/I-GenderType.png)
Problem Statement
Extend the Student class to now include information about the student’s home address. Create an Address class to represent a simple, generic address. In addition, the Student class must represent the Gender using an enumeration.
The solution must meet the following requirements (new requirements are in bold):
-
The Address class must
- Get and set the city, state, street, unit and zip code.
- The Student class must
- Verify that an address object is supplied (is not null)
- Represent the Gender as a GenderType of Male and Female
- Should get and set the student’s name, gender, GPA, program of studies, and whether or not the student is full-time.
- Should override the toString() method to get the student’s ID and name in this format:
(ID) Name - Should n * longer allow the student ID to be set (it’s only set through the constructor)
- Should reject empty text (and null values) for the student’s name and program of studies.
- Should trim the student’s name and the program name
- Should only accept ‘M’ and ‘F’ as valid genders
- Should set the gender to upper-case
- Should reject negative GPAs and GPAs over 9
Use the following class diagrams to guide your design.
![](/site_images/programming0101/I-Address.png)
![](/site_images/programming0101/I-Student.png)
1
public
enum
GenderType
2
{
3
MALE
,
FEMALE
4
}
5
6
public
class
Address
7
{
8
public
string
Street
{
get
;
set
;
}
9
public
string
Unit
{
get
;
set
;
}
10
public
string
City
{
get
;
set
;
}
11
public
string
State
{
get
;
set
;
}
12
public
string
ZipCode
{
get
;
set
;
}
13
14
public
Address
(
string
unit
,
string
street
,
string
city
,
string
state
,
15
string
zipCode
)
16
{
17
this
.
Unit
=
unit
;
18
this
.
Street
=
street
;
19
this
.
City
=
city
;
20
this
.
State
=
state
;
21
this
.
ZipCode
=
zipCode
;
22
}
23
}
24
25
public
class
Student
26
{
27
private
string
_name
;
// The full name of the student
28
private
string
_program
;
// The course program; e.g.: "CST"
29
private
double
_gradePointAverage
;
// GPA is from 1.0 to 9.0
30
private
Address
_homeAddress
;
31
32
public
Student
(
string
name
,
Address
homeAddress
,
GenderType
gender
,
33
int
studentId
,
string
program
,
double
gradePointAverage
,
34
bool
isFullTime
)
35
{
36
if
(
studentId
<
100000000
||
studentId
>
999999999
)
37
throw
new
System
.
Exception
(
"Student Ids must be 9 digits"
);
38
Name
=
name
;
39
HomeAddress
=
homeAddress
;
40
Gender
=
gender
;
41
StudentId
=
studentId
;
42
Program
=
program
;
43
GradePointAverage
=
gradePointAverage
;
44
IsFullTime
=
isFullTime
;
45
}
46
47
public
GenderType
Gender
{
get
;
set
;
}
48
public
bool
IsFullTime
{
get
;
set
;
}
49
public
int
StudentId
{
get
;
private
set
;
}
50
51
public
string
Name
52
{
53
get
54
{
return
_name
;
}
55
set
56
{
57
if
(
string
.
IsNullOrEmpty
(
value
)
||
58
string
.
IsNullOrEmpty
(
value
.
Trim
()))
59
throw
new
System
.
Exception
(
"name cannot be empty"
);
60
this
.
_name
=
value
.
Trim
();
61
}
62
}
63
64
public
Address
HomeAddress
65
{
66
get
67
{
return
_homeAddress
;
}
68
set
69
{
70
if
(
value
==
null
)
71
throw
new
System
.
Exception
(
"Address is required"
);
72
this
.
_homeAddress
=
value
;
73
}
74
}
75
76
public
string
Program
77
{
78
get
79
{
return
_program
;
}
80
set
81
{
82
if
(
string
.
IsNullOrEmpty
(
value
)
||
83
string
.
IsNullOrEmpty
(
value
.
Trim
()))
84
throw
new
System
.
Exception
(
"Program cannot be empty"
);
85
this
.
_program
=
value
.
Trim
();
86
}
87
}
88
89
public
double
GradePointAverage
90
{
91
get
92
{
return
_gradePointAverage
;
}
93
set
94
{
95
if
(
value
<
0
||
value
>
9
)
96
throw
new
System
.
Exception
(
"GPA must be between 0 and 9 inclusiv\
97
e
");
98
this
.
_gradePointAverage
=
value
;
99
}
100
}
101
102
103
public
override
string
ToString
()
104
{
105
return
"("
+
StudentId
+
") "
+
Name
;
106
}
107
}
ImproperFraction + MixedNumber + ProperFraction
In this sample, the idea of a Fraction class is made more specific by replacing it with three more specific types of numbers: MixedNumber, ProperFraction, and ImproperFraction. A MixedNumber is made up of a whole number and a ProperFraction. A MixedNumber can also be expressed as or derived from an ImproperFraction. The reciprocal of a ProperFraction is an ImproperFraction and the reciprocal of an ImproperFraction is a ProperFraction.
Problem Statement
The generic Fraction class is now being replaced with a set of three more specific classes for numbers with fractional values: ProperFraction, ImproperFraction, and MixedNumber. Create these classes, using the following requirements and class diagrams.
- ProperFraction should ensure that it is indeed a proper fraction
- ImproperFraction should ensure that it is indeed an improper fraction
- MixedNumber should construct either from a whole number and a proper fraction or from an improper fraction
- ProperFraction and ImproperFraction should get their respective reciprocals as well as their values as real numbers
- ProperFraction and ImproperFraction should ensure that the denominator is always positive
- MixedNumber should get the whole number portion as well as the fractional portion
- MixedNumber should get its value as a real number as well as get its value as an ImproperFraction
![](/site_images/programming0101/I-ProperFraction.png)
![](/site_images/programming0101/I-ImproperFraction.png)
![](/site_images/programming0101/I-MixedNumber.png)
1
public
class
ProperFraction
2
{
3
public
ProperFraction
(
int
numerator
,
int
denominator
)
4
{
5
if
(
denominator
==
0
)
6
throw
new
System
.
Exception
(
"zero denominator fractions are undefined\
7
");
8
if
(
Math
.
Abs
(
numerator
)
>=
Math
.
Abs
(
denominator
))
9
throw
new
System
.
Exception
(
"Proper fractions must have a numerator t\
10
hat
is
less
than
the
denominator
");
11
12
if
(
denominator
<
0
)
13
{
14
numerator
*=
-
1
;
15
denominator
*=
-
1
;
16
}
17
this
.
Numerator
=
numerator
;
18
this
.
Denominator
=
denominator
;
19
}
20
21
public
int
Numerator
{
get
;
private
set
;
}
22
public
int
Denominator
{
get
;
private
set
;
}
23
public
ImproperFraction
Reciprocal
24
{
25
get
26
{
return
new
ImproperFraction
(
Denominator
,
Numerator
);
}
27
}
28
29
public
double
ToDouble
()
30
{
31
return
(
double
)(
Numerator
)
/
Denominator
;
32
}
33
34
public
override
string
ToString
()
35
{
36
return
Numerator
+
"/"
+
Denominator
;
37
}
38
}
39
40
public
class
ImproperFraction
41
{
42
public
ImproperFraction
(
int
numerator
,
int
denominator
)
43
{
44
if
(
denominator
==
0
)
45
throw
new
System
.
Exception
(
"zero denominator fractions are undefined\
46
");
47
if
(
Math
.
Abs
(
numerator
)
<
Math
.
Abs
(
denominator
))
48
throw
new
System
.
Exception
(
"Improper fractions must have a numerator\
49
that
is
greater
than
or
equal
to
the
denominator
");
50
51
if
(
denominator
<
0
)
52
{
53
numerator
*=
-
1
;
54
denominator
*=
-
1
;
55
}
56
this
.
Numerator
=
numerator
;
57
this
.
Denominator
=
denominator
;
58
}
59
60
public
int
Numerator
{
get
;
private
set
;
}
61
public
int
Denominator
{
get
;
private
set
;
}
62
public
ProperFraction
Reciprocal
63
{
64
get
{
return
new
ProperFraction
(
Denominator
,
Numerator
);
}
65
}
66
67
public
double
ToDouble
()
68
{
69
return
(
double
)(
Numerator
)
/
Denominator
;
70
}
71
72
public
override
string
ToString
()
73
{
74
return
Numerator
+
"/"
+
Denominator
;
75
}
76
}
77
78
public
class
MixedNumber
79
{
80
public
int
WholeNumber
{
get
;
private
set
;
}
81
public
ProperFraction
Fraction
{
get
;
private
set
;
}
82
83
public
MixedNumber
(
int
wholeNumber
,
ProperFraction
fraction
)
84
{
85
if
(
wholeNumber
==
0
)
86
throw
new
System
.
Exception
(
"wholeNumber portion cannot be zero for a\
87
Mixed
Number
");
88
if
(
fraction
==
null
)
89
throw
new
System
.
Exception
(
"MixedNumbers must have a fractional port\
90
ion
");
91
if
(
fraction
.
Numerator
<
0
)
92
{
93
fraction
=
new
ProperFraction
(-
fraction
.
Numerator
,
fraction
.
Denomina
\
94
tor
);
95
wholeNumber
*=
-
1
;
96
}
97
this
.
WholeNumber
=
wholeNumber
;
98
this
.
Fraction
=
fraction
;
99
}
100
101
public
MixedNumber
(
ImproperFraction
improperFraction
)
:
102
this
(
improperFraction
.
Numerator
/
improperFraction
.
Denominator
,
103
new
ProperFraction
(
improperFraction
.
Numerator
%
104
improperFraction
.
Denominator
,
105
improperFraction
.
Denominator
))
106
{
107
}
108
109
public
ImproperFraction
ToImproperFraction
()
110
{
111
return
new
ImproperFraction
(
WholeNumber
*
112
Fraction
.
Denominator
+
Fraction
.
Numerator
,
113
Fraction
.
Denominator
);
114
}
115
116
public
double
ToDouble
()
117
{
118
double
realValue
=
Math
.
Abs
(
WholeNumber
)
+
Fraction
.
ToDouble
();
119
if
(
WholeNumber
<
0
)
120
realValue
*=
-
1
;
121
return
realValue
;
122
}
123
}
Practice Exercises
- LetterGrade + BahamaLetterGrade – The BahamaLetterGrade also uses the LetterGrade enumerated type, assigning its own specific ranges and values to the possible LetterGrade values.
- HazardousMaterial + ClassCode – The various types of hazardous materials are now identified by their ClassCode enumerated type.
- CanadianAddress + Province – The CanadianAddress class is modified to now use a Province enumeration to properly capture the provinces and territories of Canada.
- Employee/Student + CanadianAddress + Province – The Employee and Student classes now have address information.
- Company + Month + CanadianAddress + Province – The Company now has a CanadianAddress.
LetterGrade + BahamaLetterGrade
The BahamaLetterGrade also uses the LetterGrade enumerated type, assigning its own specific ranges and values to the possible LetterGrade values.
Problem Statement
Write the code for the BahamaLetterGrade class and the LetterGrade enumeration to represent a letter grade as assigned in universities in the Bahamas. (For more information on Bahaman letter grades, see http://en.wikipedia.org/wiki/Letter_grade.) . The solution must meet the following requirements (new requirements are in green, bold italic font):
- The LetterGrade enumeration should be “generic” and support letter grades of A through F inclusive
- The BahamaLetterGrade should reject the LetterGrade of E (which is not allowed in the Bahamas) as well as any null letter grade
- The BahamaLetterGrade should get the appropriate descriptions for the grade, based on the following table:
Grade | Grade | Value Description |
---|---|---|
A | 4 | A-4 - 90-100% |
B | 3 | B-3 - 71-89% |
C | 2 | C-2 - 56-70% |
D | 1 | D-1 - 46-55% |
F | 0 | F-0 - 0-45% |
Use the following class diagram when creating your solution.
![](/site_images/programming0101/I-LetterGrade.png)
![](/site_images/programming0101/I-BahamaLetterGrade.png)
HazardousMaterial + ClassCode
The various types of hazardous materials are now identified by their ClassCode enumerated type.
Problem Statement
Rewrite the code for the HazardousMaterial class to make use of the ClassCode enumerated type. The solution must meet the following requirements (new requirements are in green, bold italic font):
- Should return the class code as the classification
- Should make sure the class code is supplied (is not null)
- Should get the description for the class, based on the following table
You must use a switch statement to get the results
Class Code | Description |
---|---|
A | Compressed Gas |
B | Flammable and Combustible Material |
C | Oxidizing Material |
D | Poisonous and Infectious Material |
E | Corrosive Material |
F | Dangerously Reactive Material |
- Should override the ToString() method to get the full description and class code in the following format:
- “Class ClassCode - Description”
Use the following class diagram when creating your solution.
![](/site_images/programming0101/I-HazardousMaterial.png)
CanadianAddress + Province
The CanadianAddress class is modified to now use a ProvinceType enumeration to properly capture the provinces and territories of Canada.
Problem Statement
Modify the CanadianAddress class to now use an enumeration for the province. Use the following class diagram as a guide in creating the class and the enumeration.
![](/site_images/programming0101/I-ProvinceType.png)
![](/site_images/programming0101/I-CanadianAddress.png)
Employee/Student + CanadianAddress + Province
The Employee and Student classes now have address information.
Problem Statement
Modify the Employee and Student classes to now use the CanadianAddress type for their addresses.
![](/site_images/programming0101/I-Employee.png)
![](/site_images/programming0101/I-Student-2.png)
Company + Month + CanadianAddress + Province
The Company now has a CanadianAddress.
Problem Statement
Modify the Company class to now make use of the CanadianAddress type for the address. Also, create an enumeration for the months of the year for representing the company’s fiscal year end.
![](/site_images/programming0101/I-Month.png)
![](/site_images/programming0101/I-Company.png)
Topic J - Looping Structures
Overview
LOGs
General Programming Concepts and Terms
- Identify the C# statements that correspond to Do-While and Do-Until logical structures
- Translate Do-While structures into code
- Translate Do-Until structures into code
- Identify and distinguish the parts of the for statement in code
- Describe the common situations in which the for statement is used
- Demonstrate how the various looping statements can be interchanged with slight alterations of the logical structures to maintain the overall logic of a given routine.
Code Samples
- Aggregator – The Aggregator class supports static methods for doing various types of aggregation on Numbers. (Numbers is a supplied class that stores a series of real values that can be obtained by calling getNext().) The common aggregations of totalItems(), averageItems(), maxValue() are given as examples of simple looping.
- Math – fibonnacciNumber() and isPerfect()
- Fraction – The fraction example is now enhanced to simplify the fractional value by finding the greatest common denominator of the fraction’s numerator and denominator.
- GuessingGame – This example uses a supplied class called SecretNumber, which picks a random whole number between a specific range. An instance of the SecretNumber is passed to the constructor of the GuessingGame, and the GuessingGame’s guess() method attempts to get the correct guess within a specified number of tries.
Aggregator
The Aggregator class supports static methods for doing various types of aggregation on Numbers. (Numbers is a supplied class that stores a series of real values that can be obtained by calling GetNext().) The common aggregations of TotalItems(), AverageItems(), MaxValue() are given as examples of simple looping.
The Numbers Class
The methods of the Aggregator class all take a single argument: a Numbers object. The Numbers object contains a bunch of real numbers and it has two methods that the Aggregator methods will use:
- HasNext() – This returns a Boolean indicating that the object has another number available.
- GetNext() – This returns a real number from the set of values in the Numbers object.
For example, if a Numbers object has a set of four values such as 1.0, 5.5, 3.2, and 5.3, then the GetNext() method can be called four times to retrieve each value. Any attempt to call GetNext() when the object’s HasNext() is false will cause an exception.
Note: This class is already coded for you in the samples.
![](/site_images/programming0101/J-Numbers.png)
Aggregator Methods
The following Aggregator methods will demonstrate looping logic and syntax. All of these examples demonstrate the while statement.
- TotalItems() – This method loops through all the values inside of the Numbers object to calculate and return the total of the values.
- AverageItems() – This method gets all the values inside of the Numbers object so as to calculate the average value. If no values exist in the Numbers object, then the method returns an average of zero.
- MaxValue() – This method examines the Numbers object’s values to see which value is the largest. If there are no values inside of the Numbers object, then the method returns the smallest possible value that is supported by the programming language.
![](/site_images/programming0101/J-Aggregator.png)
1
public
class
Aggregator
2
{
3
public
static
double
TotalItems
(
Numbers
items
)
4
{
5
double
total
=
0
;
6
while
(
items
.
HasNext
())
7
total
+=
items
.
Next
();
8
return
total
;
9
}
10
11
public
static
double
AverageItems
(
Numbers
items
)
12
{
13
double
average
,
total
=
0
;
14
int
count
=
0
;
15
while
(
items
.
HasNext
())
16
{
17
total
+=
items
.
Next
();
18
count
++;
19
}
20
if
(
count
>
0
)
21
average
=
total
/
count
;
22
else
23
average
=
0
;
24
return
average
;
25
}
26
27
public
static
double
MaxValue
(
Numbers
items
)
28
{
29
double
max
=
double
.
MinValue
;
30
while
(
items
.
HasNext
())
31
{
32
double
value
=
items
.
Next
();
33
if
(
max
<
value
)
34
max
=
value
;
35
}
36
return
max
;
37
}
38
}
Math
The Math class provides methods for the following mathematical algorithms not found in the default Math class.
- FibonacciNumber() – Returns a number from the Fibonacci sequence for a given position. If the given position is less than or equal to zero, then this method should throw an exception. This example demonstrates the for statement. An alternative version illustrates the do-while statement.
- IsPerfect() – Indicates whether or not a number is a “perfect” number. A perfect number is a number where the sum of all the factors equals the number. By definition, any number less than 1 (including all negative numbers) are not perfect numbers. This example uses a while statement. An alternative version illustrates a do-while statement.
![](/site_images/programming0101/J-Math.png)
1
public
class
Math
2
{
3
public
static
int
FibonacciNumber
(
int
i
)
4
{
5
int
current
=
1
,
previous
=
1
,
beforePrevious
=
0
;
6
if
(
i
>=
1
)
7
{
8
for
(
int
counter
=
3
;
counter
<=
i
;
counter
++)
9
{
10
beforePrevious
=
previous
;
11
previous
=
current
;
12
current
=
beforePrevious
+
previous
;
13
}
14
}
15
else
16
throw
new
Exception
(
"Can only create a fibonnaci number based on a p\
17
ositive
non
-
zero
position
");
18
return
current
;
19
}
20
21
public
static
bool
IsPerfect
(
int
number
)
22
{
23
bool
perfect
=
true
;
24
if
(
number
<=
1
)
25
perfect
=
false
;
26
else
27
{
28
// The following logic attempts to prove it is imperfect
29
int
halfWay
=
number
/
2
;
30
int
total
=
0
;
31
int
count
=
1
;
32
while
(
total
!=
number
&&
total
<=
halfWay
&&
total
<
number
)
33
{
34
if
(
number
%
count
==
0
)
// Then count is a factor of number
35
total
+=
count
;
36
count
++;
37
}
38
if
(
total
!=
number
)
39
perfect
=
false
;
40
}
41
return
perfect
;
42
}
43
}
Fraction
The fraction example is now enhanced to simplify the fractional value by finding the greatest common denominator of the fraction’s numerator and denominator.
The Fraction class represents a fraction as two integers: one for the numerator and one for the denominator. When a Fraction object is created, the class must now simplify the fractional values by calculating the greatest common denominator.
- GreatestCommonDenominator() – This private method is used by the Simplify() method to get the greatest common denominator for the numerator and denominator. Remember to allow for dealing with negative fractions (in which case, the negative sign will be on the numerator). This example uses a while statement (though it is possible to re-work the logic to use a do-while statement).
![](/site_images/programming0101/J-Fraction.png)
1
private
int
GreatestCommonDenominator
()
2
{
3
int
commonDenominator
=
1
;
4
int
count
=
2
,
halfWay
;
5
int
absoluteNumerator
=
System
.
Math
.
Abs
(
Numerator
);
6
if
(
absoluteNumerator
>
Denominator
)
7
halfWay
=
absoluteNumerator
/
2
;
8
else
9
halfWay
=
Denominator
/
2
;
10
11
while
(
count
<=
halfWay
)
12
{
13
if
(
absoluteNumerator
%
count
==
0
&&
14
Denominator
%
count
==
0
)
15
commonDenominator
=
count
;
16
count
++;
17
}
18
19
return
commonDenominator
;
20
}
GuessingGame
This example uses a supplied class called SecretNumber, which picks a random whole number between a specific range. An instance of the SecretNumber is passed to the constructor of the GuessingGame, and the GuessingGame’s Guess() method attempts to get the correct guess within a specified number of tries.
In a regular number guessing game between two people, one person asks another person to guess a whole number between a pair of values. In this example, two different classes take on the roles of the two people in the game: The SecretNumber class takes on the role of the person who has picked a value between some lower and upper limit, while the GuessingGame class takes on the role of the person who has to guess what that hidden number is.
Note: This class is already coded for you in the samples.
SecretNumber
Objects of this class will store a hidden value between some upper and lower limit (inclusive). The SecretNumber class supports three public methods:
- GetLowerLimit() – Returns a number representing the lower end (inclusive) of the range of possible values for the hidden value.
- GetUpperLimit() – Returns a number representing the upper end (inclusive) of the range of possible values for the hidden value.
- Guess() – Returns true if the supplied value matches the hidden value, otherwise it returns false.
![](/site_images/programming0101/missing.png)
GuessingGame
This class simulates the action of guessing what hidden value is stored inside of a SecretNumber object. The SecretNumber is supplied to the constructor of the GuessingGame, and the following methods attempt to find out what that number is.
- GuessNumber() – This first method simply tries to guess the hidden value of the SecretNumber. It has “unlimited” guesses, and it will return the number of attempts it took to find out what that hidden number is.
- GuessNumber(MaxAttempts : Integer) – This method will also try to guess the SecretNumber’s hidden value, but it is limited to a maximum number of guesses. This method will return the actual number of attempts it took to find the hidden value, or it will return the GUESS_FAILED constant if it was unable to guess the secret number.
Try creating alternate versions of this GuessingGame that will use a while statement and a for statement in the GuessNumber methods.
![](/site_images/programming0101/J-GuessingGame.png)
1
public
class
GuessingGame
2
{
3
private
SecretNumber
Number
{
get
;
set
;
}
4
public
const
int
GUESS_FAILED
=
-
1
;
5
6
public
GuessingGame
(
SecretNumber
number
)
7
{
8
if
(
number
==
null
)
9
throw
new
System
.
Exception
(
"SecretNumber cannot be null"
);
10
this
.
Number
=
number
;
11
}
12
13
public
int
GuessNumber
(
int
maxAttempts
)
14
{
15
int
numberOfAttempts
=
0
;
16
bool
correct
=
false
;
17
while
(
maxAttempts
>
0
&&
!
correct
)
18
{
19
// Make a guess
20
int
myBestGuess
=
Rnd
.
Next
(
Number
.
LowerLimit
,
Number
.
UpperLimit
);
21
if
(
Number
.
Guess
(
myBestGuess
))
22
correct
=
true
;
23
numberOfAttempts
++;
24
maxAttempts
--;
25
}
26
if
(!
correct
)
27
numberOfAttempts
=
GUESS_FAILED
;
// a "flag" to say the guess was in\
28
correct
29
return
numberOfAttempts
;
30
}
31
32
public
int
GuessNumber
()
33
{
34
bool
correct
=
false
;
35
int
numberOfAttempts
=
0
;
36
while
(
numberOfAttempts
<
int
.
MaxValue
&&
!
correct
)
37
{
38
// Make a guess
39
int
myBestGuess
=
Rnd
.
Next
(
Number
.
LowerLimit
,
Number
.
UpperLimit
);
40
if
(
Number
.
Guess
(
myBestGuess
))
41
correct
=
true
;
42
numberOfAttempts
++;
43
}
44
if
(!
correct
)
45
numberOfAttempts
=
GUESS_FAILED
;
46
return
numberOfAttempts
;
47
}
48
}
Practice Exercises
- Aggregator – countItems(), minValue()
- Math – factorial(), isPrime(), power(), and greatestCommonDenominator()
- GuessingGame – This example expands on the sample GuessingGame by 1) re-working the guess() method to make guessing more efficient by using the SecretNumber’s guessWithHint() method, and 2) overloading the guess() method to continue guessing until the correct answer is found (and returning the number of attempts it took to find the correct answer).
Aggregator
Expand on the sample Aggregator class to perform the following aggregations.
- CountItems() – Return the count of the number of values in the Numbers object.
- MinValue() – Return the smallest value in the set of values of the supplied Numbers object. If no values exist in the Numbers object, return the largest whole number supported by the programming language.
![](/site_images/programming0101/J-Aggregator-2.png)
Math
Expand on the sample Math class by providing methods to perform the following.
- Factorial() – Calculate the factorial of a given number. If the given number is negative, throw an exception. If the calculated value for the factorial will exceed the maximum integer value (int.MaxValue), then return zero (0) as a result.
- IsPrime() – Identify if a number is or is not a prime number. A prime number is a number with only two divisors: 1 and the number itself. By definition for this problem, numbers less than one are not considered prime numbers.
- Power() – Calculate the value of x to the power of y (as in xy). Use looping logic (addition) to get the result.
- GreatestCommonDenominator() – Find the greatest common denominator between two whole numbers.
![](/site_images/programming0101/J-Math-2.png)
GuessingGame
This example expands on the sample GuessingGame by adding more guess methods to make guessing more efficient by using the SecretNumber’s guessWithHint() method.
In a regular number guessing game between two people, one person asks another person to guess a whole number between a pair of values. In this example, two different classes take on the roles of the two people in the game: The SecretNumber class takes on the role of the person who has picked a value between some lower and upper limit, while the GuessingGame class takes on the role of the person who has to guess what that hidden number is.
SecretNumber
Objects of this class will store a hidden value between some upper and lower limit (inclusive). The SecretNumber class supports these public methods:
- GetLowerLimit() – Returns a number representing the lower end (inclusive) of the range of possible values for the hidden value.
- GetUpperLimit() – Returns a number representing the upper end (inclusive) of the range of possible values for the hidden value.
- GuessWithHint() – Returns CORRECT if the supplied value matches the hidden value, otherwise it returns GUESS_HIGHER if the attempted guess was too low or GUESS_LOWER if the attempted guess was too high.
Note: This class is already coded for you in the samples.
![](/site_images/programming0101/J-SecretNumber-2.png)
GuessingGame
This class simulates the action of guessing what hidden value is stored inside of a SecretNumber object. The SecretNumber is supplied to the constructor of the GuessingGame, and the following methods attempt to find out what that number is.
- GuessUsingHints() – This first method simply tries to guess the hidden value of the SecretNumber. It has “unlimited” guesses, and it will return the number of attempts it took to find out what that hidden number is. Use the GuessWithHint method of the SecretNumber object.
- GuessUsingHints(MaxAttempts : Integer) – This method will also try to guess the SecretNumber’s hidden value, but it is limited to a maximum number of guesses. This method will return the actual number of attempts it took to find the hidden value, or it will return the GUESS_FAILED constant if it was unable to guess the secret number. Use the GuessWithHint method of the SecretNumber object.
As an additional exercise, create a simple driver that instantiates a SecretNumber object and supplies it to a GuessingGame object. Show how many attempts it took to guess the hidden number when using hints.
![](/site_images/programming0101/J-GuessingGame-2.png)
Interlude 2 - A General-Purpose Driver
The following is a nice general-purpose console-based driver that can be used for the remaining topics.
1
class
Program
2
{
3
#region Driver Method
4
static
void
Main
(
string
[]
args
)
5
{
6
string
menuChoice
;
7
do
8
{
9
DisplayMenu
();
10
menuChoice
=
Console
.
ReadLine
().
ToUpper
();
11
ProcessMenuChoice
(
menuChoice
);
12
}
while
(
menuChoice
!=
"X"
);
13
}
14
#endregion
15
16
#region General Purpose Methods
17
private
static
void
DisplayMenu
()
18
{
19
Console
.
ForegroundColor
=
ConsoleColor
.
DarkGreen
;
20
21
Console
.
WriteLine
(
"A) "
);
22
Console
.
WriteLine
(
"B) "
);
23
Console
.
WriteLine
(
"C) "
);
24
Console
.
WriteLine
(
"X) "
);
25
Console
.
ResetColor
();
26
Console
.
Write
(
"Select an option from the menu: "
);
27
}
28
29
private
static
void
ProcessMenuChoice
(
string
choice
)
30
{
31
switch
(
choice
)
32
{
33
case
"A"
:
34
break
;
35
case
"B"
:
36
break
;
37
case
"C"
:
38
break
;
39
case
"X"
:
40
break
;
41
default
:
42
Console
.
ForegroundColor
=
ConsoleColor
.
DarkRed
;
43
Console
.
WriteLine
(
"Invalid menu choice."
);
44
break
;
45
}
46
Pause
();
47
Console
.
ResetColor
();
48
}
49
50
private
static
void
Pause
()
51
{
52
Console
.
ForegroundColor
=
ConsoleColor
.
Gray
;
53
Console
.
WriteLine
(
"\n\nPress any key to continue..."
);
54
Console
.
ReadKey
(
true
);
55
Console
.
Clear
();
56
}
57
#endregion
58
59
#region Menu Processing Methods
60
// TODO: Your specific menu processing methods.
61
#endregion
62
}
Topic K - Looping and Collections
Overview
This topic provides further examples of looping logic, but involves the use of collections. All of these samples make use of the List<T> class to maintain a collection or group of objects.
The List<T> class is a Generic class, meaning that the item in the angled brackets - <T> - is a placeholder for the name of the actual class that is being managed in the List. For example, to have a list of Integers we would declare that as List<Integer>. Likewise, if we wanted a list of Student objects, it would be declared as List<Student>.
The List<T> class supports a number of methods and properties for working with the collection.
- Add() – Used to add an item to the collection
- [index] – Used to retrieve an item in the collection
- Remove() – Used to remove an item from the collection
- Count – Identifies the number of items in the collection
LOGs
OOP Basics
- Define the term Generics as used in C# and give an example
General Programming Concepts and Terms
- Describe what is meant by a “collection” class and give an example
- List and describe the common methods of collection classes such as the List<T>
- Identify the parts of the foreach statement
- Describe the common situations in which the foreach statement is typically used
- Identify the major benefit of using Generics
- List the major benefits of using collections instead of arrays
Code Samples
- Math – The Math class is expanded to produce a collection of Integers for the sequence of Fibonacci numbers.
- PhoneBook – The PhoneBook class provides simple management of a collection of PhoneNumber objects. The PhoneBook allows for adding and retrieving phone numbers; it supports search for phone numbers by the telephone number or by a last name.
- ClassList – The ClassList example maintains a list of students for a particular course by offering methods to add and remove students from a course. In addition, the ClassList ensures that students are not added to the course twice (based on the student’s Id).
- MultipleChoiceMarker – This class is used for marking multiple choice exams. It takes a collection of MultipleChoice objects as the answer key when it is first created. It provides a method to mark the student’s answers.
- BankStatement – This class represents a bank statement for a BankAccount for a given month. The statement allows BankTransaction objects to be added, and performs deposits and withdrawals on the BankAccount. The statement reports the starting and ending balance and also summarizes the total amount deposited and withdrawn for the month.
- DeckOfCards –The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports a method to draw a card.
Math
This sample leverages the existing calculation of a number in the Fibonacci sequence to generate the sequence itself.
- FibonacciSequence(Length : Integer) – This method generates the sequence of Fibonacci numbers to a specific length in the sequence.
![](/site_images/programming0101/K-Math.png)
1
public
static
List
<
int
>
FibonacciSequence
(
int
length
)
2
{
3
List
<
int
>
fib
=
new
List
<
int
>();
4
if
(
length
>=
1
)
5
{
6
for
(
int
index
=
0
;
index
<
length
;
index
++)
7
fib
.
Add
(
FibonacciNumber
(
index
+
1
));
8
}
9
return
fib
;
10
}
PhoneBook
The PhoneBook class provides simple management of a collection of PhoneNumber objects. The PhoneBook allows for adding and retrieving phone numbers; it supports search for phone numbers by the telephone number or by a last name.
- Constructor – Create a new List<PhoneNumber> for the numbers field.
- AddPhoneNumber(Entry : PhoneNumber) – Add a PhoneNumber to the collection. Ensure that the PhoneNumber exists (is not null) before adding; if the PhoneNumber is null, throw an exception.
- GetPhoneNumber(Index : Integer) : PhoneNumber – Get an item from a particular position in the collection.
- GetCount() : Integer – Get the size of the collection, which is a count of how many PhoneNumber objects are in the collection.
- FindPhoneNumber(TelephoneNumber : String) : PhoneNumber – Look through the collection and return a PhoneNumber with a matching telephone number. If none is found, return null.
- FindPhoneNumbersByLastName(LastName : String) : List<PhoneNumber> - Look through the collection for PhoneNumber objects with a matching last name. Add those objects to a new collection and return the collection of matching PhoneNumbers. If no items are found, return an empty collection.
Supporting Classes
The PhoneNumber class used in this sample is provided for you. The following class diagram shows the design of this class.
![](/site_images/programming0101/K-PhoneNumber.png)
PhoneBook Class
![](/site_images/programming0101/K-PhoneBook.png)
1
public
class
PhoneBook
2
{
3
private
List
<
PhoneNumber
>
Number
{
get
;
set
;
}
4
5
public
PhoneBook
()
6
{
7
Number
=
new
List
<
PhoneNumber
>();
8
}
9
10
public
void
AddPhoneNumber
(
PhoneNumber
entry
)
11
{
12
if
(
entry
==
null
)
13
throw
new
System
.
Exception
(
"The phone number entry cannot be null"
);
14
Number
.
Add
(
entry
);
15
}
16
17
public
PhoneNumber
GetPhoneNumber
(
int
index
)
18
{
19
return
Number
[
index
];
20
}
21
22
public
int
Count
23
{
24
get
25
{
26
return
Number
.
Count
;
27
}
28
}
29
30
public
PhoneNumber
FindPhoneNumber
(
string
telephoneNumber
)
31
{
32
PhoneNumber
found
=
null
;
33
foreach
(
PhoneNumber
item
in
Number
)
34
{
35
if
(
item
.
Number
.
Equals
(
telephoneNumber
))
36
{
37
found
=
item
;
38
break
;
39
}
40
}
41
return
found
;
42
}
43
44
public
List
<
PhoneNumber
>
FindPhoneNumbersByLastName
(
string
lastName
)
45
{
46
List
<
PhoneNumber
>
found
=
new
List
<
PhoneNumber
>();
47
foreach
(
PhoneNumber
item
in
Number
)
48
{
49
if
(
item
.
LastName
.
Equals
(
lastName
))
50
{
51
found
.
Add
(
item
);
52
}
53
}
54
return
found
;
55
}
56
}
ClassList
The ClassList example maintains a list of students for a particular course by offering methods to add and remove students from a course. In addition, the ClassList ensures that students are not added to the course twice (based on the student’s Id). The following parts of the ClassList must be coded to complete the solution.
- Constructor – Set the course id and the collection of students. Ensure that the supplied arguments are valid
- CourseId cannot be empty or null, and must be trimmed of leading or trailing spaces
- The collection object cannot be null and cannot have more students than the constant CLASS_LIMIT
- There cannot be any duplicate students in the collection (where a duplicate is defined as two or more Student objects with identical Ids)
- AddStudent() – Add the supplied student object to the collection. Ensure that
- The Student object is not null
- The class limit is not exceeded
- The Student object does not already exist in the collection (that is, there are no duplicates allowed, based on the student’s id)
- FindStudent() – Search the collection for a Student with a matching Id. If none is found, return null.
- RemoveStudent() – Search for a Student with a matching Id; if one is found, remove it from the collection.
Student
![](/site_images/programming0101/K-Student.png)
ClassList
![](/site_images/programming0101/K-ClassList.png)
1
public
class
ClassList
2
{
3
public
const
int
CLASS_LIMIT
=
25
;
4
public
string
CourseId
{
get
;
private
set
;
}
5
private
List
<
Student
>
students
;
6
7
public
ClassList
(
string
courseId
,
List
<
Student
>
students
)
8
{
9
if
(
String
.
IsNullOrEmpty
(
courseId
)
||
string
.
IsNullOrEmpty
(
courseId
.
Trim
\
10
()))
11
throw
new
Exception
(
"Course Id is required"
);
12
if
(
students
==
null
)
13
throw
new
Exception
(
"Students cannot be a null list"
);
14
if
(
students
.
Count
>
CLASS_LIMIT
)
15
throw
new
Exception
(
"Class Limit Exceeded"
);
16
for
(
int
index
=
0
;
index
<
students
.
Count
-
1
;
index
++)
17
{
18
int
id
=
students
[
index
].
StudentId
;
19
for
(
int
innerLoop
=
index
+
1
;
innerLoop
<
students
.
Count
;
innerLoo
\
20
p
++)
21
if
(
students
[
innerLoop
].
StudentId
==
id
)
22
throw
new
Exception
(
23
"Duplicate student Ids not allowed in the class list\
24
");
25
}
26
this
.
CourseId
=
courseId
.
Trim
();
27
this
.
students
=
students
;
28
}
29
30
public
ClassList
(
string
courseId
)
:
31
this
(
courseId
,
new
List
<
Student
>())
32
{
33
}
34
35
public
int
ClassSize
36
{
37
get
38
{
39
return
students
.
Count
;
40
}
41
}
42
43
public
void
AddStudent
(
Student
anotherStudent
)
44
{
45
if
(
anotherStudent
==
null
)
46
throw
new
Exception
(
"Cannot add null student"
);
47
if
(
students
.
Count
>=
CLASS_LIMIT
)
48
throw
new
Exception
(
"Class Limit Exceeded - Cannot add student"
);
49
for
(
int
index
=
0
;
index
<
students
.
Count
-
1
;
index
++)
50
{
51
int
id
=
students
[
index
].
StudentId
;
52
if
(
anotherStudent
.
StudentId
==
id
)
53
throw
new
Exception
(
54
"Duplicate student Ids not allowed in the class list"
);
55
}
56
students
.
Add
(
anotherStudent
);
57
}
58
59
public
Student
FindStudent
(
int
studentId
)
60
{
61
Student
found
=
null
;
62
for
(
int
index
=
0
;
index
<
students
.
Count
&&
found
==
null
;
index
++)
63
if
(
students
[
index
].
StudentId
==
studentId
)
64
found
=
students
[
index
];
65
return
found
;
66
}
67
68
public
Student
RemoveStudent
(
int
studentId
)
69
{
70
Student
found
=
FindStudent
(
studentId
);
71
if
(
found
!=
null
)
72
students
.
Remove
(
found
);
73
return
found
;
74
}
75
}
MultipleChoiceMarker
This class is used for marking multiple choice exams. It takes a collection of MultipleChoice objects as the answer key when it is first created. It provides a method to mark the student’s answers. The following methods must be coded to complete the solution.
- MarkExam() – This method takes the supplied exam answers and compares them against the answers in the marking key. It then constructs a Mark object, based on the earned marks and the possible marks (each answer is worth one mark). Before marking the exam, the method must ensure that
- The supplied collection of multiple choice answers is not null
- The supplied collection of multiple choice answers has the same number of answers as the MultipleChoiceMarker’s answer key
MultipleChoice and Mark Classes
![](/site_images/programming0101/K-MultipleChoice.png)
![](/site_images/programming0101/K-Mark.png)
MultipleChoiceMarker
![](/site_images/programming0101/K-MultipleChoiceMarker.png)
1
public
class
MultipleChoiceMarker
2
{
3
private
List
<
MultipleChoice
>
Key
{
get
;
set
;
}
4
5
public
MultipleChoiceMarker
(
List
<
MultipleChoice
>
key
)
6
{
7
if
(
key
==
null
)
8
throw
new
Exception
(
"Answer key cannot be null"
);
9
this
.
Key
=
key
;
10
}
11
12
public
Mark
MarkExam
(
List
<
MultipleChoice
>
examAnswers
)
13
{
14
if
(
examAnswers
==
null
)
15
throw
new
Exception
(
"Cannot mark null answers"
);
16
if
(
examAnswers
.
Count
!=
Key
.
Count
)
17
throw
new
Exception
(
18
"The number of student answers does not match the number of \
19
items
in
the
answer
key
");
20
int
possible
=
Key
.
Count
;
21
int
earned
=
0
;
22
// Calculate earned marks
23
for
(
int
index
=
0
;
index
<
Key
.
Count
;
index
++)
24
{
25
if
(
examAnswers
[
index
]
!=
null
)
26
if
(
Key
[
index
].
Choice
==
examAnswers
[
index
].
Choice
)
27
earned
++;
28
}
29
Mark
examMark
=
new
Mark
(
possible
,
earned
);
30
return
examMark
;
31
}
32
33
public
int
Count
34
{
35
get
36
{
37
return
Key
.
Count
;
38
}
39
}
40
}
BankStatement
This class represents a bank statement for a BankAccount for a given month. The statement allows BankTransaction objects to be added, and performs deposits and withdrawals on the BankAccount. The statement reports the starting and ending balance and also summarizes the total amount deposited and withdrawn for the month. The following methods must be coded to complete the solution.
- GetTotalDeposits() – Loop through the collection of transactions to total all those transactions with a positive amount.
- GetTotalWithdrawals() – Loop through the collection of transactions to total all those transactions with a negative amount.
Account and BankTransaction
![](/site_images/programming0101/K-Account.png)
![](/site_images/programming0101/K-BankTransaction.png)
Bank Statement
![](/site_images/programming0101/K-BankStatement.png)
1
public
class
BankStatement
2
{
3
public
Account
BankAccount
{
get
;
private
set
;
}
4
public
double
StartingBalance
{
get
;
private
set
;
}
5
public
Month
Month
{
get
;
private
set
;
}
6
public
List
<
BankTransaction
>
Transactions
{
get
;
private
set
;
}
7
public
double
EndingBalance
8
{
9
get
10
{
11
return
BankAccount
.
Balance
;
12
}
13
}
14
15
16
public
BankStatement
(
Account
bankAccount
,
Month
month
)
17
{
18
if
(
bankAccount
==
null
)
19
throw
new
System
.
Exception
(
"Bank account cannot be null"
);
20
this
.
BankAccount
=
bankAccount
;
21
this
.
StartingBalance
=
bankAccount
.
Balance
;
22
this
.
Month
=
month
;
23
this
.
Transactions
=
new
List
<
BankTransaction
>();
24
}
25
26
public
void
Add
(
BankTransaction
trans
)
27
{
28
if
(
trans
==
null
)
29
throw
new
System
.
Exception
(
"Cannot add null transactions"
);
30
double
amount
=
trans
.
Amount
;
31
if
(
amount
<
0
)
32
BankAccount
.
Withdraw
(-
amount
);
// Amount is "negated" to make positi\
33
ve
34
else
35
BankAccount
.
Deposit
(
amount
);
36
Transactions
.
Add
(
trans
);
37
}
38
39
public
double
TotalDeposits
40
{
41
get
42
{
43
double
total
=
0
;
44
for
(
int
index
=
0
;
index
<
Transactions
.
Count
;
index
++)
45
{
46
BankTransaction
aTransaction
=
Transactions
[
index
];
47
if
(
aTransaction
.
Amount
>
0
)
48
total
+=
aTransaction
.
Amount
;
49
}
50
return
total
;
51
}
52
}
53
54
public
double
TotalWithdrawals
55
{
56
get
57
{
58
double
total
=
0
;
59
foreach
(
BankTransaction
aTransaction
in
Transactions
)
60
if
(
aTransaction
.
Amount
<
0
)
61
total
+=
aTransaction
.
Amount
;
62
return
total
;
63
}
64
}
65
}
DeckOfCards
The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports a method to draw a card. The following methods must be coded to complete the solution.
- Constructor – Create all the cards for all the CardSuit values and all the CardValue values.
- DrawCard() – Return the card at the “top” of the deck (that is, at position zero). If the deck is empty, return a null.
- Shuffle() – Mix up the order of the PlayingCards in the Cards list. Shuffle should work regardless of the number of cards still in the deck.
PlayingCard and DeckOfCards
![](/site_images/programming0101/K-PlayingCard.png)
![](/site_images/programming0101/K-DeckOfCards.png)
1
public
class
DeckOfCards
2
{
3
private
List
<
PlayingCard
>
Cards
{
get
;
set
;
}
4
5
public
int
Count
6
{
get
{
return
Cards
.
Count
;
}
}
7
8
public
bool
IsEmpty
9
{
get
{
return
Count
==
0
;
}
}
10
11
public
DeckOfCards
()
12
{
13
Cards
=
new
List
<
PlayingCard
>();
14
foreach
(
PlayingCard
.
CardSuit
suit
in
System
.
Enum
.
GetValues
(
typeof
(
Playi
\
15
ngCard
.
CardSuit
)))
16
foreach
(
PlayingCard
.
CardValue
value
in
System
.
Enum
.
GetValues
(
typeof
\
17
(
PlayingCard
.
CardValue
)))
18
Cards
.
Add
(
new
PlayingCard
(
value
,
suit
));
19
}
20
21
public
PlayingCard
DrawCard
()
22
{
23
PlayingCard
card
=
null
;
24
if
(
Cards
.
Count
!=
0
)
25
{
26
card
=
Cards
[
0
];
27
Cards
.
Remove
(
card
);
28
}
29
return
card
;
30
}
31
32
public
void
Shuffle
()
33
{
34
for
(
int
counter
=
0
;
counter
<
100
;
counter
++)
35
{
36
int
index
=
Rnd
.
Next
(
Cards
.
Count
);
37
PlayingCard
card
=
Cards
[
0
];
38
Cards
.
RemoveAt
(
0
);
39
Cards
.
Insert
(
index
,
card
);
40
}
41
}
42
}
Practice examples
- PhoneBook – This extends the PhoneBook class by ensuring that duplicate phone numbers are not added to the collection.
- Registrar – The Registrar class is responsible to support the enrollment of students. This class maintains the student body as a collection of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program.
- BookBag – The BookBag class represents a simple “shopping cart” for a book consignment store. Books are sold on consignment, and customers can add or remove books from their BookBag as well as search their BookBag for books by ISBN. Customers can also see the total price of the items in their BookBag.
- DeckOfCards –The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports two public methods: Draw() and Shuffle().
PhoneBook
This extends the PhoneBook class by ensuring that duplicate phone numbers are not added to the collection. Make the following additions and modifications to complete the solution.
- AddPhoneNumber() – This method must be modified to ensure that the telephone number does not already exist; that is, no duplicate phone numbers are allowed, and an exception must be thrown if the supplied PhoneNumber already exists.
Registrar
The Registrar class is responsible to support the enrolment of students. This class maintains the student body as a collection of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program. Code the following methods to complete the Registrar class.
- Add() – This method takes the supplied Person information as well as the program of study to create a new Student, adding them to the collection of students in the student body. It returns the student Id for the new enrolment.
- FindStudent() – This method searches the student body for a student with a matching Id.
- RemoveStudent() – This method searches the student body for a student with a matching Id and removes them from the collection, if found.
- GetProgramEnrollment() – This method searches the collection of students to find out how many are enrolled in a particular program. Validate the Program name before performing the search.
BookBag
The BookBag class represents a simple “shopping cart” for a book consignment store. Books are sold on consignment, and customers can add or remove books from their BookBag as well as search their BookBag for books by ISBN. Customers can also see the total price of the items in their BookBag. Code the following methods to complete the BookBag class.
- GetTotal() – Loop through the collection of books and total the price of all the books. Ensure that the amount is rounded to two decimal places (for dollars and cents).
- FindBook() – Look through the collection of books to find a book with the specified ISBN number. Throw an exception if the supplied ISBN is null.
- RemoveBook() – Remove the book with a matching ISBN from the collection of book consignments.
DeckOfCards
Modify the DeckOfCards class to support shuffling of the deck.
- Shuffle() – This method resets the deck to a full deck of cards and then “shuffles” the deck until the cards are randomly distributed through the collection.
Topic L - Arrays - Not Sorted
Overview
All of these classes are used to illustrate working with un-sorted arrays.
LOGs
General Programming Concepts and Terms
- Describe what makes an array different from other collections in C#
- Describe the situations in which arrays are preferable over the use of collections
Code Samples
- Math - The Math class is modified to produce the sequence of Fibonacci numbers as an array.
- PhoneBook - The PhoneBook class provides simple management of an array of PhoneNumber objects. The PhoneBook allows for adding and retrieving phone numbers; it supports search for phone numbers by the telephone number or by a last name. The PhoneBook is initialized with a physical limit for the arrays, and the actual number of entries in the phone book is tracked as phone numbers are added to the phone book.
- ClassList - The ClassList example maintains an array of students for a particular course by offering methods to add and remove students from a course. In addition, the ClassList ensures that students are not added to the course twice (based on the student’s Id). The internal array is of a fixed size (ClassList.CLASS_LIMIT) as well as the logical size of the array. If the ClassList is provided with an array of students in its constructor, that list is “copied” to the internal array of the ClassList object.
- MultipleChoiceMarker - This class is used for marking multiple choice exams. It takes an array of MultipleChoice objects as the answer key when it is first created. It provides a method to mark the student’s answers.
- BankStatement - This class represents a bank statement for a BankAccount for a given month. The statement allows BankTransaction objects to be added, and performs deposits and withdrawals on the BankAccount. The statement reports the starting and ending balance and also summarizes the total amount deposited and withdrawn for the month.
- DeckOfCards -The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports a method to draw a card.
Math
This sample leverages the existing calculation of a number in the Fibonacci sequence to generate the sequence itself. The sequence is returned as an array of integers.
- FibonacciSequence(Length : Integer) - This method generates the sequence of Fibonacci numbers to a specific length in the sequence; the results are returned as an array of integers. If the specified length is negative, throw an exception.
1
public
static
int
[]
FibonacciSequence
(
int
length
)
2
{
3
int
[]
fib
=
new
int
[
0
];
4
if
(
length
>=
1
)
5
{
6
fib
=
new
int
[
length
];
7
for
(
int
index
=
0
;
index
<
length
;
index
++)
8
fib
[
index
]
=
FibonacciNumber
(
index
+
1
);
9
}
10
return
fib
;
11
}
PhoneBook
The PhoneBook class provides simple management of an array of PhoneNumber objects. The PhoneBook allows for adding and retrieving phone numbers; it supports search for phone numbers by the telephone number or by a last name. The PhoneBook is initialized with a physical limit for the arrays, and the actual number of entries in the phone book is tracked as phone numbers are added to the phone book.
- Constructor - Create a new array of PhoneNumber objects for the numbers field.
- AddPhoneNumber(Entry : PhoneNumber) - Add a PhoneNumber to the array. Ensure that the PhoneNumber exists (is not null) before adding; if the PhoneNumber is null, throw an exception. If there isn’t any room to add the PhoneNumber, then throw an exception.
- GetPhoneNumber(Index : Integer) : PhoneNumber - Get an item from a particular position in the array.
- Count : Integer - Get the logical size of the array.
- FindPhoneNumber(TelephoneNumber : String) : PhoneNumber - Look through the array and return a PhoneNumber with a matching telephone number. If none is found, return null.
- FindPhoneNumbersByLastName(LastName : String) : PhoneNumber[ ] - Look through the array for PhoneNumber objects with a matching last name. Add those objects to a new array and return it. If no items are found, return an empty array.
- Supporting Classes
- ArrayFullException - This class is used to indicate that the array is full and no more items can be added to the array.
- PhoneNumber - This class contains a telephone number and the name that the number is registered to.
![](/site_images/programming0101/L-ArrayFullException.png)
![](/site_images/programming0101/L-PhoneNumber.png)
![](/site_images/programming0101/L-PhoneBook.png)
1
public
class
PhoneBook
2
{
3
private
const
int
MAX_RECORDS
=
1000
;
4
private
PhoneNumber
[]
Number
{
get
;
set
;
}
5
public
int
Count
{
get
;
private
set
;
}
6
7
public
PhoneBook
()
8
{
9
Number
=
new
PhoneNumber
[
MAX_RECORDS
];
10
}
11
12
public
void
AddPhoneNumber
(
PhoneNumber
entry
)
13
{
14
if
(
entry
==
null
)
15
throw
new
System
.
Exception
(
"The phone number entry cannot be null"
);
16
if
(
Count
==
MAX_RECORDS
)
17
throw
new
ArrayFullException
(
"The phone book cannot hold any more Ph\
18
one
Numbers
");
19
20
Number
[
Count
]
=
entry
;
21
Count
++;
22
}
23
24
public
PhoneNumber
GetPhoneNumber
(
int
index
)
25
{
26
return
Number
[
index
];
27
}
28
29
public
PhoneNumber
FindPhoneNumber
(
string
telephoneNumber
)
30
{
31
PhoneNumber
found
=
null
;
32
int
foundIndex
=
-
1
;
33
for
(
int
index
=
0
;
index
<
Count
;
index
++)
34
{
35
if
(
Number
[
index
].
Number
.
Equals
(
telephoneNumber
))
36
{
37
foundIndex
=
index
;
38
break
;
39
}
40
}
41
if
(
foundIndex
>=
0
)
42
found
=
Number
[
foundIndex
];
43
return
found
;
44
}
45
46
public
PhoneNumber
[]
FindPhoneNumbersByLastName
(
string
lastName
)
47
{
48
PhoneNumber
[]
found
=
new
PhoneNumber
[
MAX_RECORDS
];
49
// Find the numbers
50
int
foundCounter
=
0
;
51
for
(
int
index
=
0
;
index
<
Count
;
index
++)
52
{
53
PhoneNumber
item
=
Number
[
index
];
54
if
(
item
.
LastName
.
Equals
(
lastName
))
55
{
56
found
[
foundCounter
]
=
item
;
57
foundCounter
++;
58
}
59
}
60
61
// Trim the array
62
PhoneNumber
[]
foundTrimmed
=
new
PhoneNumber
[
foundCounter
];
63
for
(
int
index
=
0
;
index
<
foundCounter
;
index
++)
64
{
65
foundTrimmed
[
index
]
=
found
[
index
];
66
}
67
68
return
foundTrimmed
;
69
}
70
}
ClassList
The ClassList example maintains an array of students for a particular course by offering methods to add and remove students from a course. In addition, the ClassList ensures that students are not added to the course twice (based on the student’s Id). The internal array is of a fixed size (ClassList.CLASS_LIMIT) as well as the logical size of the array. If the ClassList is provided with an array of students in its constructor, that list is “copied” to the internal array of the ClassList object.
- Constructor - Set the course id and the array of students. Ensure that the supplied arguments are valid
- CourseId cannot be empty or null, and must be trimmed of leading or trailing spaces
- The array of students cannot be null and cannot have more students than the constant CLASS_LIMIT
- There cannot be any duplicate students in the array (where a duplicate is defined as two or more Student objects with identical Ids)
- AddStudent() - Add the supplied student object to the array. Ensure that
- The Student object is not null
- The class limit is not exceeded
- The Student object does not already exist in the array (that is, there are no duplicates allowed, based on the student’s id)
- FindStudent() - Search the array for a Student with a matching Id. If none is found, return null.
- RemoveStudent() - Search for a Student with a matching Id; if one is found, remove it from the array.
- Supporting Classes
- Student -
![](/site_images/programming0101/L-Student.png)
![](/site_images/programming0101/L-ClassList.png)
1
public
class
ClassList
2
{
3
public
const
int
CLASS_LIMIT
=
25
;
4
public
string
CourseId
{
get
;
private
set
;
}
5
public
Student
[]
Students
{
get
;
private
set
;
}
6
public
int
ClassSize
{
get
;
private
set
;
}
7
8
public
ClassList
(
string
courseId
)
:
9
this
(
courseId
,
new
Student
[
CLASS_LIMIT
])
10
{
11
}
12
13
public
ClassList
(
string
courseId
,
Student
[]
existingStudentList
)
14
{
15
if
(
String
.
IsNullOrEmpty
(
courseId
)
||
string
.
IsNullOrEmpty
(
courseId
.
Trim
\
16
()))
17
throw
new
Exception
(
"Course Id is required"
);
18
if
(
existingStudentList
==
null
)
19
throw
new
Exception
(
"Students cannot be a null list"
);
20
if
(
existingStudentList
.
Length
>
CLASS_LIMIT
)
21
throw
new
Exception
(
"Class Limit Exceeded"
);
22
CopyClassList
(
existingStudentList
);
23
CheckforDuplicates
();
24
this
.
CourseId
=
courseId
.
Trim
();
25
}
26
27
private
void
CopyClassList
(
Student
[]
students
)
28
{
29
ClassSize
=
0
;
30
this
.
Students
=
new
Student
[
CLASS_LIMIT
];
31
for
(
int
i
=
0
;
i
<
students
.
Length
;
i
++)
32
{
33
if
(
students
[
i
]
!=
null
)
34
{
35
this
.
Students
[
ClassSize
]
=
students
[
i
];
36
ClassSize
++;
37
}
38
else
39
break
;
// Treat the first null instance as a "flag" indicating t\
40
he
end
of
actual
student
objects
in
the
array
41
}
42
}
43
44
private
void
CheckforDuplicates
()
45
{
46
for
(
int
index
=
0
;
index
<
ClassSize
-
1
;
index
++)
47
{
48
int
id
=
Students
[
index
].
StudentId
;
49
for
(
int
innerLoop
=
index
+
1
;
innerLoop
<
ClassSize
;
innerLoop
++)
50
if
(
Students
[
innerLoop
].
StudentId
==
id
)
51
throw
new
Exception
(
52
"Duplicate student Ids not allowed in the class list\
53
");
54
}
55
}
56
57
public
void
AddStudent
(
Student
anotherStudent
)
58
{
59
if
(
anotherStudent
==
null
)
60
throw
new
Exception
(
"Cannot add null student"
);
61
if
(
ClassSize
>=
CLASS_LIMIT
)
62
throw
new
ArrayFullException
(
"Class Limit Exceeded - Cannot add stud\
63
ent
");
64
for
(
int
index
=
0
;
index
<
ClassSize
-
1
;
index
++)
65
{
66
int
id
=
Students
[
index
].
StudentId
;
67
if
(
anotherStudent
.
StudentId
==
id
)
68
throw
new
Exception
(
69
"Duplicate student Ids not allowed in the class list"
);
70
}
71
Students
[
ClassSize
]
=
anotherStudent
;
72
ClassSize
++;
73
}
74
75
public
Student
FindStudent
(
int
studentId
)
76
{
77
Student
found
=
null
;
78
int
foundPosition
=
FindIndexPosition
(
studentId
);
79
if
(
foundPosition
>=
0
)
80
found
=
Students
[
foundPosition
];
81
return
found
;
82
}
83
84
private
int
FindIndexPosition
(
int
studentId
)
85
{
86
int
foundPosition
=
-
1
;
87
for
(
int
index
=
0
;
index
<
ClassSize
;
index
++)
88
if
(
Students
[
index
].
StudentId
==
studentId
)
89
foundPosition
=
index
;
90
return
foundPosition
;
91
}
92
93
public
Student
RemoveStudent
(
int
studentId
)
94
{
95
Student
found
=
null
;
96
int
foundPosition
=
FindIndexPosition
(
studentId
);
97
if
(
foundPosition
>=
0
)
98
{
99
found
=
Students
[
foundPosition
];
100
Students
[
foundPosition
]
=
Students
[
ClassSize
-
1
];
101
ClassSize
--;
102
}
103
return
found
;
104
}
105
}
MultipleChoiceMarker
This class is used for marking multiple choice exams. It takes an array of MultipleChoice objects as the answer key when it is first created. It provides a method to mark the student’s answers. The following methods must be coded to complete the solution.
- MarkExam() - This method takes the supplied exam answers and compares them against the answers in the marking key. It then constructs a Mark object, based on the earned marks and the possible marks (each answer is worth one mark). Before marking the exam, the method must ensure that
- The supplied array of multiple choice answers is not null
- The supplied array of multiple choice answers has the same number of answers as the MultipleChoiceMarker’s answer key
- Supporting Classes
- MultipleChoice -
![](/site_images/programming0101/L-MultipleChoice.png)
![](/site_images/programming0101/L-MultipleChoiceMarker.png)
1
public
Mark
MarkExam
(
MultipleChoice
[]
examAnswers
)
2
{
3
if
(
examAnswers
==
null
)
4
throw
new
Exception
(
"Cannot mark null answers"
);
5
if
(
examAnswers
.
Length
!=
Key
.
Length
)
6
throw
new
Exception
(
7
"The number of student answers does not match the number of \
8
items
in
the
answer
key
");
9
int
possible
=
Key
.
Length
;
10
int
earned
=
0
;
11
// Calculate earned marks
12
for
(
int
index
=
0
;
index
<
Key
.
Length
;
index
++)
13
{
14
if
(
examAnswers
[
index
]
!=
null
)
15
if
(
Key
[
index
].
Choice
==
examAnswers
[
index
].
Choice
)
16
earned
++;
17
}
18
Mark
examMark
=
new
Mark
(
possible
,
earned
);
19
return
examMark
;
20
}
BankStatement
This class represents a bank statement for a BankAccount for a given month. The statement allows BankTransaction objects to be added, and performs deposits and withdrawals on the BankAccount. The statement reports the starting and ending balance and also summarizes the total amount deposited and withdrawn for the month. The following methods must be coded to complete the solution.
- Add() - Add a BankTransaction to the array of transactions. If the BankTransaction is null, throw an exception. Otherwise, process the transaction as either a deposit or a withdrawal, depending on if the amount is positive or negative, and then add it to the array of transactions.
- GetTotalDeposits() - Loop through the array of transactions to total all those transactions with a positive amount.
- GetTotalWithdrawals() - Loop through the array of transactions to total all those transactions with a negative amount.
- Sort() - Sorts the array of transactions by date.
- Supporting Classes
- Account -
- BankTransaction -
- AccountType -
![](/site_images/programming0101/L-Account.png)
![](/site_images/programming0101/L-BankTransaction.png)
![](/site_images/programming0101/L-AccountType.png)
![](/site_images/programming0101/L-BankStatement.png)
![](/site_images/programming0101/L-BankTransactionDateComparer.png)
1
public
class
BankStatement
2
{
3
private
const
int
MAX_TRANSACTIONS
=
500
;
4
private
int
LogicalSize
{
get
;
set
;
}
5
public
Account
BankAccount
{
get
;
private
set
;
}
6
public
double
StartingBalance
{
get
;
private
set
;
}
7
public
Month
Month
{
get
;
private
set
;
}
8
public
BankTransaction
[]
Transactions
{
get
;
private
set
;
}
9
public
double
EndingBalance
10
{
11
get
12
{
13
return
BankAccount
.
Balance
;
14
}
15
}
16
17
public
BankStatement
(
Account
bankAccount
,
Month
month
)
18
{
19
if
(
bankAccount
==
null
)
20
throw
new
Exception
(
"Bank account cannot be null"
);
21
this
.
BankAccount
=
bankAccount
;
22
this
.
StartingBalance
=
bankAccount
.
Balance
;
23
this
.
Month
=
month
;
24
this
.
Transactions
=
new
BankTransaction
[
MAX_TRANSACTIONS
];
25
LogicalSize
=
0
;
26
}
27
28
public
void
Add
(
BankTransaction
trans
)
29
{
30
if
(
trans
==
null
)
31
throw
new
Exception
(
"Cannot add null transactions"
);
32
if
(
LogicalSize
==
MAX_TRANSACTIONS
)
33
throw
new
ArrayFullException
(
"The bank statement cannot accept furth\
34
er
transactions
;
the
array
is
full
");
35
36
double
amount
=
trans
.
Amount
;
37
if
(
amount
<
0
)
38
BankAccount
.
Withdraw
(-
amount
);
// Amount is "negated" to make positi\
39
ve
40
else
41
BankAccount
.
Deposit
(
amount
);
42
Transactions
[
LogicalSize
]
=
trans
;
43
LogicalSize
++;
44
}
45
46
public
double
TotalDeposits
47
{
48
get
49
{
50
double
total
=
0
;
51
for
(
int
index
=
0
;
index
<
LogicalSize
;
index
++)
52
{
53
BankTransaction
aTransaction
=
Transactions
[
index
];
54
if
(
aTransaction
.
Amount
>
0
)
55
total
+=
aTransaction
.
Amount
;
56
}
57
return
total
;
58
}
59
}
60
61
public
double
TotalWithdrawals
62
{
63
get
64
{
65
double
total
=
0
;
66
for
(
int
index
=
0
;
index
<
LogicalSize
;
index
++)
67
{
68
BankTransaction
aTransaction
=
Transactions
[
index
];
69
if
(
aTransaction
.
Amount
<
0
)
70
total
+=
aTransaction
.
Amount
;
71
}
72
return
total
;
73
}
74
}
75
76
public
void
Sort
()
77
{
78
Array
.
Sort
<
BankTransaction
>(
Transactions
,
new
BankTransactionDateCompare
\
79
r
());
80
}
81
}
1
public
class
BankTransactionDateComparer
:
IComparer
<
BankTransaction
>
2
{
3
#region IComparer<BankTransaction> Members
4
5
public
int
Compare
(
BankTransaction
x
,
BankTransaction
y
)
6
{
7
return
x
.
Date
.
CompareTo
(
y
.
Date
);
8
}
9
#endregion
10
}
DeckOfCards
The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports a method to draw a card. The following methods must be coded to complete the solution.
- Constructor - Create all the cards for all the CardSuit values and all the CardValue values.
- DrawCard() - Return the card at the “top” of the deck (that is, at position zero). If the deck is empty, return a null.
- IsEmpty - Returns true if the logical size of the deck of cards has reached zero, otherwise it returns false.
- Supporting Classes
- PlayingCard - The PlayingCard class, along with its two enumerated types CardSuit and CardValue, are the basis for the DeckOfCards class.
![](/site_images/programming0101/L-PlayingCard.png)
![](/site_images/programming0101/L-DeckOfCards.png)
1
public
class
DeckOfCards
2
{
3
private
PlayingCard
[]
Cards
{
get
;
set
;
}
4
public
int
Count
{
get
;
private
set
;
}
5
public
bool
IsEmpty
{
get
{
return
Count
==
0
;
}
}
6
7
public
DeckOfCards
()
8
{
9
Cards
=
new
PlayingCard
[
52
];
10
11
foreach
(
PlayingCard
.
CardSuit
suit
in
System
.
Enum
.
GetValues
(
typeof
(
Playi
\
12
ngCard
.
CardSuit
)))
13
foreach
(
PlayingCard
.
CardValue
value
in
System
.
Enum
.
GetValues
(
typeof
\
14
(
PlayingCard
.
CardValue
)))
15
{
16
Cards
[
Count
]
=
new
PlayingCard
(
value
,
suit
);
17
Count
++;
18
}
19
}
20
21
public
PlayingCard
DrawCard
()
22
{
23
PlayingCard
card
=
null
;
24
if
(
Count
!=
0
)
25
{
26
// get the first card
27
card
=
Cards
[
0
];
28
// "pull" the other items up in the array
29
for
(
int
i
=
0
;
i
<
Count
-
1
;
i
++)
30
{
31
Cards
[
i
]
=
Cards
[
i
+
1
];
32
}
33
// "clear" the last element & adjust the count
34
Cards
[
Count
-
1
]
=
null
;
35
Count
--;
36
}
37
return
card
;
38
}
39
40
public
void
Shuffle
()
41
{
42
for
(
int
counter
=
0
;
counter
<
100
;
counter
++)
43
{
44
int
index
=
Rnd
.
Next
(
Count
);
45
PlayingCard
card
=
Cards
[
0
];
46
Cards
[
0
]
=
Cards
[
index
];
47
Cards
[
index
]
=
card
;
48
}
49
}
50
}
Practice Exercises
- PhoneBook – This extends the PhoneBook class by ensuring that duplicate phone numbers are not added to the collection.
- Registrar – The Registrar class is responsible to support the enrollment of students. This class maintains the student body as a collection of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program.
- BookBag – The BookBag class represents a simple “shopping cart” for a book consignment store. Books are sold on consignment, and customers can add or remove books from their BookBag as well as search their BookBag for books by ISBN. Customers can also see the total price of the items in their BookBag.
- DeckOfCards –The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports two public methods: Draw() and Shuffle().
- CD – [Not yet implemented] This class represents an array of Songs. It supports the ability to calculate the total running time and the average running time of all the songs on the CD.
PhoneBook
This extends the PhoneBook class by ensuring that duplicate phone numbers are not added to the collection. Make the following additions and modifications to complete the solution.
- AddPhoneNumber() – This method must be modified to ensure that the telephone number does not already exist; that is, no duplicate phone numbers are allowed, and an exception must be thrown if the supplied PhoneNumber already exists.
Registrar
The Registrar class is responsible to support the enrolment of students. This class maintains the student body as a collection of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program.
The Registrar class is responsible to support the enrolment of students. This class maintains the student body as an array of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program. Code the following methods to complete the Registrar class.
- Add() – This method takes the supplied Person information as well as the program of study to create a new Student, adding them to the array of students in the student body. It returns the student Id for the new enrolment.
- FindStudent() – This method searches the student body for a student with a matching Id.
- RemoveStudent() – This method searches the student body for a student with a matching Id and removes them from the collection, if found.
- GetProgramEnrollment() – This method searches the array of students to find out how many are enrolled in a particular program. Validate the Program name before performing the search.
BookBag
The BookBag class represents a simple “shopping cart” for a book consignment store. Books are sold on consignment, and customers can add or remove books from their BookBag as well as search their BookBag for books by ISBN. Customers can also see the total price of the items in their BookBag. Code the following methods to complete the BookBag class.
- GetTotal() – Loop through the array of books and total the price of all the books. Ensure that the amount is rounded to two decimal places (for dollars and cents).
- FindBook() – Look through the array of books to find a book with the specified ISBN number. Throw an exception if the supplied ISBN is null.
- RemoveBook() – Remove the book with a matching ISBN from the array of book consignments.
DeckOfCards
The DeckOfCards class represents a complete deck of cards. When the deck is first created, a card is created for each suit. The DeckOfCards supports two public methods: Draw() and Shuffle(). Modify the DeckOfCards class to support shuffling of the deck.
- Shuffle() – This method resets the deck to a full deck of cards and then “shuffles” the deck until the cards are randomly distributed through the collection.
CD
[Not yet implemented]
This class represents an array of Songs. It supports the ability to calculate the total running time and the average running time of all the songs on the CD.
Topic M - Arrays - Sorted
Overview
The focus of this topic is sorting arrays and performing searches, inserts, and deletions from a sorted array.
LOGs
Code Samples
- BranchVault - The BranchVault class manages safety deposit boxes. Each box has a unique number, and may be assigned to a particular account number. This class demonstrates the bubble sort and the binary search.
- PhoneBook - The PhoneBook class provides simple management of an array of PhoneNumber objects. The PhoneBook allows for adding and retrieving phone numbers; it supports search for phone numbers by the telephone number or by a last name. The PhoneBook is initialized with a physical limit for the arrays, and the actual number of entries in the phone book is tracked as phone numbers are added to the phone book. The AddPhoneNumber() method demonstrates adding to an array that is to be sorted.
- ClassList -The ClassList example maintains an array of students for a particular course by offering methods to add and remove students from a course. In addition, the ClassList ensures that students are not added to the course twice (based on the student’s Id). The internal array is of a fixed size (ClassList.CLASS_LIMIT) as well as the logical size of the array. If the ClassList is provided with an array of students in its constructor, that list is “copied” to the internal array of the ClassList object.
- BankStatement - [Not Implemented - Sorting by Date] This class represents a bank statement for a BankAccount for a given month. The statement allows BankTransaction objects to be added, and performs deposits and withdrawals on the BankAccount. The statement reports the starting and ending balance and also summarizes the total amount deposited and withdrawn for the month.
BranchVault
The BranchVault class manages safety deposit boxes. Each box has a unique number, and may be assigned to a particular account number. This class demonstrates the bubble sort and the binary search. Code the following methods to complete this class.
- SortBoxes() - This private method performs a bubble sort of the array of SafetyDepositBox objects. The boxes are to be sorted in ascending order according to their box number.
- Find() - This public method performs a binary search of the SafetyDepositBox array for a particular box number. If the box number is not found, it returns a null.
PhoneBook
The PhoneBook class provides simple management of an array of PhoneNumber objects. The PhoneBook allows for adding and retrieving phone numbers; it supports search for phone numbers by the telephone number or by a last name. The PhoneBook is initialized with a physical limit for the arrays, and the actual number of entries in the phone book is tracked as phone numbers are added to the phone book. The AddPhoneNumber() method demonstrates adding to an array that is to be sorted. Code the following methods to complete this class.
- BubbleSortByPhoneNumber() - This private method performs a bubble sort of the array of PhoneNumber objects. They are to be sorted in ascending order, based on the telephone number.
- InsertSortedByPhoneNumber() - This private method will insert a PhoneNumber object into the array while preserving the sort order of the array (based on the array being sorted in ascending order by telephone number).
ClassList
The ClassList example maintains an array of students for a particular course by offering methods to add and remove students from a course. In addition, the ClassList ensures that students are not added to the course twice (based on the student’s Id). The internal array is of a fixed size (ClassList.CLASS_LIMIT) as well as the logical size of the array. If the ClassList is provided with an array of students in its constructor, that list is “copied” to the internal array of the ClassList object (to ensure that the internal array has the appropriate physical size).
All of the Student objects in the ClassList are stored in a sorted array, based on the student Id. Code the following methods to complete this class.
- AddInsertSortedByStudentId() - This private method is called by both the AddStudent method and the constructor. It adds a student to the class list while maintaining a sort order (sorted by student Id in ascending order).
- FindStudent() - This public method performs a binary search of the array of Student objects. If the Student is found, this method will return that Student object, otherwise it will return null.
- RemoveStudent() - This public method will remove a particular Student from the array, while maintaining the sort order of the array. If the Student is found, this method will return that Student object, otherwise it will return a null.
- GetStudents() - This public method will generate and return a copy of the array of Student objects.
Supporting Classes
Practice Exercises
- PhoneBook - [Sorting by Name and Sorting by Phone Number] This extends the PhoneBook class by adding sorting by phone number and a binary search.
- Registrar - [Sorting by ID] The Registrar class is responsible to support the enrollment of students. This class maintains the student body as a collection of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program.
- CDLibrary - [Not Yet Implemented] This class manages a collection of CDs that are stored in alphabetical order. It supports searching the library for CDs based on the title.
PhoneBook
Extend the PhoneBook class by adding sorting by name and a binary search when sorted by number.
- FindPhoneNumberUsingBinarySearch() - This private method will do a binary search of the PhoneNumber array to find a PhoneNumber with a matching telephone number.
- BubbleSortByLastNameThenFirstName() - This private method sorts the array by first name within last name, in ascending alphabetical order.
Registrar
[Sorting by ID] The Registrar class is responsible to support the enrolment of students. This class maintains the student body as an array of Student objects. It supports the ability to find and remove students, switch students to another program, and get the number of students enrolled in a specific program. Code the following methods to complete the Registrar class.
- RemoveStudent() - This method must be modified to maintain the sort order when removing a student from the array.
CDLibrary
[Not Yet Implemented]
OOP - Getting Real
Topic N - Modularization and Utility Classes
Overview
This topic examines the technique of modularization as a way to simplify complex logic. In addition, this topic looks at the use of “utility” classes to aid in simplifying code and enabling better “code-reuse” for repetitive tasks. This technique of “simplifying” complex logic is also known as “refactoring”.
Modularization will be examined in the context of simplifying the internal working of a class’ methods and in the context of organizing and simplifying a driver. For classes, modularization is simply taking any repetitive or overly-complex code out of the class’ existing methods and placing that code inside of private methods. For console drivers (which typically consist of static methods), to be continued…
LOGs
Code Sample
- CD - This class represents a CD of Songs. It supports a public method to get long songs (which are songs whose RunningTime is greater than the average running time). A private method called resizeArray() is created to “modularize” this public method’s behaviour.
- RunningTime - This class represents an amount of time in minutes and seconds, and is used as the length of time for a Song. This class introduces the Scanner class for one of its constructors, which generates the running time from a string that is formatted as “minutes:seconds” (such as “5:39”, which would be 5 minutes and 30 seconds).
This class also uses an internal private method called paddZero() that ensures the seconds whose values are less than 10 have a leading zero when converted to a string. - TextFormatter - This class provides static methods for common string formatting needs, such as right and left justifying strings.
- MusicInfoFormatter - This class provides static methods for formatting CD information, such as the CD’s title and the information for a given Song. This kind of formatting is commonly seen, for example, in CD players that display the currently playing song.
CD
This class represents a CD of Songs. It supports a public method to get long songs (which are songs whose RunningTime is greater than the average running time). A private method called resizeArray() is created to “modularize” this public method’s behaviour.
- getLongSongs() - Refactor this method so that the code that resizes the array of songs is put into its own private method, called resizeArray.
RunningTime
This class represents an amount of time in minutes and seconds, and is used as the length of time for a Song. This class introduces the Scanner class for one of its constructors, which generates the running time from a string that is formatted as “minutes:seconds” (such as “5:39”, which would be 5 minutes and 30 seconds).
This class also uses an internal private method called paddZero() that ensures the seconds whose values are less than 10 have a leading zero when converted to a string.
- toString() - Refactor this method to use a new private method called paddZero. The paddZero method will return a string version of the integer value passed in and will ensure that the string has a leading zero character if the supplied value is less than ten.
TextFormatter
This class provides static methods for common string formatting.
- leftJustify() - This static method will append spaces after the supplied text until the supplied text is at least the required length. Note that this method will not trim the supplied text if it is longer than the required length.
- rightJustify() - This static method will prepend spaces before the supplied text until the supplied text is at least the required length. Note that this method will not trim the supplied text if it is longer than the required length.
- shortenWithEllipsis() - This static method will check the length of the supplied text against the desired length. If the supplied text is longer, it will trim off trailing characters and append an ellipsis (…) , while ensuring that the resulting text is the desired length.
MusicInfoFormatter
This class provides static methods for formatting CD information, such as the CD’s title and the information for a given Song. This kind of formatting is commonly seen, for example, in CD players that display the currently playing song.
- formatTitleInfo() - This method generates a string that has title information for a CD that includes the CDs title and the name of the performing artist. The title name must be shortened with an ellipsis to a maximum length of 30 characters. The generated string must use the following overall format:
Title: ‘CD Title’ (Artist: Performing Artist Name) - formatSongInfo() - This method generates a string that follows specific formatting for a given song. It must use the following format:
Track Number: Song Title [Running Time] (by Song Writer)
The running time must be in the format of MM:SS.
## Practice Exercises
- TextFormatter - This class provides static methods for formatting strings. Expand this class by providing overloaded versions of the leftJustify() and rightJustify() methods that allow the padding character to be supplied through the parameter list.
TextFormatter
This class provides static methods for formatting strings. Expand this class by providing overloaded versions of the leftJustify() and rightJustify() methods that allow the padding character to be supplied through the parameter list.
Topic O - File I/O
Overview
All of the File I/O examples follow the same design pattern. This pattern is a form of what is called the Adapter Pattern. Each class has the following characteristics.
All of the text files used in this topic have their records delimited by carriage returns and their fields delimited by commas. File input is achieved through use of the Scanner class. The Scanner is also used to parse each record by specifying the use of the comma delimiter.
File Input/Output (IO) is all about using files for storing and retrieving data. These files exist “outside” of your program, and code is required to transfer the data between the file and the objects/variables in your program.
Data inside of files can be stored in either a binary or a text format. All of these examples will deal with text files. When using text files, the text itself needs to follow some pattern in order to distinguish the individual pieces of data from each other.
An old and traditional way of storing the text is to use a CSV (Comma-Separated Values) format. In this format, each row of information (also known as a “record” of data) is broken down into individual pieces of data by separating each piece (or “field”) by a comma. Rows are separated by a new line (or “carriage return”) marker. This format has had the advantage of being easy for humans to read and edit directly; it is also fairly flexible and programmers can easily adapt the form to fit the shape of the data they wish to store.
A more modern approach is to store the textual information in XML (eXtensible Markup Language) format. While also being human-readable and easy to format, XML has the advantage of making it easier for computer programs to read and save data that is both relational and complex. XML format uses “tags” (or “mark-up”) to wrap data. For example, if information on a person (“Bob Smith”) is stored in an XML file, it might look like this.
1
<Person>
2
<FirstName>
Bob</FirstName>
3
<LastName>
Smith</LastName>
4
</Person>
File Input/Output is best performed by having one class (or object) deal with formatting the data and a separate class to deal with directly accessing the file. In the following examples, the CSVFileIO and XMLFileIO classes read and write directly to the files, while the other classes (which end with “Adapter”) are concerned with determining the format of the data.
CSVFileIO
1
/// <summary>
2
/// The CSVFileStorage class provides simple reading of all the lines of text of\
3
a
CSV
(
Comma
-
Separated
-
Values
)
file
.
4
/// </summary>
5
public
class
CSVFileIO
6
{
7
public
string
FilePath
{
get
;
private
set
;
}
8
9
/// <summary>
10
/// Initializes a new instance of the CSVFileStorage class.
11
/// </summary>
12
public
CSVFileIO
(
string
filePath
)
13
{
14
FilePath
=
filePath
;
15
}
16
17
public
List
<
string
>
ReadAllLines
()
18
{
19
List
<
string
>
lines
=
new
List
<
string
>();
20
using
(
TextReader
reader
=
new
StreamReader
(
FilePath
))
21
{
22
string
aSingleLine
=
reader
.
ReadLine
();
23
while
(
aSingleLine
!=
null
)
24
{
25
lines
.
Add
(
aSingleLine
);
26
aSingleLine
=
reader
.
ReadLine
();
27
}
28
}
29
return
lines
;
30
}
31
32
public
void
WriteAllLines
(
List
<
string
>
lines
,
bool
append
)
33
{
34
using
(
TextWriter
writer
=
new
StreamWriter
(
FilePath
,
append
))
35
{
36
foreach
(
string
line
in
lines
)
37
{
38
writer
.
WriteLine
(
line
);
39
}
40
}
41
}
42
}
XMLFileIO
1
/// <summary>
2
/// The XMLFileIO class manages loading and saving any type to an XML file.
3
/// </summary>
4
public
class
XMLFileIO
<
T
>
5
{
6
public
string
FilePath
{
get
;
private
set
;
}
7
8
public
XMLFileIO
(
string
filePath
)
9
{
10
FilePath
=
filePath
;
11
}
12
13
public
List
<
T
>
LoadAll
()
14
{
15
XmlSerializer
deserializer
=
new
XmlSerializer
(
typeof
(
List
<
T
>));
16
List
<
T
>
data
;
17
using
(
TextReader
textReader
=
new
StreamReader
(
FilePath
))
18
{
19
data
=
(
List
<
T
>)
deserializer
.
Deserialize
(
textReader
);
20
textReader
.
Close
();
21
}
22
return
data
;
23
}
24
25
public
void
SaveAll
(
List
<
T
>
data
,
bool
append
)
26
{
27
if
(
append
&&
File
.
Exists
(
FilePath
))
28
{
29
List
<
T
>
existingData
=
LoadAll
();
30
existingData
.
AddRange
(
data
);
31
data
=
existingData
;
32
}
33
using
(
Stream
stream
=
File
.
Open
(
FilePath
,
FileMode
.
OpenOrCreate
))
34
{
35
XmlSerializer
serializer
=
new
XmlSerializer
(
typeof
(
List
<
T
>));
36
using
(
TextWriter
writer
=
new
StreamWriter
(
stream
))
37
{
38
serializer
.
Serialize
(
writer
,
data
);
39
writer
.
Close
();
40
}
41
}
42
}
43
}
LOGs
- A constructor that takes a valid File object
- A method called fill() that takes an array as the parameter and returns the number of entries created in the array from having read the file.
Code Samples
- PhoneNumberFileAdapter - This reads a text file to fill a list of PhoneNumber data.
- StudentFileAdapter - This reads a text file to fill a list of Student data.
- BookFileAdapter - This reads a text file to fill a list of Book data. Note that in this example, not every field in the record structure is used in creating the required Book objects; unused fields are simply read and “discarded” by the BookFileAdapter. In addition, the Book class and text file used in this example allows for a book to have multiple authors.
- SafetyDepositBoxFileAdapter - This reads a text file to fill a list of SafetyDepositBox data. Note that in this particular example, some records may not have an account number for the box number.
PhoneNumberFileAdapter
This reads a text file to fill a list of PhoneNumber data.
- Record Structure:
- Telephone Number : String
- Last Name : String
- First Name : String
1
public
class
PhoneNumberFileAdapter
2
{
3
#region Read from a file
4
public
static
List
<
PhoneNumber
>
LoadList
(
string
filePath
,
FileFormat
format
)
5
{
6
List
<
PhoneNumber
>
data
;
7
if
(
format
==
FileFormat
.
CSV
)
8
data
=
LoadList
(
new
CSVFileIO
(
filePath
));
9
else
10
data
=
LoadList
(
new
XMLFileIO
<
PhoneNumber
>(
filePath
));
11
return
data
;
12
}
13
14
private
static
List
<
PhoneNumber
>
LoadList
(
CSVFileIO
reader
)
15
{
16
List
<
PhoneNumber
>
data
=
new
List
<
PhoneNumber
>();
17
List
<
string
>
lines
=
reader
.
ReadAllLines
();
18
foreach
(
string
individualLine
in
lines
)
19
{
20
// code specifics here..
21
string
[]
fields
=
individualLine
.
Split
(
','
);
22
string
firstName
=
fields
[
0
],
lastName
=
fields
[
1
],
number
=
fields
[
\
23
2
];
24
data
.
Add
(
new
PhoneNumber
(
firstName
,
lastName
,
number
));
25
}
26
return
data
;
27
}
28
29
private
static
List
<
PhoneNumber
>
LoadList
(
XMLFileIO
<
PhoneNumber
>
reader
)
30
{
31
return
reader
.
LoadAll
();
32
}
33
#endregion
34
35
#region Write to a file
36
public
static
void
SaveList
(
List
<
PhoneNumber
>
data
,
string
fileName
,
FileFor
\
37
mat
format
,
bool
append
)
38
{
39
if
(
format
==
FileFormat
.
CSV
)
40
SaveList
(
new
CSVFileIO
(
fileName
),
data
,
append
);
41
else
42
SaveList
(
new
XMLFileIO
<
PhoneNumber
>(
fileName
),
data
,
append
);
43
}
44
45
private
static
void
SaveList
(
CSVFileIO
writer
,
List
<
PhoneNumber
>
data
,
bool
\
46
append
)
47
{
48
List
<
string
>
lines
=
new
List
<
string
>();
49
foreach
(
PhoneNumber
item
in
data
)
50
{
51
lines
.
Add
(
item
.
FirstName
+
","
+
item
.
LastName
+
","
+
item
.
Number
);
52
}
53
writer
.
WriteAllLines
(
lines
,
append
);
54
}
55
56
private
static
void
SaveList
(
XMLFileIO
<
PhoneNumber
>
writer
,
List
<
PhoneNumber
\
57
>
data
,
bool
append
)
58
{
59
writer
.
SaveAll
(
data
,
append
);
60
}
61
#endregion
62
}
StudentFileAdapter
This reads a text file to fill a list of Student data.
- Record Structure:
- Student Id : Integer
- Name : String
- Gender : GenderType
1
public
class
StudentFileAdapter
2
{
3
#region Read from a file
4
public
static
List
<
Student
>
LoadList
(
string
filePath
,
FileFormat
format
)
5
{
6
List
<
Student
>
data
;
7
if
(
format
==
FileFormat
.
CSV
)
8
data
=
LoadList
(
new
CSVFileIO
(
filePath
));
9
else
10
data
=
LoadList
(
new
XMLFileIO
<
Student
>(
filePath
));
11
return
data
;
12
}
13
14
private
static
List
<
Student
>
LoadList
(
CSVFileIO
reader
)
15
{
16
List
<
Student
>
data
=
new
List
<
Student
>();
17
List
<
string
>
lines
=
reader
.
ReadAllLines
();
18
foreach
(
string
individualLine
in
lines
)
19
{
20
// code specifics here..
21
string
[]
fields
=
individualLine
.
Split
(
','
);
22
int
id
=
System
.
Convert
.
ToInt32
(
fields
[
0
]);
23
string
name
=
fields
[
1
];
24
GenderType
gender
=
(
GenderType
)
System
.
Enum
.
Parse
(
typeof
(
GenderType
)
\
25
,
fields
[
2
]);
26
data
.
Add
(
new
Student
(
name
,
gender
,
id
));
27
}
28
return
data
;
29
}
30
31
private
static
List
<
Student
>
LoadList
(
XMLFileIO
<
Student
>
reader
)
32
{
33
return
reader
.
LoadAll
();
34
}
35
#endregion
36
37
#region Write to a file
38
public
static
void
SaveList
(
List
<
Student
>
data
,
string
fileName
,
FileFormat
\
39
format
,
bool
append
)
40
{
41
if
(
format
==
FileFormat
.
CSV
)
42
SaveList
(
new
CSVFileIO
(
fileName
),
data
,
append
);
43
else
44
SaveList
(
new
XMLFileIO
<
Student
>(
fileName
),
data
,
append
);
45
}
46
47
private
static
void
SaveList
(
CSVFileIO
writer
,
List
<
Student
>
data
,
bool
appe
\
48
nd
)
49
{
50
List
<
string
>
lines
=
new
List
<
string
>();
51
foreach
(
Student
item
in
data
)
52
{
53
lines
.
Add
(
item
.
StudentId
.
ToString
()
+
","
+
item
.
Name
+
","
+
item
.
G
\
54
ender
.
ToString
());
55
}
56
writer
.
WriteAllLines
(
lines
,
append
);
57
}
58
59
private
static
void
SaveList
(
XMLFileIO
<
Student
>
writer
,
List
<
Student
>
data
,
\
60
bool
append
)
61
{
62
writer
.
SaveAll
(
data
,
append
);
63
}
64
#endregion
65
}
BookFileAdapter
This reads a CSV text file to fill a list of Book data. Note that in this example, not every field in the record structure of CSV files is used in creating the required Book objects; unused fields are simply read and “discarded” by the BookFileAdapter. In addition, the Book class and text file used in this example allows for a book to have multiple authors.
- Record Structure in the file:
- Title : String
- Authors : String - delimited by semi-colons
- Publication year : Integer
- Publisher : String
- Format : String
- Dewey Decimal Number : String - could be empty in the file
- ISBN : String
- Number of Pages : Integer
- Cover Price : Money
1
/// <summary>
2
/// BookFileAdapter provides a way to read and write
3
/// Book information to and from text files.
4
/// </summary>
5
/// <remarks>
6
/// This class requires that the file structure be in the following format:
7
/// <ol><li>Title : String
8
/// <li>Authors : String[]
9
/// <ol><li>The Author information is a semicolon (;) separated list of authors
10
/// </li></ol>
11
/// <li>Publication Year : Integer
12
/// <li>Publisher : String
13
/// <li>Format : String
14
/// <li>Dewey Decimal Number : String
15
/// <li>ISBN : String
16
/// <li>Number of Pages : Integer
17
/// <li>Cover Price : Money
18
/// </ol>
19
/// <para>
20
/// This method fills a List of Book data. Each Book only needs
21
/// the title, the authors (as an array of Strings), and the ISBN.
22
/// Therefore, the other data in the file will simply be discarded as it
23
/// is read. In the file, the Author information is a semicolon (;)
24
/// separated list of authors.
25
/// </para>
26
/// </remarks>
27
public
class
BookFileAdapter
28
{
29
#region Read from a file
30
public
static
List
<
Book
>
LoadList
(
string
filePath
,
FileFormat
format
)
31
{
32
List
<
Book
>
data
;
33
if
(
format
==
FileFormat
.
CSV
)
34
data
=
LoadList
(
new
CSVFileIO
(
filePath
));
35
else
36
data
=
LoadList
(
new
XMLFileIO
<
Book
>(
filePath
));
37
return
data
;
38
}
39
40
private
static
List
<
Book
>
LoadList
(
CSVFileIO
reader
)
41
{
42
List
<
Book
>
data
=
new
List
<
Book
>();
43
List
<
string
>
lines
=
reader
.
ReadAllLines
();
44
foreach
(
string
individualLine
in
lines
)
45
{
46
string
title
,
authorList
;
47
ISBN
bookUPC
;
48
// Parse the record
49
string
[]
fields
=
individualLine
.
Split
(
','
);
50
title
=
fields
[
0
];
51
authorList
=
fields
[
1
];
52
// fields[2] Publication Year
53
// fields[3] Publisher
54
// fields[4] Format
55
// fields[5] Dewey Decimal Number
56
bookUPC
=
new
ISBN
(
fields
[
6
]);
57
// fields[7] Number of Pages
58
// fields[8] Cover Price
59
60
// Parse the authorList
61
string
[]
authors
=
null
;
62
authors
=
authorList
.
Split
(
';'
);
63
64
// Create the book and add it to the array
65
data
.
Add
(
new
Book
(
title
,
authors
,
bookUPC
));
66
}
67
return
data
;
68
}
69
70
private
static
List
<
Book
>
LoadList
(
XMLFileIO
<
Book
>
reader
)
71
{
72
return
reader
.
LoadAll
();
73
}
74
#endregion
75
76
#region Write to a file
77
public
static
void
SaveList
(
List
<
Book
>
data
,
string
fileName
,
FileFormat
for
\
78
mat
,
bool
append
)
79
{
80
if
(
format
==
FileFormat
.
CSV
)
81
SaveList
(
new
CSVFileIO
(
fileName
),
data
,
append
);
82
else
83
SaveList
(
new
XMLFileIO
<
Book
>(
fileName
),
data
,
append
);
84
}
85
86
private
static
void
SaveList
(
CSVFileIO
writer
,
List
<
Book
>
data
,
bool
append
)
87
{
88
List
<
string
>
lines
=
new
List
<
string
>();
89
foreach
(
Book
item
in
data
)
90
{
91
string
formattedRecord
;
92
formattedRecord
=
item
.
Title
;
93
formattedRecord
+=
string
.
Join
(
";"
,
item
.
Authors
);
94
formattedRecord
+=
item
.
Isbn
.
BarCode
;
95
96
lines
.
Add
(
formattedRecord
);
97
}
98
writer
.
WriteAllLines
(
lines
,
append
);
99
}
100
101
private
static
void
SaveList
(
XMLFileIO
<
Book
>
writer
,
List
<
Book
>
data
,
bool
a
\
102
ppend
)
103
{
104
writer
.
SaveAll
(
data
,
append
);
105
}
106
#endregion
107
}
SafetyDepositBoxFileAdapter
This reads a text file to fill a list of SafetyDepositBox data. Note that in this particular example, some records may not have an account number for the box number.
- Record Structure:
- Box Number : Integer
- Account Number : Integer - may not exist
1
/// <summary>
2
/// SafetyDepositBoxFileAdapter provides a way to read and write
3
/// SafetyDepositBox information to and from text files.
4
/// </summary>
5
/// <remarks>
6
/// This class requires that the file structure be in the following format:
7
/// <ol><li>StudentId : Integer
8
/// <li>StudentName : String
9
/// <li>StudentGender : GenderType
10
/// </ol>
11
/// </remarks>
12
public
class
SafetyDepositBoxFileAdapter
13
{
14
#region Read from a file
15
public
static
List
<
SafetyDepositBox
>
LoadList
(
string
filePath
,
FileFormat
fo
\
16
rmat
)
17
{
18
List
<
SafetyDepositBox
>
data
;
19
if
(
format
==
FileFormat
.
CSV
)
20
data
=
LoadList
(
new
CSVFileIO
(
filePath
));
21
else
22
data
=
LoadList
(
new
XMLFileIO
<
SafetyDepositBox
>(
filePath
));
23
return
data
;
24
}
25
26
private
static
List
<
SafetyDepositBox
>
LoadList
(
CSVFileIO
reader
)
27
{
28
List
<
SafetyDepositBox
>
data
=
new
List
<
SafetyDepositBox
>();
29
List
<
string
>
lines
=
reader
.
ReadAllLines
();
30
foreach
(
string
individualLine
in
lines
)
31
{
32
// code specifics here..
33
string
[]
fields
=
individualLine
.
Split
(
','
);
34
int
boxNumber
,
accountNumber
;
35
boxNumber
=
Convert
.
ToInt32
(
fields
[
0
]);
36
if
(
fields
.
Length
>
1
)
37
{
38
accountNumber
=
Convert
.
ToInt32
(
fields
[
1
]);
39
data
.
Add
(
new
SafetyDepositBox
(
boxNumber
,
accountNumber
));
40
}
41
else
42
{
43
data
.
Add
(
new
SafetyDepositBox
(
boxNumber
));
44
}
45
}
46
return
data
;
47
}
48
49
private
static
List
<
SafetyDepositBox
>
LoadList
(
XMLFileIO
<
SafetyDepositBox
>
r
\
50
eader
)
51
{
52
return
reader
.
LoadAll
();
53
}
54
#endregion
55
56
#region Write to a file
57
public
static
void
SaveList
(
List
<
SafetyDepositBox
>
data
,
string
fileName
,
Fi
\
58
leFormat
format
,
bool
append
)
59
{
60
if
(
format
==
FileFormat
.
CSV
)
61
SaveList
(
new
CSVFileIO
(
fileName
),
data
,
append
);
62
else
63
SaveList
(
new
XMLFileIO
<
SafetyDepositBox
>(
fileName
),
data
,
append
);
64
}
65
66
private
static
void
SaveList
(
CSVFileIO
writer
,
List
<
SafetyDepositBox
>
data
,
\
67
bool
append
)
68
{
69
List
<
string
>
lines
=
new
List
<
string
>();
70
foreach
(
SafetyDepositBox
item
in
data
)
71
{
72
string
lineOfText
=
item
.
BoxNumber
.
ToString
();
73
if
(
item
.
IsLeased
)
74
lineOfText
+=
","
+
item
.
AccountNumber
;
75
lines
.
Add
(
lineOfText
);
76
}
77
writer
.
WriteAllLines
(
lines
,
append
);
78
}
79
80
private
static
void
SaveList
(
XMLFileIO
<
SafetyDepositBox
>
writer
,
List
<
Safety
\
81
DepositBox
>
data
,
bool
append
)
82
{
83
writer
.
SaveAll
(
data
,
append
);
84
}
85
#endregion
86
}
Practice Exercises
- PersonFileAdapter – This reads a text file to fill an array of Person data.
- SongFileAdapter – This reads a text file to fill an array of Song data.
PersonFileAdapter
This reads a text file to fill an array of Person data.
- Record Structure:
- Record Structure:
- First Name : String
- Last Name : String
- Gender : GenderType
- Birthdate : Date
SongFileAdapter
This reads a text file to fill an array of Song data.
- Record Structure:
- Record Structure:
- Title : String
- Song Writer : String
- Length : RunningTime
Topic P - Exception Handling
Overview
The code for real-world programs is typically divided into distinct “layers” in order to make programs more flexible and maintainable. The layer that corresponds to the drivers we have seen so far is called the “Presentation Layer”. It’s called a “presentation layer” because its sole purpose is to interact with a user.
Almost all exception handling should take place in the driver, or presentation layer, of an application. Part of the reason for this is because the presentation layer is the “top” or “front-most” part of the program. When exceptions are handled at this layer, an application can report on the errors that occurred and give opportunity for the user to choose their desired response to the error.
LOGS
Code Samples
- DemoTestingForExceptions - This class is a very simple demonstration of how to catch exceptions and how exception handling allows a program to keep running even when a problem occurs.
- DemoBookFileAdapter - This class demonstrates displaying book information read from a file. It also demonstrates attempting to read from a file or directory that does not exist, and capturing an exception thrown by classes within the .Net Framework.
- (Not Available) MediaPlayer - This class demonstrates a complete working program that presents the user with a menu of various tasks related to loading and displaying songs on a CD. This class also demonstrates exception handling.
DemoTestingForExceptions
This class is a very simple demonstration of how to catch exceptions and how exception handling allows a program to keep running even when a problem occurs.
1
public
class
DemoTestingForExceptions
2
{
3
private
static
ConsoleColor
_Normal
=
Console
.
ForegroundColor
;
4
5
public
static
void
Start
()
6
{
7
string
[]
actualAuthors
=
{
"Dan Gilleland"
,
"B. N. D'erdundat"
,
"Dr. Ink\
8
" };
9
string
actualTitle
=
"Java: Bean There, Done That"
;
10
string
actualBarCode
=
"0-12345678-9"
;
11
12
// Demo a normal creation of a Book object
13
Console
.
WriteLine
(
"Testing valid data"
);
14
TestBook
(
actualTitle
,
actualAuthors
,
actualBarCode
);
15
16
// Demo testing the Book class for various combinations of data
17
Console
.
WriteLine
(
"Testing empty title"
);
18
TestBook
(
""
,
actualAuthors
,
actualBarCode
);
19
Console
.
WriteLine
(
"Testing null title"
);
20
TestBook
(
null
,
actualAuthors
,
actualBarCode
);
21
Console
.
WriteLine
(
"Testing empty author list"
);
22
TestBook
(
actualTitle
,
new
String
[
0
],
actualBarCode
);
23
Console
.
WriteLine
(
"Testing null author list"
);
24
TestBook
(
actualTitle
,
null
,
actualBarCode
);
25
Console
.
WriteLine
(
"Testing empty bar code"
);
26
TestBook
(
actualTitle
,
actualAuthors
,
""
);
27
Console
.
WriteLine
(
"Testing null bar code"
);
28
TestBook
(
actualTitle
,
actualAuthors
,
null
);
29
Console
.
WriteLine
(
"Testing all nulls"
);
30
TestBook
(
null
,
null
,
null
);
31
}
32
33
private
static
void
TestBook
(
string
title
,
string
[]
authors
,
string
barCode
)
34
{
35
try
36
{
37
Book
theBook
=
new
Book
(
title
,
authors
,
new
ISBN
(
barCode
));
38
Console
.
WriteLine
(
"I creatd the following book:"
);
39
Console
.
WriteLine
(
" Title: "
+
theBook
.
Title
);
40
Console
.
Write
(
" Authors: "
);
41
foreach
(
string
author
in
theBook
.
Authors
)
42
Console
.
Write
(
author
+
", "
);
43
Console
.
WriteLine
(
"("
+
theBook
.
Authors
.
Length
+
" authors)"
);
44
Console
.
WriteLine
(
" ISBN: "
+
theBook
.
Isbn
.
BarCode
);
45
Console
.
WriteLine
(
"-----------------------------------------"
);
46
Console
.
WriteLine
();
47
}
48
catch
(
Exception
ex
)
49
{
50
Console
.
ForegroundColor
=
ConsoleColor
.
Red
;
51
Console
.
WriteLine
(
"!-- "
+
ex
.
Message
+
" --!"
);
52
Console
.
ForegroundColor
=
_Normal
;
53
}
54
}
55
}
DemoBookFileAdapter
This class demonstrates displaying book information read from a file. It also demonstrates attempting to read from a file or directory that does not exist, and capturing an exception thrown by classes within the .Net Framework.
1
public
class
DemoBookFileAdapter
2
{
3
private
static
ConsoleColor
_Normal
=
Console
.
ForegroundColor
;
4
5
public
static
void
Start
()
6
{
7
try
8
{
9
Book
[]
myBooks
;
10
myBooks
=
BookFileAdapter
.
LoadList
(
"BookList.txt"
,
FileFormat
.
CSV
).
T
\
11
oArray
();
12
DisplayBooks
(
myBooks
);
13
14
myBooks
=
BookFileAdapter
.
LoadList
(
@"V:\ThisDriveNameDoesNotExist"
,
\
15
FileFormat
.
CSV
).
ToArray
();
16
myBooks
=
BookFileAdapter
.
LoadList
(
"ThisFileNameDoesNotExist"
,
FileF
\
17
ormat
.
CSV
).
ToArray
();
18
19
DisplayBooks
(
myBooks
);
20
}
21
catch
(
DirectoryNotFoundException
ex
)
22
{
23
Console
.
ForegroundColor
=
ConsoleColor
.
Red
;
24
Console
.
WriteLine
(
"!-- "
+
ex
.
Message
+
" --!"
);
25
Console
.
ForegroundColor
=
_Normal
;
26
}
27
catch
(
FileNotFoundException
ex
)
28
{
29
Console
.
ForegroundColor
=
ConsoleColor
.
Red
;
30
Console
.
WriteLine
(
"!-- "
+
ex
.
Message
+
" --!"
);
31
Console
.
ForegroundColor
=
_Normal
;
32
}
33
catch
(
Exception
ex
)
34
{
35
Console
.
ForegroundColor
=
ConsoleColor
.
Red
;
36
Console
.
WriteLine
(
"!-- "
+
ex
.
Message
+
" --!"
);
37
Console
.
ForegroundColor
=
_Normal
;
38
}
39
}
40
41
private
static
void
DisplayBooks
(
Book
[]
myBooks
)
42
{
43
for
(
int
index
=
0
;
index
<
myBooks
.
Length
;
index
++)
44
{
45
Console
.
WriteLine
(
"Title : "
+
myBooks
[
index
].
Title
);
46
Console
.
WriteLine
(
"ISBN : "
+
myBooks
[
index
].
Isbn
.
BarCode
);
47
Console
.
WriteLine
(
"Authors: "
);
48
foreach
(
string
author
in
myBooks
[
index
].
Authors
)
49
Console
.
WriteLine
(
"\t"
+
author
);
50
Console
.
WriteLine
();
51
}
52
}
53
}
MediaPlayer
This class demonstrates a complete working program that presents the user with a menu of various tasks related to loading and displaying songs on a CD. This class also demonstrates exception handling.
Practice Exercises
- Testing Suite - Using any two classes from previous topics, create a program that tests the construction of objects with complete exception handling.
- Working Program - With the help of the UserPrompt class, create a simple program involving any classes from previous topics. Be sure to include exception handling in your program.
Testing Suite
Using any two classes from previous topics, create a program that tests the construction of objects with complete exception handling.
Working Program
With the help of the UserPrompt class, create a simple program involving any classes from previous topics. Be sure to include exception handling in your program.
Appendix
Learning Outcome Guide Review
Learning Outcome Guides (LOGs) are an excellent tool for instructors in the classroom and for students when they are reviewing their notes for each class. A Learning Outcome Guide is simply a list of specific things that the student (or reader, in this case) should be able to do or understand as a result of learning the material. LOGs give the learner the ability to self-check their progress (“Can I do X?”).
This appendix provides a shortened review of what each learning outcome is all about. For instructors, it provides a quick summary of the intent of the LOG. For students, it provides the answers. :)
Topic A - Starting Classes
OOP Basics
- Define the term “class” as used in OOP
- A class is a template that acts as the basis for creating objects and describes a) What it “looks like”, and b) How it “works”.
- Explain the purpose of classes in computer programs
- Classes allow programmers to define their own complex data types, complete with their own internal data (fields) and behaviours (methods).
- Describe the primary keywords used in declaring a class
- public/private - identifies whether the class is visible to other code; public means all other code can see this class, while private means
- class - declares that this is a class definition (tells the compiler to interpret this as a new “classification” or “kind” of data type; that is, a complex )
- Define the term “method” and give an example
- A method is a set of instructions that manipulate information.
- Create simple classes with methods only
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Explain what is meant by “overloading”
- Overloading describes creating more than one method with the same method name (but different parameters) in the same class. Overloaded methods allow for alternate ways to perform the same general behaviour of an object or a class.
- Describe the syntax of a method declaration (aka, method implementation)
- …
- Explain how classes with identical names can be distinguished from each other
- Different classes can have identical names provided that they exist in different namespaces. (Namespaces help to prevent a “collision” or confusion on the part of a compiler when confronted with two or more classes with the same name.)
General Programming Concepts and Terms
- Define the term “keyword” as it applies to programming languages
- A keyword is a special command or instruction that is part of (that is, built in to, or “intrinsic” to) a programming language. Keywords are “reserved” words, meaning that they cannot be used for other purposes, such as being a name of a class, a variable, or a method.
- Define the term “identifier” as it applies to programming languages
- An identifier is a programmer-supplied name for some item, either a class name, a field or local variable, or a method.
- Define the term “program statement” and identify how the computer recognizes a program statement
- A program statement is combination of keywords, identifiers, punctuation, and/or literal values that, together, represent a single “instruction” or “command” that a compiler can translate into executable code.
- Define the term “syntax” as it applies to programming languages.
- Syntax refers to the rules of a programming language that define how to combine keywords, identifiers, literal values, and other symbols to create specific instructions for a computer program.
- Identify the entry point for every computer program
- Every computer program must supply a method called “main” as the method that the operating system will call (execute) to begin running the program.
- Perform simple output to the console using System.Console
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Identify the basic structure of a simple C# program
- A C# program must consist of at least one class and have a single “main” method as the program’s entry point. Typically, a C# program will consist of a “driver” (the class that has the main method) and other classes used to represent objects (data) in the program.
- Explain what is meant by a “driver”
- A “driver” is a method or set of methods that “run” or control the execution of a program; it’s responsibility is to direct and maintain the “lifetime” of a program, and makes use of classes and objects to achieve the purpose of the program. Every driver begins its execution in a method called “main” (which is the name given for the entry point for every computer program).
- Explain what is meant by a “case-sensitive” programming language
- A case-sensitive language is one where the compiler regards “identical” words as different if they differ only in their case. In other words, a case-sensitive language will regard two identifiers are distinct if the only difference is whether they are spelled with upper- or lower-case characters. For example, HelloWorld and Helloworld will be regarded as different because one has a capital “W” and the other has a lower-case “w”.
- Explain what is meant by a “strongly-typed” programming language
- A “strongly-typed” programming language is one that requires all variables or objects to always match or conform to whatever data type they were originally declared as. Some programming languages (such as C#Script) allow variables or objects to “change” their data type whenever a programmer wishes to use it for other purposes; strongly-typed languages do not allow variables to “change” the type of data they can store. Strongly-typed programming languages provide better security and make it more difficult for programmers to inadvertently corrupt, mangle or expose important data.
- Explain what “string concatenation” is and how it works
- String concatenation is where two or more strings are “combined” to create a longer string; this is represented in C# by “adding” strings together. For example, given two literal strings whose values are “One” and “word”, the result of “One” + “word” would be the string “Oneword”.
- Define and distinguish the terms “argument” and “parameter”
- A parameter is a variable declared in the parameter list of a method declaration; parameters are used to hold or capture information (values) that are sent or passed into the method. An argument is some value (either a literal value, a value stored in a variable, or some other value that comes from an “expression”) that is sent (passed) into a method; arguments appear in the syntax of method calls.
- Use single-line, multi-line and XML comments as a means of documenting code
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- List the four pieces of information to include in comments at the top of every source file
- The file name, author, creation date, and purpose of the file.
Intro to IDEs
- Define the term “IDE” as it relates to software development tools
- The acronym “IDE” stands for “Integrated Development Environment”. An IDE brings together separate, but complementary, software development tools that aide developers in creating computer programs. For example, most IDEs bring a sophisticated text editor together with file management tools, a compiler, a debugger, and a program execution environment, as well as other useful tools.
- Define the terms “project” and “solution”
- A solution is a folder in which one or more projects can be managed and “kept together”; it is the “area” in which a developer can create projects. A project is as set of classes designed to achieve a particular purpose; a project may represent a complete program in and of itself, or may be a single component of a larger, more complex computer program.
- Identify the various parts of the IDE (Integrated Development Environment) used in this course
- [– image here –]
- Create a new project in the IDE for this course
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Create new source files in the IDE for this course
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Add existing files to a project
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
Topic B - Starting Classes
OOP Basics
- Define the term “object” as used in OOP
- An object is an instance of a class.
- Each object has its own “state” (values) for its fields, and all objects based on any given class are distinct from each other. The internal values (state)for an object’s fields can be changed independently of other objects of the same class.
- Describe the syntax of static and non-static method declarations
- Static methods are “shared” by all instances (objects) of a class, and can be called without even having to have an instance of the method’s class.
- Non-static methods, on the other hand, can only be called for a given object (instance of a class) and will “act on” (or “act on behalf of”) that object (and any other objects are not affected by the given object’s method call).
- Compare and contrast the syntax for method declarations (implementations) vs. method calls (for both static and non-static methods)
- …
- Define the term “field” as used in OOP and give an example
- A field is a variable that belongs to a class and is shared by all the methods of a class.
private static int sharedCount; // a static field
private String name; // an instance field
- Compare and contrast instance and class members, for both methods and fields
- Static methods are shared by all instances of a class, and can be called independently from instances of a class, whereas instance methods can only be called if you have an object (an instance of a class).
- Static fields are shared by and fully accessible to all methods, but non-static fields, also called “instance” fields, are only shared by other non-static methods. In the following example, the first field is a static fields and the second is an instance field.
- Identify the “member access operator” and explain it’s purpose
- The member access operator (also called the “dot” operator) is the period. It is used to access a field or method of an object or a class.
- Create (instantiate) objects
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Distinguish between classes and objects in OOP
- A class is merely a “template” for creating objects and describes a) what the object will “look like” (that is, what fields or data it will contain) and b) how the object works (that is, what methods can be called and what those methods will do).
- Explain what is meant by the phrase “type extensibility” and how classes represent “complex” data types in OOP
- “Type extensibility” is where a programming language allows developers to create or design their own “data types”.
- All programming languages support the “simplistic” data types (for numeric information, such as whole and real numbers, as well as simple text or character representation). These simple data types are intrinsic (“build into”) the programming language. A language that supports “type extensions” simply allows the programmer to create or design new data types; these new types are typically “complex” types made up of zero or more other (either simple or complex) data types.
General Programming Concepts and Terms
- List the three categories of simple information
- Textual, numeric, and conceptual
- Define the term “intrinsic data type”
- An “intrinsic data type” is one that is built into the programming language.
- Explain what an assignment statement is and how it works
- An assignment statement is an instruction to the computer to store a value into a specific variable (or object). The variable (or object) is placed on the left-hand side of the equals sign, and the value to be stored in the object is placed on the right-hand side of the equals sign.
- The left-hand side of an assignment statement must be a single variable, whereas the right-hand side can be any expression as long as the resulting value of the expression is the same (or compatible) data type as the variable on the left-hand side.
- Compare and contrast the three categories of simple information with the complex types of information which classes represent
- Simple information is either textual (such as a name), numeric (such as a total or count), or “conceptual” (that is, representing a more “abstract” value that is neither textual or numeric). An example of a textual type in C# is the char type. An example of a numeric type in C# is the double type. An example of a “conceptual” type is the boolean type. A variable whose type is one of the simple types can only hold a single, simple value at any given time.
- Complex types of information can be constructed from many simple types or from simple and complex types. A “class” is used to describe or define what the complex type looks like and how it works. Complex types are the basis for creating objects, and while any given “object variable” can only reference a single object, that object may consist of many distinct “values”, each one being stored in a field that is “hidden” (or “encapsulated”) inside the object.
- Explain the advantages of using classes and objects instead of only using intrinsic data types
- By using objects, the programmer is no longer limited to having to only deal with simple values. By designing and using complex types (classes), the programmer is able to create complex programs using less code in a way that is simpler and more reliable than if the programmer were only allowed to use the simple types built into the programming language.
Topic C - Starting Classes
OOP Basics
- Define the term “encapsulation” as used in OOP
- Encapsulation is a design principle of “hiding” fields in a class by always making them private and only allowing a “controlled access” to the values in fields by providing getters and setters.
- Encapsulation also includes the idea that all of the items (methods and fields) in a class always have access to each other (inside the class) while also providing the ability to control the external access to those items (methods and fields) by other classes.
- Explain why encapsulation is a good design principle
- Encapsulation is a good design principle because every object must be responsible for its own data; if an object “exposes” its fields for direct access (that is, makes those fields public), then that object cannot exert any control over the values that may be stored in those fields.
- Encapsulation, as a part of Object Oriented design, also facilitates the aspect of “grouping together” related fields and methods.
- Define the term “access specifier” and identify where it occurs in the code for a class
- An access specifier is a keyword in a programming language that identifies whether an item, such as a field or a method, is or is not accessible from outside of an object.
- List the two access specifiers that are used in this course
- The two main access specifiers of this course are public and private.
- Describe the difference between “private” and “public” members of a class
- Private methods and fields are not accessible from outside the class (they are only internally accessible). Public methods and fields are accessible both from outside and from inside the class.
- Describe the concepts of “Properties” as used in OOP
- “Properties” allow for controlled access to read (get) or change (set) fields in a class. When fields are used with properties, the field is sometimes called a “backing store” because it stores the actual value that is accessed through the property.
- Properties do not have to have fields as “backing stores”; a property can calculate its value (during a get) instead of simply retrieving it from a field. These types of properties are sometimes called “derived” properties.
- A “getter” is a method whose sole responsibility is to provide a means for retrieving (getting) a value. Getters are typically (that is, almost always) public, thereby allowing information (typically stored in a field) to be “extracted” from outside the class.
- A “setter” is a method whose sole responsibility is to control the storing of a value into a field of a class. Setters are typically (that is, almost always) public, thereby allowing code that is outside the class a way to store information inside the class (that is, inside of the fields of a class).
- Define the term “backing store” as it applies to properties and fields
- A “backing store” is a field that stores information which is accessible only through a property; the field variable is used in the “background” by the property’s get and/or set.
- Describe and explain the purpose and function of a constructor for a class
- A constructor has one purpose: To ensure that all the fields of the class are filled with meaningful values at the moment that an object is created (instantiated).
- Describe the syntax of a class constructor
- TBA…
- Identify when a class constructor is “called”
- A class’ constructor is never explicitly “called” in the traditional sense of “invoking” (calling) a method on a class. Rather, the class constructor is “called” when an object is instantiated using the new keyword.
- Define the term “class scope” as used in OOP
- Class scope is the idea that all of the methods and fields of a class are accessible to all the methods in a class.
- Define the term “local scope” as used in OOP
- Local scope is the idea that all of the variables declared in a parameter list and inside of the body of a method are only accessible from within that method. In other words, parameters and “local variables” are only accessible from within the method (or block of code) in which they were declared.
- Define the term “state” as applied to objects used in OOP
- “State” is the idea that objects have an “internal value” at any given point in time (as viewed from outside the class’ methods). In other words, an object has “state” simply because it has fields which hold (or “store”) information.
- Objects are responsible for ensuring that their internal state is always valid (or “stable”) at the end of each method’s execution.
- Define the term “override” as used in OOP
- Override is a term used to indicate that a class is re-defining the behaviour of a method that it is inheriting from a base class.
- All classes inherit from a class called Object. The Object class defines common methods that every class must have, such as equals() and ToString(). Any class has the option to “override” or re-define how the equals() and ToString() methods work for that class.
- Explain the purpose and function of the ToString() method and why we sometimes want to change its default behaviour when we create classes
- The ToString() method is meant to provide a way to represent any given object as a String. This method is inherited from the Object class; the Object class, by default, returns the data type of the object, expressed as a String.
- A programmer may choose to override the default behaviour of the ToString() method in order to represent the internal state of the object (that is, the values stored in some select fields) as a String.
- Create simple class diagrams to represent classes
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
General Programming Concepts and Terms
- List three levels of scope
- Class scope - All the fields and methods of a class share a common class scope, and are accessible to any and all methods of a class.
- Local scope - All the variables and parameters of a method are accessible only to the body of the method; local variables and parameters are not accessible to other methods.
- Block scope - All the variables declared inside a block are only accessible to the code inside that block. A block of code is denoted by being enclosed by a set of curly braces - { }.
Topic D - Debugging and Testing
General Programming Concepts and Terms
- Explain the role of testing as it applies to software development
- Testing is a form of “quality assurance” in which steps are taken to verify that a program is behaving or working as intended.
- Testing has traditionally been treated as a “follow-up” activity that takes place after a program is written. Currently, other approaches, such as TDD (Test-Driven Development) place the “testing” activity at the start of the programming efforts, thereby integrating tests as a driving element in software development.
- Define and compare the terms “compile-time error” and “run-time error”
- A “compile-time error” is an error where a program does not “compile”. In other words, compile-time errors are due to code that does not follow the rules of the programming language.
- A “run-time error” is an error where a running program does not produce the desired result. In other words, run-time errors are due to logical errors in a computer program. Sometimes these errors are “fatal” (meaning that they result in “abnormal program termination” - the program “crashes”). Other times the errors are subtle; the subtle errors can be the most difficult to detect, particularly when relying on “manual” verification, such as found with ad-hoc test drivers.
- Define the term “test driver”
- A “test driver” is a driver (which is a program with a main method) whose sole purpose is to “test” the components of a program. Test drivers provide a simple “ad-hoc” form of testing. Test drivers are basically considered “throw-away” programs, as their usefulness does not extend beyond the tests.
- Create simple ad-hoc test drivers to test for run-time errors
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Define the term “TDD”
- TDD refers to “Test Driven Development”. Test Driven Development is an approach to programming that starts with creating “unit tests” that reflect the business and design requirements of a program, and then writing the classes and methods that will pass the unit tests. The idea here is to help drive the programmer toward code that “stays on focus” of the needs of and solutions for a given problem.
- Compare and contrast Test Drivers and Unit Tests
- Test Drivers are small programs with a main() that tests classes by creating objects, calling methods, and output results to the console.
- Unit Tests are small “units” (which are simply methods) that calls methods on objects and classes and “tests” if they work as intended by running “asserts”. Unit Tests display the results of the test in Red/Green/Yellow results, where Red ( ) represents run-time errors, Yellow ( ) represents ignored tests, and Green ( ) represents success.
- Define the terms “false positive” and “false negative”
- A “false positive” is a test result that shows success for a test which in reality should be a failure.
- A “false negative” is a test result that shows failure for a test which in reality should be a success.
- Both false positives and false negatives are a result of an error in the unit test (or test driver).
- List three downfalls of using Test Drivers
- Can grow in size and become bulky & difficult to use (poor scalability)
- Requires considerable effort to generate and distinguish tests
- Difficult to verify tests due to heavy manual intervention & verification
- Identify four benefits of using Unit Tests
- Provides simple tests to verify specific parts of a system
- Easy to verify tests (minimal manual effort); errors are clearly identified and described
A clear graphical response it provided, leading to the popular development mantra “Keep it Green” - Increases productivity (by focusing development efforts)
- Captures design requirements in code
- Increases programmer confidence when modifying and expanding code
- Easily isolate smaller parts (“units”) of the program for verification; these tests can run independently of each other (even if the other tests have compiler issues with the classes being tested).
- Add unit testing libraries and unit testing packages to existing programs
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Use unit tests to validate the requirements of a class’ design and behaviour
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Diagnose and correct software problems by using unit tests
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
## Topic E - Expressions and Math
OOP Basics
- Explain how method overloading is applied to constructors
- Using overloaded constructors means that it is possible to create objects in “different ways”. What this means is that when a class has an overloaded constructor, anytime we wish to instantiate (create) an object using the new keyword, we must be explicit about which constructor we are invoking (calling).
General Programming Concepts and Terms
- Name at least three kinds of program statements commonly seen in all high-level programming languages
- Declaration/initialization statements
- Assignment statements
- Flow-control statements
- Distinguish between Variables, Values and Data Types
- Variables act as “containers” for values, allowing programmers to access and manipulate the value via the variable.
- A Value is simply a piece of data. It may be simple (such as a number or some text), or it may be complex (that is, based on a class).
- Data Types are “blueprints” or “templates” that describe what values “look like” and how they “work”.
- When a variable is declared to be of a certain data type, this means that the variable is only allowed to hold values that match that data type.
- List the five basic rules governing variables, values and data types
- Any value stored in a variable must be of the same data type as the variable.
- Variables must be declared before they can be used.
- A variable’s data type can only be declared once.
- Each primitive variable can only hold one value at a given time.
- Each variable must have a distinct name.
- List the intrinsic (built-in) data types in C#
- Textual data types: char
- Numeric data types: int, long, short, byte, double, float
- Conceptual data types: bool
- Explain what is meant by the phrase “type extensibility”
- Modern languages are able to define brand new data types (classes), thereby increasing the ability to manage complex information and perform complex operations.
- Define the terms Reference Type and Value Type as they apply to data types in C#
- A “value type” is a data type whose information is stored “directly” in a variable. In memory, this means that there is only one direct location in memory where the data is stored. The only data types that are “value types” are those that are built into the language: char, int, byte, short, long, double, float, and bool.
For example, in the following statements,
double count;
count = 0;
the value of zero is stored directly at the memory location labelled count. - A “reference type” is a data type whose information is stored and accessible only “indirectly” through the variable. Whenever you declare a “reference type” variable, that variable actually stores a memory address of where the “actual” object is stored. The “actual” object is only created using the new keyword; that new keyword will set aside a separate, “new”, area of memory which is then accessed “indirectly” through the “reference type” variable.
For example, in the following statements,
Car hotrod;
hotrod = new Car();
the first line creates a single memory location, labelled hotrod, which will store the address to a Car object. The second line creates the actual Car object somewhere in memory and then the address to that object is stored in the hotrod variable.
All classes, whether those supplied in the C# library (such as the String and Date classes) or those created by you, are “reference types”. - Define the term Identifier
- An identifier is the term used to refer to some “named” item in your code. Typically, we apply the term identifier to variable names, field names, property names and method names.
- Create and initialize variables in C#
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Explain what is meant by the terms “scope” and “lifetime” as they apply to variables
- Scope refers to the “context” in which a variable is accessible. Fields are variables with “Class Scope”, meaning that they are accessible to all the methods from within the class; properties, methods and constructors also have class scope. Parameters and variables declared within a method have “local scope”, meaning that they can only be accessed by code from within the method that they are declared in.
- Lifetime refers to the period of time from when a variable is first declared to the time that they are “destroyed”. For fields, their lifetime exists as long as the object in which they are declared. For parameters and local variables, they exist only as long as there is still code to be executed in the method to which they belong; as soon as the method “returns” or exits, these local variables and parameters are destroyed.
- Describe what is meant by the term “expression”
- An expression is any combination of literal values (literal strings or numbers), variables, operators, or method calls which return a value. An expression can be as simple as a single variable or literal value, or it can be as complex as a long mathematical expression that involves calls to various methods.
- An important characteristic of expressions is to note that they are always reduced to a single value by the computer.
- Explain the difference between program statements and expressions as well as how the two relate to each other
- A program statement represents a complete instruction that the compiler can translate into machine language. An analogy can be made that a program statement is like a sentence: Just as a sentence communicates a complete thought or idea, so a program statement represents a complete instruction.
- An expression is not a complete instruction; rather it is a combination of values, variables, method calls, and operators that will eventually be reduced to a single “value” by the computer. Expressions are often a part of program statements, and their role in program statements is akin to the role of phrases in English sentences: A phrase is not, by itself, a complete thought or idea; it must exist in a context in order to have its complete meaning. In a similar way, expressions play a part in the grammar of various kinds of program statements, providing a way of generating values that will be used by the program statement.
- List the four general sets of operators in C#
- Assignment, Arithmetic, Relational, and Logical
- Describe the two basic rules of using arithmetic operators that every compiler must follow.
- For an arithmetic operator to work, both sides of the operator must be the same data type.
- The resulting value of an arithmetic operation is of the same data type as the operands involved in the operation.
- Use the arithmetic operators to create arithmetic expressions
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Explain what is meant by “integer division” and how that can be useful in solving particular problems regarding numbers.
- “Integer division” is the term for what occurs when both operands of a division operation are whole numbers (which can apply to byte, int, short, and long data types). Because the basic rule of arithmetic operations is that the data type of the final value of an operation is the same as that of the operands, any time we divide one whole number by another whole number, the result is a whole number: Any “fractional portion” is automatically discarded.
For example,1 / 3 -> 0
7 / 2 -> 3
- Explain the purpose of the modulus (%) operator.
- The modulus operator (%) is used to find the remainder of a division operation. This operator is typically used with integers.
- List and describe how to use the various assignment operators in C#
- All assignment operators require a variable on the left side and an expression on the right side. Assignment operators take the final value of the expression on the right and stores that value in the variable on the left.
- =
This is the standard assignment operator. It performs a simple assignment of the value on the right to the variable on the left. - +=
This assignment operator takes the value on the right and adds it to the value already existing in the variable on the left. For examplex += y;
is the same as writingx = x + y;
- -=
This assignment operator takes the value on the right and subtracts it from the value already existing in the variable on the left. For examplex -= y;
is the same as writingx = x - y;
- *=
This assignment operator takes the value on the right and multiplies it to the value already existing in the variable on the left. For examplex *= y;
is the same as writingx = x * y;
- /=
This assignment operator takes the value on the right and divides it into the value already existing in the variable on the left. For examplex /= y;
is the same as writingx = x / y;
- %/
This assignment operator takes the value on the right and divides it into the value already existing in the variable on the left to generate the remainder. For examplex %= y;
is the same as writingx = x % y;
- Explain the difference between binary and unary operators
- Binary operators require a variable or value on both sides of the operator.
- Unary operators only require a variable or value on one side of the operator for it to perform its operation.
- Demonstrate understanding of operator precedence and how to override the default precedence of the arithmetic operators
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Summarize and distinguish the rules for automatic type conversion involving arithmetic operators and the assignment operator
- Automatic type conversion takes place for the data types that are built in to the programming language.
- The basic rule of automatic type conversion involving arithmetic operators is that if two operands of a binary operator are of different data types, then the value of the one that is “smaller” is “upsized” to the data type of the “larger” operand.
- For the assignment operators, automatic type conversion is limited to only allowing the right-hand value to be converted to the data type of the variable on the left-hand side. Type conversion cannot convert a value from the right hand side if that value’s data type is larger than the data type of the left hand side; if the right hand side is a larger data type than the left hand side, then a compiler error is generated that states the value cannot “fit” into the variable on the left.
- Determine the final data type for expressions involving mixed data types and type conversion
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Describe “type casting” and explain how to use it appropriately.
- Type casting is where we explicitly tell the compiler to “re-interpret” a particular value as a different data type than what the compiler is currently treating it as.
- Type casting is appropriate when we want to avoid integer division in order to retain the fractional portion in the final result. For example, if the variables numerator and denominator are both integers, it is appropriate to use type casting in the following line of code:
double value = (double) (numerator) / denominator;
- It is also appropriate when we need to “downcast” a value from a larger data type to a smaller data type (and can do so safely).
- Note that type casting does not (and can not) change the data type of a variable; type casting is only a re-interpretation of a value.
- Note that type casting is not the same as converting. For example, any attempt to type cast the char value of the character ‘4’ to an int will not produce a numeric value of 4; rather, it will produce the numeric value of 52 (which is the underlying decimal value for the character ‘4’).
- Compare and contrast the prefix and postfix behaviour of the unary arithmetic operators
- …
- Identify and explain how to use the common Math library routines (for Power, Square Root, Absolute, random numbers, pi, trigonometry, and the various types of rounding)
- …
- Use Math rounding methods with arithmetic expressions to round real numbers to a specific precision
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Create random whole number values within a specific range
- …
- Use type casting appropriately in C#
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Create constants in C#
- Constants in C# are created using the keyword final and assigning the value to the constant at the time that it is declared. For example, to create a constant value for GST, you could code the following:
const double GST = 0.05; // 5% GST
- Explain how arithmetic operations affect character values in C#
- Because the char data type is regarded as one of the “integral” data types, along with int, short and long, any arithmetic operations on char values will manipulate the underlying value as if it were simply a whole number.
(Note: “Integral” data types are data types without a fractional component.) - List the most common math functions of the Math class
- …
- Demonstrate how to use the various Math functions in simple programs
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- List and describe some of the commonly used fields and methods of the String class
- .ToUpper() - returns a String that has all the characters converted to their upper-case equivalents.
- .ToLower() - returns a String that has all the characters converted to their lower-case equivalents.
- .Trim() - returns a String that has all leading and trailing whitespace removed from the original String.
- .Chars(int index) - returns the character at the index position for the string. (All strings have the first character as index position zero.)
- .Substring(int beginIndex) and .Substring(int beginIndex, int endIndex) - returns a string that is the text inside of the first string beginning at a specified index. (All strings have the first character as index position zero.)
- .Length - returns the total number of characters in the string.
- Demonstrate how to use “String Arithmetic” (concatenation)
- To concatenate two or more strings, use the plus (+) operator.
- To append one string onto another, simply add the string to be appended to the end of the original string. For example, to append “ing” to the word “end” in order to produce “ending”, you could do the following:
String myWord = "end";
myWord = myWord + "ing"
- To pre-pend one string on another, add the string to be prepended to the start of the original string. For example, to prepend “un” to the word “imaginative” so as to produce “unimaginative”, you would do the following:
String myWord = "imaginative";
myWord = "un" + myWord;
- List the equivalent “wrapper” classes for each of the primitive types.
-
Integer
forint
-
Character
forchar
-
Double
fordouble
-
Byte
forbyte
-
Long
forlong
-
Short
forshort
-
Float
forfloat
## Topic F - If-Else Structures
General Programming Concepts and Terms
- Describe and draw a diagram of the If-Then-Else logical structure
- …
- Identify the programming statement that corresponds to the If-Then-Else logical structure.
- The if-else statement is used for If-Then-Else logical structures in C#.
- Translate If-Then-Else structures into code.
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Describe what is meant by a “conditional expression”
- A conditional expression is any expression which results in a Boolean (true/false) value.
- List the operator precedence for mixing logical, arithmetic, and relational operations
- Logical Not (!), Arithmetic, Relational, Logical And/Or
- List the relational operators
-
, >=, ==, <=, <
- Greater Than (>)
- Greater Than or Equal To (>=)
- Is Equal To (==)
- Less Than or Equal To (<=)
- Less Than (<)
- List the logical operators
-
&&, , ! - And (&&)
-
Or ( ) - Not (!)
- Use relational, logical, and arithmetic operators to construct conditional expressions
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Demonstrate an understanding of operator precedence in conditional expressions
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Use statement blocks to allow nesting program statements into control structures
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Define the term “boundary condition” as it relates to if-else statements and testing
- A “boundary condition” is also known as a “fence-post condition”.
- The “boundary” is the border of a range of values that are regarded as “acceptable” for some variable. For example, if a particular variable named percent is to represent a range of values from zero through 100 inclusive, then the “boundary” values are zero and 100.
A boundary condition, then, is a test or comparison that is made against some boundary values. For example,
1
if
(
percent
>=
0
&&
percent
<=
100
)
2
{
3
// code to perform if true
4
}
5
else
6
{
7
// code to perform if false
8
}
- Identify the correct way to compare or check the contents of strings in conditional expressions
- The proper way to compare String values is to use the .Equals(), .CompareTo() and .IsNullOrEmpty() methods.
- Generally, the relational operators (==, <, etc) should not be used directly on string values.
- List and describe the commonly used fields and methods of the String class that would be used in if-else statements
- .Equals(String) - returns a Boolean, true or false, as to whether the two strings are or are not equal.
- .Equals(String, StringComparison) - returns a Boolean, true or false, as to whether the two strings are or are not equal, according to the value of the StringComparison argument (which includes values to ignore any differences in upper and lower case).
- .CompareTo(String anotherString) - compares two strings “lexographically” (that is, alphabetically) and returns either
a. a zero if they are the same, or
b. a negative number if anotherString is greater than the first string, or
c. a positive number if anotherString is less than the first string - .IsNullOrEmpty(string) - returns true if the string is an empty string (“”), false if it is not an empty string.
- .IsNullOrWhiteSpace(string) - (only in .NET 4.0 and higher) returns true if the string is null, an empty string (“”), or all “whitespace” (tab, newline) characters; false if it is not.
- .Length - returns the total number of characters in the string.
Topic G - Raising Exceptions
General Programming Concepts and Terms
- Describe how object-oriented programs run.
- A computer program is a set of instructions for manipulating information.
- Every computer program has a single starting (or entry) point called the Main method. The main method is responsible to “run” (or “execute) the program, and when the main method exits, the program closes and stops “running”. The length of time that a program is running is called its “lifetime”. As a program runs, it executes instructions in the program’s code, one at a time; this is called the “flow of execution”.
- During the lifetime of a program, the main method creates objects and calls methods on those objects. Each method is basically a set of instructions to be executed. Those methods can, in turn, create other objects and call other methods.
- Whenever a method is called, the operating system keeps track of which method is calling another method through something known as a “call stack”.
- Describe what is meant by a “call stack”.
- A call stack is a mechanism to track which method is calling another method while the program is running. Call stacks allow the computer to know where to “return to” when a method exits.
- At any given point during the program’s execution, the method that is currently executing is referred to as the “called method”. When the called method exits, it returns control back to the “calling method”, thereby allowing the calling method to continue its own execution.
- Whenever a method calls another method, the “calling method” pauses and waits for the “called method” to finish; once the called method returns, the calling method will resume executing its own code.
- Define the term “Exception”
- An exception is a message of some run-time error that has occurred in a program. Exceptions interrupt the normal flow of execution in methods, forcing the method to immediately exit. Methods generate exceptions by using the “throw” statement. Any method may generate an exception (including constructors).
- The throw statement exits the method by sending back an object (called an “Exception Object”, or simply an “Exception”) that can be used to identify the kind of error that has occurred. The calling method then has the opportunity to deal with (or “handle”) the error; if the calling method does not handle the error, then the exception continues to go back through the call stack until it finds a method that will handle the exception.
- If none of the methods on the call stack handle the exception that was thrown, control is eventually returned to the main method. If the main method does not handle the exception, then the exception is sent to the operating system. At that point, the operating system shuts down the program in what is called an “abnormal program termination”.
- Describe what is meant by the phrase “raising (or throwing) an exception”
- To “raise an exception” (or “throw an exception”) is to force a method to exit prematurely by sending back an “Exception object”.
- Describe the role that exceptions play in a computer program
- An exception is an interruption in the normal flow of execution in a method; exceptions force the method to immediately exit.
- Exceptions provide a way for methods (including constructors) to report errors to whatever code that is calling the method. These errors are usually (but not always) due to invalid information passed into the methods via the parameters. Through the use of exceptions, methods can perform validation on their parameters and report any errors that might prevent the method from being able to perform its task.
- Identify the three most commonly used Exception types used in this course.
- .NET Framework
ArgumentException - Typically thrown whenever an argument passed to a parameter does not have an “acceptable” value.
For example, if a method has a parameter called “percent”, it might perform validation to ensure that the value is not less than zero or greater than 100. If the value is not valid, it may be appropriate to throw an ArgumentException.
ArgumentNullException - Typically thrown whenever an object is checked for and found to be “null”.
(ArgumentNullException will be discussed in the topic on Enumerations and Composition.)
*Exception** - This represents a general exception, and can be used whenever there is no other suitable exception type.
OOP Basics
- Explain why methods (including constructors) should perform validation of their parameter values
- One of the principles of object-oriented design is that objects must be responsible for ensuring that their fields have correct values. This is known as ensuring a “valid state” for an object.
- Typically, the values that are stored in fields come in through the parameters of a constructor or a method. Because objects are responsible for ensuring a valid state, the class’ methods must check all parameters that might allow “invalid” data to be passed in.
- Explain the significance of raising an exception in the constructor
- If an exception is thrown from a constructor (or passes through it on its way up the call stack), the object’s construction is interrupted. Because the construction of that object is interrupted, the object does not get instantiated.
- Use exceptions as part of the validation of parameter values in methods and constructors.
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Explain why property setters are a good place for throwing exceptions.
- Generally speaking, the only method that should directly modify a field is the property setter associated with the field. Because of this principle, the property setter is the ideal place to perform validation and to throw exceptions. When validation takes place here, it eliminates the need for duplicating the validation elsewhere in the class.
- Validating input and throwing exceptions from within setters is a good way to follow the DRY principle: “Don’t Repeat Yourself”.
- Identify when constructors should throw exceptions directly.
- Whenever a field has a property setter that performs validation, the constructor should use that setter to store information in the field. If no property setter is available to process the parameter values sent through the constructor, then the constructor should perform its own validation on those parameters.
Topic H - Case Structures
General Programming Concepts and Terms
- Describe the syntax of the switch statement
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
- Discuss the limitations of the switch statement in C# and the available alternatives for the times that we can’t use a switch statement
- Switch statements only work with integral data types (such as char and int).
- The individual case values must be constants; variable expressions are not allowed for the matching cases.
- Switch statements only check for exact matches (meaning that there is an implied “is-equal-to” comparison); other relational comparisons, such as greater than or less than, are not allowed.
- When it is not possible to use switch statements, case structures can be written up as nested and/or stacked if-else structures to make use of the if-else statement.
Topic I Enumerations and Composition
General Programming Concepts and Terms
- Define the term Enumeration
- An enumeration is a simple program-defined data type with a limited set of possible values. Enumerations represent information that is “conceptual” in nature (as opposed to information that is textual, numeric, or complex).
For example, a coin has two sides that are commonly referred to as HEADS and TAILS. Rather than creating two constant strings with the values “Heads” and “Tails” and a String variable called FaceShowing, you can use an enumeration. - There are two parts to enumerations:
a. The name of the enumeration, which is the name of the new data type; this is sometimes referred to as the “enumerated data type”.
b. A set of enumerated values, which represent all of the possible values for a variable of that enumerated type. These values act like “constants” that can be used to distinguish different “states” for the conceptual data. - List the benefits of using enumerations
- Type Safety - Enumerations allow a program to be “type safe”, meaning that there is less likelihood of creating logical errors or other mistakes through the use of constants or literal values.
- Code Readability - Enumerations make code more readable than constants or literal values (like integers).
- Compatibility with Switch Statements - Enumerations are compatible with switch statements, making them a great option for describing distinct values for matching against different cases. Because enumerations are like constants, and are treated as integral data types by the compiler, they are often the best choice when working with case structures.
-
Useful as Flags - Because the programmer can associate specific integer values to the enumerated values, it is possible to use an enumerated data type to create complex “flags” for representing distinct “states” that can be combined together.
For example, if you had an enumerated type such as the following, you could combine two states together in a variable’s value to represent distinct but compatible states, such asACTIVE
andMEDIUM_PRIORITY
.
1
enum
Status
2
{
3
INACTIVE
=
0
4
ACTIVE
=
1
5
LOW_PRIORITY
=
2
6
MEDIUM_PRIORITY
=
4
7
HIGH_PRIORITY
=
8
8
}
- Describe where and when enumerations are used
- Enumerations are used wherever a clearly defined set of values can be “classified” and used to represent conceptual information.
- Enumerations should be used whenever you might be inclined to use a set of two or more constants to represent distinct “states” or values for comparing against a variable.
For example, if you want to represent the two sides of a coin, it is better to use an enumeration for the coin’s HEADS and TAILS sides, rather than declaring some String or integer constants. The problem with using strings or simple integers to represent possible coin faces is that any variable that is defined as a string or integer can have values that won’t match either of the declared constants, as in this example:
1
const
string
Heads
=
"Heads"
;
2
const
string
Tails
=
"Tails"
;
3
// There is nothing preventing "invalid" values for the following coin face...
4
string
theFaceShowingOnTheCoin
=
"Sailboat"
;
An enumerated type called
CoinFace
with the valuesHEADS
andTAILS
is better, because any variable declared of typeCoinFace
can only have the values defined in the enumeration.```csharp
// The only other possible value that could be assigned is
// CoinFace.TAILS
CoinFace theFaceShowingOnTheCoin = CoinFace.HEADS;
`` - Compare and contrast enumerations and classes
- Enumerations and classes both define new data types that can be used by our program to represent custom data. However, while classes are useful in describing complex data types (that is, data types with assorted fields and that can perform various tasks), enumerations are only used to create new data types that are simple in nature. Enumerations only define a set of possible values, and each variable defined by an enumeration can only hold one of those possible values at any given time; there is no inner complexity to enumerations, as there is with classes.
- Use enumerations to define simple data types that are conceptual in nature and that have a limited set of possible “values”
- Demonstrate your ability to meet this learning outcome guide by completing the related assignments.
OOP Basics
- Describe the idea of Composition
- Composition refers to the situation where one or more of the fields in a class are objects. All classes are capable of having objects as fields, rather than just using the simple primitive types that come with the language.
For example, if a class called Address represents some mailing address, another class, such as Student, Company, School, or Business, could have a field whose data type is Address. - List the benefits of Composition
- Composition is an aspect of modern programming languages that makes it possible to create new data types (classes) of ever increasing complexity.
- Composition also makes it possible to get better code re-use, because classes can be more distinct, rather than overlapping. For example, both Students and Employees can have Addresses, so it is not necessary to code individual fields in the Student and Employee class for each part of an address; rather, a common type (called Address) can be shared by both classes.
1
public
class
Employee
{
2
// ... other fields, followed by these Address fields:
3
public
string
street
{
get
;
set
;
}
4
public
string
city
{
get
;
set
;
}
5
public
string
province
{
get
;
set
;
}
6
// ... etc.
7
}
8
9
public
class
Student
{
10
// ... other fields, followed by these Address fields:
11
public
string
street
{
get
;
set
;
}
12
public
string
city
{
get
;
set
;
}
13
public
string
province
{
get
;
set
;
}
14
// ... etc.
15
}
These could be coded like this:
1
public
class
Employee
{
2
// ... other fields, followed by these Address fields:
3
public
Address
mailingAddress
{
get
;
set
;
}
4
}
5
6
class
Student
{
7
// ... other fields, followed by these Address fields:
8
public
Address
homeAddress
{
get
;
set
;
}
9
}
: advanced benefit - Composition promotes the “Has-A” approach to designing objects rather than the “Is-A” design approach that makes use of inheritance. This “Has-A” approach gives programmers more flexibility in their coding and promotes the use of Design Patterns.
Topic J - Looping Structures
General Programming Concepts and Terms
- Identify the C# statements that correspond to Do-While and Do-Until logical structures
- TBA
- Translate Do-While structures into code
- TBA
- Translate Do-Until structures into code
- TBA
- Identify and distinguish the parts of the for statement in code
- TBA
- Describe the common situations in which the for statement is used
- TBA
- Demonstrate how the various looping statements can be interchanged with slight alterations of the logical structures to maintain the overall logic of a given routine.
- TBA
Topic K - Looping and Collections
OOP Basics
- Define the term Generics as used in C# and give an example
- TBA
General Programming Concepts and Terms
- Describe what is meant by a “collection” class and give an example
- TBA
- List and describe the common methods of collection classes such as the List<T>
- TBA
- Identify the parts of the foreach statement
- TBA
- Describe the common situations in which the foreach statement is typically used
- TBA
- Identify the major benefit of using Generics
- Type Safety –
- List the major benefits of using collections instead of arrays
- Collections such as List<T> can grow in capacity whenever items are added
- Collections such as List<T> do not need special management of the boundaries (such as the index of the upper limit of an array)
- Collections provide simple methods for quick adding and removing of “elements”
Topic L - Arrays - Not Sorted
General Programming Concepts and Terms
- Describe what makes an array different from other collections in C#
- The programmer is responsible to manage the boundaries of the array when manipulating the array’s contents.
- Arrays do not automatically “re-size” when “adding” or “removing” elements; the size of the array is fixed at the time the array is created.
- Describe the situations in which arrays are preferable over the use of collections
- Arrays are preferred whenever multi-dimensional data is required (such as 2D, 3D, or n-dimensional data is needed)
- Arrays are sometimes preferred whenever the size (number of elements) is unlikely to change and/or whenever the array is based on a primitive data type or an enumeration.
Notes
Thinking In OOP
What is a Computer Program
1The rule that “once a variable’s data type has been declared, its data type cannot be changed” is true for those programming languages which are described as type-safe, such as C#, Java and VB.Net. Other modern languages, such as JavaScript, do not have this rule.↩