0% found this document useful (0 votes)
18 views

CSE 210 Programming With Classes

The document outlines the curriculum for CSE 210, focusing on programming with classes and version control using Git. It covers essential topics such as file organization, C# programming fundamentals, abstraction, encapsulation, inheritance, and polymorphism. Each chapter includes learning activities, design projects, and practical coding exercises to reinforce the concepts taught.

Uploaded by

Carlos Medina
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

CSE 210 Programming With Classes

The document outlines the curriculum for CSE 210, focusing on programming with classes and version control using Git. It covers essential topics such as file organization, C# programming fundamentals, abstraction, encapsulation, inheritance, and polymorphism. Each chapter includes learning activities, design projects, and practical coding exercises to reinforce the concepts taught.

Uploaded by

Carlos Medina
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 141

CSE 210

Programming
with classes

Contents
Chapter 1 Introduction.........................................................................7
1.1 Version control.............................................................................7
1.1.1 What is version control?........................................................7
1.1.2 Files and folders....................................................................8
1.1.3 The file system......................................................................9
1.1.3.1 Moving around in the file system..................................10
1.1.3.2 Accessing files and folder.............................................11
1.1.4 Using git..............................................................................12
1.1.5 Create a new repository......................................................12
1.1.6 Clone the repository............................................................13
1.1.7 Making changes..................................................................13
1.1.7.1 Adding files...................................................................14
1.1.7.2 Commiting files.............................................................14
1.1.7.3 Pushing your changes to GitHub...................................15
1.1.7.4 Checking the status of your repo..................................15
1.1.8 A typical workflow...............................................................16
1.1.9 Assignment instructions......................................................16
1.2 Prove: Articulate – Version control.............................................16
1.3 Prove: Developer – C# Programming........................................17
1.3.1 C# Prep 1 – Variables, Input, and Output............................17
1.3.1.1 C# Language Fundamentals.........................................17
1.3.2 C# Prep 2 – Conditionals.....................................................22
1.3.2.1 Conditionals..................................................................23
1.3.2.1.1 If statements...........................................................23
1.3.2.1.2 Else and else if........................................................23
1.3.2.1.3 Operators................................................................24
1.3.2.1.4 And, Or, and Not Operators....................................25
1.3.2.2 Variables and types.......................................................25
1.3.2.2.1 Converting types....................................................25
1.3.2.3 Numbers to strings........................................................26
1.3.2.4 Assignment Instructions................................................26
1.3.3 C# Prep 3 – Loops...............................................................28
1.3.3.1 Loops.............................................................................28
1.3.3.1.1 While loops.............................................................28
1.3.3.1.2 Do-While loops........................................................28
1.3.3.1.3 For loops.................................................................29
1.3.3.1.4 Foreach loops..........................................................29
1.3.3.2 Random numbers..........................................................30
1.3.3.3 Assigment instructions..................................................30
1.3.4 C# Prep 4 – Lists.................................................................32
1.3.4.1 Collections....................................................................32
1.3.4.1.1 Lists........................................................................32
1.3.4.2 Adding items to the list.................................................33
1.3.4.2.1 Getting the list size.................................................34
1.3.4.2.2 Iterating through a list............................................34
1.3.4.3 Other Operations..........................................................35
1.3.4.4 Assingment instructions................................................35
1.3.5 C# Prep 5 – Functions.........................................................37
1.3.5.1 Functions vs Methods....................................................39
1.3.5.2 Variable Scope..............................................................39
1.3.5.3 Other Operations..........................................................40
Chapter 2 Abstractions.......................................................................41
2.1 Learning activity........................................................................41
2.1.1 What is Abstraction?...........................................................41
2.1.2 Objects and classes.............................................................42
2.1.2.1 Classes and files...........................................................44
2.1.3 Classes and instances.........................................................45
2.1.4 Custom data types..............................................................46
2.1.4.1 Adding behavior............................................................49
2.1.4.2 Objects within objects...................................................51
2.1.4.3 Lists of custom types....................................................52
2.1.5 Summary.............................................................................53
2.1.6 Activity instructions.............................................................54
2.1.6.1 Step 1: Design the classes............................................54
2.1.6.2 Step 2 Start the project.................................................55
2.1.6.3 Step 3: Create the job class..........................................55
2.1.6.4 Step 4: Test your Job class............................................56
2.1.6.5 Step 5: Add a display method to the job class..............56
2.1.6.6 Step 6: Create the Resume Class..................................56
2.1.6.7 Step 7: Test your resume Class.....................................57
2.1.6.8 Step 8: Add a display method to the resume class.......57
2.1.7 Reading text files in C#.......................................................58
2.1.8 Writing text files in C#........................................................59
2.1.9 Working with dates in C#....................................................59
2.2 Team activity: Designer.............................................................60
2.2.1 Journal Program...................................................................60
2.2.2 Review the program specification.......................................63
2.2.3 Determine the classes.........................................................64
2.2.4 Define class behaviors........................................................65
2.2.5 Define class attributes........................................................66
2.2.6 Review the design...............................................................67
2.2.7 Start the code.....................................................................68
2.3 Articulate activity......................................................................68
Chapter 3 Encapsulation....................................................................70
3.1 Encapsulation............................................................................70
3.1.1 Prepare................................................................................70
3.1.2 Why Encapsulation Matters.................................................71
3.1.3 Video example....................................................................72
3.1.4 Using access modifiers........................................................72
3.1.4.1 Attributes......................................................................73
3.1.4.2 Methods........................................................................73
3.1.4.3 Example........................................................................73
3.1.5 Getters and setters.............................................................74
3.1.6 On Getters and setters........................................................75
3.1.7 Constructors........................................................................76
3.1.8 Summary.............................................................................79
3.1.9 Activity instructions.............................................................79
3.1.9.1 Design the Classes........................................................79
3.1.9.2 Start the project............................................................80
3.1.9.3 Create the fraction class...............................................80
3.1.9.4 Create the constructors................................................80
3.1.9.5 Create the getters and setters......................................81
3.1.9.6 Create methods to return the representations..............81
3.1.10 Sample Solution................................................................82
3.2 Team activity: Designer.............................................................82
3.2.1 Discussing preparation learning activity.............................82
3.2.2 Review the Program Specification.......................................82
3.2.3 Determine the classes.........................................................83
3.2.4 Define class behaviors........................................................83
3.2.5 Define class attributes........................................................84
3.2.6 Define Constructors............................................................85
3.2.7 Review the Design...............................................................87
3.2.8 Conclude.............................................................................88
3.3 Scripture Memorizer..................................................................88
Chapter 4 Reinforcing abstraction and encapsulaption......................92
4.1 Learning activity........................................................................92
4.2 Activity designer........................................................................96
4.3 Participation report....................................................................96
4.4 Foundation program #1 Abstraction.........................................96
4.5 Foundation program #2 Encapsulation.....................................99
Chapter 5 Inheritance.......................................................................102
5.1 Learning..................................................................................102
5.1.1 Super and Base.................................................................104
5.1.2 Accessing private data......................................................105
5.1.3 Substitution and Is-A Relationships...................................106
5.1.4 Video demonstrations.......................................................107
5.1.5 A word of caution..............................................................107
5.1.6 In summary.......................................................................107
5.1.7 Activity instructions...........................................................108
5.2 Design activity.........................................................................111
5.3 Prove: Developer – Mindfullness..............................................118
5.3.1 Problem Overview.............................................................118
5.3.2 Solution idea.....................................................................118
5.3.3 Specification......................................................................119
5.3.4 Functional requirements....................................................119
5.3.5 Design requirements.........................................................122
5.3.6 Simplifications...................................................................123
5.3.7 Showing creativity and exceeding requirements..............123
5.3.8 Video demo.......................................................................123
5.3.9 Code helps........................................................................124
5.3.10 Design.............................................................................125
5.3.11 Develop the program......................................................126
5.3.12 Submission......................................................................126
Chapter 6 Polymorphism..................................................................127
6.1 Learning activity......................................................................127
6.1.1 A powerful combination....................................................128
6.1.2 Polymorphism in action.....................................................129
6.1.3 Abstract methods..............................................................131
6.1.4 It is all about the interface................................................132
6.1.5 Video example..................................................................133
6.1.6 In Summary.......................................................................134
6.2 Learning Activity instructions..................................................134
Chapter 1 Introduction
1.1Version control
1.1.1What is version control?
 Read: About Git

A version control system, or VCS, tracks the history of changes as


people and teams collaborate on projects together. As developers
make changes to the project, any earlier version of the project can be
recovered at any time.

Developers can review project history to find out:

 Which changes were made?

 Who made the changes?

 When were the changes made?

 Why were changes needed?


VCSs give each contributor a unified and consistent view of a project,
surfacing work that's already in progress. Seeing a transparent history
of changes, who made them, and how they contribute to the
development of a project helps team members stay aligned while
working independently.

In a distributed version control system, every developer has a full


copy of the project and project history. Unlike once popular
centralized version control systems, DVCSs don't need a constant
connection to a central repository. Git is the most popular distributed
version control system. Git is commonly used for both open source
and commercial software development, with significant benefits for
individuals, teams and businesses.

 Git lets developers see the entire timeline of their changes,


decisions, and progression of any project in one place. From the
moment they access the history of a project, the developer has
all the context they need to understand it and start
contributing.

 Developers work in every time zone. With a DVCS like Git,


collaboration can happen any time while maintaining source
code integrity. Using branches, developers can safely propose
changes to production code.

 Businesses using Git can break down communication barriers


between teams and keep them focused on doing their best
work. Plus, Git makes it possible to align experts across a
business to collaborate on major projects.

1.1.2 Files and folders


Before you can do very much Git, it is important to make sure you are
comfortable with Files and Folders on your computer.

As you start to create larger programs, it is no longer feasible to keep


all of your code in one single file. When you separate your code into
different files, you should put all of the code that relates to a certain
concept or idea together. This is another application of the principle
of abstraction that is a fundamental concept of this course.

In addition to the cognitive benefits of not keeping thousands of lines


of code in your brain and scrolling around in extremely long files,
separating your code into multiple files is also very helpful when
multiple people are developing the program together. When different
people are working on separate parts of the program, they won't be
be editing the same files as much, which makes merging the changes
in a version control system even easier.

By the end of this course, you will be writing programs that use a
fairly large number of files. This can seem overwhelming at first, but
as you'll learn, each one of those files will be small and narrowly
focused to one idea, so it makes working with a large system much
easier.

To prepare for this, you first need to be familiar with file and folder
organization on your computer generally, then, you'll need to learn
the conventions of how Python programs are distributed into multiple
files.

1.1.3 The file system


All of the data stored on your computer is stored in a file system. This
is a hierarchical structure of folders and files.

A folder can contain multiple files and also can contain other folders.
The following image shows an organization where the root, or top-
most level is a "home" folder, that contains other folders such as
"brigham" and "mary", each of which could contain other folders or
files.

Folder example

You can browse the files and folders on your computer using a
graphical file browser, and you can also navigate using a command
line terminal. You can use a terminal directly from your operating
system, or there is also a terminal window available in editors like VS
Code where you can enter commands.
The specific commands can differ between operating systems, but
they generally follow the same principles. If you are using the
command line terminal "Git Bash" on Windows, it will let you use
Linux style commands (used by MacOS as well), so those are what will
generally be shown in the course materials.

Heads up! Folders or Directories?

Is it called a folder or directory? Both—You'll find that people use


these terms interchangeably.

The term "directory" was more common in the command line terminal
world, but as people moved into graphical file system browsers, they
started to use the term "folder." As a programmer, you'll see both
terms and should be comfortable with them.

1.1.3.1Moving around in the file system


One principle that is important to understand is that when you are
using a command line terminal, you will be currently "in" a particular
directory or folder. This is called the current working directory. You
learn see the current directory by typing the command pwd (print
working directory).

You can change directories by using the cd command followed by the


name of the directory to change to. For example, cd pictures moves
into a folder beneath or in the current folder named, "pictures". A
single period . refers to the current directory, and two periods .. refers
to the parent directory. Thus, typing cd .. will change to the parent
folder of the one you were in.

Folder example showing cd


1.1.3.2 Accessing files and folder
There are two ways to refer to a location in the file system, an
absolute, or full path to the location, or a relative path that describes
the location in relation to your current location.

For example, a file might have an absolute path


of /home/brigham/pictures/family.jpg and you could always use
that full path to refer to it, but if you were already in
the /home/brigham directory, you could refer to it
as pictures/family.jpg (or an equivalent way that uses the the single
period, current directory notation: ./pictures/family.jpg ). If you
were in the directory /home/brigham/documents and wanted to
use a relative path to find that file, you could use the parent directory
notation ../pictures/family.jpg to first "go up" a directory and then
go to the proper location.

Full and relative paths

Is it a forward slash or backslash?

The difference of forward slash / and backslash \ is another awkward


difference of operating systems that stems from their history.

Linux/Unix based systems (including MacOS) use forward slash / in


their paths, and do not begin full absolute paths with a drive letter
(for example, they use /home/brigham ).

Windows based systems tend to use a backslash \ and start with a


drive letter (for example, they use C:\Users\Brigham ). Sometimes
Windows systems are tolerant of using the forward slash, but MacOS
and Linux very rarely allow backslashes.
1.1.4 Using git
The following will describe how to use Git at the level you will need
from this course. This only scratches the surface of what Git can do.
You will get more practice with Git in future courses where you will
collaborate with team members and make use of Branching and
Merging. In the course, we will focus only on adding, committing, and
pushing code to GitHub.

Command line versus a Graphical User Interface

Tools like Git were originally designed as command line tools. There
are also Graphical User Interface (GUI) tools and plugins for most
editors that make it easy and convenient to do many things in Git.
These are great to use and can simplify your development work, but
you should also learn how to use them from the command line.

There are a few very important reasons to learn to use Git from the
command line, one is that when you tell people you "know Git", such
as on a resume or in an interview, they will assume you have a basic
understanding of how to use it at the command line as well. Another
is that while the GUI tools are very convenient when everything is in a
clean working state, sometimes unexpected things happen. When
they do, it is almost always easiest to close down the GUI tool, return
back to the command line and start with `git status` and work from
there.

In this example you will learn both.

1.1.5 Create a new repository


The first step to using git is to create a new repository (or "repo" for
short). One way to do this is to create the repo at GitHub and then
clone it to your computer. (It is also possible to create one directly
using git init and then push it to GitHub later.)

In the Course Setup instructions you did the following:

1. Created an account at GitHub.com.

2. Signed in to GitHub.

3. Created a new repository from a template.

Those steps helped you create your first repository which is hosted at
GitHub.com.

Wait, is it Git or GitHub?


It's worth recognizing that Git and GitHub are different. Git is a
program that helps us manage versions of the files in our projects. Git
stores these files and their history in a repository (or "repo" for short).
Git is different than previous version control systems in every
computer stores a complete copy of the repo. Then, you can push
your repo to another computer, which says "make that one look like
mine." Or, you can pull from another computer, which says, "make
mine look like that one."

Rather than having to push and pull to every person on your team, we
can instead set up a central server and have each person interface
with that. This is where GitHub comes in. GitHub allows us to host a
repository on their servers and use that as a central place for our
team. They also provide a number of other tools to aid in the
management of the repo. There are a number of other places that
provide this same functionality, but GitHub is a popular choice that
we'll use in this course.

1.1.6 Clone the repository


Once your repository is created at GitHub you can get a copy of it on
your local computer with the git clone command.

Remember that the repository contains all the files in the project and
the complete history of changes made to them. So when you clone
this repository to your computer, you now have a copy of the
complete history showing all the changes that everyone on your team
has made.

In the Course Setup instructions, you did this when you entered the
URL for your repository and clicked "Clone this Repository." In the
background, this ran the git clone command for you.

1.1.7 Making changes


Creating a repository and cloning it to your computer only needs to be
done once at the beginning of the project, so those commands are not
used as frequently. Once you have everything set up, you will begin
your regular process of making changes and pushing them to GitHub.

Any changes need to go through the following steps:

1. Make your changes

2. Add them to a staging area where they get ready for the next
commit.

3. Commit all the changes that have been staged.


o This stores the changes in the repo on your computer, but
they are not at GitHub yet.

4. Push your repo to GitHub.

o This sends your changes and makes sure the two repos
(on your computer and at GitHub) are in sync.

o If you were working with another person, Git would make


you "pull" from GitHub at the same time to make sure you
get a copy of any changes that GitHub has that your
computer does not have yet.

1.1.7.1Adding files
To add a file to the staging area so that it can be part of the next
commit, you use the command git add followed by the name of the
file that has changed or been created. For example:
git add myFile.txt

If you are running the git command from a different folder, it is


important that you specify the full name of the file, using either an
absolute or a relative path. For example:

git add csharp-prep/Prep1/Program.cs

You can also specify a directory, which will add anything that has
changed in that directory (or any subdirectories beneath it).
Remembering that the single period . represents the current
directory, you can use a shorthand syntax to add the current directory
and everything beneath it by typing:

git add .

If you would like to use the VS Code extension for Git, you can click on
the Source Control tab on the left menu. This will show you any files
that have changed. You can click the "+" icon next to any of these
files to add them to the staging area for the next commit.

1.1.7.2 Commiting files


When you are ready to commit all of the files that have been staged,
you use the git commit command followed by a commit message.
For example:
git commit -m "Fixed problems where nothing was displayed on the screen."

It is important to choose a message that will help you and any


teammates know why you made the changes you did, in case you
need to track down problems later.

In fact, it is so important to leave a message that Git will not let you
do a commit without a message.

If you are using the VS Code extension for Git, on the Source Control
tab on the left menu, there is a box for you to type your message and
then you can click the button to commit.

Things to watch out for: Forgetting your comment

If you forget to include a commit message, git will take you to a text
editor to type one in. On most systems this will take you to a flavor an
editor called vi by default. This may or may not be your favorite
editor. If it is not, and you simply want to exit, press the Escape key a
couple of times and then type :q! (the : tells it you are entering a
command, the q says you want to quit, and the ! says you are not
worried about saving changes).

This will help you exit the editor. You can then run the commit
command again, this time with the -m for your message.

1.1.7.3 Pushing your changes to GitHub


Once you have committed your changes to your local repository, you
can push them to GitHub using the git push command. For example:
git push origin main

In this example, "origin" is the name of the remote server, and the
word "origin" is convention for your main server. The word "main" is
the branch that you would like to push to in case you are trying to
keep certain changes separate from one another. This semester we
will always use "origin" and "main". And, in fact, when you clone a
repo from GitHub, these will be set as defaults, so if you want to use
them, you only need to type:

git push

If you are using the VS Code Extension for Git, on the Source Control
tab on the left side, after you have committed your changes, you can
click the button to "Sync Changes", or alternatively, you can click on
the three dots and select "Push".

When you sync, it will check for any changes that have been made at
GitHub and pull them down, and then push your changes up. Because
you are the only one working on your project, you will likely not need
to pull any changes down.

1.1.7.4 Checking the status of your repo


One of the most helpful git commands is git status. It will tell you the
current status of your files and repository and have commands that
you might want to run (such as if you want to undo a staged file, etc.).

When everything is running smoothly the commands above or using


the VS Code Extension works great. But, if anything out of the
ordinary happens, git status can be very helpful in understanding
what has happened and what to do next.

1.1.8 A typical workflow


The typical process for working on your program is to change files,
add them, commit changes, and then push to GitHub. The following
video shows this in action:

Direct Link: A Typical Workflow using Git (10 minutes)

1.1.9 Assignment instructions


Practice working with Git by doing the following:

1. Open your course project folder in VS Code.

2. Make a change to the README.md file such as adding your


name or removing the line that says, "This is the starter code."

3. Add your changes to the staging area.

4. Commit your staged files to your local repository.

5. Push your changes to GitHub.

6. In a Web browser, navigate to GitHub.com and verify that you


can see your changes in the README.md file.
1.2 Prove: Articulate – Version control
Now that you have learned about the principle of version control and
practiced using Git and GitHub, answer the following question (the
way you would in a job interview):

What is version control and why is it important?

Your response must:

 Explain the meaning of Version Control

 Highlight a benefit of Version Control

 Example of version control: Describe the way version control


might be used on a software development team.

 Show a command used in Version Control (for example a Git


command)

 Thoroughly explain these concepts (this likely cannot be done in


less than 100 words)

Version control refers to the functionality of git that allows to teams to


work in a particular project, making changes that will be shown to
everyone in the group and tracked. Different versions of the project
can be seen also. It is important because it allows the team to work
from anywhere and at any time.

The Git command to see the changes made in any file is “git status”.

To update the changes to the main project the command is “git add
“file location””

To bring the changes to stage the command is “git commit -m


“message here””

To sync the changes the command is “git push”

1.3 Prove: Developer – C# Programming


1.3.1 C# Prep 1 – Variables, Input, and Output
Overview

Ensure that your tools are installed and that you can compile and run
a basic program in C#.

C# (pronounced C-Sharp)is very similar to other procedural or


objected-oriented programming languages, so if you have learned to
program in one of them, you should be able to leverage the core
concepts that you already know, and focus on the slight differences in
syntax.

You should already be familiar with programming. This course


assumes you are very comfortable with variables, loops, lists,
conditionals (if statements), and functions. If you are not, you are not
prepared to start this course.

Preparation Material

This material will outline some of the major differences between C#


and Python, highlighting the pieces you'll need to complete this
assignment.

In addition to the text here, you should consider the Web as a primary
source for learning. Once you know what to do, but just not how to do
it in a certain language, it's easy to search for "C# print statement" or
"C# for loop" or even something more complicated like, "C# open file
and read line by line". StackOverflow, in particular, is a great site to
help you with these kinds of questions.

1.3.1.1 C# Language Fundamentals


C# uses the same concepts as Python, in terms of variables, loops,
expressions, and so forth. Here are a few differences you need to be
aware of:

Defined types

In C#, when a variable is declared, its data type must be specified.


The computer then knows how much memory to allocate for it. Once
a variable's type is defined, it cannot be changed later.

You declare a variable, by specifying the type. Later, when you use
the variable, you do not need to specify the type again.
int x;
x = 5;
Console.WriteLine(x);

You can also declare a variable an initialize it in one statement:


int x = 5;
Console.WriteLine(x);

Common built-in variable types are:

 int - Integers (whole numbers, positive and negative)


 string - Strings (a sequence of characters, including letters,
numbers, or symbols)
 float - Floating point numbers (numbers that use decimals)
 double - Double precision floating point numbers (just like
a float, except it takes up twice as much memory, so it can
hold larger numbers or numbers with more decimal places)
 bool - Boolean variables (true or false)

Inputs and outputs

In C#, to print, or write something as output to the console, you use


the Console.WriteLine("") function.

Python

print("Hello World!")

C#

Console.WriteLine("Hello World!");

Console.WriteLine("") will print, or write, a full line, including the


new line. If you do not want a new line at the end, you can
use Console.Write("") to display the text with no newline afterward.
Console.Write("There will not be a newline after this.");

To get input from the user in C#, use


the Console.ReadLine() function, which will return a string that
comes from whatever the user typed. Please note that it is
a string (not an integer or floating point number), and that you need
to use Console.ReadLine() not Console.Read().

Also, please be aware that, unlike input in Python, you do not provide
the text of the prompt to the Console.ReadLine() function in C#, so
you must display it first with Console.Write("").

Python

color = input("What is your favorite color? ")

C#

Console.Write("What is your favorite color? ");


string color = Console.ReadLine();

Curly braces define blocks


In C#, curly braces {} define the body of an if statement or a
function. In Python, the body is defined by indenting. In C#, you still
indent the body, but this is only a convention, the actual mechanism
to define the body is the curly braces {}.

Also, in C#, you do not use a colon : to start the body, and when
using if statements, you must always put the condition in
parentheses ().

C#

if (x > y)
{
Console.WriteLine("greater");
}

Python

if x > y:
print("greater")

Statements end in semicolons

As you may have noticed above, in C#, statements end with the
semicolon ; character. Typically one statement will be one line,
however, sometimes you may have a long statement that extends on
multiple lines until the semicolon ; is reached.

The rule to end statements with semicolons applies to statements


such as calling a function, declaring a variable, setting a variable, and
so forth. You do not put a semicolon between the condition of
an if statement and its body, or the name of a function and its body.

String Interpolation

In C#, if you would like to use a variable inside a string, you start the
string with a dollar sign $ in the same way that in Python, you start a
format string with an f.

Python

school = "BYU-Idaho"
print(f"I am studying at {school}.")

C#
string school = "BYU-Idaho";
Console.WriteLine($"I am studying at {school}.");

Video Demo

These fundamentals are demonstrated in the following video:

These videos mention using the dotnet new command to start a


project, which can be done. However, in this course, you are provided
with a project shell already in the GitHub template repository, so you
don't have to worry about that.

Also, as you'll see, the dotnet new command inserts


a namespace around your code. This is important for larger projects,
but to keep things simple the starting templates we will use in this
class will not use namespaces.

Assignment Instructions

Learning activities

As you will see, each learning activity in this course will have two
components, they begin with preparation material to read or watch,
and then there is a small programming assignment where you
practice the concepts you have just read.

You need to finish this assignment and then return to Canvas to report
on your work.

Now that you have seen basic C# syntax, complete the following
assignment. This was a program you completed earlier in CSE 110,
but in this case, you will write the program in C#.

Getting the Project Template

1. If you haven't already done so, please refer to the instructions


on the Development Environment Setup page to make sure that
your computer is prepared for this course and that you have
cloned the project template to your computer.

2. Open your project in VS Code.

3. Then, in VS Code, navigate to the csharp-prep/Prep1 folder


and click on Program.cs. This is the file you will be editing for
this project.

4. On the "Run and Debug" menu, select "C# Prep 1" from the
dropdown menu and click the green play button to run the
program. In the terminal window, it should display the
text Hello Prep 1 World!.
Program Specification

Here are the instructions that you saw previously in CSE 110 that we
will use as our program specification:

Overview

An iconic line from the James Bond movies is that he would introduce
himself as "Bond, James Bond." For this assignment you will write a
program that asks for your name and repeats it back in this way.

Assignment

Prompt the user for their first name. Then, prompt them for their last
name. Display the text back all on one line saying, "Your name is last-
name, first-name, last-name" as shown:

What is your first name? Scott


What is your last name? Burton

Your name is Burton, Scott Burton.

What is your first name? Brigham


What is your last name? Young

Your name is Young, Brigham Young.

Make sure to be precise! You should have the spacing, comma, and
period appear exactly as shown in the examples.

Finish the program

Write and test the program as defined above.

Warning: Do not ever click "Debug Anyway".

If you have an error in your program and try to run it, VS Code will tell
you that it cannot build a new version of your program to run. But, it
may find an old version from the last time it successfully built the
program. If you click "Debug Anyway" it will run the old version.

If you "Debug Anyway" you will be running a program that is different


from your current code. This leads to lots of confusion, because you
might make changes to your code, but the program does not show
the changes.
To avoid these pitfalls, you should never click "Debug Anyway"
instead, click "Abort" and track down your errors, or click "Show
Errors" to go directly to them.

Sample solution

When you have finished the program, please compare your approach
to the one from this sample solution:

 C# Prep 01 Sample Solution

If you are having difficulty with this and future programs, you are
welcome to look at the sample solution to help you finish it.
Remember, though that the goal is for you to learn how to write code
on your own, and often we learn this best by working through a
number of things that don't work, before we find the one that does
work. So don't jump in here too quickly.

Also, you should make sure that you type every line of code yourself.
Do not copy and paste this code. It is important for your learning that
you practice writing every line of code.

1.3.2 C# Prep 2 – Conditionals


C# uses if statements just Python, but the syntax is slightly different.

1.3.2.1Conditionals
1.3.2.1.1If statements
First, the condition of the if statement must be put in parentheses ().
Then, to define the body of the if statement, you still indent by
convention, but it is the curly braces {} that define the body. (You
also do not use the colon : that Python does to start the block.)

C#

if (x > y)
{
Console.WriteLine("greater than");
}

Python

if x > y:
print("greater than")
Notice that the convention in C# is to put the curly braces {} on their
own lines. There are religious debates about "the one true bracing
style," but putting them on their own line is the defined convention
for C#, so that's what you should follow.

If you put one block of code inside another, it should be indented as


follows:

if (x > y)
{
if (x > z)
{
Console.WriteLine("greater than both");
}
}

1.3.2.1.2 Else and else if


C# supports else and else if, similar to else and elif in Python.

The else condition defines a body, just like the if condition:

C#

if (x > y)
{
Console.WriteLine("greater than");
}
else
{
Console.WriteLine("less than");
}

Python

if x > y:
print("greater than")
else:
print("less than")

The else if condition also defines its body in the same fashion. Please
note that in C#, the keywords are else if not elif:

C#

if (x > y)
{
Console.WriteLine("greater than y");
}
else if (x > z)
{
Console.WriteLine("greater than z");
}
else
{
Console.WriteLine("less than both");
}

Python

if x > y:
print("greater than y")
elif x > z:
print("greater than z")
else:
print("less than both")
1.3.2.1.3 Operators
C# uses the == operator to check if two variables are equal, just like
in Python. It also supports other operators you are familiar with, such
as !=, >=, <=, and so forth:
if (name == "John")
{
Console.WriteLine("The name is John");
}

if (color != favoriteColor)
{
Console.WriteLine("That color is not my favorite");
}

1.3.2.1.4
And, Or, and Not Operators
In C#, the and operator is && the or operator is || and
the not operator is ! which can be combined together with other
expressions and parentheses.

if (name == "Peter" || name == "James" || name == "John")


{
Console.WriteLine("This is a biblical name.");
}

if (firstName == "Brigham" && lastName == "Young")


{
Console.WriteLine("Welcome Brother Brigham!");
}

if (!(name == "Peter" || name == "James" || name == "John"))


{
Console.WriteLine("This is a not one of those three");
}
1.3.2.2 Variables and types
In C#, the naming convention for variables is to use "camel case."
This means that the variable starts with a lower case letter and then
additional words in the variable start with an upper case letter like
humps on a camel:
string color;
string firstName;
string lastName;
int velocityBeforeImpactWasMade;

1.3.2.2.1 Converting types


As mentioned before, in C#, all variables must have their data type
defined when the variable is first declared. Once defined, variables
cannot change type, so you cannot set a variable to an integer first
and later reassign it to a string.

You can, however convert a the value of a variable to a different type.


For example, you can create an integer from the digits stored in a
string using the int.Parse() function.
string valueInText = "42";
int number = int.Parse(valueInText);

This is especially important if the value comes from the user via
a Console.ReadLine() statement, which always returns a string:
Console.Write("What is your favorite number? ");
string userInput = Console.ReadLine();
int number = int.Parse(userInput);

If the user typed in something other than a number, this would result
in type of error called a Runtime Exception.

1.3.2.3 Numbers to strings


Similarly, an integer can be converted to a string using
the .ToString() function of the variable.
int number = 42;
string textVersion = number.ToString();

Video Demo

These fundamentals are demonstrated in the following video:

https://byui-cse.github.io/cse210-ww-course/week01/csharp-2.html
1.3.2.4 Assignment Instructions
For this assignment, you will complete another assignment that you
did previously in CSE 110, but in this case, write the program in
C#:

Program Specification

Here are the instructions that you saw previously in CSE 110 that we
will use as our program specification:

Overview

Write a program that determines the letter grade for a course


according to the following scale:

 A >= 90

 B >= 80

 C >= 70

 D >= 60

 F < 60

Assignment

Start by completing the core requirements, then when that part is


complete, if you have time, see if you can complete some of the
stretch challenges as well.

Please work through the requirements in order rather than jumping


ahead to more complicated steps, to ensure that everyone is
following the concepts.

Core Requirements

1. Ask the user for their grade percentage, then write a series
of if-elif-else statements to print out the appropriate letter
grade. (At this point, you'll have a separate print statement for
each grade letter in the appropriate block.)

2. Assume that you must have at least a 70 to pass the class. After
determining the letter grade and printing it out. Add a separate
if statement to determine if the user passed the course, and if
so display a message to congratulate them. If not, display a
different message to encourage them for next time.

3. Change your code from the first part, so that instead of printing
the letter grade in the body of each if, elif, or else block,
instead create a new variable called letter and then in each
block, set this variable to the appropriate value. Finally, after
the whole series of if-elif-else statements, have a single print
statement that prints the letter grade once.

Stretch Challenge

1. Add to your code the ability to include a "+" or "-" next to the
letter grade, such as B+ or A-. For each grade, you'll know it is a
"+" if the last digit is >= 7. You'll know it is a minus if the last
digit is < 3 and otherwise it has no sign.

After your logic to determine the grade letter, add another section to
determine the sign. Save this sign into a variable. Then, display both
the grade letter and the sign in one print statement.

Hint: To get the last digit, you could divide the number by 10, and get
the remainder. You might review the standard math operators and
find the one that does division and gives you the remainder.

At this point, don't worry about the exceptional cases of A+, F+, or F-.

2. Recognize that there is no A+ grade, only A and A-. Add some


additional logic to your program to detect this case and handle
it correctly.

3. Similarly, recognize that there is no F+ or F- grades, only F. Add


additional logic to your program to detect these cases and
handle them correctly.

Write and Test the program

1. Write and test the program as described above.

2. You should complete the 3 Core Requirements.

3. The stretch challenges are optional.

4. Make sure to use the same project template that you did for the
C# Prep 1 activity. However, this time, you should add your
code in Program.cs file in the the Prep 2 project.

Sample Solution

When you have finished the program, please compare your approach
to the one from this sample solution:

 C# Prep 02 Sample Solution

1.3.3 C# Prep 3 – Loops


1.3.3.1 Loops
C# provides four kinds of loops:
 while

 do-while

 for

 foreach

1.3.3.1.1While loops
While loops in C# work exactly the same way as in Python or other
languages. The only difference is that C# uses curly braces {} to
define the body of the loop, and the condition, must be surrounded by
parentheses ().

C#

string response = "yes";

while (response == "yes")


{
Console.Write("Do you want to continue? ");
response = Console.ReadLine();
}

Python

response = "yes"

while response == "yes":


response = input("Do you want to continue? ")
1.3.3.1.2 Do-While loops
Many languages have a construct called a do-while loop (Python does
not). This loop works the same as a while loop, with the exception
that the body of the loop runs once first, before the check is
made for the first time. This means that the body of the loop
is guaranteed to run at least once.

The syntax for a do-while loop is to use the keyword do, followed by
the body, followed by the the while keyword with the expression and
a semi-colon as shown:

string response;

do
{
Console.Write("Do you want to continue? ");
response = Console.ReadLine();
} while (response == "yes");
1.3.3.1.3 For loops
The standard for loop in C# is more like a "for x in range" loop in
Python. The condition has three parts, separated by semi-colons. The
first initializes the value, the second is the condition to check, and the
third is an increment step that is run at the end of each loop.

The following code shows the syntax of a for loop that counts from 0
to 9.

for (int i = 0; i < 10; i++)


{
Console.WriteLine(i);
}

In that code, you will see the use of the ++ operator which
increments the value in the variable by one.

The code above is the most common way to see one of these loops,
but you could put other values or statements in these spots, such as
counting from 2 to 20 by two's:

for (int i = 2; i <= 20; i = i + 2)


{
Console.WriteLine(i);
}

1.3.3.1.4 Foreach loops


C# contains a foreach loop that is similar to a standard for loop in
Python. It is important to remember that the iterator variable must
have its type defined, just like when declaring any other variable:

foreach (string color in colors)


{
Console.WriteLine(color);
}

The foreach loop will be used extensively in the next preparation


material that discusses lists.

1.3.3.2 Random numbers


In addition, for this assignment you'll need to get a random number
from the computer. In C#, this is done by creating an instance of the
Random class, and then using it to get the next integer in a particular
range.

Random randomGenerator = new Random();


int number = randomGenerator.Next(1, 11);

1.3.3.3 Assigment instructions


For this assignment, you will complete another assignment that you
did previously in CSE 110, but in this case, write the program in
C#:

Program Specification

Here are the instructions that you saw previously in CSE 110 that we
will use as our program specification:

Overview

In the Guess My Number game the computer picks a magic number,


and then the user tries to guess it. After each guess, the computer
tells the user to guess "higher" or "lower" until they guess the magic
number.

This assignment is a little tricky, because it brings together many of


the concepts you've learned in this course including loops and if
statements.

Core Requirements

Work through these core requirements step-by-step to complete the


program. Please don't skip ahead and do the whole thing at once,
because many people benefit from seeing the program built up step
by step.

1. Start by asking the user for the magic number. (In future steps,
we will change this to have the computer generate a random
number, but to get started, we'll just let the user decide what it
is.)

Ask the user for a guess.

Using an if statement, determine if the user needs to guess higher or


lower next time, or tell them if they guessed it.

At this point, you won't have any loops.

The following shows the expected output at this point:


What is the magic number? 6
What is your guess? 4
Higher

What is the magic number? 6


What is your guess? 7
Lower
What is the magic number? 6
What is your guess? 6
You guessed it!
2. Add a loop that keeps looping as long as the guess does not
match the magic number.

At this point, the user should be able to keep playing until they get
the correct answer.

The following shows the expected output at this point:


What is the magic number? 18
What is your guess? 5
Higher
What is your guess? 6
Higher
What is your guess? 7
Higher
What is your guess? 20
Lower
What is your guess? 19
Lower
What is your guess? 18
You guessed it!

3. Instead of having the user supply the magic number, generate a


random number from 1 to 100.

Play the game and make sure it works!

Stretch Challenge

1. Keep track of how many guesses the user has made and inform
them of it at the end of the game.

2. After the game is over, ask the user if they want to play again.
Then, loop back and play the whole game again and continue
this loop as long as they keep saying "yes".

Write and Test the program

1. Write and test the program as described above.

2. You should complete the 3 Core Requirements.

3. The stretch challenges are optional.

4. Make sure to use the same project template that you did for the
previous activities. However, this time, you should add your
code in Program.cs file in the the Prep 3 project.

Sample Solution
When you have finished the program, please compare your approach
to the one from this sample solution:

 C# Prep 03 Sample Solution

1.3.4 C# Prep 4 – Lists


1.3.4.1 Collections
The core C# libraries provide all of the standard collections and data
structures you are likely to need in your programs, including Lists,
Sets, Dictionaries, and so forth. This article will focus on lists, but you
can easily look up the information for any other data structure you
might need.

1.3.4.1.1 Lists
As you know, a major difference between C# and Python is that you
must declare your variable types in C#. While at first, this may seem
like a burden in C#, you'll soon discover that it helps you avoid many
runtime errors.

In a similar way, when you declare a new list variable in C#, you not
only declare that it is a List, you must also declare the type of data
that can be put in the list. That way, if you create a list of users, you
will be prevented from accidentally adding an order or a product
variable to this list.

To create a new list of integers, you specify int inside angle


brackets <> directly following the name of the data
structure: List<int> and if you want to have a list of strings, you
would use: List<string> as shown below.

Generic Data Types

Rather than having to implement separate code for the data structure
for every kind of data that could ever be put into it, the developers of
the C# List library make use of a concept called "Generics."

With generics, the library is written generically and then the type can
be provided to fill in the template. In documentation, you'll often
see T used as the template value to be filled in later.
List<int> numbers;
List<string> words;

The code above declares a variable to hold the list, but before you
can use one, you need to create a new one to use with
the new keyword.
List<int> numbers;
numbers = new List<int>();

This is typically done on the same line:


List<int> numbers = new List<int>();
List<string> words = new List<string>();

Notice the extra parentheses () at the end, that we use any time we
create a new object.

One more important thing to be aware of: Any file that uses Lists
(or any other standard collection), must refer to that library at the top
of the file. (This is so common that sometimes your settings for C#
can be specified so that you do not not have include this, but it is
important to know about it, in case you run into problems.)
using System.Collections.Generic;

What is "new" and why do we need it?

It turns out that List is a class or custom data type and we are
creating a new object or instance of that class. This is actually the
complete focus of this course, and beginning next week you will learn
how to create your very own custom classes.

With this in mind, you will learn much more about this in coming
weeks, but for now, just remember to include new before you start
using a list.

1.3.4.2 Adding items to the list


To add items to the list, you use the .Add() method:

C#

using System.Collections.Generic;

...

List<string> words = new List<string>();

words.Add("phone");
words.Add("keyboard");
words.Add("mouse");

Python

words = []
words.append("phone")
words.append("keyboard")
words.append("mouse")

1.3.4.2.1 Getting the list size


You can get the size of the list with the Count property.

C#

Console.WriteLine(words.Count);

Python

print(len(words))

Notice that you do not include parentheses () after Count because it


is a property, not a function.

1.3.4.2.2 Iterating through a list


The easiest (and safest) way to iterate through a list in C# is to use
the foreach loop:

C#

foreach (string word in words)


{
Console.WriteLine(word);
}

Python

for word in words:


print(word)

You can also access the items by their index:

C#

for (int i = 0; i < words.Count; i++)


{
Console.WriteLine(words[i]);
}

Python
for i in range(len(words)):
print(words[i])

1.3.4.3Other Operations
There are many other things you can do with lists. You can view the
official documentation or also, just begin typing in VS Code and see
the options that the Intellisense editor pops up for you.

In addition, don't forget that you can easily find syntax with a quick
Web search!

1.3.4.4 Assingment instructions


For this assignment, you will complete another assignment that you
did previously in CSE 110, but in this case, write the program in
C#:

Program Specification

Here are the instructions that you saw previously in CSE 110 that we
will use as our program specification:

Assignment

Ask the user for a series of numbers, and append each one to a list.
Stop when they enter 0. (Remember: You should not add 0 to the
list. If you do, later calculations and operations will not be correct.)

Once you have a list, have your program do the following:

Core Requirements

Work through these core requirements step-by-step to complete the


program. Please don't skip ahead and do the whole thing at once,
because others on your team may benefit from building the program
up slowly.

1. Compute the sum, or total, of the numbers in the list.

2. Compute the average of the numbers in the list.

3. Find the maximum, or largest, number in the list.

The following shows the expected output:


Enter a list of numbers, type 0 when finished.
Enter number: 18
Enter number: 36
Enter number: 2
Enter number: 48
Enter number: 6
Enter number: 12
Enter number: 9
Enter number: 0
The sum is: 131
The average is: 18.714285714285715
The largest number is: 48

Stretch Challenge

1. Have the user enter both positive and negative numbers, then
find the smallest positive number (the positive number that is
closest to zero).

2. Sort the numbers in the list and display the new, sorted list.
Hint: There are C# libraries that can help you here, try
searching the internet for them.

The following shows the expected output after completing the stretch
challenges:
Enter a list of numbers, type 0 when finished.
Enter number: 3
Enter number: 5
Enter number: 7
Enter number: 3
Enter number: 2
Enter number: -1
Enter number: -4
Enter number: -8
Enter number: 0
The sum is: 7
The average is: 0.875
The largest number is: 7
The smallest positive number is: 2
The sorted list is:
-8
-4
-1
2
3
3
5
7

Write and Test the program

1. Write and test the program as described above.

2. You should complete the 3 Core Requirements.

3. The stretch challenges are optional.


4. Make sure to use the same project template that you did for the
previous activities. However, this time, you should add your
code in Program.cs file in the the Prep 4 project.

Sample Solution

When you have finished the program, please compare your approach
to the one from this sample solution:

 C# Prep 04 Sample Solution

1.3.5 C# Prep 5 – Functions


Like most other languages, functions are an important part of C#.

Functions in C# are defined and work very similarly to those in


Python. In both languages you define the function with a name and
list of parameters. The function then has a body that performs tasks
and it can potentially return a value.

One key difference in C# is that in the same way that each variable
must define a type, each function must define its return type, for
example, whether it will return an int, a string, or nothing (the return
type for nothing is void). Also, each parameter must have a data type
as well. This is very helpful because, unlike in Python, you will know
exactly what kind of data you are receiving.

The style guidelines for C# say that a function name should use "Title
Case" where the name begins with a capital letter and then each
subsequent word is capitalized such as: ThisIsALongFunction.

The general structure of a function definition in C# is:


returnType FunctionName(dataType parameter1, dataType
parameter2)
{
// function_body
}

Here is an example of a function that does not have parameters or a


return type (hence the use of void):

C#

void DisplayMessage()
{
Console.WriteLine("Hello world!");
}

Python

def display_message():
print("Hello World")
The next example shows a function that accepts a single string
parameter:

C#

void DisplayPersonalMessage(string userName)


{
Console.WriteLine($"Hello {userName}");
}

Python

def display_personal_message(user_name):
print(f"Hello {user_name}")

The next example shows a function that accepts two integers as


parameters. It adds them together and returns the result. Notice that
the function specifies a return value of int at the beginning of the
definition.

C#

int AddNumbers(int first, int second)


{
int sum = first + second;
return sum;
}

Python

def add_numbers(first, second):


sum = first + second
return sum

1.3.5.1Functions vs Methods
From previous courses, you may recall a distinction between
standalone functions and member functions, which are
called methods. Methods play a very important role in Programming
with Classes and they will be discussed at length in the coming
lessons.

In C#, because the language is so dedicated to the principles of


Programming with Classes, the default case for all functions is to be
methods, which must be called in the context of an object. (Again,
more on this later!) But this has an important ramification for you
now. If you want to define "regular" standalone function, you need to
use the static keyword. This tells C# that you want your functions to
be able to be called without any other context.

To define a standalone function in C#, use the static keyword before


the return type:
static void DisplayMessage()
{
Console.WriteLine("Hello world!");
}

static void DisplayPersonalMessage(string userName)


{
Console.WriteLine($"Hello {userName}");
}

static int AddNumbers(int first, int second)


{
int sum = first + second;
return sum;
}

Until we start writing classes, you should put the static keyword in
front of all your functions.

Use static for all of your functions until we start writing classes.

1.3.5.2 Variable Scope


Just like in Python, variables declared and used in the body of a
function can only be accessed within that function (they cannot be
accessed in main or any other function).

1.3.5.3 Other Operations


There are many other things you can do with functions, but at this
point we will starting by focusing on the basics.

Also, don't forget that you can easily find syntax with a quick Web
search!

Assignment Instructions
For this assignment, write a C# program that has several simple
functions:

 DisplayWelcome - Displays the message, "Welcome to the


Program!"

 PromptUserName - Asks for and returns the user's name (as a


string)

 PromptUserNumber - Asks for and returns the user's favorite


number (as an integer)

 SquareNumber - Accepts an integer as a parameter and


returns that number squared (as an integer)

 DisplayResult - Accepts the user's name and the squared


number and displays them.

Your Main function should then call each of these functions saving the
return values and passing data to them as necessary.

Sample output of the program could look as follows:


Welcome to the program!
Please enter your name: Brother Burton
Please enter your favorite number: 42
Brother Burton, the square of your number is 1764

Write and Test the program

1. Write and test the program as described above.

2. Make sure to use the same project template that you did for the
previous activities. However, this time, you should add your
code in Program.cs file in the the Prep 5 project.

Sample Solution

When you have finished the program, please compare your approach
to the one from this sample solution:

 C# Prep 05 Sample Solution


Chapter 2 Abstractions
2.1Learning activity
2.1.1What is Abstraction?
Abstraction is the process of turning complex ideas into simple ones.
It is removing characteristics from something so that only the
essential ones remain. As programmers, we create and use
abstractions all the time. Consider the following line of Python code.
print("hello world")

Whether or not you're familiar with Python, you probably recognize


this as the first program we all learn to write. You also probably
understand this statement will show the words, "hello world", on a
computer display. However, relatively few programmers know the
details of how this is accomplished. As it turns out, it takes over 3000
lines of C to implement this function.

The print function in Python is an abstraction. It is the simplification of


something that is actually quite complex. In order to use it, all we
need to know is the function name itself, or "print", and the required
arguments, some literal text or a variable that can be transformed
into literal text.

The print function might be used within another function we write to


create yet another abstraction. That is, a different function that
simplifies a higher order idea or task. This layering of abstractions is
exactly how all of the software used in the world today, from text
editors like Notepad to social media platforms like Facebook, is
written.
2.1.2 Objects and classes
Programming with classes is another way of creating abstractions in
software. We begin, however, by thinking about objects. An object is
a conceptual model for a category of things, real or imagined,
that has a specific responsibility within our program. For
example, we might think of an object that holds and provides
identifying information about a person.

Objects have state and behavior that allow them fulfill their
responsibility. The person object may have state like "given name"
and "family name". It may also have related behaviors like "show
western name" and "show eastern name". Following is a graphical
depiction of our person object.

Person responsabilities

Thinking about a person this way is an abstraction. It is a


simplification of something that is more complex. It might seem trivial
at first but not having to worry about differences in lexical name form
anywhere else in our software is significant. We can just rely on the
person object to take care of it.

There aren't any unrelated behaviors either. There are certainly many
other ones we could think of as belonging to a person. However, our
conceptualization only contains those that help fulfill its specific
responsibility.

With an object in mind we are ready to translate it to a code template


called a class. The object's state is translated to variables
called attributes. The object's behaviors are translated to
functions called methods.
As a stepping stone to writing the actual code, we can create a Class
Diagram which is a box that has the name of the class at the top, the
member variables or attributes in the middle, and the methods at the
bottom. Member variables are followed by a colon and their data
type, and methods are followed by a colon and their return type. The
following is an example of the Class Diagram for the Person class
described above:

Person class diagram

You can observe from the class diagram that the standard in C# is
to use TitleCase for class and method names, and to use
_underscoreCamelCase for our member variable names. The
underscore at the beginning helps you recognize that the variables
are members of the class and are different from regular, local
variables.

Once we have a class diagram, we have enough detail to begin to


implement the class in code. The following is an example of the
Person translated to a class in code. Be sure to read all of the
comments and code carefully.
// A code template for the category of things known as Person. The
// responsibility of a Person is to hold and display personal information.
public class Person
{
// The C# convention is to start member variables with an underscore _
public string _givenName = "";
public string _familyName = "";

// A special method, called a constructor that is invoked using the


// new keyword followed by the class name and parentheses.
public Person()
{
}
// A method that displays the person's full name as used in eastern
// countries or <family name, given name>.
public void ShowEasternName()
{
Console.WriteLine($"{_familyName}, {_givenName}");
}

// A method that displays the person's full name as used in western


// countries or <given name family name>.
public void ShowWesternName()
{
Console.WriteLine($"{_givenName} {_familyName}");
}
}

2.1.2.1 Classes and files


To make it easy to find classes, the standard for C#, and many other
languages, is to put each public class in its own file. The name of this
file should exactly match the class name, including capitalization, and
then it should have an extension of .cs for C Sharp.

For example, the Person class should be in Person.cs. Similarly,


a Book class should be found in Book.cs,
an IllustratedComicBook class should be found
in IllustratedComicBook.cs, and so forth.

A Note on Creating Diagrams

There are many tools to help you create class diagrams, and as you
learn about more details of programming with classes you will learn
that there are lots of elements that can be added to a diagram.

For this course, the important part is to focus on the name,


the attributes (member variables), and the behaviors
(methods). If you would like to find and use a tool to create the
diagrams, that is great, but you can also do this as simply as creating
a bulleted list in any text editor:
Class: Person
Attributes:
* _givenName : string
* _familyName : string

Behaviors:
* ShowEasternName() : void
* ShowWesternName() : void
2.1.3 Classes and instances
By itself, a class is just a template for something. It only
becomes useful when an instance is created and assigned to a
variable in your program. An instance is the realization of
attributes and methods in the computer's memory.

Another way to think about creating an instance of a class is to


imagine baking a cake. In this metaphor, a class is like the recipe.
It is a template for a cake but not the actual baked good. In contrast,
an instance is what comes out of the oven. It is a realization of the
recipe details in a sweet tasting crumb! Consider the following code.
Person person = new Person();
person._givenName = "Joseph";
person._familyName = "Smith";
person.ShowWesternName();
person.ShowEasternName();

Output
Joseph Smith
Smith, Joseph

In this example, an instance of the Person class is created and


assigned to the variable called "person". It is created by
invoking a special method, called the constructor, which is the
name of the class followed by parentheses. Some programming
languages, like Java, C# and others, require the "new" keyword when
calling a constructor. (You will learn more about constructors in the
next unit.)

“An instance is created by invoking a special method, called the


constructor, which is the name of the class followed by parentheses,
using the keyword ‘new’, then, this is assigned to a variable”

One of the most important aspects of programming with classes is


that multiple instances can be created and used in the same program.
The following example shows the creation of two Person instances.
Notice how the "given name" attributes are assigned different values,
varying the behavior of the "show western name" method from one
instance to the other.
person1 = new Person();
person1._givenName = "Emma";
person1._familyName = "Smith";
person1.ShowWesternName();
person2 = new Person();
person2._givenName = "Joseph";
person2._familyName = "Smith";
person2.ShowWesternName();

Output
Emma Smith
Joseph Smith

2.1.4 Custom data types


When you create classes, you are really creating a new
custom data type. For example, in C# there are built-in data types
for integers and strings. When you declare a variable of these types, it
is like making a box that can hold that type of data, and putting a
label on the outside of the box with the variable name. For example,
consider the following code:
int height;
string color;

This code creates boxes that you can later fill with values. Then, when
you assign the value, it puts it in the box. For example, the following
code puts the number 17 in the box:

height = 17;

And this code, changes it to 24:


height = 24;
Now suppose you were working for a window covering company that
manufactured blinds (persianas), and you wanted a program to work
with these blinds. Your code would need to store the width, height,
and color of each blind in the program.

Imagine how great it would be if C# came with a data type


like string or int but that was designed specifically with blinds in
mind that could store all three of these components together. With
classes, we can create this new datatype as follows:

public class Blind


{
public double _width;
public double _height.
public string _color;
}

With this new custom data type, you can now create a new variable
whose type is Blind. We can think about this as creating a new box
for it. The difference is that this box has a little separator inside it
making three smaller compartments, one for each of the three
member variables.

Every time you create a new Blind variable, it creates another large
box that has these three components. The class is what defines the
structure of the large box, and each of these large boxes that you
create is an object or instance of that class.

For example:
Blind kitchen = new Blind();

In your code, whenever you use the variable kitchen it refers to a


large box, and if you want to refer to anything inside the box, you use
the "dot" operator. You can set the values as follows:
kitchen._width = 60;
kitchen._height = 48;
kitchen._color = "white";

And you can access the values in the same way:


Console.WriteLine(kitchen._width);
Storing all of these values together in one larger box can greatly
simplify your code, because, for example, you can now pass that
whole large box to a function as a parameter, or return it.

2.1.4.1 Adding behavior


In addition to storing values together than belong together, you can
also put the member functions, or methods, that use that data right in
the box with them.

For example, continuing with the same window covering example,


suppose that you wanted a method to compute the area of the blind,
so the program could display the amount of material you needed. This
could be added as a function inside the box, called, GetArea().

public class Blind


{
public double _width;
public double _height;
public string _color;

public double GetArea()


{
return _width * _height;
}
}

The GetArea() function now belongs inside the box as well. And
because it is inside the box, you use the "dot" notation to call it:
double materialAmount = kitchen.GetArea();

(The red lines in the image are meant to indicate that there are lines
of code associated with this method.)

The following shows all of these lines together:

Blind kitchen = new Blind();

kitchen._width = 60;
kitchen._height = 48;
kitchen._color = "White";

double materialAmount = kitchen.GetArea();


Notice that to call the GetArea() method, you must supply the name
of the object first, followed by a dot. Then, also notice that you
do not need to pass it variables for the width and the height. This is
because this method is a member of the class, so it is already "in the
box," so it can access any of the member variables it needs.

The fact that the method accesses the member variables in its box, is
also why GetArea() will return different values for
different Blind objects, such
as kitchen.GetArea() and livingRoom.GetArea(), because these
two objects will have different values for their widths and heights.
2.1.4.2 Objects within objects

In the previous example, all of the member variables had simple


types (double or string). But member variables can also have custom
types. This is similar to putting another box inside the larger one.

For example, in the window covering example, you might consider


creating another class for the whole house. Internally, it might contain
other member variables, some of which could be simple types, and
others could be complex types. For example:
public class House
{
public string _owner;
public Blind _kitchen;
public Blind _livingRoom;
}

Remember, that you must initialize these blinds to new values. You
can do this after you create a new House object:
House johnsonHome = new House();

johnsonHome._kitchen = new Blind();


johnsonHome._livingRoom = new Bind();

Or, you can initialize these variables right in the class definition:
public class House
{
public string _owner = "";
public Blind _kitchen = new Blind();
public Blind _livingRoom = new Blind();
}
Once you have created a new House object, you can access its
member variables using the "dot" operator just as before:
House johnsonHome = new House();
johnsonHome._owner = "Johnson Family";

When you want to access the internal values of one of these complex-
type, member variables, you can just chain together multiple "dot"
operations, such as:
johnsonHome._kitchen._width = 60;

2.1.4.3 Lists of custom types

In the same way that you can create a list of strings or a list of
doubles, you can also create a list of a new custom type. For example,
instead of the House class containing variables for the kitchen and
the living room blinds, it might have a list of blinds:
public class House
{
public string _owner;
public List<Blind> _blinds = new List<Blind>();
}

With this new version of the House class, you could write code like:
johnsonHome._blinds.Add(kitchen);

or:
double amount = johnsonHome._blinds[0].GetArea();

or:
foreach (Blind b in johnsonHome._blinds)
{
double amount = b.GetArea();
}

The following figure shows the way you might think about the storage
of the johnsonHome object. Notice that the _blinds member
variable now refers to a list of Blind objects. Each Blind object can be
referenced by its index, and each has its own values for
the _width, _height, and _color variables.

2.1.5 Summary

Think back to the beginning paragraphs in this article. One of the


more interesting aspects of abstraction is that we can layer them, as
you have just seen, putting objects within objects. Each of these
objects can have their own responsibility, behaviors and state.

Abstraction is the first principle of programming with classes. As you


get better at applying it, you'll find you're able to think and talk about
your software, with programmers and non-programmers alike, in a
very natural way. Please don't underestimate the value of this ability.
Being able to communicate clearly about what is needed and what
you're doing is at the very heart of creating software that is ready for
change.

Terms and Definitions

Class - A new custom data type that defines attributes (member


variables) and methods. This is like a blueprint to create instances or
objects of that class. Example: A Person has given name and family
name.

Instance - A variable whose data type is the class. We often use the
term Object interchangeably. Example: We can have two instances of
the Person class: one for John, and one for Mary.

Instantiate - A verb that means "to create an instance of." Example:


We can instantiate the Person class to create a new object.

Method - A member function. Methods are called using "dot notation"


with an instance of the class before the
dot. Example: person1.GetEasternName()

2.1.6 Activity instructions


Practice the principle of abstraction by creating classes to represent a
resume or an job history for a person like you might see on LinkedIn.

2.1.6.1 Step 1: Design the classes


You program should contain two classes one for a Job and one for the
Resume itself, as follows:

Class: Job

 Responsibilities:

o Keeps track of the company, job title, start year, and end
year.

 Behaviors:

o Displays the job information in the format "Job Title


(Company) StartYear-EndYear", for example:
"Software Engineer (Microsoft) 2019-2022".

Class: Resume
 Responsibilities:

o Keeps track of the person's name and a list of their jobs.

 Behaviors:

o Displays the resume, which shows the name first, followed


by displaying each one of the jobs.

Based on these descriptions, you could create class diagrams like the
following:

2.1.6.2 Step 2 Start the project

1. Open the class project in VS Code.

2. Navigate to the Learning02 project in the prepare folder. Find


the Program.cs file, which will be your entry point for the
program.

3. Verify that you can run the project and see the beginning "Hello
World" output.

2.1.6.3 Step 3: Create the job class

1. Create a new file for your job class. By convention this should
be named Job.cs .

2. Create the class (Hint this is the public class Job syntax).

3. Create member variables in the class for each element that this
class should contain. By convention these member variables
should begin with an underscore and a lowercase letter such
as _jobTitle .

2.1.6.4 Step 4: Test your Job class

1. Back in your Program.cs file, add code to your Main function.

2. Create a new job instance named job1 .

3. Set the member variables using the dot notation (for


example, job1._jobTitle = "Software Engineer";

4. Verify that you can display the company of this job on the
screen, again using the dot notation to access the member
variable.

5. Create a second job, set its variables, display this company on


the screen as well.

Sample Output
Microsoft
Apple

2.1.6.5 Step 5: Add a display method to the job class

1. Return to your Job.cs file and add a method (member function)


to display the job details. This method should not have any
parameters and does not need to return anything. By
convention, this method should begin with a capital letter, such
as Display, and if you have multiple words each word should be
capitalized, such as DisplayJobDetails .

2. This method should display the job details on the screen in the
correct format. Remember that the method can access the
member variables directly, without needing them to be passed
into it.

3. Return to your Program.cs file. Remove the lines of code


where you displayed the company earlier, and replace them
with calls to your new method. Remember that you call the
method using the same dot notation such as job1.Display(); .

Sample Output
Software Engineer (Microsoft) 2019-2022
Manager (Apple) 2022-2023

2.1.6.6 Step 6: Create the Resume Class

1. Create a new file for your Resume class. Each class should be
in its own file and the file name should match the name of the
class.

2. Create the Resume class.

3. Create the member variable for the person's name.

4. Create the member variable for the list of Jobs. (Hint: the data
type for this should be List<Job> , and it is probably easiest to
initialize this to a new list right when you declare it..)

2.1.6.7 Step 7: Test your resume Class

1. Return to your Program.cs. Add the end of the Main function,


create a new instance of the Resume class.

2. Add the two jobs you created earlier, to the list of jobs in the
resume object.

3. Verify that you can access and display the first job title using
dot notation similar to myResume._jobs[0]._jobTitle .

2.1.6.8 Step 8: Add a display method to the resume class

1. Return to your Resume class and add a method to display its


details.

2. This method should not have any parameters and should not
return anything.

3. In the method body, you should display the person's name and
then iterate through each Job instance in the list of jobs and
display them.

4. Hint: remember that you can call each job's Display method
that you created earlier.
5. Return to your main function, remove any code that is
displaying information, and instead, add a call at the end to
the Display method from your Resume class to display the
name and all the jobs in one line.

Sample Output

Name: Allison Rose


Jobs:
Software Engineer (Microsoft) 2019-2022
Manager (Apple) 2022-2023

Sample Solution

When you have finished please compare your approach to the


following sample solution (you may also use this sample solution as a
guide if you need help finishing).

 Learning Activity 02 Sample Solution.

Submission

1. Verify that your program works as described.

2. Commit and push your code to your GitHub repository.

3. Verify that you can see your updated code at GitHub.

4. Submit the Canvas quiz to report on your work.

2.1.7 Reading text files in C#

The easiest way to read a text file in C# is to read the entire file into
an array of strings (one per line) using
the System.IO.File.ReadAllLines() function. Then, you can iterate
through each string as you would with any list.

As you go through each string, you can split it based on a separator


character and get the pieces you need by their index.

The following shows an example of reading a file and splitting up the


strings.
string filename = "myFile.txt";
string[] lines = System.IO.File.ReadAllLines(filename);

foreach (string line in lines)


{
string[] parts = line.Split(",");

string firstName = parts[0];


string lastName = parts[1];
}

There are many other ways to work with files in C# some of which
would be more efficient if the file is very large and you don't want to
store it all in memory at once, but this approach will work just fine for
this project.

2.1.8 Writing text files in C#


You can create or write a text file in C# using a class
the System.IO.StreamWriter class. When you create an object of
this class you can use the Write() and WriteLine() methods in the
same way as the Console.Write() methods, except that they will
write the strings to the file instead of to the Console.

To make sure the file gets closed and cleaned up appropriately when
you are done, it is best practice to put the StreamWriter object in
a using() block. This works the same as a "with" block in Python and
ensures that the resources are cleaned up when you leave that area
of the code.

The following shows an example of writing text to a new file


// Don't forget to put this at the top, so C# knows where
to find the StreamWriter class
using System.IO;

...

string fileName = "myFile.txt";

using (StreamWriter outputFile = new


StreamWriter(filename))
{
// You can add text to the file with the WriteLine
method
outputFile.WriteLine("This will be the first line in
the file.");

// You can use the $ and include variables just like


with Console.WriteLine
string color = "Blue";
outputFile.WriteLine($"My favorite color is {color}");
}
2.1.9 Working with dates in C#
C# has a class that is used for working with dates and time of day
called, DateTime.

You can get an object representing the current day and time
with DateTime.Now. Then, it has various methods that are helpful,
such as .ToShortDateString().
DateTime theCurrentTime = DateTime.Now;
string dateText = theCurrentTime.ToShortDateString();

Still having difficulty reading and writing files?

The following video walks through through the development of a


program that reads and writes a list of objects to a file in a similar
way that you will need to for your program:

CSV Reading and Writing Demo (20 Minutes)

2.2 Team activity: Designer


2.2.1 Journal Program
Problem Overview

Many people see the value of keeping a journal to record important


events, and many people even set this as a goal. And yet, very few
people actually follow through and keep a journal consistently.

Think to yourself for a moment: What are some reasons people do not
follow through with their goal to keep a journal? Could a program or
app help with any of these?

Some of the reasons you thought of might include the following:

 We forget

 It's not convenient to get out our written journal or find the
electronic document

 We don't feel like we have anything interesting to say

 We don't feel like we have time for it

 We aren't sure what to write


 We feel overwhelmed with writing every event of the day, so we
just don't write anything.

While it will not solve all of people's problems, a great program or an


app could help remove some of these barriers. For example, an app
could give you a reminder at a certain time of day or give you a direct
link to your document.

Consider the last challenge mentioned above, that of being


overwhelmed because it feels like you must write every event during
the day, this seems to be a big problem for many people. Could an
app help with this?

Solution Idea

What if the Journal app gave people a simple prompt to respond to


every day? It could also record the response somewhere for them and
even add elements like the data automatically.

These features could help address some of the challenges that keep
people from journaling, and could be included in a mobile app or on a
web page. The actual interface is not that critical, but the ability for a
program to help solve a real problem is important to recognize.

Program Specification

For this assignment you will write a program to help people record the
events of their day by supplying prompts and then saving their
responses along with the question and the date to a file.

Functional Requirements

This program must contain the following features:

1. Write a new entry - Show the user a random prompt (from a list
that you create), and save their response, the prompt, and the
date as an Entry.

2. Display the journal - Iterate through all entries in the journal and
display them to the screen.

3. Save the journal to a file - Prompt the user for a filename and
then save the current journal (the complete list of entries) to
that file location.

4. Load the journal from a file - Prompt the user for a filename and
then load the journal (a complete list of entries) from that file.
This should replace any entries currently stored the journal.

5. Provide a menu that allows the user choose these options


6. Your list of prompts must contain at least five different prompts.
Make sure to add your own prompts to the list, but the following
are examples to help get you started:

o Who was the most interesting person I interacted with


today?

o What was the best part of my day?

o How did I see the hand of the Lord in my life today?

o What was the strongest emotion I felt today?

o If I had one thing I could do over today, what would it be?

7. Your interface should generally follow the pattern shown in the


video demo below.

Design Requirements

In addition, your program must:

1. Contain classes for the major components in the program. (Each


class should be in its own file where the filename matches the
class name.)

2. Contain at least two classes in addition to the Program class.

3. Demonstrate the principle of abstraction by using member


variables and methods appropriately.

Simplifications

For the core requirements you do not need to worry about the
following:

1. Saving your file as a .csv file requires you to handle commas


and quotes in the content appropriately. At this point, you can
ignore that and just choose a symbol for a separator that you
think is unlikely to show up in the content (such as | or ~ or ~|
~).

2. You do not need to store the date as an actual


C# DateTime object in your class or in the file. You can simply
store it as a string.

Showing Creativity and Exceeding Requirements

Meeting the core requirements makes your program eligible to


receive a 93%. To receive 100% on the assignment, you need to show
creativity and exceed these requirements.
Here are some ideas you might consider:

 Think of other problems that keep people from writing in their


journal and address one of those.

 Save other information in the journal entry.

 Improve the process of saving and loading to save as a .csv file


that could be opened in Excel (make sure to account for
quotation marks and commas correctly in your content.

 Save or load your document to a database or use a different


library or format such as JSON for storage.

Report on what you have done to exceed requirements by adding a


description of it in a comment in the Program.cs file.

Video Demo

The following video demonstrates the way this program should work:

Link: Journal program demo

The following video demonstrates the way this program should work:

Direct link: Journal Program Demo (3 minutes)

Develop the Program

In the course repository, find the Develop02 project in


the Prove folder and write your program there.

Submission

1. Develop the program using the principle of Abstraction as


described above.

2. Make sure to describe anything you have done to exceed the


requirements in comments in the Program.cs file.

3. Commit your source code and push it to GitHub.

4. Verify that you can see your updated code at GitHub.

5. In Canvas, submit a link to your GitHub repository. In the


submission comment, describe anything you have done to show
creativity and exceed the core requirements.
2.2.2 Review the program specification
Refer to the Journal program specification. As a team, review the
program requirements and how it is supposed to work.

1. What does the program do?

It helps people to write a journal, by providing questions to


respond, editing and saving records

2. What user inputs does it have?

It has at least 3 inputs, a number to choose from the options,


answers for the questions, and the name of the file where the
writings will be recorded.

3. What output does it produce?

A record for the writings in the text files, options for the user to
choose.

4. How does the program end?

It ends when the user selects the quit save.

2.2.3 Determine the classes

1. What are good candidates for classes in this program?

Write

Display

Load

Save

2. What are the primary responsibilities of each class?

My proposal

Class Responsibility
Write To show questions to the user
and store the answers in empty
variables.
Display It shows the user entries
Load To read from a file the answers
and display them
Save It saves the user entries in a file
Class: Person
Attributes:
* _givenName : string
* _familyName : string

Behaviors:
* ShowEasternName() : void
* ShowWesternName() : void

Mentor proposal

Class Responsibility
Journal Stores a list of journal entries
Entry Represents a single journal entry
PromptGenerator Supplies random prompts
whenever needed
In addition, your program will also have a Program class that is the
starting point for the program and handles much of the user
interaction. Because all programs contain this class, and because it
is usually simple, only containing a few static methods, and we do
not not even create an instance of it, you will often see it excluded
from lists like this, where instead, we focus on the classes that
model the components of our specific problem.
You might have also considered a "file" class, but in this case, the
main concepts to model are the journal and the entry. Being able to
load and save these journal entries could be behaviors of these
classes, and then you wouldn't need an extra File class. It could
certainly be a valid approach to have a class for all the file
interaction with methods like SaveToFile and LoadFromFile. These
are the hard decisions that programmers have to weigh back and
forth. For this program, we will let the Journal class take care of this
behavior.
Does the prompt generator really need to be it's own class or could
it simply be a method? This is a good question. But by making the
prompt generator a class, it can abstract any details associated with
generating prompts, such as whether they are loaded from a file,
scraped from an internet source, or to make sure make sure
duplicate prompts are not given. You may not want all those
features now, but the benefit of abstraction is that you could add
them later on and not have to change the way the rest of the
program works. So, for that reason, it makes good sense to create it
as a class now.
2.2.4 Define class behaviors
Now that you have decided on the classes you will need and their
responsibilities, the next step is to define the behaviors of these
classes. These will become the methods of each class.

Go through each of your classes and ask:

1. What are the behaviors this class will have in order to fulfill its
responsibilities? (In other words, what things should this
class do?)

Clearly, the PromptGenerator class needs to generate prompts.

Many behaviors of the Journal class also come out nicely from the
specification. For example, a journal needs to include behaviors such
as:

 Adding an entry

 Displaying all the entries

 Saving to a file

 Loading from a file

The Entry class doesn't have too many behaviors. It's main
responsibility is to hold data. And yet, because it is in charge of
everything that has to do with entries, it would make sense for it to at
least have it's own display method. Then, the Journal display method
could iterate through all Entry objects and call the Entry display
method. The Journal wouldn't have to worry about the details of how
the Entry was displayed, this would all be contained within
the Entry class.

Converting these ideas to concise method names gives us the


following (note that the variable types and return types are shown
after the : colon character):

 Journal
o AddEntry(newEntry : Entry) : void
o DisplayAll() : void
o SaveToFile(file : string)
o LoadFromFile(file : string)
 Entry
o Display() : void
 PromptGenerator
o GetRandomPrompt() : string
What are the potential benefits of having a Display method in
the Entry class rather than allowing the Journal's display method to
display an entry's date and text directly?

If the Entry is changed to contain other information, other classes


would not have to be updated.

If the Entry variables are renamed, other classes would not have to be
updated.

2.2.5 Define class attributes

Now that you have defined the classes, their responsibilities, and their
behaviors, the next step is to determine what attributes the class
should have, or what variables it needs to store.

Go through each of your classes and ask:

1. What attributes does this class need to fulfill its behaviors? (In
other words, what member variables should this class store?)

2. What are the data types of these member variables?

A Journal should store a list of Entry objects. The data type for this
should be List<Entry>

An Entry should keep track of the date, prompt text, and the text of
the entry itself.

In our design, the prompt generator should store a list of potential


prompts that it can select from randomly when needed.

Converting these ideas into concise variable names along with their
data types gives us the following:

 Journal
o _entries : List<Entry>
 Entry
o _date : string
o _promptText : string
o _entryText : string
 PromptGenerator
o _prompts : List<string>

2.2.6 Review the design

Take a minute to review your final design.


1. Are there any classes, methods, or variables, that you do not
understand?

The following is a final class diagram for each of the classes that you
can use as a guide as you being writing your code.

Using this design, when you want to add a new entry to the journal,
you will use code such as theJournal.AddEntry(anEntry); instead
of using the _entries variable and its add method like
this theJournal._entries.Add(anEntry);. What is a benefit of our
design approach (the AddEntry method), instead of accessing the
variable directly?

2.2.7 Start the code

Now that you have a design for your classes in mind. The next step is
to start the code of the program.

You begin programs with classes by creating "stubs" for everything in


your design, or in other words, an empty skeleton that contains all of
the classes from your design with all of the member variables and
methods. At this point, the methods can be (mostly) empty. You will
fill them in later as you begin the program.

Avoid Build Errors


One important factor as you "stub out" your program is that you want
to make sure that it can built (we often say "compiled") without
errors. This is why some of your methods cannot be completely
empty.

If the function has a void return type, meaning it does not return
anything, it can be left completely empty.

However, if the function has a return type, you will need to


return something, or else you will have errors when you try to run it.
For example, if the return type is string then you might
include return ""; as a single line of the function so that it will not
have errors.

After the team activity, each person needs to individually do the


following:

1. Open the project in VS Code. Create new files that contain the
"stubs" or empty code for all the classes, member variables,
and functions in your design.

o At this point the body of the methods can be empty,


except for the necessary return statements.

o Each class should be in its own file and the name of the
file should match the class name (for
example, Journal.cs).

2. Make sure that your program can build without errors.

3. Commit and push your code to your GitHub repository.

2.3 Articulate activity

Abstraction is the principle of writing classes that are composed of


variables and functions which are called within the class attributes
and behaviors respectively. The behaviors make use of the attributes
frequently. These classes must be written in a separate ‘cs’ file with
the same name as the class.

One benefit of classes is that they are pieces of code that are
reusable, e.g. they can be used in a program the same as other
methods are used.

A useful class would be looping through a list of strings to print its


elements as follows in the example below:
public class LoopingList
{
public List<string> _names;

public void LoopThroughList()


{
foreach (string name in _names)
{
Console.Writeline(name);
}
}
}

The attribute of this class is ‘_names’ and the behavior is


‘LoopThroughList()’.

To use this class in any other program the following must be done

Code

LoopingList Loop1 = new LoopingList();


Loop1._names = new List<string> {“Laura”, “Damian”, “Luz”,
“Joel”};
Loop1.LoopThroughList();

Output
Laura
Damian
Luz
Joel

By simply assigning a list to the attribute and calling the method the
behavior is applied.
Chapter 3 Encapsulation
3.1Encapsulation
Overview

In this activity you will learn and practice the principle of


Encapsulation.

3.1.1Prepare
Encapsulation is the act of enclosing something, as if it were in
a capsule. It means thinking carefully about the behaviors your
classes need and then hiding the details of how they perform those
behaviors, even making it so other code cannot see or manipulate
these details.

Previously, you learned about the power and value of abstraction in


writing programs that can handle change. One of the main principles
was to let a class be responsible for the details of a particular task.
Then, the other parts of the program do not have to worry about
those details, as long as they know how to interact with the class
itself.

With encapsulation, we push this idea further by preventing other


parts of the program from accessing those details. The idea is that a
class should completely encapsulate, or contain, all of the data and
logic surrounding the task. If other parts of the program need to
perform the task or something related to it, they should not try to
access the data directly. Instead, they should communicate with the
class in question, and it can access the data as necessary. If the class
has well-designed methods, other parts of the program
shouldn't need direct access to the internal data, they can rely on the
methods provided.

In this way, a major component encapsulation in programming


involves information hiding or controlling access to internal data.
3.1.2 Why Encapsulation Matters
At first glance, it may seem a little silly to hide information or restrict
access to parts of the code from other places of the program, but it
turns out to be critical for two main reasons:

 If something is broken, any code that has access might be to


blame.

 If something needs to change, any code that has access might


need to change.

Consider the following code.

public class Account


{
public int _balance = 0;

public void Deposit(int amount)


{
_balance = _balance + amount;
}
}

Account savings = new Account();


savings._balance = 50;
savings.Deposit(100);

What would happen if we decided to change the balance attribute in


the Account class to a list of transactions? On one hand, we'd be able
to keep track of individual deposits. On the other hand, we'd break a
different part of the program.
public class Account
{
public List<int> _transactions = new List<int>(); // if we change
this to a list...

public void Deposit(int amount)


{
transactions.Add(amount);
}
}

Account savings = new Account();


savings._balance = 50; // if we make the change above, this doesn't
work anymore!
savings.Deposit(100); // however, this approach would continue to work

In this case, the details of the Account class are not well
encapsulated. We need a way of hiding the class attributes so that
other code does not attempt to change them directly. If we can, it will
allow us to minimize the interdependencies between different parts of
our code and protect them from breaking changes.

3.1.3 Video example


Please watch the following video that highlights this example of
Encapsulation.

Direct Link: Encapsulation (6 minutes)

3.1.4 Using access modifiers


Some programming languages, like C#, use access modifiers, or
special keywords, to specify which attributes and methods are
public or private. Public class members are accessible from
anywhere in the program. Private class members are only accessible
by methods in the class that contains them. Other languages, like
Python, use coding conventions to indicate how a class member
should be treated.

In C#, Any class members that should be kept private or hidden from
other parts of the program should begin with the private keyword.
Any class members that should be available for use in other parts of
the program should begin with the public keyword. These are called
access modifiers.

public class Account


{
private List<int> _transactions = new List<int>();

public void Deposit(int amount)


{
_transactions.Add(amount);
}
}

Sometimes it's difficult to decide what class members should be


public or private. A good rule of thumb is to restrict access to
class members as much as possible.

Hiding information from who?


Keep in mind that when we talk about making data private or hiding
it, we are not talking about encrypting sensitive data like credit card
numbers to hide it from the user or from hackers. Instead, we are
limiting the parts of our program than can directly access a
variable. So we are hiding it from ourselves in other parts of
the program.

The idea is to limit access to only those parts of the code they really
need it.

3.1.4.1 Attributes
As a general rule, attributes (or member variables) should be
made private. Other classes should not know the details of how the
class stores its information. Instead, the other parts of the program
should ask the class to perform tasks related to that information
through public methods.

The following example shows how to declare private member


variables:
public class Person
{
private string _title;
private string _firstName;
private string _lastName;

...
}

3.1.4.2Methods
Many methods (or member functions) of a class are public. This is the
interface that other parts of the program can use to perform the tasks
they need.

Are there ever private methods? Yes! Often, a public method will have
internal steps or computations to perform to help it do its job. These
"helper functions" are often private, because the only code that needs
to access them is in the class.

As stated above, the general rule to follow is: restrict access as


much as possible. Only make an attribute or method public if
there is a specific need.
3.1.4.3 Example
The following example shows how to declare public and private
member functions. It gives examples of getting two kinds of email
signatures, one that is formal ("Sincerely"), and one that is informal
("Thanks"). The formal one makes use of the person's full name.

In order to get the full name from a class that stores the first and last
names separately, the class might make use of a private, helper
function to prepare the full name. This function could be made private
initially, because others only need access to the email signature. (If it
is later determined that others need access to the full name itself, you
could consider making it public as well. But in all cases you are
keeping the variables private.)

public class Person


{
private string _title;
private string _firstName;
private string _lastName;

public string GetInformalSignature()


{
return "Thanks, " + _firstName;
}

public string GetFormalSignature()


{
return "Sincerely, " + GetFullName();
}

private string GetFullName()


{
return _title + " " + _firstName + " " + _lastName;
}
...
}

3.1.5 Getters and setters


Sometimes you may feel that other parts of the program need access
to a member variable. If this is the case, instead of making the
variable public, you should create methods to get and set the value.
This ensures that the class still controls access to the variables and
that the variables themselves are hidden.

These functions are called "getters" and "setters" or accessors and


mutators, and they are very common.
The following example shows how to create a getter and setter for
the _firstName variable:

public class Person


{
private string _title;
private string _firstName;
private string _lastName;

public string GetFirstName()


{
return _firstName;
}

public void SetFirstName(string firstName)


{
_firstName = firstName;
}

...
}

This would then be called from another part of the program as follows:

Person p = new Person();


p.SetFirstName("Peter");

Console.WriteLine(p.GetFirstName());

Notice that the other part of the program now has the ability to set
the first name, and can also access it when needed, but it does so
by calling these methods, rather than interacting with the
variables directly.

3.1.6 On Getters and setters


Getters and setters are so common that many well known code
editors will automatically generate them for you. But they have also
been the subject of debate since at least 2003 when Allen Holub
published an article called, Why Getter and Setter Methods Are Evil.

While we encourage you to develop your own opinion we think Mr.


Holub's advice is sound. When you're programming with classes,
focus on what the class must do rather than how it will do it
and many of the getters and setters in your code will
naturally disappear. You simply won't have to worry about it.

C# Properties

Because the notion of getters and setters is so powerful and so common,


some languages, including C#, have created a special language construct
for them called, properties. These properties allow you to create getters
and setters that behave like methods, but can be used more like a variable.
You may see the syntax for these properties in code on the internet in a
manner such as public int Age { get; set; }.

In this course, we have deliberately decided to avoid teaching and using


these properties for two reasons. First, they are not available in all
languages. And second, they can cause confusion as you are just getting
started and give you the wrong mental model, because of the way they blur
the line between methods and variables. They almost start to feel like
magic, and give the impression that this is a good way to make public
member variables, and then you lose the very principle of encapsulation.

For all these reasons, as you get started with getters and setters, you are
encouraged to use the actual getter and setter methods. Then, as you get
more comfortable with them, it will be an easy switch for you to begin using
3.1.7 Constructors
In the previous lesson you were introduced to Constructors.
Constructors are special methods that are called
automatically when an object is created. Their purpose is to help
set up the initial state of an object. The name of a constructor must
match the class name, and the return type is left empty (not
even void). The simplest constructor is a no-argument constructor,
that allows an object to be created without specifying any extra
information.

Person p = new Person(); // This calls a no-argument


constructor and doesn't need any information

You can use this constructor to help set default values. For example,
the following code specifies a no-argument constructor to set a
default name for all new Person objects that are created.

public class Person


{
private string _title;
private string _firstName;
private string _lastName;

public Person()
{
_title = "";
_firstName = "Anonymous";
_lastName = "Unknown";
}

...

In addition to a no-argument constructor you might want to have


another one to allow the user to pass in the values for some of the
member variables. For example, the following code shows a class with
three constructors, one that doesn't require any information,
another that accepts values for the first and last names (but
not the title), and another that accepts values for all three
member variables.

public class Person


{
private string _title;
private string _firstName;
private string _lastName;

public Person()
{
_title = "";
_firstName = "Anonymous";
_lastName = "Unknown";
}

public Person(string first, string last)


{
_title = "";
_firstName = first;
_lastName = last;
}
public Person(string title, string first, string last)
{
_title = title;
_firstName = first;
_lastName = last;
}
...

These three constructors allow you to create a new person object in


any of those three ways:

Person p1 = new Person(); // Don't pass any information to


get the default values
Person p2 = new Person("Jane", "Doe"); // pass the first
and last names
Person p3 = new Person("Mrs.", "Jane", "Doe"); // pass all
three variables

If you don't specify any constructors, C# will provide an empty no-


argument constructor for you. However, if you specify another
constructor that does receive values, you will not have a default
constructor unless you explicitly create it. This is actually nice if you
want to force people to always pass in values when creating a new
object.

You can indicate constructors in your class diagram just like methods,
but without a return type. For example:
Person class
Diagram

3.1.8 Summary
Encapsulation is the second principle of programming with classes. A
key component of encapsulation is hiding or controlling access to
information. Careful use of access modifiers will help protect you and
your coworkers from breaking your programs.

But also remember that Encapsulation is more than just making


member variables private. Building on the principle of Abstraction,
Encapsulation is all about making sure that your classes define the
appropriate behaviors and then internally take care of the details
needed to carry out those behaviors. Well-designed classes make
careful use of constructors and provide meaningful methods for
anything that needs to be done, rather than simply exposing the
internal data with getters and setters.

The benefits don't stop there though. Practice encapsulation diligently


and your abstractions will become more refined, your objects more
purposeful, and your classes more understandable. Continue to work
at it, and over time, your programs will be vastly more flexible and
easy to change.

3.1.9 Activity instructions


Practice the principle of encapsulation by creating classes to hold a
fraction, such as 2/3. As you recall from your Math classes, a fraction
has a top number (numerator) and a bottom number (denominator).
The fraction can be expressed as two integers with a slash between
them, such as 3/4 or as a decimal, such as 0.75.

3.1.9.1 Design the Classes


You need to create a class for a fraction that has:

 Attributes for the top and bottom numbers


 Constructors

 Getters and setters for the top and bottom numbers

 Methods to return representations of both the fractional and


decimal views.

A class diagram for this class would then look as follows:

3.1.9.2 Start the


project
1. Open the class project in VS Code.

2. Navigate to the Learning03 project in the prepare folder. Find


the Program.cs file, which will be your entry point for the
program.

3. Verify that you can run the project.

3.1.9.3 Create the fraction class


1. Create a class to hold fraction.

2. The class should be in its own file.

3. The class should have two attributes for the top and bottom
numbers.
4. Make sure the attributes are private.

3.1.9.4 Create the constructors


1. Create the following constructors:

o Constructor that has no parameters that initializes the


number to 1/1.

o Constructor that has one parameter for the top and that
initializes the denominator to 1. So that if you pass in the
number 5, the fraction would be initialized to 5/1.

o Constructor that has two parameters, one for the top and
one for the bottom.

2. In your Program.cs file, verify that you can create fractions


using all three of these constructors. For example, create an
instance for 1/1 (using the first constructor), for 6/1 (using the
second constructor), for 6/7 (using the third constructor).

3.1.9.5 Create the getters and setters


1. Create getters and setters for both the top and the bottom
values.

2. In your Program.cs file, verify that you can call all of these
methods and get the correct values, using setters to change the
values and then getters to retrieve these new values and then
display them to the console.

3.1.9.6 Create methods to return the representations

1. Create a method called GetFractionString that returns the


fraction in the form 3/4.

2. Create a method called GetDecimalValue that returns


a double that is the result of dividing the top number by the
bottom number, such as 0.75.

3. Verify that you can call each constructor and that you can
retrieve and display the different representations for a few
different fractions. For example, you could try:

o 1

o 5

o 3/4

o 1/3
Sample Output

1/1
1
5/1
5
3/4
0.75
1/3
0.3333333333333333

3.1.10 Sample Solution


When you have finished please compare your approach to the
following sample solution (you may also use this sample solution as a
guide if you need help finishing).

 Learning Activity 03 Sample Solution.

3.2 Team activity: Designer


3.2.1 Discussing preparation learning activity
1. What part of the learning activity was the hardest for you?

Guidance from a Mentor

Remember:

 Every member variable should be private. Getters and Setters


should be used to access the data if necessary.

 Getters should not have any parameters and should not prompt
the user for anything, but instead, simply return a value.

 Setters should accept a single parameter and have


a void return type.

3.2.2 Review the Program Specification


Refer to the Scripture Memorizer program specification. As a team,
review the program requirements and how it is supposed to work.

1. What does the program do?

2. What user inputs does it have?

3. What output does it produce?

4. How does the program end?


Guidance from a Mentor

 The program can end in one of two ways: Either the user types
quit, or all of the words in the scripture have been hidden.

3.2.3 Determine the classes


The first step in designing a program like this is to think about the
classes you will need. When thinking about classes, it is often helpful
to consider the strong nouns in the program description.

1. What are good candidates for classes in this program?

2. What are the primary responsibilities of each class?

Guidance from a Mentor

The following are good choices for classes, listed with their
responsibilities:

 Scripture: Keeps track of both the reference and the text of the
scripture. Can hide words and get the rendered display of the
text.

 Reference: Keeps track of the book, chapter, and verse


information.

 Word: Keeps track of a single word and whether it is shown or


hidden.

Evaluate the Design

 You could consider creating a Hider class that has the


responsibility for hiding the words in the scripture. What would
be drawbacks of creating a Hider class instead of leaving that
responsibility to the Scripture and Word classes?

3.2.4 Define class behaviors


Now that you have decided on the classes, you will need and their
responsibilities, the next step is to define the behaviors of these
classes. These will become methods for the class.

Go through each of your classes and ask:

1. What are the behaviors this class will have in order to fulfill its
responsibilities? (In other words, what things should this
class do?)

Guidance from a Mentor


The key behaviors for the Scripture class are to hide random
words and also to get the display text as a string. (The "display
text" refers to the text with some words shown normally, and some
replaced by underscores.) It would also be nice to have a behavior to
check if the scripture is completely hidden so that you know when
to end the program.

The key behaviors for the Word class are to hide and show a word
and to check if a word is hidden or not. In addition, a Word should
have a behavior to get the display text of that word, which would be
either the word itself (for example, "prayer") or, if the word were
hidden, this behavior would return underscores (for example,
"______").

The Reference class is pretty simple as far as behaviors go. It should


have the ability to get the display text of the reference, which is
just a string combining the book, chapter, and verse (or verses). You
could consider having getters and setters for each of the data
elements that this class stores, but it may be even better to use a
constructor to set them. The constructor will be discussed in more
detail below.

Converting these ideas to concise method names gives us the


following (note that the variable types and return types are shown
after the : colon character):

 Scripture
o HideRandomWords(numberToHide : int) : void
o GetDisplayText() : string
o IsCompletelyHidden() : bool
 Word
o Hide() : void
o Show() : void
o IsHidden() : bool
o GetDisplayText() : string
 Reference
o GetDisplayText() : string
o Possible getters and setters

Evaluate the Design

 Which other methods should be called by


the Scripture class's HideRandomWords method to help do
its work?

Ramdom method
 What is a benefit of the Reference class containing its
own GetDisplayText method, instead of having the Scripture
class display the book chapter and verse directly?

3.2.5 Define class attributes


Now that you have defined the classes, their responsibilities, and their
behaviors, the next step is to determine what attributes the class
should have, or what variables it needs to store.

Go through each of your classes and ask:

1. What attributes does this class need to fulfill its behaviors? (In
other words, what variables should this class store?)

2. What are the data types of these member variables?

Guidance from a Mentor

The Scripture class will need member variables for a reference and
list of all of the words in the scripture. The data type for the reference
is Reference, the custom class defined above. The data type for the
list of words would be List<Word> (notice it is a list of Word objects,
rather than a list of strings.)

The Word class will need to store the text of the word itself (a string)
and a variable to indicate whether that word is shown or hidden (a
boolean).

The Reference class will need to store a variable for the book
(string), the chapter (int), and the verse (int). Then, it will also need to
store one additional variable for second, or "end," verse of the range
to handle the case of Proverbs 3:5-6.

The following shows all the member variables:

 Scripture
o _reference : Reference
o _words : List<Word>
 Word
o _text : string
o _isHidden : bool
 Reference
o _book : string
o _chapter : int
o _verse : int
o _endVerse : int

Evaluate the Design


 What is a benefit of the Scripture containing a list
of Word objects instead of a list of strings?

3.2.6 Define Constructors


Now that you have defined the classes, including their behaviors and
attributes, the next step is to think about the constructors that will be
used to create new instances of these classes. Remember that you
can create multiple constructors with different parameters to make it
easy to work with your classes.

Remember that constructors help set up the initial state of the object,
so you should consider what data is necessary for that initial state.

1. What constructors should each class have?

o In other words, what parameters should you pass in when


creating an object of that type.

2. What other work needs to be done to set up these objects?

o For example, does the constructor need to run code to


perform set up tasks, like creating lists, iterating through
variables, etc.

Guidance from a Mentor

A class for a Scripture will need a constructor that accepts both a


reference and the text of the scripture. If the Scripture class
internally stores a List of Word objects, the first thought would be to
pass a List<Word> variable to the constructor. While this could
work, it would have some downsides. First, it would expose the
internal storage of the Scripture to the person using the class (losing
the benefits of encapsulation). Second, it would require the person
using the class to do the work of splitting their text into the list, the
way this class expects it. Not only is this extra work, but it also breaks
the principle of encapsulation, and will limit your ability to change
your class in the future.

Instead of passing in a list of words, it would better align with the


principle of encapsulation to pass in a string that is the text of the
scripture. Then, the constructor would have the responsibility of
creating the list, and splitting up the words in the string to
create Word objects for each one and put them in the list.

While including the logic of creating the word list may seem like a lot
of work for the constructor, it is helpful to encapsulate this logic in
the Scripture class so that other code does not have to worry about
the internal storage of the Scripture. This would enable the program
to be easily changed in the future, if a different implementation
choice were made.

A class for a Word will need a constructor as well. This constructor


should accept the text of the word to save it as an attribute. In
addition, the constructor will need to set the initial visibility of the
word (whether it is shown or hidden). Notice that you should not need
to pass in the visibility of the word. It can be set to be visible by
default.

A class for a Reference should have two different constructors to


account for cases where there is a single verse or multiple verses.
Notice that you can have two different constructors as long as the
parameter list is different. The first constructor would just receive a
book, chapter, and verse, whereas the second would receive a book,
chapter, start verse and end verse. (This ability to have multiple
versions of a function, as long as the parameters are different is
called Function Overloading, and it is possible with any function not
just constructors.)

Evaluate the Design

 What is a benefit of passing the string of the verse text to


the Scripture constructor rather than a List of Word objects?

This would enable the program to be easily changed in the future,


if a different implementation choice were made.

It preserves the principle of encapsulation.

3.2.7 Review the Design


Take a minute to review your final design.

1. Are there any classes, methods, or variables, that you do not


understand?

Guidance from a Mentor

The following is a final class diagram for each of the classes that you
can use as a guide as you being writing your code.
3.2.8 Conclude
At this point, you have the design of the classes you will need for this
project. If your design is not "perfect," or it needs to change as you
begin working on the project, that is just fine! As you learn more
details, you will naturally need to adjust your planning. This is why the
principles of programming with class are so valuable, because they
allow your program to easily change.

At the end of your meeting:

1. Determine who will be the lead student for the next meeting.

2. After the Meeting: Start the code

After the team activity, each person needs to individually do the the
following:

1. Open the project in VS Code. Create new files that contain the
"stubs" or empty code for all the classes, member variables,
and functions in your design.

o At this point the body of the methods can be empty,


except for the necessary return statements.

o Each class should be in its own file and the name of the
file should match the class name.
2. Make sure that your program can build without errors.

3. Commit and push your code to your GitHub repository.

3. Submission

After completing this activity, Return to Canvas to submit two quizzes


associated with this activity:

1. The Evaluate the Design quiz

2. The Participation quiz

3.3 Scripture Memorizer


Overview

People often try to memorize poems or passages of scripture. One of


the challenges they encounter is that they want to hide the scripture
while they are practicing, but they may not be able to recite the
whole scripture from memory just yet.

To help solve this problem so that people can better memorize a


scripture, write a program that displays the full scripture and then
hides a few words at a time until the complete scripture is hidden.

Specification

Functional requirements

Your program must do the following:

1. Store a scripture, including both the reference (for example


"John 3:16") and the text of the scripture.

2. Accommodate scriptures with multiple verses, such as


"Proverbs 3:5-6".

3. Clear the console screen and display the complete scripture,


including the reference and the text.

4. Prompt the user to press the enter key or type quit.

5. If the user types quit, the program should end.

6. If the user presses the enter key (without typing quit), the
program should hide a few random words in the scripture, clear
the console screen, and display the scripture again. (Hiding a
word means that the word should be replace by underscores (_)
and the number of underscores should match the number of
letters in that word.)
7. The program should continue prompting the user and hiding
more words until all words in the scripture are hidden.

8. When all words in the scripture are hidden, the program should
end. (The final display of the scripture should show the scripture
with all words hidden.)

9. When selecting the random words to hide, for the core


requirements, you can select any word at random, even if the
word was already hidden. (As a stretch challenge, try to
randomly select from only those words that are not already
hidden.)

Design Requirements

In addition your program must:

1. Use the principles of Encapsulation, including proper use of


classes, methods, public/private access modifiers, and follow
good style throughout.

2. Contain at least 3 classes in addition to the Program class: one


for the scripture itself, one for the reference (for example "John
3:16"), and to represent a word in the scripture.

3. Provide multiple constructors for the scripture reference to


handle the case of a single verse and a verse range ("Proverbs
3:5" or "Proverbs 3:5-6").

Showing Creativity and Exceeding Requirements

Meeting the core requirements makes your program eligible to


receive a 93%. To receive 100% on the assignment, you need to show
creativity and exceed these requirements.

Here are some ideas you might consider:

 Think of other challenges that people find when trying to


memorize a scripture. Find a way to have your program help
with these challenges.

 Have your program work with a library of scriptures rather than


a single one. Choose scriptures at random to present to the
user.

 Have the program to load scriptures from a files.

 Anything else you can think of!

Report on what you have done to exceed requirements by adding a


description of it in a comment in the Program.cs file.
Video Demo

The following video demonstrates the way this program should work:

Direct link: Scripture Memorizer Demo (2 minutes)

Code Helps

You might find the following code helps useful in this project:

Clearing the Console

In the demo video, you can see that when the user pressed the enter
key, words on the screen "disappeared" or were replaced by
underscores. In reality, what happened is the console was cleared,
and then the scripture was printed out again, but this time with
underscores in place of certain words.

You can clear the console with the Console.Clear() method.


// This will start by displaying "AAA" and waiting for the
user to press the enter key
Console.WriteLine("AAA");
Console.ReadLine();

// This will clear the console


Console.Clear();

// This will show "BBB" in the console where "AAA" used to


be
Console.WriteLine("BBB");

Design

You will work with your team to create a design for this program.
Then, you will each write the code for the program individually.

For reference purposes, here is a copy of the design that was created
during the design activity.

In order to understand the decisions that led to this design, make sure
to walk through the design activity step by step before using this
design to start your code.
Develop the Program

In the course repository, find the Develop03 project in


the Prove folder and write your program there.

Submission

1. Develop the program using the principle of Encapsulation as


described above.

2. Make sure to describe anything you have done to exceed the


requirements in comments in the Program.cs file.

3. Commit your source code and push it to GitHub.

4. Verify that you can see your updated code at GitHub.

5. In Canvas, submit a link to your GitHub repository. In the


submission comment, describe anything you have done to show
creativity and exceed the core requirements.
Chapter 4 Reinforcing abstraction and
encapsulaption

4.1 Learning activity

Question 1
1 / 1 pts
What is the primary goal of abstraction in programming?

To simplify a component by removing the implementation details.

To ensure that code is duplicated every where it is needed.

To optimize the performance of code.

To make a component complex enough to contain all of the detail


necessary.

Question 2
1 / 1 pts
In object-oriented programming, abstraction is typically achieved
using:

Loops

Classes

Conditionals

Lists
Question 3
1 / 1 pts
What is the relationship between a class and an instance?

They are two words for the same concept.

Classes are like templates. Instances are the actual objects created in
memory, using that template.

Every custom class in a program is called an instance.

Instances are classes that relate to other classes.

Question 4
1 / 1 pts
Objects can contain other objects as member variables.

True

False

Question 5
1 / 1 pts
What is a method?

A member function of a class.

A custom class.

The instantiation of a class.

A member variable of a class.


Question 6
1 / 1 pts
What is encapsulation in object-oriented programming?

The technique of hiding the internal implementation details and


protecting the data.

The process of creating a new object from a class.

The ability to reuse code.

The technique of combining multiple methods into a single method.

Question 7
1 / 1 pts
When we talk about information hiding in a program, who are we
hiding it from?

The end user.

Potential hackers.

Other parts of the program.

Anyone on the internet.

Question 8
1 / 1 pts
Methods can call other methods.

True

False
Question 9
1 / 1 pts
Why might blindly creating getters and setters be a bad idea?

Because they are exposing the way the data is stored internally,
reducing the benefits of information hiding.

Because there are so many of them that they tend to clutter up a


program.

Because they are not typically used in code in industry.

Because they require so many unit tests to be created that they are
not helpful.

Question 10
1 / 1 pts
In C#, if you do not define any constructors what happens?

You will not be able to instantiate the object.

It will create a default, no-argument constructor for you.

The program will not compile.

You will only be able to create one object from the class.

4.2 Activity designer


Discuss the Foundation Programs

Discuss each of the Foundation programs:


 Foundation Program #1: Abstraction with YouTube Videos

 Foundation Program #2: Encapsulation with Online Ordering

For each program discuss the following:

1. What does the program do?

2. What are candidates for classes?

3. What are the responsibilities of each class?

Conclude

At this point, you have the beginning of a design for the classes you
will need for your programs. It is ok if your designs are not perfect or
need to change once you think about it more deeply.

4.3 Participation report


4.4 Foundation program #1 Abstraction

Overview

The first principle of Programming with Classes is Abstraction. For this


assignment, you will write a program that demonstrates your
knowledge of abstraction.

Scenario

Assume you have been hired by a company that monitors product


awareness by tracking the placement of their products in YouTube
videos. They want you to write a program that can help them work
with the tens of thousands of videos they have identified as well as
the comments on them.

Note: The YouTube example is just to give you a context for creating
classes to store information. You will not actually be connecting to
YouTube or downloading content in any way.
Program Specification

Write a program to keep track of YouTube videos and comments left


on them. As mentioned this could be part of a larger project to
analyze them, but for this assignment, you will only need to worry
about storing the information about a video and the
comments.

Your program should have a class for a Video that has the
responsibility to track the title, author, and length (in seconds) of the
video. Each video also has responsibility to store a list of comments,
and should have a method to return the number of comments. A
comment should be defined by the Comment class which has the
responsibility for tracking both the name of the person who made the
comment and the text of the comment.

Once you have the classes in place, write a program that creates 3-4
videos, sets the appropriate values, and for each one add a list of 3-4
comments (with the commenter's name and text). Put each of these
videos in a list.

Then, have your program iterate through the list of videos and for
each one, display the title, author, length, number of comments (from
the method) and then list out all of the comments for that video.
Repeat this display for each video in the list.

User Interaction

The focus of the Foundation programs is to help you design and build
the classes and work with the relationships among these classes. With
that in mind, you do not need to create a menu system or a user
interface. Instead, your Program.cs file should create the required
objects, set their values, and display them as specified, without any
user interaction.

Showing Creativity

Because the purpose of these Foundation programs is to help you


practice the principles of the course in a very direct way, you are not
expected to show creativity and exceed the core requirements the
way you have in previous projects. You can earn 100% by completing
the requirements as specified.

Develop the Program

In the course repository, find the Foundation1 project in the


foundation folder and write your program there.

Submission Instructions

Because this project does not have any user interaction, for
submission, you will include a screenshot of your program execution
in your GitHub repository alongside the corresponding code. (See
below for detailed instructions about capturing a screenshot.)

Once you have added your screenshot to your GitHub repository,


return to Canvas to submit a link to your GitHub repo.

Capturing a Screenshot

To capture and upload screenshot of the program execution, follow


these steps:

1. Run your program in VS Code.

2. Maximize your VS Code window and ensure entire


program execution is visible.

3. Capture screenshot.

o On Windows:

 Open Snipping Tool (Windows key + Shift + S).

 Select 'Fullscreen Snip' from context menu.

 Click on notification that appears.

 Select the Save icon in the upper-right of window,


select your Desktop folder, then click Save.

o On Mac:
 Capture screenshot with Command + Shift + 3
(screenshot will be automatically saved to your
Desktop).

4. Drag and drop screenshot from your Desktop to your VS Code


window, in the corresponding Foundation folder.

5. Commit and push changes to GitHub.

6. View your project on GitHub and verify the screenshot has been
added.

4.5 Foundation program #2 Encapsulation

Overview

The first principle of Programming with Classes is Encapsulation. For


this assignment, you will write a program that demonstrates your
knowledge of encapsulation.

Scenario

Assume you have been hired to help a company with their product
ordering system. They sell many products online to a variety of
customers and need to produce packing labels, shipping labels, and
compute final prices for billing.

Program Specification

Write a program that has classes for Product, Customer, Address,


and Order. The responsibilities of these classes are as follows:

Order

 Contains a list of products and a customer. Can calculate the


total cost of the order. Can return a string for the packing label.
Can return a string for the shipping label.

 The total price is calculated as the sum of the total cost of each
product plus a one-time shipping cost.

 This company is based in the USA. If the customer lives in the


USA, then the shipping cost is $5. If the customer does not live
in the USA, then the shipping cost is $35.

 A packing label should list the name and product id of each


product in the order.
 A shipping label should list the name and address of the
customer

Product

 Contains the name, product id, price, and quantity of each


product.

 The total cost of this product is computed by multiplying the


price per unit and the quantity. (If the price per unit was $3 and
they bought 5 of them, the product total cost would be $15.)

Customer

 The customer contains a name and an address.

 The name is a string, but the Address is a class.

 The customer should have a method that can return whether


they live in the USA or not. (Hint this should call a method on
the address to find this.)

Address

 The address contains a string for the street address, the city,
state/province, and country.

 The address should have a method that can return whether it is


in the USA or not.

 The address should have a method to return a string all of its


fields together in one string (with newline characters where
appropriate)

Other considerations

Make sure that all member variables are private and getters, setters,
and constructors are created as needed.

Once you have created these classes, write a program that creates at
least two orders with a 2-3 products each. Call the methods to get the
packing label, the shipping label, and the total price of the order, and
display the results of these methods.

User Interaction

The focus of the Foundation programs is to help you design and build
the classes and work with the relationships among these classes. With
that in mind, you do not need to create a menu system or a user
interface. Instead, your Program.cs file should create the required
objects, set their values, and display them as specified, without any
user interaction.

Showing Creativity

Because the purpose of these Foundation programs is to help you


practice the principles of the course in a very direct way, you are not
expected to show creativity and exceed the core requirements the
way you have in previous projects. You can earn 100% by completing
the requirements as specified.

Develop the Program

In the course repository, find the Foundation2 project in


the foundation folder and write your program there.

Submission Instructions

Because this project does not have any user interaction, for
submission, you will include a screenshot of your program execution
in your GitHub repository alongside the corresponding code. (For
detailed instructions about capturing a screenshot, see
the Foundation #1 program description.)

Once you have added your screenshot to your GitHub repository,


return to Canvas to submit a link to your GitHub repo.
Chapter 5 Inheritance

5.1 Learning
What is Inheritance?

Inheritance is the ability for one class to obtain the attributes and
methods of another class directly, without having to type them. It
follows the same idea of people inheriting certain characteristics from
their parents.

Consider two classes, a Person and a Student. A person may have a


certain set attributes and methods that all people share, such
as GetName(). A student is a person, so the student should have all
the properties and behaviors that a person does, but then a student
may have other more specific items, such as a student ID number,
which could be accessed via a GetNumber() method. In this case,
we could have the Student class inherit all Person class functionality,
and then add to it.

Consider the following code.

// a regular class called Person


public class Person
{
public string GetName()
{
return "Joseph";
}
}

// a class that inherits from Person


public class Student : Person
{
public string GetNumber()
{
return "0123456789";
}
}

// the student instance automatically has the GetName()


method!
Student student = new Student();
string name = student.GetName();
Console.WriteLine(name);

Output
Joseph

In this case, the Person class is known as a parent class.


The Student class is known as a child class. They are also
called base and derived or super and sub classes. It doesn't matter
what pair of terms you use as long as you understand the principle.

The syntax for specifying an inheritance relationship is different from


language to language but is always found in the declaration of the
child class. In C#, when defining the name of the class, you use a
colon followed by the name of the parent class. No other special
syntax is required.

A class diagram showing this relationship shows the base class on top
and the derived class beneath it. An arrow with an open arrowhead
goes from the derived class to the base class.

Class diagram showing inheritance

The real benefit of inheritance is demonstrated in the last part of the


example above. You are able to call the GetName method on an
instance of Student even though it is not defined in that class.
The Student class automatically got it by virtue of the inheritance
relationship with Person.

5.1.1 Super and Base


In some circumstances, it is helpful to be able to call methods in a
parent class from a child class. In C#, you use the base keyword.
Consider the following code:

// a parent class called Person


public class Person
{
private string _name;

public Person(string name)


{
_name = name;
}

public string GetName()


{
return _name;
}
}

// a child class called Student


public class Student : Person
{
private string _number;

// calling the parent constructor using "base"!


public Student(string name, string number) : base(name)
{
_number = number;
}

public string GetNumber()


{
return _number;
}
}

Student student = new Student("Brigham", "234");


string name = student.GetName();
string number = student.GetNumber();
Console.WriteLine(name);
Console.WriteLine(number);

Output
Brigham
234

In this example, the Student class inherits from the Person class.
The Student constructor calls the Person constructor using
the base keyword, and passes the name parameter through.

Note that base is not limited to constructors. We can use it anywhere


in the derived class methods, with dot notation, to invoke a behavior
in the parent class as the following example shows.
string number = base.GetName();
Console.WriteLine($"Student Number: {number}");

5.1.2 Accessing private data


In the example above, the Student inherits the member
variable _name from the base class, but because it is private, you
cannot access _name directly in methods defined in
the Student class. Consider a method for students
called, GetStudentInfo() that returns both the student's name and
id number. You may want to write something like the following:
public class Student : Person
{
private string _number;

...

public string GetStudentInfo()


{
// ERROR! This line doesn't work, because _name
is private in the base class
return _name + " " + _number;
}
}

There are two ways to fix this problem. The first is to create a getter
for the _name variable in the base class and then, in this method,
you could call the getter to access the value.

The other approach is to make the variable accessible to the derived


class. We have previously learned about public and private, but
there is another level in between them called protected. Member
variables and methods that are labeled as protected can be
accessed by methods in the class as well as by methods in derived
classes, but they cannot be accessed by code outside of these
classes.

So which is better?

Generally speaking, we should try to limit the access to variables as


much as possible, so because making a member
variable protected rather than private increases access to it, it can
open the door for more problems later. So it is usually better to leave
the variable private and use the getter. There are cases, however,
where this causes more problems than it helps and it makes sense to
make the variable protected and access it directly in the derived
class.

5.1.3 Substitution and Is-A Relationships


An important point to note with inheritance is that because a derived
class "is a" more specific version of a super class (for example, a
student "is a" person), not only does the derived class inherit all of
the traits and behaviors of the super class, but you should be able to
use the derived class anywhere you can use the super class.

For example, because a Student is a Person, any code that works


with a Person object should be able to work with a Student object
without breaking. This includes passing the Student object to
functions that expect a Person object, as well as putting
a Student object in a list of Person objects.

This concept of substitution will become even more important with


principle of Polymorphism, which is the topic of the next lesson.

Liskov Substitution Principle

The idea of being able to substitute a derived object in place


of an inherited type is formally called the Liskov Substitution
Principle, named after Barbara Liskov who introduced it at a
conference in 1987.

You might also note that the Liskov Substitution Principle is


the "L" of the popular SOLID design principles of object

5.1.4 Video demonstrations


Please watch the following videos that discuss these concepts in more
detail:

Inheritance (8 minutes) (Direct link)

Rule of thumbs:

- “is a”. Is a student a person?


- “Separate the things that change from the things that don’t”

Inheritance in C# (7 minutes) (Direct link)

Inheritance Details in C# (8 minutes) (Direct link)

5.1.5 A word of caution


Inheritance is a powerful principle that can save many hours of
coding. However, overusing it may lead to problems. Consider a long
inheritance chain of 10, 15, 20 or even more classes! It can be
extremely difficult and time consuming to inspect a long inheritance
hierarchy just to understand a single class at the bottom.

Patrick Wyatt, a long time game developer, wrote about this problem
in a blog post called, Tough times on the road to Starcraft. Inheritance
belongs in programs with classes. However, Mr. Wyatt's experience is
very instructive.

Opinions vary, but a good rule of thumb is to limit inheritance levels


to the average number of items a person can remember at once. For
most people, that means three or four. If you find yourself creating
more, stop and ask the question, "Do I actually need a different
abstraction?"

5.1.6 In summary
Inheritance is the third principle of programming with classes. The key
to understanding it is to remember that inheritance is mechanism for
code reuse. Instead of writing the same thing over and over again we
can simply inherit from one class to another.

Be careful though. As a certain uncle once said to his budding


superhero nephew, "with great power comes great responsibility!"
Discipline yourself in how you apply inheritance. Keep your
hierarchies shallow and manageable. You'll be able to add more
functionality in less time all while ensuring your program stays
maintainable.
5.1.7 Activity instructions
Practice the principle of inheritance by creating a base class and
derived classes.

For this activity, you will write classes to represent different kinds of
homework assignments. Consider the following example of Math and
writing assignments.

Math Assignments

A Math assignment may need to store the student's name, the topic
(for example, "Fractions"), the textbook section (for example, "7.3"),
and the problems from that section (for example, "3-10, 20-21").

The Math assignment should have a constructor that requires a value


for each of the items that it stores.

The Math assignment needs to provide a method to return a summary


of the assignment that contains the student's name and the topic,
and it also needs to provide a method to display the Math homework
list including the section number and the problems (for example,
"Section 7.3 Problems 8-19").

Writing Assignments

A writing assignment may need to store the student's name, the topic
(for example, "European History"), and the title of the assignment (for
example, "The Causes of World War II").

The writing assignment should have a constructor that requires a


value for each of the items that it stores.

The writing assignment needs to provide a method to return a


summary of the assignment that contains the student's name and the
topic, and it also needs to provide a method to get the writing
information which consists of the title and the student's name (for
example, "The Causes of World War II by Mary Waters").

Step 1 Design the classes

There are a number of things these classes have in common and a


number of differences. Using inheritance, you can separate the things
that change from the things that stay the same, putting the common
elements in a base class and the differing elements in a derived class.

Consider the following class diagram:


Class diagram without inheritance

From these diagrams you can see that


the _studentName and _topic attributes are the same in both
classes, and so is the GetSummary() method. Instead of duplicating
these items, you can create a base class that they both inherit from.

The following class diagram shows an approach that uses inheritance.


This is the approach you will use for this assignment.

Class diagram showing inheritance

Step 2 Star the project

1. Open the class project in VS Code.


2. Navigate to the Learning05 project in the prepare directory.
Find the Program.cs file, which will be your entry point for the
program.

3. Verify that you can run the project.

Step 3 Create the base class

1. Begin by creating a new file and a class for your


base Assignment class.

2. Add the attributes as private member variables.

3. Create a constructor for this class that receives a student name


and topic and sets the member variables.

4. Add the method for GetSummary() to return the student's


name and the topic.

5. Test your class by returning to the Main method in


the Program.cs file. Create a simple assignment, call the
method to get the summary, and then display it to the screen.

Sample Output
Samuel Bennett - Multiplication

Step 4 Create the MathAssignment class

1. Create a new file for the MathAssignment class.

2. Create this class and make sure to specify that it inherits from
the base Assignment class.

3. Add the attributes as private member variables. Make sure that


you do not create new member variables for the ones you
inherited from the base class.

4. Create a constructor for your class that accepts all four


parameters, have it call the base class constructor to set the
base class attributes that way.

5. Add the GetHomeworkList() method.

6. Test your class by returning to the Main method and creating a


new MathAssignment object and set its values. Make sure to
test both the GetSummary() and
the GetHomeworkList() methods.

Sample Output
Roberto Rodriguez - Fractions
Section 7.3 Problems 8-19

Step 5 Create the WritingAssignment class

1. Follow the same pattern as before by creating a new file for


the WritingAssignment class.

2. Create the class and set up the inheritance relationship.

3. Add the member variables and set up the constructor as you did
for the MathAssignment class.

4. Add the GetWritingInformation() method.

5. Notice that this method needs to access


the _studentName variable defined in the base class. Even
though WritingAssignment class inherited this attribute, it is
private, so you cannot access it directly in the derived class.

To get the data you need for the method you can either make the
variable protected in the base class, or you can create a
public GetStudentName method to return it.

6. Return to Main and test your new class.

Sample Output
Mary Waters - European History
The Causes of World War II by Mary Waters

Sample Solution

When you have finished please compare your approach to the


following sample solution (you may also use this sample solution as a
guide if you need help finishing).

 Learning Activity 05 Sample Solution.

5.2 Design activity


Review the program specification

Refer to the Mindfulness program specification. As a team, review the


program requirements and how it is supposed to work.

1. What does the program do?


It allows the user to choose between three mindfulness
activities and the time the user wants the activity to last. Then
the program provides the activity.

2. What user inputs does it have?

A number to choose an activity, the amount of time for the


activity to last.

3. What output does it produce?

According to the activity the program provides questions to


promote meditation or sequences of time to help the user to
breathe.

4. How does the program end?

The program ends with the user selecting the option “quit”.

Guidance from a Mentor

Looking at the menu for the program can be a good place to start.

Take the time to go through each activity and discuss the way that
activity should work. What does it require the user to type in? What
does it display to the user?

Determine the classes

The first step in designing a program like this is to think about the
classes you will need. When thinking about classes, it is often helpful
to consider the strong nouns in the program description.

1. What are good candidates for classes in this program?

2. What are the primary responsibilities of each class?

Guidance from a Mentor

The main components of this program are the activities. Recognizing


that they will all have some behaviors and attributes in common, it
makes sense to have a base class and then derived classes for each
specific kind of activity, such as:

 Activity (The base class that contains all shared functionality)

 BreathingActivity

 ReflectingActivity

 ListingActivity
Notice that these classes all pass the "is a" test, because a
Breathing activity is an activity, etc.

You might also to have a class to handle the menu and interaction, or
you might choose to handle this directly in your Main method in
the Program class.

Evaluate the Design

 What is a benefit of having a base Activity class, instead of


having only the three specific activity classes themselves?

It allows to have attributes and behaviors that will be used for


many classes in a single one and then inherit them to other
classes.

Define class behaviors

Now that you have decided on the classes, you will need and their
responsibilities, the next step is to define the behaviors of these
classes. These will become methods for the class.

Go through each of your classes and ask:

1. What are the behaviors this class will have in order to fulfill its
responsibilities? (In other words, what things should this
class do?)

Guidance from a Mentor

The biggest trick here is that if any behavior is used by all the
activities then you should include it in the base class.

For example, each of the following are common behaviors that should
be in the base class:

 Displaying the starting message

 Displaying the ending message

 Pausing while showing a spinner for a certain number of


seconds

 Pausing while showing a countdown timer for a certain number


of seconds

The following behaviors might be similar in name, but different in the


way they behave, so they would need to be defined separately for
each derived class: (As a side note, in the next unit you will learn an
even more clever way to handle methods like this.)
 Run the activity

Finally, there are behaviors for each activity that are completely
unique to that activity. For example, the ListActivity also needs to
provide behaviors for:

 Get a random prompt

 Get a list of responses from the user

The Reflecting activity needs to provide the following:

 Get a random prompt to show

 Get a random question about the prompt

 Display the prompt

 Display questions about the prompt and get answers

In addition, as you start to implement these behaviors, you might find


it beneficial to have other "helper" functions that are used internally
to perform part of the task of these behaviors. These become private
methods of the class.

Converting these ideas to concise method names gives us the


following:

 Activity
o DisplayStartingMessage() : void
o DisplayEndingMessage() : void
o ShowSpinner(seconds : int) : void
o ShowCountDown(second : int) : void
 BreathingActivity
o Run() : void
 ListingActivity
o Run() : void
o GetRandomPrompt() : string
o GetListFromUser() : List<string>
 ReflectingActivity
o Run() : void
o GetRandomPrompt() : string
o GetRandomQuestion() : string
o DisplayPrompt() : void
o DisplayQuestions() : void

Evaluate the Design


 Notice that all three of the derived classes contain a run
function. Why can it not be defined in the base class and
inherited?

 Can a derived class method call a base class method? For


example, can DisplayQuestions() in
the ReflectingActivity class call the ShowSpinner() method?
Why or Why not?

Define class attributes

Now that you have defined the classes, their responsibilities, and their
behaviors, the next step is to determine what attributes the class
should have, or what variables it needs to store.

Go through each of your classes and ask:

1. What attributes does this class need to fulfill its behaviors? (In
other words, what variables should this class store?)

2. What are the data types of these member variables?

Guidance from a Mentor

Once again, you need to think about the attributes that are in
common and include them in the base class. Then, each derived class
may have its own unique attributes as well.

Base class attributes should include:

 The activity name

 The description

 The duration in seconds

The Breathing Activity likely does not need any attributes, but the
listing activity should store a count of the number of items listed, and
a list of prompts to draw from. Similarly, the Reflecting Activity should
store a list of questions and a list of prompts to draw from.

The following shows all the member variables:

 Activity
o _name : string
o _description : string
o _duration : int
 BreathingActivity
o None needed
 ListingActivity
o _count : int
o _prompts : List<string>
 ReflectingActivity
o _prompts : List<string>
o _questions : List<string>

Evaluate the Design

 Notice that two of the three activity classes store a list of


prompts. What is a potential benefit of defining it in those
classes as apposed to including it in the base class and having
the activity that does not need it simply ignore it and leave it
empty?

Define Constructors

Now that you have defined the classes, including their methods and
attributes, the next step is to think about the constructors that will be
used to create new instances of these classes. Remember that you
can create multiple constructors with different parameters to make it
easy to work with your classes.

Remember, that constructors help set up the initial state of the


object, so you should consider what data is necessary for that initial
state.

1. What constructors should each class have?

o In other words, what parameters should you pass in when


creating an object of that type.

2. What other work needs to be done to set up these objects?

o For example, does the constructor need to run code to


perform set up tasks, like creating lists, iterating through
variables, etc.

Guidance from a Mentor

The base class will need to initialize all of its member variables. You
might require them to be passed in as parameters or you might have
a constructor that sets some/all to default values to be changed later.

Then, the derived class constructor may be able to set good values in
the base class even if you don't pass parameters to it. For example, a
constructor that has no parameters could look like this:
public ReflectingActivity()
{
_name = "Reflecting";
_description = "This activity will help you reflect
on times ...";
_duration = 50;

// Set other values here that are unique to the


Reflecting Activity
}

The code above shows the most simple and straightforward way to do
this and assumes the variables are protected (not private) in the base
class. You could also use setters or pass them to the base base class
constructor directly.

In addition to initializing the variables, the constructors for


the ListingActivity and the ReflectingActivity need to initialize the
list of prompts (and questions for the Reflecting activity) and populate
them with values.

Evaluate the Design

 What is a benefit to requiring parameters for a constructor,


instead of simply using the no-argument constructor and letting
people use setters later to set the values?

Review the Design

Take a minute to review your final design.

1. Are there any classes, methods, or variables, that you do not


understand?

Guidance from a Mentor

The following is a final class diagram for each of the classes that you
can use as a guide as you being writing your code.
Conclude

At this point, you have the design of the classes you will need for this
project. If your design is not "perfect," or it needs to change as you
begin working on the project, that is just fine! As you learn more
details, you will naturally need to adjust your planning. This is why the
principles of programming with class are so valuable, because they
allow your program to easily change.

At the end of your meeting:

1. Determine who will be the lead student for the next meeting.

After the Meeting: Start the code

After the team activity, each person needs to individually do the the
following:

1. Open the project in VS Code. Create new files that contain the
"stubs" or empty code for all the classes, member variables,
and functions in your design.

o At this point the body of the methods can be empty,


except for the necessary return statements.
o Each class should be in its own file and the name of the
file should match the class name.

2. Make sure that your program can build without errors.

3. Commit and push your code to your GitHub repository.

Submission

After completing this activity, Return to Canvas to submit two quizzes


associated with this activity:

1. The Evaluate the Design quiz

2. The Participation quiz

5.3 Prove: Developer – Mindfullness


5.3.1Problem Overview
We live in a fast-paced world full of stress and anxiety. We could each
benefit from taking time for mindfulness activities where we can
reflect and unwind.

Most people would agree that we should take more time to be


mindful, but relatively few of us do. Think to yourself for a moment
about some reasons that you think keep people from doing this. Could
a program or an app help with any of these reasons?

Some of the problems you considered may have included:

 We forget

 We get busy

 We think it will take too long, so we don't start

 We don't know where to begin. We know we should reflect on


something but don't know what to start with.

While it may not resolve all of the issues that keep people from taking
more time for reflection, a great program could help people by
providing structure and prompts to guide them through various
exercises.

5.3.2 Solution idea


Consider an app that provides three different kinds of mindfulness
opportunities. It could give some guidance and structure to users in
the following activities:

 Breathing Activity - Help the user pace their breathing to have a


session of deep breathing for a certain amount of time. They
might find more peace and less stress through the exercise.

 Reflection Activity - Guide the user to think deeply, by having


them consider a certain experience when they were successful
or demonstrated strength. Then, prompt them with questions to
reflect more deeply about details of this experience. They might
discover more depth than they previously realized.

 Listing Activity - Guide the user to think broadly, by helping


them list as many things as they can in a certain area of
strength or positivity. They might discover more breadth than
they previously realized.

The application could additional help the user keep track of the time
or frequency they spend in these activities and give them gentle
prompts and reminders.

The user interface of a program like this could be anything from a


Website or Mobile App to one that runs on a Smart Watch and it could
be done in many different kinds of colors, shapes, and styles.
Learning to write a program to solve the real-world problem is the
most critical part, so this assignment will focus on that, rather than
creating a flashy interface.

5.3.3 Specification
Write a program that provides the three activities described above. It
should help them work through these activities in stages using basic
forms of delay (animation or countdown).

5.3.4Functional requirements
Your program must do the following:

1. Have a menu system to allow the user to choose an activity.

2. Each activity should start with a common starting message that


provides the name of the activity, a description, and asks for
and sets the duration of the activity in seconds. Then, it should
tell the user to prepare to begin and pause for several seconds.
3. Each activity should end with a common ending message that
tells the user they have done a good job, and pause and then
tell them the activity they have completed and the length of
time and pauses for several seconds before finishing.

4. Whenever the application pauses it should show some kind of


animation to the user, such as a spinner, a countdown timer, or
periods being displayed to the screen.

5. The interface for the program should remain generally true to


the one shown in the video demo.

6. Provide activities for reflection, breathing, and enumeration, as


described below:

Breathing activity

1. The activity should begin with the standard starting message


and prompt for the duration that is used by all activities.

2. The description of this activity should be something like: "This


activity will help you relax by walking your through breathing in
and out slowly. Clear your mind and focus on your breathing."

3. After the starting message, the user is shown a series of


messages alternating between "Breathe in..." and "Breathe
out..."

4. After each message, the program should pause for several


seconds and show a countdown.

5. It should continue until it has reached the number of seconds


the user specified for the duration.

6. The activity should conclude with the standard finishing


message for all activities.

Reflection activity

1. The activity should begin with the standard starting message


and prompt for the duration that is used by all activities.

2. The description of this activity should be something like: "This


activity will help you reflect on times in your life when you have
shown strength and resilience. This will help you recognize the
power you have and how you can use it in other aspects of your
life."

3. After the starting message, select a random prompt to show the


user such as:

o Think of a time when you stood up for someone else.

o Think of a time when you did something really difficult.

o Think of a time when you helped someone in need.

o Think of a time when you did something truly selfless.

4. After displaying the prompt, the program should ask the to


reflect on questions that relate to this experience. These
questions should be pulled from a list such as the following:

o Why was this experience meaningful to you?

o Have you ever done anything like this before?

o How did you get started?

o How did you feel when it was complete?

o What made this time different than other times when you
were not as successful?

o What is your favorite thing about this experience?

o What could you learn from this experience that applies to


other situations?

o What did you learn about yourself through this


experience?

o How can you keep this experience in mind in the future?

5. After each question the program should pause for several


seconds before continuing to the next one. While the program is
paused it should display a kind of spinner.

6. It should continue showing random questions until it has


reached the number of seconds the user specified for the
duration.

7. The activity should conclude with the standard finishing


message for all activities.
Listing activities

1. The activity should begin with the standard starting message


and prompt for the duration that is used by all activities.

2. The description of this activity should be something like: "This


activity will help you reflect on the good things in your life by
having you list as many things as you can in a certain area."

3. After the starting message, select a random prompt to show the


user such as:

o Who are people that you appreciate?

o What are personal strengths of yours?

o Who are people that you have helped this week?

o When have you felt the Holy Ghost this month?

o Who are some of your personal heroes?

4. After displaying the prompt, the program should give them a


countdown of several seconds to begin thinking about the
prompt. Then, it should prompt them to keep listing items.

5. The user lists as many items as they can until they they reach
the duration specified by the user at the beginning.

6. The activity them displays back the number of items that were
entered.

7. The activity should conclude with the standard finishing


message for all activities.

5.3.5 Design requirements

In addition your program must:

1. Use inheritance by having a separate class for each kind of


activity with a base class to contain any shared attributes or
behaviors.

2. Avoid duplicating code in classes where it could instead be


placed in a base class.

3. Follow the principles of encapsulation and abstraction by having


private member variables and putting related items in the same
class.
5.3.6 Simplifications

For the core requirements you do not need to worry about the
following:

1. Your program does not need to track any statistics such as how
many times or how frequently the user has done an activity.

2. When getting random questions or prompts, you can just


choose a random one from the list. You don't have to worry
about if it was already chosen this session, or worry about
running out of prompts.

5.3.7 Showing creativity and exceeding requirements


Meeting the core requirements makes your program eligible to
receive a 93%. To receive 100% on the assignment, you need to show
creativity and exceed these requirements.

Here are some ideas you might consider:

 Adding another kind of activity.

 Keeping a log of how many times activities were performed.

 Make sure no random prompts/questions are selected until they


have all been used at least once in that session.

 Saving and loading a log file.

 Adding more meaningful animations for the breathing (such as


text that grows out quickly at first and then slows as they near
the end of the breath).

 Anything else you can think of!

Report on what you have done to exceed requirements by adding a


description of it in a comment in the Program.cs file.

5.3.8 Video demo

The following video demonstrates the way this program should work:

Direct link: Mindfulness Program Demo (4 minutes)


5.3.9 Code helps

You might find the following code helps useful in this project:

Pausing

In the demo video, you can see the program pausing for a certain
period of time. This can be done with the Thread.Sleep() method
which takes an integer as the number of milliseconds for the current
"thread of execution" to sleep or pause.

The following example shows how to make the computer to wait for 1
second (1000 milliseconds):

Console.WriteLine("Going to sleep for a second...");

Thread.Sleep(1000);

Console.WriteLine("I'm back!!");

Display Animations

To display an animation, such as the spinner or the countdown timer,


you need to have the computer pause for a period of time, and then
replace the previous character with a new one. This can be done by
writing the backspace character "\b" and which works like pushing
the left arrow. Then, you can write a new character over the top of it.

Because the backspace character works like pressing the left arrow,
instead of a backspace, it does not delete the character on the
screen. With this in mind, it is common to write "\b \b" which moves
left, writes a blank space over the previous character and then moves
left again so it is ready for your new character.

The following example shows how to overwrite a character after half a


second:
Console.Write("+");

Thread.Sleep(500);

Console.Write("\b \b"); // Erase the + character


Console.Write("-"); // Replace it with the - character
Working with Time

The C# language has a powerful Date and Time library. You might find
it useful to get the current time, add a number of seconds to it, and
then check if the current time is less than the new time.

This can be accomplished with the DateTime class. An object with


the current time can be obtained withe DateTime.Now . Then, it has
methods such as .AddSeconds(numberOfSeconds), and it works
with the less than < operator as you would expect.

The following code snippet shows an example:


DateTime startTime = DateTime.Now;
DateTime futureTime = startTime.AddSeconds(5);

Thread.Sleep(3000);

DateTime currentTime = DateTime.Now;


if (currentTime < futureTime)
{
Console.WriteLine("We have not arrived at our future
time yet...")
}

The follow video shows how to use these code snippets to achieve
basic display animations.

 Direct Link: Display Animations (13 minutes)

5.3.10 Design
You will work with your team to create a design for this program.
Then, you will each write the code for the program individually.

For reference purposes, here is a copy of the design that was created
during the design activity.

In order to understand the decisions that led to this design, make sure
to walk through the design activity step by step before using this
design to start your code.
5.3.11Develop the program
In the course repository, find the Develop05 project in
the Prove folder and write your program there.

5.3.12 Submission

1. Develop the program using the principle of Inheritance as


described above.

2. Make sure to describe anything you have done to exceed the


requirements in comments in the Program.cs file.

3. Commit your source code and push it to GitHub.

4. Verify that you can see your updated code at GitHub.

5. In Canvas, submit a link to your GitHub repository. In the


submission comment, describe anything you have done to show
creativity and exceed the core requirements.
Chapter 6 Polymorphism
6.1Learning activity
What is Polymorphism?

Polymorphism is the ability to take on many forms. In programming,


this principle is shown when one line of code can have different
behavior depending on the context.

Method Overriding

To see polymorphism in action with objects and inheritance, you first


need to learn about method overriding. Method overriding is the
ability of a child class to override, or change the behavior of, a
method that it inherited from a parent class. The method name stays
the same but the behavior, or the code to run is different.

An Example

When using inheritance, a derived class can inherit both member


variables and methods from a super-class. For example, a payroll
system might define an employee that had a name, tax id number,
address, and many other attributes. It may also have a method to
calculate the pay for that employee.

For a salary employee, perhaps the salary is just returned as shown in


this example:

// a parent class
public class Employee
{
private float salary = 100f;

public float CalculatePay()


{
return salary;
}
}

But if the payroll system also has to account for hourly employees
that get paid a certain amount of money based on the number of
hours they worked. These employees are very similar to the standard
employee class, but they need different logic for
the CalculatePay method. This could be defined in a child class that
overrides the method from the Employee class. To do this, we first
mark the method in the base class with the keyword virtual which
tells C# that this method is eligible for another class to override it.
Then, in the child class, we use the keyword override as shown in
this example:

// the parent class showing the "virtual" keyword included


public class Employee
{
private float salary = 100f;

public virtual float CalculatePay()


{
return salary;
}
}

// a child class
public class HourlyEmployee : Employee
{
private float rate = 9f;
private float hours = 100f;

public override float CalculatePay()


{
return rate * hours; // pay is calculated differently
}
}

Changing a behavior this way is called method overriding. Different


languages have slightly different syntax for overriding methods. In C#
you override the method using the keywords virtual and override in
the parent and child class methods as shown.

Notice that both Employees and HourlyEmployees have a method


for CalculatePay, so in that way they are the same. But the actual
behavior or code for the method is different.

6.1.1 A powerful combination


Inheritance and Method Overriding are a powerful combination. Used
together they provide a way to vary runtime behavior according to
the context.
Recall from the lesson on Inheritance that you should be able to use a
derived object anywhere you can use the base class (the Liskov
Substitution Principle). With this in mind, if you create a list
of Employee objects, you should be able to
insert HourlyEmployee objects into the list as well.

Review the following code carefully.

// Create a list of Employees


List<Employee> employees = new List<Employee>();

// Create different kinds of employees and add them to the


same list
employees.add(new Employee());
employees.add(new HourlyEmployee());

// Get a custom calculation for each one


foreach(Employee employee in employees)
{
float pay = employee.CalculatePay();
Console.WriteLine(pay);
}

Output:
100
900

In this example, a new instance


of Employee and HourlyEmployee are added to
the employees list. In the loop that follows,
the CalculatePay method is invoked for each one. The actual method
that is called and the resulting value depends on the context, or the
type of employee, during each iteration. If the object happens to be
an Employee the base method will be called. However, if the object
is an HourlyEmployee the version defined for hourly employees will
be used instead.

The significance of the last statement cannot be overstated. All it


takes to vary the behavior of the loop is to create new derivations
of Employee, override the CalculatePay method, and add an
instance to the list. None of the previously written code needs to be
modified in any way. Changing the program is easy!
6.1.2 Polymorphism in action
The previous code example shows polymorphism in action. Recall the
following line of code from that example:

float pay = employee.CalculatePay();

As stated, this exact same line of code can take on "many forms", or
more specifically, it will call different methods depending on the type
of the employee object encountered at run time.

Another example: parameter passing

In addition to seeing polymorphism used in the context of iterating


through a list of base class objects. You can see it in action by
passing an object to a method. Consider the following code:
public class Program
{
// ...

static void DisplayPayCheck(Employee e)


{
float pay = e.CalculatePay();
// ...
}
}

Notice that in this example, the DisplayPayCheck function has a


parameter of Employee. Again, we should be able to substitute any
derived class and have it work, so you could call the function with
an HourlyEmployee object, and it will work just fine. The
code e.CalculatePay() will call the correct method based on the
actual object at run time.

Another example: return values

Another common use of Polymorphism is that when the return type of


a method is a base class, you can also return objects of derived
classes. Consider the following code:

public class Program


{
// ...

static Employee GetManager()


{
// ... code here to find the manager ...
return theManager;
}

static void DisplayManagerPay()


{
Employee manager = GetManager();
float pay = manager.CalculatePay();
// ...
}
}

The code that determines the manager may return may end up
returning either a base class Employee object or it may return
an HourlyEmployee object. Regardless of the type of employee
returned, the manager.CalculatePay() code will call the appropriate
method.

6.1.3 Abstract methods


In the example above, the base class contained a default
implementation for the CalculatePay method that worked for base
employees. But sometimes, it is not possible to create a good default
method. For example, instead of having the base class represent a
Salary Employee and then the derived class is for the Hourly
Employee, you might define the base class for a generic Employee
with two derived classes. In this case, you couldn't provide a good
default implementation of the method in the base class, so you would
want to leave it blank.

A blank virtual method has a special name, it is called an Abstract


method. Any class that has at least one abstract method is
an Abstract class. This means that the base abstract class cannot
be directly instantiated, you can only create objects from the derived
types.

You specify abstract methods with the abstract keyword instead of


virtual. Then, the class definition must also contain
the abstract keyword. For example:
// the parent class showing the "virtual" keyword included
public abstract class Employee
{
private string _employeeName;
// Notice the abstract method doesn't have a body at all
(not even an empty one)
// and it is followed by a semicolon.
public abstract float CalculatePay();
}

// a child class
public class SalaryEmployee : Employee
{
private float salary = 100f;

public override float CalculatePay()


{
return salary;
}
}

// a child class
public class HourlyEmployee : Employee
{
private float rate = 9f;
private float hours = 100f;

public override float CalculatePay()


{
return rate * hours; // pay is calculated differently
}
}

6.1.4 It is all about the interface

The most important aspect of the previous example is the shared


method called CalculatePay. It is a formal contract that
all Employee derivations, no matter what their specific type, will
provide the same capability, namely a method with the
name CalculatePay and in this case, no parameters, and a return
value of a float. That guarantee is relied on by any other parts of the
program that use Employees of any kind.

Take a moment and cast your mind back to the second principle of
programming with classes. One of the more important aspects of
applying encapsulation was to focus on what a class must do rather
than how it will do it. The same advice applies here.

Interfaces
Abstract methods give us a way to specify that a method must be
present in derived classes without providing a default
implementation. This idea is so powerful many times all we want to do
is define the public methods that a derived class must have--we do
not even want to provide any member variables or method bodies in
the base class.

A base class that only contains these abstract methods and nothing
else has a special name, it is called an Interface because it defines
the interface or public methods that any classes that implement it
must have. In this case, you define the "class" as an interface, and
then, you don't have to specify that the methods are abstract or
virtual or even public, because all of these things are implied.
Consider the following code:

// the Employee interface


// The C# convention is that interface names begin with an
I
public interface IEmployee
{
float CalculatePay(); // interface method does not have a
body
}

// a specific implementation of the Employee interface


public class SalariedEmployee : IEmployee
{
private float salary = 100f;

public float CalculatePay()


{
return salary;
}
}

// another implementation of tbe Employee interface


public class HourlyEmployee : IEmployee
{
private float rate = 9f;
private float hours = 100f;

public float CalculatePay()


{
return rate * hours;
}
}

So which should you use, an Abstract class or an Interface?


The answer depends on whether your base class will have any
member variables or method bodies. If you want to provide
those, then you should create an abstract class. If your base
class is only there to define the methods that should be
overridden, then you should use an Interface.

6.1.5 Video example


Please watch the following example of how to use Polymorphism in
C#.

Direct Link: Polymorphism in C# (17 minutes)

6.1.6 In Summary

Polymorphism is the fourth and crowning principle of programming


with classes. Skillful use of abstraction, encapsulation and inheritance
are all required to apply polymorphism effectively. The result is a
simple but powerful mechanism for ensuring that programs are
flexible and ready for change.

One of the recurring themes through all of this has been the
importance of focusing on class contracts or the interface. Identifying,
defining and developing them are of prime concern for those who
practice programming with classes on a regular basis.

6.2 Learning Activity instructions


Practice the principle of polymorphism by writing a program that
computes the areas of different shapes cut out of pieces of paper.

For all shapes, you need to keep track of the color of the paper and
then have a method to compute the area. The area should not be
stored as a member variable, but instead, you should store the length
of the shapes sides and then compute the area as needed.

Your program should include squares (which store a color and a single
side), rectangles (which store a color and two sides), and a circle
(which store a color and a radius). You should create several kinds of
shapes and put them into a single list. Then, iterate through the list
and display their areas.

Step 1: Design the Classes

Based on what you learned in inheritance, it seems reasonable to


create a base shape class where you can include any responsibilities
that all shapes have in common. Then you can create derived classes
for the individual square, rectangle and circle shapes.

In this example all shapes have a color and a method to get the area,
but the implementation of that method will be different for each kind
of shape. Thus, the GetArea method should be declared in the base
class, but you should override it in the derived classes.

These relationships can be seen with the following class diagram:

Shape class diagram

Step 2: Start the Project

1. Open the class project in VS Code.

2. Navigate to the Learning06 project in the prepare folder. Find


the Program.cs file, which will be your entry point for the
program.

3. Verify that you can run the project.

Step 3: Create the base Shape class


1. In a new file, create the Shape class.

2. Add the color member variable and a getter and setter for it.

3. Create a constructor that accepts the color and set its.

4. Create a virtual method for GetArea().

Step 4: Create the Square class

1. In a new file, create the Square class.

2. Make sure this class inherits from the base class.

3. Create a constructor that accepts the color and the side, and
then call the base constructor with the color.

4. Create the _side attribute as a private member variable.

5. Override the GetArea() method from the base class and fill in
the body of this function to return the area.

Step 5: Test the Square class

1. Return to the Main method in Program.cs to test your code.

2. Create a Square instance, call


the GetColor() and GetArea() methods and make sure they
return the values you expect.

Step 6 Create the Rectangle and Circle classes

1. Repeat the steps above for the Rectangle and Circle classes,
putting them each in their own files, storing the necessary
variables, and overriding the GetArea() for each.

2. Test these classes back in Main and make sure they work as
expected.

Step 7 Build a List

1. In your Main method, create a list to hold shapes (Hint: The


data type should be List<Shape>).

2. Add a square, rectangle, and circle to this list.

3. Iterate through the list of shapes. For each one, call and display
the GetColor() and GetArea() methods.

Sample Solution

When you have finished please compare your approach to the


following sample solution (you may also use this sample solution as a
guide if you need help finishing).
 Learning Activity 06 Sample Solution.

Submission

1. Verify that each of your classes works as described above.

2. Commit and push your code to your GitHub repository.

3. Verify that you can see your updated code at GitHub.

4. Submit the Canvas quiz to report on your work.

You might also like