0% found this document useful (0 votes)
65 views276 pages

Book Corecpp

Uploaded by

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

Book Corecpp

Uploaded by

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

Core

Computer Science
Concepts

Summer 2024
CS 200: Concepts of Programming using C++
(Summer 2024 version)

Rachel Wil Sha Singh

July 15, 2024

Contents

1 Navigating this course 4


1.1 Recommended Summer 2024 schedule . . . . . . . . . . . . . . . 6

2 Reference 7
2.1 C++ quick reference . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Basic computer skills . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3 Common C++ bugs and issues . . . . . . . . . . . . . . . . . . . 17
2.4 Code and UI style guide . . . . . . . . . . . . . . . . . . . . . . . 23
2.5 How to use VSCode . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.6 How to install Git . . . . . . . . . . . . . . . . . . . . . . . . . . 41

3 Syllabus 43
3.1 Course information . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.2 Course policies . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.3 Additional information . . . . . . . . . . . . . . . . . . . . . . . . 52
3.4 Course catalog info . . . . . . . . . . . . . . . . . . . . . . . . . . 54

4 Notes - Questions to answer for review 58


4.1 Unit 00: Setup - Using the terminal . . . . . . . . . . . . . . . . 58
4.2 Unit 02: C++ Basics - Variables, pointers, input, and output . . 59
4.3 Unit 03: Functions . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.4 Unit 05: Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.5 Unit 07: Looping . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.6 Unit 08: Arrays and vectors . . . . . . . . . . . . . . . . . . . . . 64
4.7 Unit 09: Branching . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.8 Unit 13: Classes and Inheritance . . . . . . . . . . . . . . . . . . 68
4.9 Unit 14: Strings and FIle I/O . . . . . . . . . . . . . . . . . . . . 70

5 Reading 72
5.1 Unit 00: Welcome and setup . . . . . . . . . . . . . . . . . . . . . 72
5.2 Unit 01: Tech Literacy: Exploring computers . . . . . . . . . . . 78
5.3 Unit 02: C++: Variables, pointers, input, and output . . . . . . 93
5.4 Unit 03: C++: Functions . . . . . . . . . . . . . . . . . . . . . . 115
5.5 Unit 04: Tech Literacy: Debugging, testing, and researching . . . 131
5.6 Unit 05: C++: Structs . . . . . . . . . . . . . . . . . . . . . . . . 139

2
5.7 Unit 06: Tech Literacy: Careers in tech . . . . . . . . . . . . . . 145
5.8 Unit 07: C++: Looping . . . . . . . . . . . . . . . . . . . . . . . 153
5.9 Unit 08: C++: Arrays and vectors . . . . . . . . . . . . . . . . . 166
5.10 Unit 09: C++: Branching . . . . . . . . . . . . . . . . . . . . . . 182
5.11 Unit 10: C++: Searching and sorting . . . . . . . . . . . . . . . 190
5.12 Unit 11: Tech Literacy: Current trends in tech . . . . . . . . . . 200
5.13 Unit 12: Tech Literacy: Object Oriented Programming . . . . . . 207
5.14 Unit 13: C++: Classes and Inheritance . . . . . . . . . . . . . . 213
5.15 Unit 14: C++: Strings and File I/O . . . . . . . . . . . . . . . . 239
5.16 Unit 15: Tech Literacy: Ethics in tech . . . . . . . . . . . . . . . 254
5.17 Unit 16: C++: Intro to recursion . . . . . . . . . . . . . . . . . . 255
5.18 End of the semester . . . . . . . . . . . . . . . . . . . . . . . . . 267

6 Nonogram puzzles 270


6.1 Puzzle A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
6.2 Puzzle B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
6.3 Puzzle C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
6.4 Puzzle D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
6.5 Puzzle E . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
6.6 Puzzle F . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

Rachel Wil Sha Singh's Core C++ Course © 2024 by Rachel Wil Sha Singh
is licensed under CC BY 4.0. To view a copy of this license, visithttp://
creativecommons.org/licenses/by/4.0/

ˆ Digital textbooks: https://moosadee.gitlab.io/courses/


ˆ These course documents are written in emacs orgmode and the les can
be found here: https://gitlab.com/moosadee/courses
ˆ Dedicated to a better world, and those who work to try to create one.

3
1 Navigating this course

Resources used in this class:


ˆ Canvas LMS (https://canvas.jccc.edu/) During this course we will
be using Canvas LMS to organize the course content.
ˆ Git source control software (https://git-scm.com/) We will be uti-
lizing Git to backup and manage your code. Your code will be hosted
on GitLab's servers and both of us will have the repository (code) on our
computers, making it easier to work together (sometimes I add notes, and
I add additional assignments as the semester goes on).

ˆ GitLab source hosting (https://gitlab.com/) Students will be using


GitLab for storing their assignment source code. (Setup information will
be in Unit 00: Welcome and setup).

ˆ VS Code IDE (https://code.visualstudio.com/) We will be using


VS Code as our IDE throuhgout this class. If you have another IDE you
prefer you are free to use it, but I'll be teaching using VS Code because
it is available for Windows, Linux, and Mac.

ˆ Class readings will be in this textbook, with links to additional slides


and videos provided on Canvas.

 Course homepage: https://moosadee.gitlab.io/courses/


 Archived video lectures: https://www.youtube.com/@professorrwssingh960/
playlists
 Slides repo: https://gitlab.com/rachels-courses/webpage/

Using this textbook:


I hope that you will take notes in this book - answer the review questions,
scribble in the margins, draw moustaches on the art. Keep this book as a
reference for your future classes and when you need to review C++. Use it as
your go-to place for everything you need to know for this class.

Contacting the instructor:

4
ˆ The best way to contact me is via the in-Canvas email system, not through
@jccc email.

ˆ I also have a Discord char server for their classes, feel free to join in order
to ask questions. The join link is here: https://discord.gg/A2mgwrUeAj
ˆ We can also schedule time to meet on campus or via Zoom based on your
availability.

ˆ Since this is an 8 week class I would recommend reaching out as soon as


you need help with something rather than waiting.

Unlocking content in this class:

ˆ Class content is segmented into Modules on Canvas. A set of modules


will be unlocked and available to start with, and to unlock further content
in the class you need to pass the Mastery Check module every-so-often.
ˆ The Mastery Check milestone contains an exam and a project. The project
needs to be submitted and the mastery check you need to score at least
70% on to unlock the next set of items.

ˆ You can retake the exams but you need to email me in order for me
to unlock the exam for you. Exams are built randomly from a pool of
questions.

ˆ Since this is the summer semester you will need to gure out a schedule
of how many modules you want to tackle per week. I have a suggested
schedule a little later on.

 We have 8 weeks and 16 modules, though module size varies.


ˆ The last day of class in Summer 2024 is Thursday, July 25th, so all
assignments must be in by this time.

ˆ Most assignments can be redone for an improved grade as well.


ˆ See the Syllabus chapter in this book for more details about the course.

5
1.1 Recommended Summer 2024 schedule
This schedule is recommended, but the modules are available whenever you
meet the prerequisites for any of them.

Week # Monday Topics


1 June 3 Unit 00: Welcome and setup
Unit 01: Tech Literacy: Exploring computers
Unit 02: C++: Variables, input, and output
2 June 10 Milestone: Mastery Check 1
Unit 03: C++: Functions
Unit 04: Tech Literacy: Debugging and researching
3 June 17 Milestone: Mastery Check 2
Unit 05: C++: Structs
Unit 06: Tech Literacy: Careers in tech
4 June 24 Unit 07: C++: Looping
Unit 08: C++: Arrays and vectors
5 July 1 Milestone: Mastery Check 3
Unit 09: C++: Branching
Unit 10: C++ Searching and sorting
6 July 8 Unit 11: Tech Literacy: Current trends in tech
Unit 12: Tech Literacy: Object Oriented Programming, UML
Unit 13: C++: Classes and inheritance
7 July 15 Milestone: Mastery Check 4
Unit 14: C++: Strings and File I/O
Unit 15: Tech Literacy: Ethics in tech
8 July 22 Unit 16: C++: Intro to recursion

6
2 Reference

2.1 C++ quick reference


C++ basics
ˆ Starter C++ program:

// WITHOUT ARGUMENTS // WITH ARGUMENTS


int main() int main( int argCount, char* args[] )
{ {
return 0; return 0;
} }

ˆ Declare a variable: DATATYPE VARIABLENAME;

int myNumber; string myString; float myFloat;

ˆ Declare a variable and initialize it: DATATYPE VAR = VALUE;

int myNumber = 10; string myString = "Hello!"; float myFloat = 9.99;


char myChar = 'a'; bool myBool = true;

ˆ Declare a named constant: const DATATYPE NAME = VALUE;

const int NUMBER = 10; const string STATE = "Missouri";

ˆ Assign a value to a variable that has already been declared: VAR = VALUE;

myNumber = 100; myString = "Goodbye";

ˆ Copy a value from one variable to another: RECEIVER = COPYME;

vipStudent = student3;

ˆ Output text to the console: cout << ITEM << ITEM << endl;
 You can mix variables (VAR) and string literals ("HI"), as long as the
stream operator << is between each item.

ˆ Get input from the keyboard and store it in a variable: cin >> VAR;
ˆ Get a full line of text and store in a string: getline( cin, VAR );
 Only works with string variables.
 Note that if you have a cin >> statement immediately before the
getline statement, your input will get skipped. In this case you need
to add a cin.ignore() statement:

cin >> myNumber;


cin.ignore();
getline( cin, myString );

7
Branching
ˆ If statements:

// IF STATEMENT // IF/ELSE STATEMENT


if ( a == 1 ) if ( a == 1 )
{ {
// Executes when a == 1 // Executes when a == 1
} }
else
{
// Executes when a != 1
}

// IF/ELSE IF STATEMENT // IF/ELSE IF/ELSE STATEMENT


if ( a == 1 ) if ( a == 1 )
{ {
// Executes when a == 1 // Executes when a == 1
} }
else if ( a == 2 ) else if ( a == 2 )
{ {
// Executes when a != 1 // Executes when a != 1
// and a == 2 // and a == 2
} }
else
{
// Executes when a != 1
// and a != 2
}

 If: If the condition evaluates to true, then execute the code within
the if statement. Otherwise, skip that code completely.

 If/else: If the condition from if statement results to false, then the


code in the else case is executed instead. No condition is written with
the else case.

 If/else if statement: Checks each condition in order. If one is true,


then subsequent else if statements are ignored.

 If/else if/else statement: Similar to above, but if all if and else


if statements are false, then else is executed.

8
Switch statements
ˆ Switch statement: switch( VARIABLE ) { case VALUE: break; }
 The switch variable can be int, char, but not string.

switch( myNumber )
{
case 1: cout << "It's one!" << endl; break;
case 2: cout << "It's two!" << endl; break;
default: cout << "I don't know what it is!" << endl;
}

Looping
ˆ Conditional loops:

// WHILE LOOP // DO...WHILE LOOP


while ( a < b ) do
{ {
cout << a << endl; cout << "Enter a number: ";
a++; cin >> input;
} } while ( input < 0 || input > max );

 Looping with While Loops: while ( CONDITION ) { }


* Runs 0 or more times, depending on whether the CONDITION
is true.

 Looping with Do. . . While Loops: do { } while ( CONDITION );


* Runs at least once and then continues looping if the condition is
true.

ˆ For loops:

// TRADITIONAL FOR LOOP // RANGE-BASED FOR LOOP


for ( int i = 0; i < 10; i++ ) vector<int> myVec = { 1, 2, 3, 4 };
{ for ( int element : myVec )
cout << i << endl; {
} cout << element << endl;
}

 Traditional for loops: for ( INIT; CONDITION; UPDATE ) { }


* Iterate some amount of times through the loop based on your
counter variable and range.

 Range-based for loops: for ( INIT : RANGE ) { }


* Iterates over all elements in a collection. Only moves forward,
doesn't give access to index

9
Arrays
ˆ Declare a traditional C-style array: DATA_TYPE ARRAY_NAME[SIZE];
 When declaring a vanilla array, you need to set its size. You can
either hard-code the size with a number or use a named constant.

ˆ Declare an STL array object: array<DATA_TYPE, SIZE> ARRAY_NAME;


 Remember that you will need #include <array> at the top of your
le to use the array object.

 Use the array documentation (https://cplusplus.com/reference/


array/array/) for info on its functions.

ˆ Declare an STL vector object: vector<DATA_TYPE> VECTOR_NAME;


 Use the vector documentation (https://cplusplus.com/reference/
vector/) for info on its functions.

ˆ Initialize array/vector with an initializer list:

vector<string> cats3 = { "Kabe", "Luna", "Pixel", "Korra" };

ˆ Iterate over an array/vector:

// STL Array and STL Vector:


for ( size_t i = 0; i < bankBalances.size(); i++ )
{
cout << "index: " << i << ", value: " << students[i] << endl;
}

 size_t is another name for an unsigned int, which allows values of


0 and above - no negatives.

File input and output


ˆ Reading and writing with ifstream and ofstream:

// WRITE OUT TO A TEXT FILE // READ IN FROM A TEXT FILE


ofstream output; ifstream input;
output.open( "file.txt" ); input.open( "file.txt" );
if ( input.fail() )
// Write to text file {
output << "Hello, world!"; cout << "ERROR!" << endl;
}
string buffer;

// read a word
input >> buffer;

// read a line
getline( input, buffer );

10
ˆ Create an output le and write with ofstream (output le stream)

ˆ Create an input le and read with ifstream (input le stream)

 INFILE >> VAR; to read one word at a time


 getline( INFILE, VAR ); to read one line at a time
ˆ Make sure to have #include <fstream> in any les using ifstream or
ofstream!

ˆ Prevent le duplication with File Guards: When creating .h/.hpp les,
it is important to include these lines to prevent le duplication, which
happens if you #include this le in more than one place.

#ifndef _FILENAME_H // LABEL SHOULD BE UNIQUE FOR EACH .h FILE!


#define _FILENAME_H

// Code goes here

#endif

ˆ Function declaration: A function declaration contains the function header


and no body. It declares that the function exists and will be dened
elseware.

// NO output return // int output return


// NO input parameters // two int input parameters
void DisplayMenu(); int Sum(int a, int b);

ˆ Function denition: A function denition denes how the function op-


erates. It includes the function header and a function body, which has
commands in it.

void DisplayMenu() int Sum(int a, int b)


{ {
cout << "1. Deposit" << endl; return a + b;
cout << "2. Withdraw" << endl; }
cout << "3. Quit" << endl;
}

ˆ Calling a function: Calling a function requires invoking the function's


name and passing in any arguments.

DisplayMenu();

int result = Sum( 1, 2 ); // Passing in literal values

int num1 = 2;
int num2 = 5;
int result = Sum( num1, num2 ); // Passing in variable values

11
Classes
ˆ Declaring a class: Remember that classes must end with ; on their closing
curly brace!

// EXAMPLE // STUDENT CLASS


class CLASSNAME class Student
{ {
public: public:
// Constructor functions
Student();
protected: Student( string new_name, float new_gpa );

// Member functions
private: void Setup( string new_name, float new_gpa );
void Display();
};
private:
// Member variables
string name;
float gpa;
};

ˆ Dening a class member function (method): RETURNTYPE CLASSNAME::FUNCTIONNAME(


PARAMETERS )
 A class' member functions must be declared within the class decla-
ration. Then, you dene the member function within a .cpp le.

// Function definition
void Student::Setup( string name, float gpa )
{
m_name = name;
m_gpa = gpa;
}

12
ˆ Getter function, aka Accessor:

 Doesn't take in any inputs (parameters)

 Returns the value of the member variable (return type should match
the member variable)

 Getter functions can be good for formatting data before returning it

// Basic getter function // Example of formatting before returning data


float Student::GetGPA() string Person::GetFullName()
{ {
return m_gpa; return m_lastname + ", " + m_firstname;
} }

ˆ Setter function, aka Mutator:

 Takes in an input value for a new value for the member variable -
parameter should have the same data type as the member variable

 Doesn't return any data - void return type

 Setter functions should include any needed error checking and reject
invalid data

// Basic setter function // Example of data validity check


void Student::SetGPA( float newGpa ) void Student::SetGPA( float newGpa )
{ {
m_gpa = newGpa; if ( newGpa < 0 || newGpa > 4 )
} {
cout << "Error! Invalid GPA!" << endl;
return; // Return without saving data
}
else
{
m_gpa = newGpa;
}
}

Pointers
ˆ Declare a pointer: DATATYPE* PTRNAME = nullptr;
ˆ Assign an address to a pointer: PTRNAME = &VARIABLE;
 Pointer variables store addresses as their value. To get the address
of a variable, prex the variable name with the address-of operator
&.
ˆ Dereference a pointer: *PTRNAME
ˆ Dereference an object pointer and access a member variable: PTRNAME->MEMBER

// DECLARING POINTERS
int * ptrInt = nullptr;
string * ptrString = nullptr;

13
// SETTING POINTERS TO ADDRESSES
string name = "Bob"; // Normal variable
string * ptrName = &name; // Pointer

// DEREFERENCING POINTERS
cout << *ptrName; // Display contents that pointer is pointing to
cin >> *ptrName; // Overwrite contents that pointer is pointing to

// POINTERS TO OBJECTS
Student* newStudent = new Student;
newStudent->name = "Hikaru";
cout << "Student name: " << newStudent->name << endl;

// CHECKING IF POINTER IS SAFE


if ( ptrName != nullptr )
{
// Pointer is safe to use...
}

ˆ Allocate memory for a single variable: DATATYPE* PTRNAME = NEW DATATYPE;


ˆ Deallocate memory of a single variable: DELETE PTRNAME;
ˆ Allocate memory for an array: DATATYPE* PTRNAME = new DATATYPE[
SIZE ];
ˆ Deallocate memory of an array: DELETE [] PTRNAME;

// ALLOCATE MEMORY // DEALLOCATE MEMORY


// FOR A SINGLE VARIABLE // FOR A SINGLE VARIABLE
int * num = new int; delete num;
Node* newNode = new Node; delete newNode;

// ALLOCATE SPACE FOR AN ARRAY // DEALLOCATE SPACE FOR AN ARRAY


int * numList = new int[100]; delete [] numList;
Node* nodeList = new Node[10]; delete [] nodeList;

14
2.2 Basic computer skills
ˆ How to take a screenshot:
In Windows Press PRINTSCREEN on your keyboard, then go to an
image editing application (Paint, if you have nothing else) and use
EDIT > PASTE to paste the image in.

In Mac CTRL+Z, COMMAND+SHIFT+3 to take a screenshot in Mac

ˆ Identifying le extensions: You should be aware of the extensions of


our les. You will need to be able to identify source code les, such as
.cpp and .h les for C++, or .py les for Python. Additionally, most
executable (runnable) les end with the .exe extension in Windows.
ˆ Turning on viewing le extensions in Windows: By default, Win-
dows hides le extensions from you. However, it is important to know
what kind of les you're working with in a programming class. To view
le extensions, search for "File Explorer Options". Select the "View"
tab, and UNCHECK the option "Hide extensions for known le
types". Hit OK when done.

15
ˆ Project working directory: It is important to keep in mind that the
default working directory of our programs is the location where the project
le is.

 When building and running from the command line (or VS Code
Terminal), the working directory should be the folder you're running
the program from.

 For Visual Studio, the working directory is the same location as your
project .vcxproj le.

 For Code::Blocks, the working directory is the same location as your


project .cbp le.

ˆ Handy document navigation

 Cut, Copy, and Paste


* Copy: You can highlight text and use EDIT > COPY or
CTRL+C to copy it.
* Cut: You can highlight text and use EDIT > CUT or CTRL+X
to cut it.

* Paste:
You can paste copied/cut text by using EDIT > PASTE
CTRL+V.
or

 Up and down
* HOME: The HOME key on your keyboard will take you to the
top of a webpage. For a text document use CTRL+HOME to
go to the top.

* END: The END key on your keyboard will take you to the
bottom of a webpage. For a text document use CTRL+END
to go to the bottom.

 Highlighting text
* Double-click a word with your mouse to auto-highlight the entire
word.

* CTRL+A or EDIT > SELECT ALL will highlight your en-


tire document.

ˆ Handy lesystem navigation

 Hold down CTRL while clicking on separate folders/les to select


multiple.

 Click on a starting folder/le, hold SHIFT, then click the ending


folder/le to highlight all items between those two.

16
2.3 Common C++ bugs and issues
Common build errors
ˆ Undened Reference to WinMain

 Explanation: Your program can't nd main(), the main entry-point


to the program.

 Try:

* Make sure you've written int main() in your program.

* If working with Visual Studio, make sure you've opened a


project (NOT A FILE/FOLDER!) - Is your Solution Explorer
empty?

ˆ Undened reference to . . .

 Explanation: A variable or function either has not been declared or


cannot be found at the current location in the program.

 Try: Check to make sure you don't have any typos, that your vari-
ables have been declared, that your #include are set up properly,
and that any functions declared also are dened elseware.

ˆ Use of undeclared identier XYZ

 Explanation: You're trying to use a variable XYZ but you have not
declared it at this point in the program.

 Try: Look for your variable declaration and make sure it shows up
before any code that uses this variable.

ˆ Unresolved external symbol ABC

 Explanation: This usually means you've made a call to a function


that doesn't exist - perhaps you've declared it somewhere, but never
wrote the function's denition.

 Try: Double checking that all your function declarations' and


denitions' headers MATCH!
ˆ Object of abstract class type is not allowed / Cannot instantiate
abstract class
 Explanation: You're trying to create an object (that is, a variable
whose data type is a class), and the class you're using is still an
abstract class. This could be because you haven't overridden all of its
parents' pure virtual functions, or perhaps a typo between the parent
class' function signature and the child class' function signature.

 Try: Look at class' parent - for any pure virtual functions (e.g.,
virtual RETURN FUNC() = 0;), make sure you have declared and
dened them in the child class.

17
ˆ Cannot convert from ABC to XYZ
 Explanation: The program is expecting an XYZ data type in a loca-
tion where you're giving it an ABC type instead.

 Try: If you're working with a class object, perhaps you need to pass
a member variable of that class object instead?

ˆ ABC already dened in XYZ


 Explanation: This error is saying that a function has already been
dened elsewhere. There could be a few reasons.

 Try:

* Are you missing the #ifndef le guards in a .h le?

* Have you dened a given function more than once?

* Run a Clean and Rebuild in your IDE.


* DO NOT HAVE #include FOR ANY
Make sure that you
.cpp FILES!!
ˆ Operator -> applied to ABC instead of pointer type
 Explanation: You're trying to dereference an object that is not a
pointer.

 Try: Perhaps you're storing a vector of pointers? Make sure you're


accessing a single element.

ˆ Error: implicit instantiation of undened template std::basic_ifstream


 Explanation: Missing an include for the fstream library.

 Try: Don't forget to put #include <fstream> in the code les where
you're using ifstream or ofstream.

Weird software issues


ˆ Windows maximum path length error
 Explanation: Windows has a setting that limits the maximum le
path length. If your repository is deep down many folders, you may
encounter this issue.

 Fixes:

* Enable long paths - The Windows documentation (docs.microsoft.com/en-


us/windows/win32/leio/maximum-le-path-limitation) has some
information on enabling long paths.

* OR Move your project directory - If you move your project di-


C:\ instead of the desktop (which is ac-
rectory to something like
tuallyC:\Users\blahblahblah\Desktop) or the default visual
studio project path (C:\Users\blahblahblah\source\repos)
this will help avoid this maximum path length issue.

18
ˆ Visual Studio: Fatal error LNK1104: cannot open le . . . exe
 Explanation: Visual Studio is trying to build the program but cannot
overwrite the .exe le.

 Fixes:

* Try to close Visual Studio and re-open it - Sometimes if your pro-


gram crashed last time you ran it, Visual Studio will be unable
to update the .exe le and give this error.

* OR Turn o your virus scan - Sometimes your virus scan will see
the .exe le you just built as an unknown threat and prevent
it from opening, which also causes this error.

ˆ Code::Blocks: error: ld returned 1 exit status


 Try: Make sure you do not have any #include statements that in-
clude a .cpp le. Includes only work with .h and .hpp les, or library
les in < > brackets.

ˆ Code::Blocks: Modern C++ features not working


 Fix: In this case you'll need to set up your compiler to build for
a modern C++ version, rather than the default of C++98 (from
1998). In Code::Blocks, go to Settings > Compiler. . . Then,
check the box that is next to the Have g+ follow the C++17 ISO
C++ language standard [-std=c++17] option, or the C++14 one if
that's not available.

19
ˆ XCode: Cannot nd functions

 Explanation: This is a result of creating a new le in XCode, but


choosing the wrong le type. When adding .cpp les, make sure you
select a C++ le object.

ˆ XCode: Where are my output/input text les??

 You will need to set up a Working Path for your projects in XCode.
You can get to this option by going to the menu bar: Scheme ->
Edit Scheme. You will want to set your working directory to a
specic path where you can locate the text les.

20
Git issues
ˆ Git: There is no tracking information for the current branch.
$ git pull
There is no tracking information for the current branch .
Please specify which branc you want to merge with .
See git - pull (1) for details .

git pull < remote > < branch >

If you wish to set tracking information for this branch


you can do so with :

git branch --set - upstream - to = origin / < branch > master

 Explanation: Git isn't sure what branch you're working with; tell it
explicitly.

 Try: git pull origin main

ˆ Git: [rejected] error: failed to push some refs


$ git push
To <URL >
! [ rejected ] main -> main ( non - fast - forward )
error : failed to push some refs to <URL >

hint : Updates were rejected because the tip of your


current branch is behind
hint : its remote counterpart . Integrate the remote
changes ( e . g .
hint : ' git pull ... ') before pushing again .
hint : See the ' Note about fast - forwards ' in ' git push --
help ' for details .

 Explanation: There are changes on the server that you don't have on
your local machine yet. A merge needs to happen.

 Try: The hint gives you the solution: Run git pull and then repeat
your git push after the merge.

ˆ Git: fatal: not a git repository (or any of the parent directories):
.git
$ git status
fatal : not a git repository ( or any of the parent
directories ) : . git

 Explanation: You are not running your git commands from within a
repository folder.

 Try: Make sure you open Git Bash within a folder, or use the cd
commands to navigate to your repository path.

21
ˆ Git: error: Browse.VC.opendb Permission denied
error : open ("..../ Browse . VC . opendb ") : Permission denied
error : unable to index file '.../ Browse . VC . opendb '
fatal : adding files failed

 Explanation: This happens because Visual Studio is still open and


Visual Studio dislikes its project les changing.

 Try: Close Visual Studio before running git add.

22
2.4 Code and UI style guide
Repository management
ˆ For your course folder, lab assignments should be labeled clearly and con-
sistently (e.g., u02_TopicABC, u03_TopicXYZ)
ˆ Sync (add / commit / pull / push) frequently, and especially before
starting a new assignment.
ˆ Your merge request should only contain les related to the current feature
or project you're working on It shouldn't contain code from multiple
assignments.

User Interface design


ˆ Prompts before inputs:
 Before using an input statement (e.g., cin), use an output statement
(e.g., cout) to display a message to the user. Make sure you're clear
about what kind of data you're expecting them to enter.

 NO: If you use an input statement it doesn't show anything on the


screen, so it looks like your program has crashed.

My Program
_

 YES: Use an output statement to display a message before getting


the user's input.

My Program
Please enter pet name : _

ˆ Utilize numbered menus:


 Prefer using menus with number options instead of letters, as all the
numbers are near each other on the keyboard, whereas with letters
the user will have to hunt-and-peck for the option they want.

 NO:

MAIN MENU
N . New game
L . Load game
S . Save game
X . Exit

 YES:

MAIN MENU
1. New game
2. Load game
3. Save game
0. Exit

23
ˆ Validate user input:

 If the user enters an invalid selection, the program sohuld display an


error message before asking them to re-enter their selection. Other-
wise, the user will see the program did nothing but not know why.
 NO:

Your selection : 100


Your selection : 50
Your selection : 2

Loading game ...

 YES:

Your selection : 100

ERROR - Invalid choice ! Must be between 0 and 3!

Your selection : 2

Loading game ...

C++ Style Guide

ˆ Naming conventions

 Variables lowerCamelCase - Variable names should begin with a


lower-case letter and each subsequent letter use an Upper Case, in a
camel-case format.

Additionally:

* Variable names should be descriptive.

* Avoid using single-letter variable names except with for loops.

 Member variables m_lowerCamelCase - Variables that belong to a


class should be prexed with m_ to signify "member".

 Functions CamelCase - Function names should begin with an upper-


case letter and be in CamelCase form. In some cases, using an un-
derscore might be okay to group like-functions together, if it makes
things more clear.

 Classes CamelCase - Class names should begin with an upper-case


letter and be in CamelCase form.

Best practices

ˆ Basics

 You must have int main, not void main.

24
 Don't put an entire program in main() - Split out the pro-
gram into separate menu functions; ideally use a Program class that
contains functions within it.

ˆ Naming conventions

 Variable, function, and class names should be descriptive.

ˆ Arrays

 Do not use a variable for an array's size; some compilers might sup-
port this but not all do. Traditional C arrays and STL arrays must
have hard-coded integer literals or named constant integers as its
size.

ˆ Functions

 Functions should perform the minimal amount of operations - a func-


tion should have a specic purpose.

ˆ Structs and Classes

 Structs should be used for structures that only contain a few amount
of variables and no functions. Classes should be used for more so-
phisticated structures that contain functions and variables.

 Prefer making member variables private with member functions as


an interface for those items.

ˆ try/catch

 The try{} statement should wrap the most minimal amount of code
(NOT THE ENTIRE FUNCTION BODY!) - generally, try
should wrap the one function that could throw an exception.

ˆ NEVER USE GLOBAL VARIABLES.

ˆ NEVER USE goto STATEMENTS.

Cross platform compatibility


ˆ Treat everything (including les) as case-sensitive When using
an #include statement for a le in your project, make sure your cas-
ing matches the le itself. E.g., if the le is Product.h, use #include
"Product.h", not #include "product.h".
ˆ Use #ifndef leguards, not #pragma once. . . Use the #ifndef _LABEL,
#define _LABEL, #endif style of le guards as they are supported by more
compilers.

 Fileguards ONLY go in .h les.

25
ˆ The system("cls"); command only works on Windows

 Prefer creating a cross-platform function like this instead:

1 void ClearScreen ()
2 {
3 # if defined ( WIN32 ) || defined ( _WIN32 ) || defined
( __WIN32 ) && ! defined ( __CYGWIN__ )
4 system ( " cls " ) ;
5 # else
6 system ( " clear " ) ;
7 # endif
8 }

ˆ The system("pause"); command only works on Windows

 Prefer creating a cross-platform function like this instead:

1 // It 's klugey but it 's the simplest .


2 void PressEnterToContinue ()
3 {
4 cout << endl << " PRESS ENTER TO CONTINUE " <<
endl ;
5 string temp ;
6 getline ( cin , temp ) ;
7 getline ( cin , temp ) ;
8 }

ˆ File guards: Always use ifndef instead of pragma once for your le
guards.

 YES:

1 # ifndef _MYFILE_H
2 # define _MYFILE_H
3
4 // My code
5
6 # endif

 NO:

1 # pragma once
2
3 // My code

26
File organization
ˆ Function/class declarations
 Function and class declarations should go in a header (.h) le.

ˆ Function denitions
 Function denitions should go in a source (.cpp) le, EXCEPT TEM-
PLATED FUNCTIONS (those all go in .h).

ˆ Each class/struct should have its own set of .h and .cpp (as
needed) les
 Don't put multiple class declarations in one le.

ˆ Function denitions must go in .cpp le


 Don't dene class functions within the class or in the .h le.
 Except for templated classes - Everything goes in the .h le for
templated classes.

ˆ Don't dene structs/classes inside other classes


 Each struct/class should have its own .h le/set of .h and .cpp les.]

ˆ Never include .cpp les!


 Includes should only include .h or .hpp header les.

ˆ If a project has many les, separate them into folders


 Logically separate related les into subfolders, such as Exceptions,
DataStructures, Menus, etc.

Clean code
ˆ Erase unused codeblocks
 If you want to make sure to be able to reference old code later, back
it up to GitLab, then delete the comment. Don't leave commented
out code blocks in turn-in assignments.

ˆ Be consistent with naming conventions


 Choose either UpperCaseFunctionNames or lowerCaseFunctionNames
but don't interchange them. Same with variable and class naming.
Be consistent.

ˆ Whitespace
 Adequate whitespace should be used to dierentiate logical sections
of code.

 At the same time, don't use too much whitespace. The goal is to have
readable code.

27
ˆ If ( true ) return true; else return false;

 If you're writing a condition to check if something is true in order


to return true, just return the result of the condition instead.

 NO:

1 if ( a == b )
2 return true ;
3 else
4 return false ;

 YES:

1 return ( a == b ) ;

Curly braces
ˆ Follow the existing code base

 If you're writing code from scratch you can follow whatever style
you'd like as long as it is consistent.

 When working with existing code-bases, use the same style as the
existing code.

 See https://en.wikipedia.org/wiki/Indentation_style for in-


dentation styles

Preferred style:
1 if ( a == b )
2 {
3 DoThing () ;
4 }

GNU styling:
1 if ( a == b )
2 {
3 DoThing () ;
4 }

K&R Styling ("JavaScript" style):


1 if ( a == b ) {
2 DoThing () ;
3 }

28
ˆ One-line contents

 Always surround your if statement and while loop contents within


curly braces { } even though it's not required for one-line internals.

 NO:

1 if ( CONDITION )
2 DoThingA () ;
3 else if ( CONDITION2 )
4 DoThingB () ;
5 else
6 DoThingC () ;

ˆ YES 1:

1 if ( CONDITION )
2 {
3 DoThingA () ;
4 }
5 else if ( CONDITION2 )
6 {
7 DoThingB () ;
8 }
9 else
10 {
11 DoThingC () ;
12 }

ˆ YES 2:

1 if ( CONDITION ) { DoThingA () ; }
2 else if ( CONDITION2 ) { DoThingB () ; }
3 else { DoThingC () ; }

29
Bad user interface examples
Try to space out a program's output by "section" in the program. Don't
just barf out all the information to the screen. Sometimes, not all information
is required on a given screen.

BAD FIXED

################################ #################################
# NEW RECIPE # # NEW RECIPE #
############## ##############
Enter new recipe name: PB Cups
Enter URL: asdf.com Enter new recipe name: PB Cups
How many ingredients? 2 Enter URL: asdf.com
Ingredient name: How many ingredients? 2
Peanut-Butter
Ingredient unit: INGREDIENT 1:
cups - Name: Peanut butter
Ingredient amount: - Unit of measurement: cups
30 - Amount: 2
Ingredient name:
Chocolate INGREDIENT 2:
Ingredient unit: - Name: Chocolate
cups - Unit of measurement: tbsp
Ingredient amount: - Amount: 5
10
Recipe added successfully.

30
2.5 How to use VSCode
Installing and conguring VSCode
ˆ On the VSCode website you can download the program for free.

ˆ Website: https://code.visualstudio.com/Download
ˆ Select your operating system, the big blue button on top is ne, or you
can select one of the smaller buttons for more rened options.

ˆ Once downloaded, double click on the installer to begin.

 License Agreement: Click Next


 Select Destination Location: You can leave it as default and click
Next
 Select Start Menu Folder: You can leave it as default and click Next
 Select Additional Tasks: Click the checkboxes that say

* Add "Open with Code" action to Windows Explorer le context


menu

* Add "Open with Code" action to Windows Explorer directory


context menu

* (Note: if you're on Mac/Linux this may not be an option.)

 Ready to Install: Click Install.

31
Cloning your course repository
ˆ Once you have a GitLab account, the instructor will set up a course
repository for you. This is a folder on a server where you can keep your
work backed up. You can sync between the les on your desktop and any
changes on the server (the instructor may add new les or make updates
to your code to add comments).

ˆ Copy repo URL:

Go to your GitLab repository webpage and locate the blue code but-
Clone with HTTPS.
ton. Click on it, then copy the URL underneath

ˆ Clone repository:

Within VSCode, click on the icon on the left that looks like a node
branching into two nodes. This is the source control tab. Click on the
Clone Repository button.

32
ˆ Clone in VS Code:

A little box will pop up at the top of VSCode asking for arepository
URL. Paste the copied URL from the website here, then hit enter.
ˆ Select repository destination:

It will ask you to set a destination for your course folder. I would sug-
gest putting in in your Documents or Desktop. Once you've found a
location, click the Select as Repository Destination button.
ˆ View on computer:

Once it's been cloned, you will be able to see the folder on your computer
under the le explorer. You will work from this directory.

33
ˆ As you work through assignments you will periodically back up your work
and sync it with the server, but we will cover that later on.

Opening your repository folder


ˆ Open in VS Code:

Once you're ready to start programming, from the File menu, select Open
Folder. . . .
ˆ Select folder:

Locate your repository folder (named something like cs200-username-


repo). Highlight the folder and click Open Folder.

34
ˆ Project view:

You will be able to see all the contents of your repository on the left side.

ˆ The left view shows you all of the folders and les within the folder you
opened.

ˆ You can double-click one of the folders (which have a > to its left) to open
it and you can see the code within the folder. If you double-click a le it
will open it in the editor view.

ˆ The right view shows the currently opened code le. You can edit your
code in this view.

35
VSCode terminal
ˆ View > Terminal:

To open the terminal, click on the View dropdown from the top menu
and select Terminal.
ˆ The Terminal is a text interface, we will use some basic commands to
work with our code. The terminal has a prompt, which displays the
current folders that you're inside of (called the path), and ends with a >
sign. You can type commands after the >.

36
Command: ls - LiSt les and folders
ˆ If you type ls (that is a lower-case L and S) and hit ENTER, it will show
you the les and folders in this location.

Command: cd - Change Directory


ˆ If you type cd and the name of a folder, it will move you into that folder.
This can be useful to go between your dierent projects.

ˆ cd FOLDERNAME will put you inside the folder named, and

ˆ cd .. will take you out of the current folder you're in.

37
Building your C++ program

ˆ Every time you make a change to your C++ source code you will have to
compile (aka build) the code into an executable (.exe) le. To do this,
we use the g++ compiler program.

ˆ To run the program, we list the program name rst (g++) then give it any
options after a space. For g++, the option will be the code le we want
to build:

ˆ g++ test.cpp will build "test.cpp" into an executable le. On Windows,


it will generate a.exe. On Linux and Mac, it will generate a.out. You
can use the ls command to make sure your program is shown.

ˆ If the build is successful, g++ won't give you any messages and just return
you to the prompt to enter a new command. However, if there are syntax
errors in your code, it will display the errors afterwards. You will need to
x any syntax errors in order to get the program to build.

Running your program

ˆ To run the program, use the ./PROGRAMNAME command, this runs your
program. By default, g++ generates a a.exe or a.out le, so to run you
would use ./a.exe or ./a.out:

Committing and syncing to back up your work

ˆ Once you've made any changes to your repository, under the Source Con-
trol tab (the branching icon), it will show a little notication bubble with
a number in it.

38
ˆ From this page, you can back up your changes. In the little text box, add
a useful message to keep note of what you changed (e.g., "Fixed bug with
input", "Finished with u02 lab"), then click the Commit button to make
a backup snapshot.

ˆ After a commit, the button turns into a Sync Changes button. This will
send your changes to the server for long-term storage. You will also need
to save your les on the server so that the instructor can see your work.
You can click it any time you're doing a commit to back up your work.

39
ˆ Once you've synced your work, on the GitLab repo website you will be
able to see your latest commit message:

ˆ If you click on the folder and le that you edited you will be able to see
the updates online as well:

Other VSCode notes:


ˆ VSCode might ask if you want to "periodically run git fetch". Go ahead
and click Yes here. This will automatically pull down any changes from
the server, such as if the instructor adds additional les.

40
2.6 How to install Git
Installing Git
The Git software is PC software that allows you to interact with a Git server.

ˆ Download the installer here: https://git-scm.com/

ˆ Once donwloaded, double click the installer to begin.

 Most default options are ne.

 On the "Choosing the default editor used by Git", just select Notepad,
or any other program you recognize there.

ˆ After installation is done we need to congure it in VS Code.

 Open VS Code and open up the terminal by going to View > Ter-
minal:

41
 Enter each of the following commands in the terminal. (Replace
"[email protected]" with your email address)

* Congure your email address:

git config -- global user . email " you@example . com "

* Congure the name that shows up on GitLab. (Replace "Your


Name" with your name)

git config -- global user . name " Your Name "

* Congure how Git handles merging my code vs. your code:

git config -- global pull . rebase false

42
3 Syllabus

3.1 Course information


College Johnson County Community College
Division CSIT (Computer Science/Information Technology)
Instructor Rachel Wil Singh (they/them)
Semester Summer 2024 (06/03/2024 - 07/22/2024)
Course CS 200: Concepts of Programming with C++ (4 credit hours)
Section Section 300 / CRN 60580 / Online-only
Oce hours Available by appointment (on campus / Zoom)

Course description This course emphasizes problem solving using a high-


level programming language and the software development process. Algo-
rithm design and development, programming style, documentation, test-
ing and debugging will be presented. Standard algorithms and data struc-
tures will be introduced. Data abstraction and an introduction to object-
oriented programming will be studied and used to implement algorithms.
3 hrs. lecture, 2 hrs. lab by arrangement/wk. Catalog link: https:
//catalog.jccc.edu/coursedescriptions/cs/#CS_200

Prerequisites (CS 134 with a grade of "C" or higher or CIS 142 with a grade
of "C" or higher or department waiver test and MATH 131 or higher) or
MATH 241 or department approval.

Drop deadlines To view the deadline dates for dropping this course, please
refer to the schedule on the JCCC website under Admissions>Enrollment
Dates> Dropping Credit Classes. After the 100% refund date, you will
be nancially responsible for the tuition charges; for details, search on
Student Financial Responsibility on the JCCC web page. Changing your
schedule may reduce eligibility for nancial aid and other third party fund-
ing. Courses not dropped will be graded. For questions about dropping
courses, contact the Student Success Center at 913-469-3803.

Auto-withdraws Attendance for the rst week of classes at JCCC are recorded
and students marked as NOT IN ATTENDANCE get auto-withdrawn
from the course. Please pay attention to course announcements / emails
from the instructor for instructions on how to make sure you are marked
as IN ATTENDANCE.

ˆ To learn more about reinstatement, please visit: https://www.jccc.


edu/admissions/enrollment/reinstatement.html

Instructor information
Name: Rachel Wil Singh, aka R.W. (they/them)

Oce: RC 348 H

Email: [email protected] (please use Canvas email instead)

Oce phone: (913) 469-8500 x3671

43
Course delivery
This course is set up as an Online course. This means the following:

ˆ There is no scheduled class time for this course.

ˆ Instructions and assignments are given totally online

ˆ You can utilize oce hours to meet with the instructor, ask questions,
and get help.

To see more about JCCC course delivery options, please visit: https://
www.jccc.edu/student-resources/course-delivery-methods.html

Oce hours
Over the summer semester, oce hours are optional. You can schedule a
time to meet with me on campus or via Zoom (Zoom preferred), just send me
an email.

Class communication
Please use Canvas email, not the @jccc email, to contact the in-
structor! I rely upon the Canvas email system for communication with
students and only students. The direct @jccc email address also receives
non-student communication such as automated campus updates, depart-
ment emails, commitee emails, and so on. To ensure that I see your email
in a timely manner, please email me via Canvas!

Instructor will respond within 1 business day I do my best to respond


to emails as quickly as possible, at most within 1 business day. Emails
on Friday may not get a response until Monday. If I have not responded
to your email within this time period it is possible I have not seen your
email, please make sure to email me through Canvas and not to my @jccc
email.

Check course Announcements! I use the Announcements board as a way


to give additional course information, assignment corrections, and other
things. You can set up Canvas to email these announcements to you
automatically. Please don't ignore class Announcements!

3.1.1 Course supplies


1. Textbook: Rachel's CS 200 course notes (https://moosadee.gitlab.
io/courses/)
2. Zoom: Needed for remote attendance / oce hours

3. Tools: We will go over how to set this up during rst week assignments.

ˆ WINDOWS: MinGW

44
ˆ LINUX/MAC: g++

ˆ VS Code

4. Accounts: See the UNIT 00 SETUP assignments for steps on set up.

ˆ GitLab (https://gitlab.com/) for code storage

5. Optional: Things that might be handy

ˆ Dark Reader plugin (Firefox/Chrome/Safari/Edge) to turn light-


mode webpages into dark-mode. (https://darkreader.org/)

3.1.2 Recommended experience


There are certain skills that will make your time in this class easier. Please
look over this list and let me know if you need additional help with any of these
things.
Computer skills - You should have a base level knowledge of using a com-
puter, including:

ˆ Navigating your Operating System, including:

 Installing software

 Running software

 Locating saved les on your computer

 Writing text documents, exporting to PDF

 Taking screenshots

 Editing .txt and other plaintext les

ˆ Navigating the internet:

 Navigating websites, using links

 Sending emails

 Uploading attachments

Learning skills - Learning to program takes a lot of reading, and you will
be building up your problem solving skills. You should be able to exercise the
following skills:

ˆ Breaking down problems - Looking at a problem in small pieces and tack-


ling them one part at a time.

ˆ Organizing your notes so you can use them for reference while coding.

ˆ Reading an entire part of an assignment before starting - these aren't


step-by-step to-do lists.

ˆ Learning how to ask a question - Where are you stuck, what are you stuck
on, what have you tried?

ˆ Recognizing when additional learning resources are needed and seeking


them out - such as utilizing JCCC's Academic Achievement Center tutors.

45
ˆ Managing your time to give yourself enough time to tackle challenges,
rather than waiting until the last minute.

How to ask questions - When asking questions about a programming


assignment via email, please include the following information so I can answer
your question:

1. Be sure to let me know WHICH ASSIGNMENT IT IS, the specic assign-


ment name, so I can nd it.

2. Include a SCREENSHOT of what's going wrong.

3. What have you tried so far?

3.2 Course policies


3.2.1 Grading breakdown
Assessment types are given a certain weight in the overall class. Breakdown
percentages are based o the course catalog requirements (https://catalog.
jccc.edu/coursedescriptions/cs/#CS_200)
ˆ Labs: Weekly programming assignments to help practice new concepts
(20%)

ˆ Exercises: A variety of additional topics to help students learn and prac-


tice (5%)

ˆ Nonograms: Small puzzles to help students practice problem solving and


analysis

ˆ Tech Literacy discussions: Discussions about tech related areas (5%)

ˆ Check-ins: Weekly Check-Ins to let me know how you're doing in the


course and if you need anything additional (5%)

ˆ Concept Introductions (Quizzes): Concept Introductions help stu-


dents review concepts read about in the textbook (10%)

ˆ Projects: Larger programming assignments that combine multiple topics


(15%)

ˆ Exams: Mastery Checks to help the student and instructor assess how
much about a topic has been learned (40%)

Final letter grade: JCCC uses whole letter grades for nal course grades:
F, D, C, B, and A. The way I break down what your receive at the end of the
semester is as follows:

Total score Letter grade


89.5% ≤ grade ≤ 100% A
79.5% ≤ grade < 89.5% B
69.5% ≤ grade < 79.5% C
59.5% ≤ grade < 69.5% D
0% ≤ grade < 59.5% F

46
3.2.2 Tentative schedule
This schedule is recommended, but the modules are available whenever you
meet the prerequisites for any of them.

Week # Monday Topics


1 June 3 Unit 00: Welcome and setup
Unit 01: Tech Literacy: Exploring computers
Unit 02: C++: Variables, input, and output
2 June 10 Milestone: Mastery Check 1
Unit 03: C++: Functions
Unit 04: Tech Literacy: Debugging and researching
3 June 17 Milestone: Mastery Check 2
Unit 05: C++: Structs
Unit 06: Tech Literacy: Careers in tech
4 June 24 Unit 07: C++: Looping
Unit 08: C++: Arrays and vectors
5 July 1 Milestone: Mastery Check 3
Unit 09: C++: Branching
Unit 10: C++ Searching and sorting
6 July 8 Unit 11: Tech Literacy: Current trends in tech
Unit 12: Tech Literacy: Object Oriented Programming, UML
Unit 13: C++: Classes and inheritance
7 July 15 Milestone: Mastery Check 4
Unit 14: C++: Strings and File I/O
Unit 15: Tech Literacy: Ethics in tech
8 July 22 Unit 16: C++: Intro to recursion

3.2.3 Class format


Unlocking class content:

ˆ On Canvas you will have access to a set amount of modules, with a Mas-
tery Check milestone gating access to subsequent modules. Each Mastery
Check includes one exam and one project.

ˆ Exams have a series of multiple choice questions as well as type-in, man-


ually graded questions. You need to score at least 70% on the exam (and
turn in the project) to unlock the next set of modules.

ˆ If you score below 70% (after the write-in questions have been graded) you
can retake the exam but you need to reach out to me to unlock it again.

47
ˆ Exams are randomly built from a pool of questions, so each attempt will
be a little dierent.

Grade scoring:

ˆ All assignment scores begin at 0% at the start of the semester, so your


grade begins at 0% at the start.

ˆ As you progress through the course and nish more course content, your
grade will continue rising. Ideally, if you get 100% on all assignments in
the course, you'll end with 100% as your nal grade.

ˆ Most assignments can be resubmitted after grading to improve your score


afterwards. (e.g., if I notice bugs in your lab, I'll make comments on why
it happens, and you can go back and x it.)

ˆ Assignments don't close until the last day of class - July 25th. See the
Academic Calendar (https://www.jccc.edu/modules/calendar/academic-calendar.
html) if needed.

3.2.4 Academic honesty


The assignments the instructor writes for this course are meant to help the
student learn new topics, starting easy and increasing the challenge over time.
If a student does not do their own work then they miss out on the lessons and
strategy learned from going from step A to step B to step C. The instructor
is always willing to help you work through assignments, so ideally the student
shouldn't feel the need to turn to third party sources for help.

Generally, for R.W. Singh's courses:


ˆ OK things:

 Asking the instructor for help, hints, or clarication, on any assign-


ment.

 Posting to the discussion board with questions (except with tests -


please email me for those). (If you're unsure if you can post a question
to the discussion board, you can go ahead and post it. If there's a
problem I'll remove/edit the message and just let you know.)

 Searching online for general knowledge questions (e.g. "C++ if state-


ments", error messages).

 Working with a tutor through the assignments, as long as they're not


doing the work for you.

48
 Use your IDE (replit, visual studio, code::blocks) to test out things
before answering questions.

 Brainstorming with classmates, sharing general information ("This


is how I do input validation").

ˆ Not OK Things:

 Sharing your code les with other students, or asking other students
for their code les.

 Asking a tutor, peer, family member, friend, AI, etc. to do your


assignments for you.

 Searching for specic solutions to assignments online/elseware.

 Basically, any work/research you aren't doing on your own, that


means you're not learning the topics.

 Don't give your code les to other students, even if it is "to verify
my work!"

 Don't copy solutions o other parts of the internet; assignments get


modied a little bit each semester.

If you have any further questions, please contact the instructor.


Each instructor is dierent, so make sure you don't assume that what is OK
with one instructor is OK with another.

3.2.5 Student success tips


ˆ I need to achieve a certain grade for my nancial aid or student
visa. What do I need to plan on?
 If you need to get a certain grade, such as an A for this course, to
maintain your nancial aid or student visa, then you need to set your
mindset for this course immediately. You should prioritize working
on assignments early and getting them in ahead of time so that you
have the maximum amount of time to ask questions and get help.
You should not be panicking at the end of the semester because you
have a grade less than what you need. From week 1, make sure you're
committed to staying on top of things.

ˆ How do I contact the instructor?

 The best way to contact the instructor is via Canvas' email system.
You can also email the instructor at [email protected], however,
emails are more likely to be lost in the main inbox, since that's where
all the instructor's work-related email goes. You can also attend
Zoom oce hours to ask questions.

ˆ What are some suggestions for approaching studying and assign-


ments for this course?
 Each week is generally designed with this "path" in mind:

* Watch lecture videos, read assigned reading.

49
* Work on Concept Introduction assignment(s).

* Work on Exercise assignment.

 Those are the core topics for the class. The Tech Literacy assignments
can be done a bit more casually, and the Topic Mastery (exams) don't
have to be done right away - do the exams once you feel comfortable
with the topic.

ˆ Where do I nd feedback on my work?

 Canvas should send you an email when there is feedback on your


work, but you can also locate assignment feedback by going to your
Grades view on Canvas, locating the assignment, and clicking on the
speech balloon icon to open up comments. These will be important
to look over during the semester, especially if you want to resubmit
an assignment for a better grade.

ˆ How do I nd a tutor?

 JCCC's Academic Achievement Center

(https://www.jccc.edu/student-resources/academic-resource-center/
academic-achievement-center/)
provides tutoring services for our area. Make sure to look for the
expert tutor service and you can learn more about getting a tutor.

ˆ How do I keep track of assignments and due dates so I don't


forget something?
 Canvas has a CALENDAR view, but it might also be useful to uti-
lize something like Google Calendar, which can text and email you
reminders, or even keeping a paper day planner that you check every
day.

3.2.6 Accommodations and life help


ˆ How do I get accommodations? - Access Services
https://www.jccc.edu/student-resources/access-services/
Access Services provides students with disabilities equal opportunity and
access. Some of the accommodations and services include testing accom-
modations, note-taking assistance, sign language interpreting services, au-
diobooks/alternative text and assistive technology.

ˆ What if I'm having trouble making ends meet in my personal


life? - Student Basic Needs Center
https://www.jccc.edu/student-resources/basic-needs-center/
Check website for schedule and location. The JCCC Student Assistance
Fund is to help students facing a sudden and unforeseen emergency that
has aected their ability to attend class or otherwise meet the academic
obligations of a JCCC student. If you are experiencing food or housing
insecurity, or other hardships, stop by COM 319 and visit with our helpful
sta.

50
ˆ Is there someone I can talk to for my degree plan? - Academic
Advising
https://www.jccc.edu/student-resources/academic-counseling/
JCCC has advisors to help you with:

 Choose or change your major and stay on track for graduation.

 Ensure a smooth transfer process to a 4-year institution.

 Discover resources and tools available to help build your schedule,


complete enrollment and receive help with coursework each semester.

 Learn how to get involved in Student Senate, clubs and orgs, ath-
letics, study abroad, service learning, honors and other leadership
programs.

 If there's a hold on your account due to test scores, academic proba-


tion or suspension, you are required to meet with a counselor.

ˆ Is there someone I can talk to for emotional support? - Personal


Counseling
https://www.jccc.edu/student-resources/personal-counseling/
JCCC counselors provide a safe and condential environment to talk about
personal concerns. We advocate for students and assist with personal
issues and make referrals to appropriate agencies when needed.

ˆ How do I get a tutor? - The Academic Achievement Center


https://www.jccc.edu/student-resources/academic-resource-center/
academic-achievement-center/
The AAC is open for Zoom meetings and appointments. See the website
for their schedule. Meet with a Learning Specialist for help with classes
and study skills, a Reading Specialist to improve understanding of your
academic reading, or a tutor to help you with specic courses and college
study skills. You can sign up for workshops to get o to a Smart Start in
your semester or analyze your exam scores!

ˆ How can I report ethical concerns? - Ethics Report Line


https://www.jccc.edu/about/leadership-governance/administration/
audit-advisory/ethics-line/
You can report instances of discrimination and other ethical issues to
JCCC via the EthicsPoint line.

ˆ What other student resources are there? - Student Resources


Directory
https://www.jccc.edu/student-resources/

51
3.3 Additional information
3.3.1 ADA compliance / disabilities
JCCC provides a range of services to allow persons with disabilities to par-
ticipate in educational programs and activities. If you are a student with a
disability and if you are in need of accommodations or services, it is your re-
sponsibility to contact Access Services and make a formal request. To schedule
an appointment with an Access Advisor or for additional information, you can
contact Access Services at (913) 469-3521 or [email protected]. Access
Services is located on the 2nd oor of the Student Center (SC202)

3.3.2 Attendance standards of JCCC


Educational research demonstrates that students who regularly attend and par-
ticipate in all scheduled classes are more likely to succeed in college. Punctual
and regular attendance at all scheduled classes, for the duration of the course,
is regarded as integral to all courses and is expected of all students. Each JCCC
faculty member will include attendance guidelines in the course syllabus that
are applicable to that course, and students are responsible for knowing and ad-
hering to those guidelines. Students are expected to regularly attend classes in
accordance with the attendance standards implemented by JCCC faculty.
The student is responsible for all course content and assignments missed
due to absence. Excessive absences and authorized absences are handled in
accordance with the Student Attendance Operating Procedure.

3.3.3 Academic Dishonesty


No student shall attempt, engage in, or aid and abet behavior that, in the
judgment of the faculty member for a particular class, is construed as academic
dishonesty. This includes, but is not limited to, cheating, plagiarism or other
forms of academic dishonesty.
Examples of academic dishonesty and cheating include, but are not limited
to, unauthorized acquisition of tests or other academic materials and/or distri-
bution of these materials, unauthorized sharing of answers during an exam, use
of unauthorized notes or study materials during an exam, altering an exam and
resubmitting it for re-grading, having another student take an exam for you or
submit assignments in your name, participating in unauthorized collaboration
on coursework to be graded, providing false data for a research paper, using
electronic equipment to transmit information to a third party to seek answers,
or creating/citing false or ctitious references for a term paper. Submitting the
same paper for multiple classes may also be considered cheating if not authorized
by the faculty member.
Examples of plagiarism include, but are not limited to, any attempt to take
credit for work that is not your own, such as using direct quotes from an author
without using quotation marks or indentation in the paper, paraphrasing work
that is not your own without giving credit to the original source of the idea,
or failing to properly cite all sources in the body of your work. This includes
use of complete or partial papers from internet paper mills or other sources of
non-original work without attribution.

52
A faculty member may further dene academic dishonesty, cheating or pla-
giarism in the course syllabus.

3.3.4 College Wellness and Safety


College Wellness and Safety (https://www.jccc.edu/media-resources/wellness-safety/)

ˆ Stay home when you're sick

ˆ Wash hands frequently

ˆ Cover your mouth when coughing or sneezing

ˆ Clean surfaces

ˆ Facial coverings are available and welcomed but not required

ˆ Wear yoru name badge or carry your JCCC photo id while on campus

3.3.5 College emergency response plan


https://www.jccc.edu/student-resources/police-safety/police-department/
college-emergency-response-plan/

3.3.6 Student code of conduct policy


http://www.jccc.edu/about/leadership-governance/policies/students/
student-code-of-conduct/student-code-conduct.html

3.3.7 Student handbook


http://www.jccc.edu/student-resources/student-handbook.html

3.3.8 Campus safety


Information regarding student safety can be found at http://www.jccc.edu/
student-resources/police-safety/. Classroom and campus safety are of
paramount importance at Johnson County Community College and are the
shared responsibility of the entire campus population. Please review the fol-
lowing:

ˆ Report emergencies: to Campus Police (available 24 hours a day)

 In person at the Midwest Trust Center (MTC 115)

 Call 913-469-2500 (direct line)  Tip: program in your cell phone

 Phone app - download JCCC Guardian (the free campus safety app:
www.jccc.edu/guardian) - instant panic button and texting capabil-
ity to Campus Police

 Anonymous reports to KOPS-Watch -

https://secure.ethicspoint.com/domain/en/report_company.asp?
clientid=25868 or 888-258-3230
ˆ Be Alert:

53
 You are an extra set of eyes and ears to help maintain campus safety

 Trust your instincts

 Report suspicious or unusual behavior/circumstances to Campus Po-


lice (see above)

ˆ Be Prepared:

 Identify the red/white stripe Building Emergency Response posters


throughout campus and online that show egress routes, shelter, and
equipment

 View A.L.I.C.E. training (armed intruder response training - Alert,


Lockdown, Inform, Counter and/or Evacuate)

* Student training video: https://www.youtube.com/watch?v=


kMcT4-nWSq0
 Familiarize yourself with the College Emergency Response Plan: (jccc.edu/student-
resources/police-safety/college-emergency-response-plan/)

ˆ During an emergency: Notications/Alerts (emergencies and inclement


weather) are sent to all employees and students using email and text mes-
saging

 students are automatically enrolled, see JCCC Alert - Emergency No-


tication: (jccc.edu/student-resources/police-safety/jccc-alert.html)

ˆ Weapons policy: Eective July 1, 2017, concealed carry handguns are


permitted in JCCC buildings subject to the restrictions set forth in the
Weapons Policy. Handgun safety training is encouraged of all who choose
to conceal carry. Suspected violations should be reported to JCCC Police
Department 913-469-2500 or if an emergency, you can also call 911.

3.4 Course catalog info


Objectives:
1. Describe computer systems and examine ethics.

2. Solve problems using a disciplined approach to software development.

3. Utilize fundamental programming language features.

4. Implement procedures.

5. Employ fundamental data structures and algorithms.

6. Write code using object-oriented techniques.

7. Write code according to commonly accepted programming standards.

8. Utilize a professional software development environment.

54
Content Outline and Competencies:
I. Computer Systems and Ethics
A. Describe basic software components.

1. Describe operating systems.

2. Describe high-level and machine languages.

3. Describe compilers.

B. Examine ethics.

1. Examine ethics in the context of software development.

2. Examine the impact of ethics violations on software developers.

3. Examine the impact of ethics violations on software users.

II. Problem-Solving in Software Development


A. Dene the problem.
B. Develop a solution.

1. Utilize top-down design.

2. Consider previous problems and solutions.

3. Reuse pertinent algorithms.

4. Represent algorithms with pseudo-code.

5. Identify input, output, processing and modules.

C. Code the solution.


D. Test the solution.

1. Perform unit and integration testing.

2. Select appropriate test data.

3. Trace code by hand (desk-checking) and with a debugger.

4. Evaluate code eciency and simplicity.

III. Fundamental Programming Features


A. Declare and initialize variables and constants.
B. Use built-in operators to create expressions and statements.

1. Write assignment statements.

2. Create expressions with arithmetic, relational and logical operators.

3. Use the conditional (ternary) operator.

4. Evaluate expressions using rules of operator precedence.

5. Compare strings and numeric types.

55
6. Dereference and assign values to pointers.

C. Perform input and output.

1. Retrieve data from the keyboard.

2. Retrieve data from input les.

3. Write data to the console window.

4. Write data to output les.

D. Call built-in mathematical functions.


E. Implement type-casting.
F. Control program ow.

1. Implement selection statements.

a. Write code with if, else and else-if statements.


b. Use switch statements.
c. Write nested selection statements.

1. Implement repetition statements

a. Write while, for and do loops.


b. Create nested loops.
c. Analyze break and continue semantics.
G. Trap errors using selection or repetition.
IV. Procedures
A. Dene and call functions with void and non-void return values.
B. Declare functions (prototyping).
C. Implement pass-by-value and pass-by-reference parameters.
D. Dierentiate between actual and formal parameters.
E. Analyze and write elementary recursive code.
F. Analyze variable scope and lifetime.
G. Implement static variables.
V. Fundamental Data Structures and Algorithms
A. Implement single dimensional arrays.

1. Implement an array of integers.

2. Implement null-terminated strings.

B. Implement two-dimensional arrays.


C. Implement dynamic arrays.

1. Use new and delete to manage memory.

2. Declare pointers.

D. Search arrays.

1. Implement sequential search.

2. Implement binary search.

56
E. Sort arrays.

1. Sort data using bubble sort.

2. Sort data using selection sort.

3. Sort data using insertion sort.

F. Implement structures.
G. Implement an array of structures.
VI. Object-oriented Programming
A. Write code using the built-in string class and associated methods.
B. Write code using the built-in vector class and associated methods.
C. Implement encapsulation and data abstraction by writing user-dened
classes.
D. Dierentiate between private and public access modiers.
E. Hide member data.
F. Write accessors, mutators and other member functions that process mem-
ber data.
G. Write code that utilizes objects.
H. Implement an array of objects.
VII. Code Standards
A. Create descriptive identiers according to language naming conventions.
B. Write structured and readable code.
C. Create documentation.
VIII. Professional Development Environment
A. Write code using a professional, integrated development environment
(IDE).
B. Utilize key editor features.
C. Debug code using the integrated debugger.
D. Include and use standard libraries.

57
4 Notes - Questions to answer for review

4.1 Unit 00: Setup - Using the terminal


4.1.1 Git
ˆ What is a commit message for?

ˆ The command to send your changes to the server is:

4.1.2 Terminal
ˆ The command to list all les and folders in a directory is:

ˆ The command to navigate to a new folder is:

ˆ The command to navigate UP out of a folder is:

ˆ The command to build a single source le is:

ˆ The command to build multiple source les is:

ˆ The command to run a program is:

58
4.2 Unit 02: C++ Basics - Variables, pointers, input, and
output
ˆ Which data types are used for the following types of data?

 Whole numbers

 Numbers with decimals

 True or False

 Text with multiple letters/characters:

 A single character:

ˆ String literals must be enclosed within. . . :

ˆ Character literals must be enclosed within. . . :

ˆ Example code to declare and initialize an integer:

ˆ Example code to declare and initialize a string:

ˆ Example code to DISPLAY a text string literal to the screen:

ˆ Example code to DISPLAY a variable's value to the screen:

ˆ Example code to DISPLAY a text string literal and a variable's value in


the same line:

ˆ Example code to get the user's INPUT and store it in an integer variable,
using cin :

ˆ Example code to get the user's INPUT and store it in a string variable,
using getline:

ˆ When is the cin.ignore() statement needed?

ˆ Which library do you need to #include to use cin and cout?

ˆ Which library do you need to #include to use string?

59
4.2.1 Pointers
ˆ What is the address-of operator? How do we access the address of a
variable?

ˆ How do we declare a pointer variable? Write some example code.

ˆ How do we assign a pointer variable the address of another variable? Write


some example code.

ˆ When a pointer is not in use, what should it be pointing to?

ˆ What is the de-reference operator? Write some example code.

4.3 Unit 03: Functions


ˆ What are the 3 parts of a function header?

ˆ What is a return type? Which return type is used if the function returns
no data?

ˆ What is an input parameter?

ˆ What is a function name?

ˆ How do you declare a function? Write some example code.

60
ˆ How do you dene a function? Write some example code.

ˆ How do you call a function? Write some example code.

ˆ What is an argument? How is it dierent from a parameter?

ˆ What is scope? How do you tell what the scope of a variable is?

ˆ Are variables pass-by-value or pass-by-reference as a default in C++?

ˆ How do you tell if a parameter is pass-by-value or pass-by-reference?

ˆ What does pass-by-value mean?

ˆ What does pass-by-reference mean?

ˆ What does a function header that takes in a pointer parameter look like?
What does calling the function, passing in a variable address, look like?

61
4.4 Unit 05: Structs
ˆ What is a struct?

ˆ Write down an example of a struct declaration.

ˆ Write down an example of declaring a variable whose data type is some


struct.

ˆ What kind of le should structs go in?

ˆ What is an object?

ˆ What does the dot operator do?

ˆ What is a member variable?

4.5 Unit 07: Looping


4.5.1 While loops
ˆ What is the structure of a while loop? Write an example

ˆ What is a condition?

62
ˆ What causes an innite loop with a while loop?

ˆ What does the continue command do?

ˆ What does the break command do?

ˆ Write example code: How to count up

ˆ Write example code: Validate user input (between min and max values)

ˆ Write example code: Basic program loop

4.5.2 For loops


ˆ What are the three parts of a for loop's header?

ˆ Give example code for how to write a for loop that iterates from i = 0 to
5 (inclusive), going up by 1 each time, and displaying the value of i within
the for loop.

63
4.6 Unit 08: Arrays and vectors
4.6.1 Arrays
ˆ What is an element of an array?

ˆ What is an index of an array?

ˆ What is the subscript operator?

ˆ How do you declare a traditional array? (Write an example)

ˆ How do you declare an array object? (Write an example)

ˆ How do you access element 0 of an array? (Write an example)

ˆ How do you access element i of an array? (Write an example)

ˆ Given an array of size n, what are the minimum and maximum valid
indices?

ˆ What happens if you try to access an element of the array at an invalid


index?

ˆ Write an example line of code given each of these instructions. Assume


the following code is already provided.

const int SIZE = 5;


string arr[SIZE];
int index = 2;

64
ˆ Write a for loop to iterate through every element of the arr array and
display the index and value of each item.

ˆ Write several cout statements to display each element of the array arr at
indices 0 through 4.

ˆ Write a cout statement that displays the element of arr at the index given
by the variable.

Note that "Iterate over all the elements of the array arr, displaying each
index and element value." translates to this code:

for ( unsigned int i = 0; i < SIZE; i++ )


{
cout << i << ". " << arr[i] << endl;
}

4.6.2 Dynamic arrays


ˆ Dynamic arrays are allocated on what kind of memory space?

ˆ How do we allocate space for a new dynamic array, via a pointer?

ˆ How do we free space from a dynamic array?

65
4.6.3 STL Array objects
Note the documentation page for Arrays: https://cplusplus.com/
reference/array/array/

ˆ Give example code on how to declare an array object.

ˆ Give example code on how to get the size of an array object.

ˆ Write an example for loop that iterates through all the elements of an
array object and couts each one.

4.6.4 STL Vector objects


Note the documentation page for Vectors: https://cplusplus.com/
reference/vector/vector/

ˆ Give example code on how to declare a vector object.

ˆ Give example code on how to get the size of a vector object.

ˆ Write an example for loop that iterates through all the elements of a vector
object and couts each one.

4.7 Unit 09: Branching


4.7.1 If statements
ˆ What is a boolean expression? What can its values be?

ˆ The contents of an if statement are executed when the CONDITION eval-


uates to. . .

66
ˆ Write out the form of an if statement.

ˆ Write out the form of an if/else statement.

ˆ Write out the form of an if/else if statement.

ˆ Fill out the relational operators:

Name Operator
Greater than
Greater than or equal to
Less than
Less than or equal to
Equal to
Not equal to

ˆ Fill out the logic operators:

Name Operator
and
or
not

4.7.2 Switch statements


ˆ Give an example of a switch statement that checks if variable num is 1, 2,
or 3.

ˆ A switch statement checks the value of a variable. What kind of relational


statement is it equivalent to? (Greater than? Less than? Equal to? Not
equal to?)

ˆ What does the default case do?

67
ˆ What does the break statement do?

ˆ What is ow-through?

ˆ What data type can't be used with switch?

4.8 Unit 13: Classes and Inheritance


4.8.1 Class
ˆ What is a class?

ˆ What is an object?

ˆ What is an access modier?

ˆ What is a member variable?

ˆ What is a member function?

ˆ How do you tell a member variable from a parameter variable when inside
of a class' function?

ˆ How do you declare a class? (Write down example code)

68
ˆ How do you declare an object variable of some class type? (Write down
example code)

ˆ What kind of le do class declarations go in?

ˆ What kind of le do class function denitions go in?

ˆ What does a class function denition function header look like? (it's a
little dierent from a non-class function)

4.8.2 Inheritance
ˆ What do the dierent accessibility settings mean?

 Public . . . Accessible by which of these?

* A. Everything

* B. The class and its family

* C. Just the class itself

 Protected . . . Accessible by which of these?

* A. Everything

* B. The class and its family

* C. Just the class itself

 Private . . . Accessible by which of these?

* A. Everything

* B. The class and its family

* C. Just the class itself

ˆ What is inheritance?

ˆ When a child inherits from a parent, which member variables and functions
are inherited?

69
ˆ Write some example code of how to use inheritance in a class' declaration.

ˆ What is composition?

ˆ How do you override a parents' version of a function from the child class?
How can you call the parents' version of a function from a child class'
function?

4.9 Unit 14: Strings and FIle I/O


4.9.1 Strings
Note the C++ documentation page for strings: https://cplusplus.
com/reference/string/string/

ˆ C++ strings are sequences of what kind of data type?

ˆ What function is used to get the amount of characters in a string? Write


out some example code for how to use it.

ˆ What operator is used to get a character at a certain index of a string?


Write out some example code for how to use it.

ˆ What operator is used to add on (concatenate) to the end of a string?


Write out some example code for how to use it.

ˆ What function is used to insert some text into the middle of a string?
Write out some example code for how to use it.

ˆ What function is used to erase some text in a string? Write out some
example code for how to use it.

70
ˆ What function is used to replace some text at some position in a string?
Write out some example code for how to use it.

ˆ What function is used to see if some text is in a string? Write out some
example code for how to use it.

4.9.2 File I/O


ˆ What library do you need to #include in order to read in and write out
to les?

ˆ When creating a le variable to read data from a text le, what data
type should that variable be?

ˆ How do you open a text le for an input le stream?

ˆ How do you check if loading the le failed?

ˆ Give an example of how to read string and numeric data from a text le
into variables in your program.

ˆ Write down how to use a while loop to read in every word or every line of
text from a text le.

ˆ When creating a le variable to write data to a text le with, what data
type should the variable be?

ˆ What function is used to open a text le for an output le stream? Give
some example code.

ˆ Give an example of how to write some text and variable values to a le
via an output le stream.

71
5 Reading

5.1 Unit 00: Welcome and setup


5.1.1 Welcome!
It feels weird to start a collection of notes (or a "textbook") without some sort
of welcome, though at the same time I know that people are probably not going
to read the introduction (Unless I put some cute art and interesting footnotes,
maybe.) I think that I will welcome you to my notes by addressing anxiety.

1. Belonging
Unfortunately there is a lot of bias in STEM elds and over decades there
has been a narrative that computer science is for a certain type of person
- antisocial, nerdy, people who started coding when they were 10 years
old.

Because of this, a lot of people who don't t this description can be hesi-
tant to get into computers or programming because they don't see people
like themselves in media portrayals. Or perhaps previous professors or
peers have acted like you're not a real programmer if you didn't start
programming as a child

If you want to learn about coding, then you belong here.

There are no prerequisites.

I will say from my own experience, I know developers who fell in love with
programming by accident as an adult after having to take a computer
class for a dierent degree. I know developers who are into all sorts of
sports, or into photography, or into fashion. There is no specic "type"
of programmer. You can be any religion, any gender, any color, from any
country, and be a programmer.

2. Challenge
Programming can be hard sometimes. There are many aspects of learning
to write software (or websites, apps, games, etc.) and you will get better
at it with practice and with time. But I completely understand the feeling
of hitting your head against a wall wondering why won't this work?! and
even wondering am I cut out for this?! - Yes, you are.
I will tell you right now, I have cried over programming assignments, over
work, over software. I have taken my laptop with me to a family holiday
celebration because I couldn't gure out this program and I had to get it
done!!

All developers struggle. Software is a really unique eld. It's very intan-
gible, and there are lots of programming languages, and all sorts of tools,
and various techniques. Nobody knows everything, and there's always
more to learn.

Just because something is hard doesn't mean that it is impossible.

72
Figure 1: Don't be like Gatekeeper Baby. You can begin coding at any age!

It's completely natural to hit roadblocks. To have to step away from your
program and come back to it later with a clear head. It's natural to be
confused. It's natural to not know.
But some skills you will learn to make this process smoother are how to
plan out your programs, test and verify your programs, how to phrase
what you don't know as a question, how to ask for help. These are all
skills that you will build up over time. Even if it feels like you're not
making progress, I promise that you are, and hopefully at the end of our
class you can look back to the start of it and realize how much you've
learned and grown.

3. Learning
First and foremost, I am here to help you learn.

73
My teaching style is inuenced on all my experiences throughout my learn-
ing career, my software engineer career, and my teaching career.

I have personally met teachers who have tried to scare me away from com-
puters, I've had teachers who really encouraged me, I've had teachers who
barely cared, I've had teachers who made class really fun and engaging.

I've worked professionally in software and web development, and indepen-


dently making apps and video games. I know what it's like to apply for
jobs and work with teams of people and experience a software's develop-
ment throughout its lifecycle.

And as a teacher I'm always trying to improve my classes - making the


learning resources easily available and accessible, making assignments help
build up your knowledge of the topics, trying to give feedback to help you
design and write good programs.

As a teacher, I am not here to trick you with silly questions or decide


whether you're a real programmer or not; I am here to help guide you to
learn about programming, learn about design, learn about testing, and
learn how to teach yourself.

74
4. Roadmap

When you're just starting out, it can be hard to know what all you're
going to be learning about. I have certainly read course descriptions and
just thought to myself "I have no idea what any of that meant, but it's
required for my degree, so I guess I'm taking it!"

Here's kind of my mental map of how the courses I teach work:

CS 200: Concepts of Programming with C++ You're learning the


language. Think of it like actually learning a human language; I'm
teaching you words and the grammar, and at rst you're just par-
roting what I say, but with practice you'll be able to build your own
sentences.

CS 235 Object-Oriented Programming with C++ You're learning


more about software development practices, design, testing, as well
as more advanced object oriented concepts.

CS 250 Basic Data Structures with C++ You're learning about data,
how to store data, how to assess how ecient algorithms are. Data
data data.

In addition to learning about the language itself, I also try to sprinkle in


other things I've learned from experience that I think you should know as
a software developer (or someone who codes for whatever reason), like

ˆ How do you validate that what you wrote actually works? (Spoilers:
How to write tests, both manual and automated.)

ˆ What tools can you use to make your programming life easier? (And
are used in the professional world?)

ˆ How do you design a solution given just some requirements?

ˆ How do you network in the tech eld?

75
ˆ How do you nd jobs?

ˆ What are some issues facing tech elds today?

Something to keep in mind is that, if you're studying Computer Science


as a degree (e.g., my Bachelor's degree is in Computer Science), technically
that eld is about "how do computers work?", not about "how do I write
software good?" but I still nd these topics important to go over.

That's all I can really think of to write here. If you have any questions,
let me know. Maybe I'll add on here.

5. What is this weird webpage/"book"?


In the past I've had all my course content available on the web on separate
webpages. However, maintaining the HTML, CSS, and JS for this over
time is cumbersome. Throughout 2023 I've been adapting my course con-
tent to emacs orgmode documents, which allows me to export the course
content to HTML and PDF les. I have a few goals with this:

(a) All course information is in one singular place

(b) At the end of the semester, you can download the entire course's
"stu" in a single PDF le for easy referencing later on

(c) Hopefully throughout this semester I'll get everything "moved over"
to orgmode, and in Summer/Fall 2024 I can have a physical textbook
printed for the courses, which students can use and take notes in so
as to have most of their course stu in one place as well

(d) It's important to me to make sure that you have access to the course
content even once you're not my student anymore - this resource is
available publicly online, whether you're in the course or not. You
can always reference it later.

I know a lot of text can be intimidating at rst, but hopefully it will be


less intimidating as the semester goes and we learn our way around this
page.

76
5.1.2 Tools for software development
1. What kind of tools are needed to make programs?

To write software, we need to write instructions - the program source


code is the list of instructions. This means we need some kind of text
editor program. To turn the program instructions into stu humans can
read into stu computers can read (that is, binary, or an executable le),
we need a compiler program.
These are the two things that are needed at minimum, but there are
plenty more tools to help us be more eective at our jobs. For instance,
if you use the default "Notepad" on Windows it's going to be a bunch
of black text on a white background. If you use a text editor meant for
code, however, you'll get syntax highlighting - which color-codes dierent
commands, helping us read the code more clearly.

1 # include < iostream >


2 using namespace std ;
3 int main ()
4 {
5 cout << " Hello , world ! " << endl ;
6 return 0;
7 }

Since we'll be writing a lot of dierent programs and referring back to


these programs throughout the semester you will also want to keep things
organized and backed up. There is special software that software devel-
opers use to keep track of their code changes over time, called source
control or version control. We will be using the Git version control
system in this course, though we are going to stick to the web interface
view for this introductory course.

77
5.2 Unit 01: Tech Literacy: Exploring computers
In this class we will be learning to write C++ programs for a computer, but
knowing why we do things in certain ways, or why things work the way they do,
often boils down to how the computer itself works. I would like to try to give
you some context about computers so you will be better prepared to understand
the topics we cover in the future.

5.2.1 Computing tools


Throughout history humans have needed to do math and store records.

Figure 2: Cuneiform tablet: inventory account, Ebabbar archive, Babylonian,


ca. 7th6th century BCE, Public Doamin, from https://www.metmuseum.org/
art/collection/search/321707

The earliest known writing system, Cuneiform, was used to store information
about inventory - how much of each thing do you have? How much copper did
you buy from Ea Nasir? And so on. Cuneiform tablets were a form of long-
term storage of records.
However, when someone needed to do math, they wouldn't write it out on a
tablet like we do on notebook paper. The Abacus was used to do computations.
This way you could have temporary data you work through, such as "add
this", "subtract that", on your way to get the nal value.
This is what we still use computers for today - long term storage, such as
storing data in a database, and short-term processing, such as calculating all
the items in your shopping cart, applying shipping and tax, and returning the
resulting cost.

5.2.2 User interface


Early computers did not have computer monitors like we use today, and didn't
even use keyboards hooked up directly to the computers. Instead, to create a
program for an old mainframe, you'd have to sit down at a punchcard typewriter,
type out your program on punchcards, then feed those cards into the computer.
Your program's output could be in the form of more punchcards, a sheet of
printed out paper, paper tape, and other things.

78
Figure 3: LEFT: Image of the TRS-80 Model I, image by Tim Colegrove/Pitti-
https://en.wikipedia.org/wiki/Commodore_PET , RIGHT: IBM
grilli, from
PC running GEM, image by Rolf Hartmann, from https://en.wikipedia.
org/wiki/History_of_the_graphical_user_interface

How we "talk" to a computer is referred to as Input, and how we receive a


response from a computer is known as Output. Together, it can be thought of
as an Interface.

Eventually, using a keyboard and a monitor became a standard method


for interacting with computers, especially with the personal computers in the
1970s-1980s. Even the computer Mouse wasn't common until later on. These
computers had a small amount of RAM for working-memory, and would use
oppy disks or casette tapes as long-term storage.
These systems were heavily text-based, though could draw rudimentary
graphics - usually for video games. These computers had a Command Line
Interface, or CLI.

Graphical User Interfaces (aka GUIs) became more mainstream in the


1990s, especially as the computer Mouse took o. As use of GUIs continued, a
type of standard evolved alongside it for how we interact - single-click, double-
click, click and drag, and so on. Similarly, a unique interface "language" has also
been developed for mobile phones. We don't usually "double-tap" the screen,
but a single-tap, a press-and-hold, or even swiping in dierent directions all map
to certain commands.

User Interfaces for our programs


In this course we are focusing on Command Line Interfaces (CLI), text based
interfaces where the interaction is mostly based around keyboard input from the
user and text output to the console. This helps us focus on learning about the
language itself, rather than getting bogged down in markup languages to build
a GUI, design, and the process of hooking up our "back end" (processing data)
to the "front end" (nice buttons, images, textboxes, etc.)

79
CLI programs are still created and used today, but usually by more technical
people - the average layperson tends to work exclusively in the GUI.

Tech Literacy discussion: Exploring software (U02.TEC.202406CS200):

ˆ Some examples of user input interfaces are the keyboard and mouse
of a computer. What other ways can you think of to interact with a
computer, giving it input?

ˆ Some examples of program output interfaces are displaying text to


the monitor or playing a sound eect. What other ways can you think
of that a computer gives you a response, as output?

5.2.3 Long-term storage: The Filesystem

Whether we're working on our phone, our computer, or a website that stores
data in "the cloud" (aka someone else's computer ), data that we want to pre-
serve between runs of the program (or even after we shut o and turn on our
computer again) goes in long-term storage. This includes information our
program processes, but also the program itself - we install software, it is saved
on the system's hard-drive, and we can use it when we want without re-installing
it each time.
As we work on our programs this semester we will be storing our source
code les on our computers (and on the GitLab servers :), and our programs
will also work with reading in and writing out to les, like text les, HTML
les, or CSV spreadsheets. Knowing how to navigate your system's lesystem
is important.

1. Files and Folders


Our computers organize things into Files and Folders. Folders (aka "di-
rectories") represent locations. Folders can contain other folders ("sub-
folders") or les. Files are all the rest - our text les, images, music,
videos, and so on. The actual data the computer stores, that we can read
and write.

80
Folders and les both have names, but les often also have extensions.
This is the information after the "." that species what kind of le it is:

File name File type


readme.txt Plain-text le
photo10.jpg jpeg photo le
song.mp3 mp3 audio le
video.mp4 mp4 video le
homework.docx Microsoft Word le
unit01.zip Compressed (zipped) le

In Windows it often turns o extensions by default. I would recommend


turning on extensions to make dierentiating your course project les more
easy. Check the Reference portion of the textbook for steps (search for
"Turning on viewing le extensions in Windows").

2. Paths
Each Operating System might store their lesystems dierently, but a
lot of the concepts are the same. A lesystem is conceptually based o of
paper folders (like in a le cabinet) where you have a lot of folders labeled,
and each folder can contain multiple les. If we didn't come up with some
way to organize the data on our computers it would be dicult to nd
everything in the jumbled mess.

Our system has some sort of root directory (or folder), like the roots of a
tree - the starting point. In Windows, it's often your C:\ drive. In Linux
and Mac, it's usually just labeled /. Often there are system folders in the
root directory, and then we have some kind of "home" or "my documents"
folder set aside for us to store our les in.

In a path, each folder is separated by a slash - in Windows, it's backslash


(\) and in Mac and Linux it's forwardslash (/).

ˆ Windows user directory: C:\Users\USERNAME\Documents


ˆ Linux/Mac user directory: /home/USERNAME/

As we navigate a lesystem, going into a subfolder will build up the direc-


tory path you're currently in. There is an "up" button on most lesystem
explorers as well, where the "up" command takes you out of your current
folder and back into its parent folder.

(a) Absolute paths and relative paths


When we type out a fullpath, such as
C:\Users\Singh\Homework\CS200\Project1.cpp
this is known as an absolute path. While we're working within our
programs, we can also use relative paths to locate nearby les.

81
Example: Homework
Let's say your CS 200 directory looks like this:

cs200/
- week1/
- laba.cpp
- labb.cpp
- myname.txt
- project1/
- data/
- savegame.txt
- hello.txt
- program.cpp
Our program is the program.cpp source le.
ˆ If we told our program to open hello.txt, we would retrieve
the hello.txt le in the same folder (project1/), without having
to type the entire absolute path
(/home/singh/cs200/week1/project1/hello.txt).

ˆ If we want to open the savegame.txt le, we would specify


the subfolder it is in as well as the lename: Program, open
data/savegame.txt.
ˆ If we wanted to access a le in the folder above the project1
folder, we could use the ../ relative path to go "up" one folder.
If our program wanted to load "myname.txt", we could reference
it as ../myname.txt.

82
5.2.4 Short-term processing: The CPU and RAM

Our program itself and the data it reads and writes all are stored on the hard-
drive in long-term storage, but long term storage is slow. When we're actively
working with something it needs to be loaded into a faster type of memory. RAM
(Random Access Memory) is the short-term working memory that a computer
uses. RAM is plugged into the computer's motherboard directly, while hard
drives are still usually hooked up with some kind of cable, which slows down its
access (input/output) speed.
While we're creating our programs, any time we create a variable it will
have a block of space set in RAM (well, the Operating System virtualizes it. . .
we're not accessing the RAM directly, but we can think of it that way for now).
While we don't have to worry about loading our program into RAM - the
operating system handles that and a lot of other things for us - we will have
a chance to look at memory addresses and how we can allocate memory for
additional data. Memory management and allocating memory for variables is a
big part of core computer science classes.

Figure 4: Block diagram of a basic uniprocessor-CPU computer. Black lines


indicate data ow, whereas red lines indicate control ow; arrows indicate
ow directions., image by Lambtron, from https://en.wikipedia.org/wiki/
Central_processing_unit

While the RAM stores the program's data, the CPU (Central Processing

83
Unit) handles doing the math operations. We're not going to go into how CPUs
work, though if you take a Computer Architecture class you will learn about
how they work and how they're designed. The main gist here is that the CPU
takes in inputs, does computations, and returns outputs.

5.2.5 The Operating System

Figure 5: Screenshot of the Windows 3.0 workspace, image by Tyomitch, from


https://en.wikipedia.org/wiki/Windows_3.0

All of our modern software runs on top of some Operating System, whether
that's something like Android on a phone, Windows on a computer, or whatever
kind of operating system your game console runs on top of. The Operating
System is a special type of software that acts as an intermediary between your
computer's hardware and its software. It helps us so that we don't have to know
exactly how the wi works, or exactly how to work with xyz brand of keyboard
- the Operating System uses programs called drivers to work with those things
itself.
Operating Systems you might have used are: Windows, Linux, Mac, iOS,
Android. If you're older, you might have used DOS as well! (I used DOS in the
1990s to load some of my video games, mostly.)

The Software we run are the programs or apps themselves: Our web browser
(Firefox, Chrome), the bank app we use, a document writer (MS Word, LibreOf-
ce). Software is often built to be packaged and shared or sold to other people,
though you can also write our own little software utilities for personal use once
you have enough experience.

84
Tech Literacy discussion: Exploring software (U02.TEC.202406CS200):

ˆ Give an example of a phone app that you use.

ˆ Give an example of desktop software that you use.

ˆ What kind of program would you like to write, if you can think of
anything?

5.2.6 What is Software?


A computer needs to be told how to do everything. If you were writing a
program totally from scratch, you would have to tell it how to load a bitmap
le, how to draw a rectangle, how to detect mouse clicks, how to animate a
transition, and everything else. However, software has been evolving for decades
now, and a lot of these features are already implemented in libraries. Libraries
are sets of pre-written code meant for other programs to import and use.

With some of the rst computers, the only commands you could program in
directly mapped to the CPU on the machine. This type of code was called ma-
chine code or assembly. Later, developers such as Grace Hopper worked on ways
to write code that lets you t multiple machine-code-pieces into one command
that was more human-readable, leading to early languages like COBOL. Many
of these "higher-level" languages (higher-level meaning further from the hard-
ware; more abstracted) eventually will get turned into machine code through a
process called compiling.

Example: Displaying "Hello, world!" output in C++:


1 # include < iostream > // Load input / output library
2 using namespace std ; // C ++ standard libraries
3
4 int main ()
5 {
6 // Display message to screen
7 cout << " Hello , world ! " << endl ;
8 // Quit
9 return 0;
10 }

85
Example: Displaying "Hello, world!" output in MIPS Assembly:
1 . data
2 Hello : . asciiz " \ n Hello , world ! "
3
4
5 . globl main
6
7 . text
8
9 main :
10 # load syscall ; address of string ( set up for string
output )
11 li $v0 , 4
12 # load address of string into parameter $a0
13 la $a0 , Hello
14 # display
15 syscall

Compiled languages aren't the only variety - Java runs in a Java Virtual
Machine, and Python is a scripting language that runs via a Python executable.
But we're focusing on C++ here.  The point is, modern software is built on
top of many layers: high-level languages that compile down to machine code,
pre-written libraries of code that handle common features for the programmers
so they don't have to reinvent the wheel.

1. How programs work


Since a computer needs to be told how to do everything, a computer
program is a list of very specic instructions on how to execute some task
(or tasks, for larger programs).

Figure 6: Inputs and Outputs

(a) Inputs
Some programs don't take any input and just run a set of pre-dened
instructions. Most programs do take some form of input, however,
whether that's when the program rst starts up or during its runtime.

Inputs could include things like passing in a lename to a program


(e.g., please open this le) or other pieces of data, or getting keyboard

86
input, gamepad input, mouse input, touch screen input, or receiving
signals via the network or internet.

(b) Outputs
Programs also often will return some form of output, but this is also
optional. If a program doesn't return output, maybe the user just
wants to tell the program to do a job, but doesn't need conrmation
that the job was done (these are usually called background processes).

Outputs could be something like displaying a message box, changing


text on the screen, playing a sound, or writing out a text le.

Figure 7: Variables

(c) Variables
Our program may also use variables to store data during its execu-
tion. Variables are locations in memory (RAM) where we can store
numbers, text, or more complex objects like an image. We give vari-
ables a name to reference it by, such as userName or cartTotal, and
we can do math operations on it, as well as write it to the screen or
read new values into it from the user.

(d) Branching and looping

Figure 8: A owchart diagram of a "decision diamond" that branches in one of


two directions.

We can also change the instructions our program runs based on some
condition we set. For example, if bankBalance < 0 then maybe we
display an error message. Otherwise, we can withdraw some amount
of money from the bankBalance.

87
Figure 9: A owchart diagram of a "decision diamond" that loops back on itself.

We may also want to take advantage of looping to do a set of instruc-


tions repeatedly, possibly with some variables changing each time
through the loop. An example for this could be to loop over all of
a student's assignmentGrades, adding up all the points so we can
nd an average.

2. Example programs

(a) Area calculator


This program asks the user to enter a width and a height and then
calculate the area of the rectangle with the given information.

1 cout << " Width : "; // Display message


2 cin >> width ; // Get user input
3
4 cout << " Height : " ; // Display message
5 cin >> height ; // Get user input
6
7 area = width * height ; // Do math
8
9 cout << " Area : " << area << endl ;

(b) ATM - Withdrawing money


This program asks the user how much they'd like to withdraw from
their account. If the withdraw amount is more than their account
balance, then an error message is displayed. Otherwise, the amount
is withdrawn from their bank account.

1 cout << " Withdraw : " ; // Display message


2 cin >> withdrawAmount ; // Get user input
3
4 if ( withdrawAmount > bankBalance )
5 cout << " Error ! Not enough money . " << endl ;
6 else
7 bankBalance = bankBalance - withdrawAmount ;

88
3. C++ Programs
Each programming language is a little dierent in how it looks, but whether
you're using C++, Java, C#, Python, or many other languages, you'll still
encounter branching with if statements, looping, functions, and classes
(though older languages may not have classes at all, like C!).

(a) main(): The starting point


With C++, Java, and C#, programs must begin in a function called
`main()`. The compiler (that turns the program into machine code)
is always expecting `main()` to be there and to begin running the
program at the top of it.

(b) Basic C++ syntax


In C++, Java, C#, and other C-like languages, there are some basic
rules of syntax you should know about:

i. Lines of code:
A code statement ends with a semi-colon. Statements are single
commands like cout (console-out) to display text to the output,
cin (console-in) to read input from the keyboard, declaring vari-
ables, assigning variables, or doing math operations.

ii. Variable names:


There are some rules for naming variables in C++. Generally,
you can use any upper or lower case letters, numbers, and un-
derscores in variable names - no spaces allowed. Beyond that,
variables cannot begin with a number, and you cannot use a
keyword (such as if) as a variable name.

iii. Code blocks:


There are certain types of instructions that contain additional
code. If statements, for example, contain a set of instructions
to execute only if its condition evaluates to `true`. Any time
an instruction contains other instructions, we use opening and
closing curly braces {} to contain this internal code. Addition-
ally, with these instructions, they do not end with semicolons.

iv. Comments:
It is often useful to add comments to programs to specify what
is going on in the code. There are two ways to add comments
in C++. Generally, you can use any upper or lower case letters,
numbers, and underscores in variable names - no spaces allowed.
Beyond that, variables cannot begin with a number, and you
cannot use a keyword (such as if) as a variable name.

v. Whitespace and code cleanliness:


Generally, C++ doesn't care if multiple commands are on one
line or several lines. The compiler is going to compile it all ei-
ther way. You should, however, care about the code's readability

89
to humans. Add enough new lines to separate sections of a pro-
gram, use consistent indentation, and give variables descriptive
names.

When writing code inside of a code block, you should


always tab forward internal code by one tab:
1 if ( order == " dessert " )
2 {
3 // One tab forward
4 cout << " Order : dessert " << endl ;
5
6 if ( have_cake )
7 {
8 // One more tab forward
9 cout << " You get cake ! " ;
10 }
11 else
12 {
13 // One more tab forward
14 cout << " Sorry , we ' re out of dessert ! " ;
15 }
16 }

5.2.7 Diagnosing, testing, and debugging

Software is an amorphous, intangible thing of arbitrary complexity. It's bad


enough when you're working alone, but once you get other people involved at
varying skill levels (and varying levels of writing clean code), the amount of
potential issues can quickly skyrocket.
There are techniques to writing software that can help you validate your
own logic and check for errors before they occur, as well as tools to help you
diagnose and debug issues, as well as error messages to also help give hints
to what's going wrong. All of these things are important to becoming a good
software developer.

90
1. Syntax errors
The best type of error you can get is a syntax error, even though it may
feel bad to get them. Syntax errors are when you have a typo or have
otherwise miswritten a statement in the code, and the compiler doesn't
know what to do with it. It will then display a build error telling you
what it needs. Diagnosing syntax error messages can be confusing at
rst: often the compiler doesn't know exactly what's wrong, just what it's
expecting. But, the good thing about syntax errors is that your program
won't run if it can't build - that means you must x these errors before
continuing. It also means that these errors can't just be hidden in the
code, like other error types.

2. Logic errors
Another type of error that's much harder to track down are logic errors.
Logic errors can be errors in formulas, bad if statement conditions, or
other things that don't do what the programmer was intending to do
(again, either because of a typo, or not quite understanding the program
ow, or for other reasons). Logic errors don't show up in the error list, but
can cause your program to crash down the line - or worse, never crash but
create bad output. Because it's not crashing, you may assume everything
is working ne, but incorrect output can cause problems.

3. Runtime errors
When a logic error causes the program to crash while it's running, it is
called a runtime error.

4. Testing
Programs need to be tested. Starting o, you will probably be manually
running the program, entering inputs, and checking outputs. However,
this gets tedious after a while and you'll probably start entering gibberish
as inputs and assuming everything works if it outputs something. Man-
ual testing is good to do, but it is easy to become sloppy. You can also
write code to automatically test certain things for you. This will become
more relevant to us once we're working with functions in C++.

The main idea behind testing is that programs or functions will be taking
some sort of inputs, and given those inputs you have some expected
outputs or results. If the actual outputs don't match the expected
outputs, then there is something wrong.

We will cover testing techniques more later on.

5. Coding techniques for newbies


When you're rst starting with C++, it can feel like your code just never
works. It can be good to adopt a few of these practices while you're still
new, to minimize errors and frustration:

91
ˆ Compile often: Get into the habit of using keyboard shortcuts to
build your code after every few lines - especially when you're rst
starting out. If you write two lines of code and get a syntax error,
it's much easier to diagnose than if you write a whole program and
then build.

ˆ Search for syntax error messages: Most of these messages have


been posted about before on boards like Stack Overow. Reading
through these can help give you insight into what the error means,
and common ways to x them.

ˆ Comment things out: If you have a lot of code but can't get it
compiling and aren't sure what to do, you can comment out large
chunks of the program until it builds again. Then, bit by bit, un-
comment out dierent regions until you nd what's causing the build
error.

These practices can help you become a more ecient and eective pro-
grammer, especially when you're rst starting out. Debugging and testing
are essential skills for any programmer, and learning them early can save
you a lot of time and frustration in the long run.

92
5.3 Unit 02: C++: Variables, pointers, input, and output
5.3.1 main(): The starting function
The bare-minimum C++ program looks like this:

1 int main ()
2 {
3
4 return 0;
5 }

No matter what all is in your program, your compiler is going to expect


that a main function exists, and this function acts as the starting point of a
C++ program.

Compiler?
A compiler is a program that converts your code (such as C++ code)
into an executable le that your computer can run.

The opening curly-brace { and closing curly-brace } denote the start and
end of the main function. The curly-braces and any code within is known as a
code-block. Program instructions will go within this code-block.

At the end of the main function we have return 0;. In this context, it means
"return (exit) the program with a status of 0", with that basically meaning
"return with no errors". If you ran into an error while the program was running,
you might do something like return 123; instead, to mark the area with an
"error code" (123), which you can then nd in the code.

For our programs starting o, we will be putting our instruction code after
the opening curly-brace { and before the return 0;, but the code given above
is the absolute, bare-minimum required to write a C++ program.

C++ source code les will end in the extension ".cpp" on your computer.
A le extension helps you and the computer identify what a le does and how
to open it, like a ".txt" le can be opened in a text editor like Notepad.

For information on how to create a project and build and run your code,
check the "Reference" section, where steps are given.

93
5.3.2 Variables: Storing our data

1. What are variables?

Intro

Variables are named locations where we can store information.

We use variables in programming as places to temporarily store data so


that we can manipulate that data. We can have the user write to it via the
keyboard, we can use les to write data to variables, we can do math op-
erations or modify these variables, and we can print* them back out to the
screen or a text le.(*Printing here meaning "display on the screen"; not to a printer.)

When we're writing programs in C++, we need to tell our program what
thedata type of each variable is, and give each variable a variable
name (aka identier). When a variable is declared, a space in RAM is
allocated to that variable and it can store its data there. That data can
be manipulated or overwritten later as needed in the program.

Some examples of things we might store as variables:


ˆ A student's information:

 string studentName, the name of a student


 float studentGpa, the GPA of that student
 int creditHoursCompleted, the total amount of credit hours
the student has completed

 bool activeStudent, whether the student is an active student


or not (e.g., graduated?)

ˆ A store website's item listing:

 string name, the name of the product


 float price, the price of the product
 int quantity, how much of this product is in stock

94
2. Data types
In C++, when we want to create a variable we need to tell the compiler
what the data type of the variable is. Data types specify what is stored
in the variable (whole numbers? numbers with decimal values? text?
true/false values?). Each data type takes up a dierent amount of space
in memory.

Data Values Size Example code


type

char single symbols - letters, 1 byte char currency = '$';


numbers, anything

boolean true or false 1 byte bool savedGame = false;

integer whole numbers 4 bytes int age = 100;

oat numbers w/ decimals 4 bytes float price = 9.95;

double numbers w/ decimals 8 bytes double price = 1.95;

string any text, numbers, 4 bytes string password = "123secure";


symbols, any length

ˆ Floats and doubles both store numbers with fractional (decimal)


parts, but a double takes updouble the memory in RAM, allow-
ing to store more accurate fractional amounts. A oat has 6 to 9 dig-
its of precision and a double has 15 to 18 digits of precision. (From
https://www.learncpp.com/cpp-tutorial/floating-point-numbers/)
ˆ Boolean data types store true and false values, but will also accept
integer values when assigned. It will convert a value of 0 to false
and any other number to true.
ˆ String variables' values must be written within double quotes "Hello!"
ˆ Character variables' values must be written within single quotes
'Z'

(a) Additional information: Unsigned data types


Sometimes it doesn't make sense to store negative values in a variable
- such as speed (which isn't directional, like velocity), the size of a
list (can't have negative items), or measurement (can't have negative
width). You can mark a variable as unsigned to essentially double
its range (by getting rid of the negative side of values). For instance,
a normal int can store values from -2,147,483,648 to 2,147,483,647,
but if you mark it as unsigned, then your range is 0 to 4,294,967,295.

95
3. Declaring variables and assigning values to variables
(a) Variable declaration
When we're declaring a variable, it needs to follow one of these
formats:

Declaration forms

ˆ DATATYPE VARIABLENAME;
ˆ DATATYPE VARIABLENAME = VALUE;
ˆ DATATYPE VAR1, VAR2, VAR3;
ˆ DATATYPE VAR1 = VALUE1, VAR2 = VALUE2;

The data type goes rst, then the variable name/identier, and
if you'd like, you can also assign a value during the same step
(though this is not required). Once a variable has been declared,
you don't need to declare it again. This means you don't need to re-
specify its data type when you're using it. Just address the variable
by its name, and that's all.

Example: Code that uses integers to gure out how many


candies each kid should get:
1 // Declaring variables and assigning values
2 int totalCandies {10};
3 int totalKids {5};
4 int candiesPerKid { totalCandies / totalKids };
5
6 // Reusing the same variables later on
7 totalCandies = 100;
8 totalKids = 10;
9 candiesPerKid = totalCandies / totalKids ;

Example: Code to display the price plus tax to the user:


1 float price = 9.99;
2 float tax = 0.11;
3 // Text output to the screen . Can do math within !
4 cout << " Please pay " << ( price + price * tax ) ;

i. Additional information: Modern C++: auto


In C++11 (from 2011) and later, you can use the keyword auto
as the "data type" in your variable declaration that includes an
assignment statement. When you use auto, it uses the assigned
value to automatically gure out the variable's data type, so you
don't have to explicitly dene it:

1 auto price = 9.99; // it 's a double !


2 auto price2 = 2.95 f ; // it 's a float !
3 auto player = '@ '; // it 's a char !
4 auto amount = 20; // it 's an int !

96
(b) Variable assignment

Assignment forms

ˆ Stores the LITERAL value in VARIABLENAME:


VARIABLENAME = LITERAL;
ˆ Copies the value from VARIABLENAME2 to VARIABLE-
NAME1.:
VARIABLENAME1 = VARIABLENAME2;

When assigning a value to a variable, the variable being assigned


to always goes on the left-hand side ("LHS") of the equal sign =.
The = sign is known here as the assignment operator.

The item on the right-hand side ("RHS") will be the value stored
in the variable specied on the LHS. This can be a literal (a hard-
coded value) or it can be a dierent variable of the same data type,
whose value you want to copy over.

Example: Assigning literal values to variables:


1 price = 9.99; // 9.99 is a float literal
2 state = " Kansas " ; // " Kansas " is a string literal
3 operation = '+ '; // '+ ' is a char literal

Example: Copying student3's value to the bestStudent vari-


able:
1 // Declare and initialize our variables
2 string student1 = " Hikaru " ;
3 string student2 = " Umi " ;
4 string student3 = " Fuu " ;
5 string bestStudent ;
6
7 // Assignment statement
8 bestStudent = student3 ;

97
(c) Variable initialization
When we declare a variable and give it a value in the same
line of code, that is called initialization. The equal sign can be used
in this regard:

1 string productName = " Candybar " ;


2 float productPrice = 3.25;

But with more modern C++, it's recommended that we use braced
initialization :
1 string productName { " Candybar " };
2 float productPrice { 3.25 };

You might see both of these ways used to initialize variables in


starter code.

Garbage!

If a variable is not initialized with some value, it will have some


garbage value assigned to it - whatever was left over in the
memory space where it was created. This data isn't useful to
us, and usually shows up as random large numbers (12734827),
so it's good to make sure to initialize your variables!

98
(d) Named constants
Whenever you nd yourself using a literal value in your assignment
statements, you may want to think about whether you should replace
it with a named constant instead.

Declaration form

ˆ const CONSTNAME = LITERAL;

A named constant looks like a variable when you declare it, but it
also has the keyword const - meaning that the value can't change
after its declaration.

Let's say you wrote a program and hard-coded the tax rate:

1 // Somewhere in the code ...


2 totalPrice = cartTotal + ( cartTotal * 0.0948 ) ;
3
4 // Somewhere else in the code ...
5 cout << 0.0948 << " sales tax " << endl ;

Then the tax rate changes later on. You would have to go into your
program and search for "0.0948" and update all those places! Instead,
it would have been easier to assign the tax rate ONCE to a named
constant and referred to that instead:

1 // Beginning of program somewhere ...


2 const SALES_TAX = 0.0948;
3
4 // Somewhere in the code ...
5 totalPrice = cartTotal + ( cartTotal * SALES_TAX ) ;
6
7 // Somewhere else in the code ...
8 cout << SALES_TAX << " sales tax " << endl ;

If you ever nd yourself using the same literal multiple times in your
program, then perhaps consider replacing it with a named constant.

99
4. Naming conventions
While you can generally name a variable whatever you'd like, you still
need to adhere to the syntax rules of the C++ language. In particular:

ˆ Names can only contain letters (upper- and lower-case), num-


bers, and underscores.
ˆ Spaces are not allowed in a variable name!
ˆ Names cannot start with a number.

ˆ A name cannot be a keyword in C++, a name reserved for some-


thing else in the language, such as void, if, int, etc.

There are also naming conventions used so that variables (and later on
functions and structs/classes) have a consistent naming scheme:

ˆ Variables:

 One common style is lowerFirstLetterThenUpperCase for vari-


able names - this is called Camel Case.
 Another style you might see in C++ code is all_lower_with_underscores.
 You might see both of these styles in my starter code or examples,
but I try to stick to one style for a program. You should also
choose one and stay consistent in each program.

ˆ Named constants:

 It is customary to give your named constants names in ALL


CAPS, using underscores (_) to separate words. For example:
TOTAL_STUDENTS, OP_TAX_RATE, etc.

Everything in C++ is case sensitive, which means if you name a variable


username, it will be a dierent variable from one named userName (or if
you type "userName" when the variable is called "username," the compiler
will complain at you because it doesn't know what you mean).

100
5. Basic operations on variables
Now that you have variables available in your program to play with, what
can you even do with them?

(a) Outputting variable values


Using the cout (console-out) statement, you can display text to the
screen with string literals:

1 cout << " Hello , world ! " << endl ;

But you can also display the values stored within variables, simply
by using the variable's name:

1 cout << myUsername << endl ;

You can also chain as many literals, variables, and commands to-
gether as long as they have the output stream operator << in-between.
1 cout << " Student : " << name
2 << endl << " GPA : " << gpa
3 << endl << " Year : " << year << endl << endl ;

(b) Inputting variable values


We can use the cin (console-in) statement to get the user to enter
something on the keyboard and store that data into a variable:

1 float gpa ;
2 cin >> gpa ;

cin >> can be used on strings, but it will not read anything after a
space. Instead, we use the getline function to read whole lines of
text into string variables:

1 string oneLine ;
2 getline ( cin , oneLine ) ;
3
4 string oneWord ;
5 cin >> oneWord ;

There will be more information on input and output in a later section.

101
(c) Math operations
With variables with numeric data types (ints, oats, doubles), we
can do arithmetic with the +, -, *, and / operators.

1 cout << " Sum : " << num1 + num2 + num3 << endl ;

Operations:

Symbol Description
+ Addition
- Subtraction
* Multiplication
/ Division

Make sure to put the result somewhere! When you do a math


operation and you want to use the result elsewhere in the program,
make sure you're storing the result in a variable via an assignment
statement! If you just do this, nothing will happen:

1 totalCats + 1;

You can use an assignment statement to store the result in a new


variable:

1 newCatTotal = totalCats + 1;

Or overwrite the variable you're working with:

1 totalCats = totalCats + 1;

(d) Compound operations: There are also shortcut operations you


can use to quickly do some math and overwrite the original variable.
This works with each of the arithmetic operations:

1 // Long way :
2 totalCats = totalCats + 5;
3
4 // Compound operation :
5 totalCats += 5;

102
(e) String operations
Strings have some special operations you can do on them. You can
also see a list of functions supported by strings here: C++ String
Reference (We will cover more with strings in a later part).

i. Concatenating strings
You can use the + symbol to combine strings together. When
used in this context, the + sign is called the concatenation op-
erator.

1 string type = " pepperoni " ;


2 string food = " pizza " ;
3
4 // Creates the string " pepperoni pizza "
5 string order = type + " " + food ;

ii. Letter-of-the-string
You can also use the subscript operator [ ] (more on this when
we cover arrays) to access a letter at some position in the string.
Note that in C++, the position starts at 0, not 1.

1 string food = " pizza " ;


2
3 char letter1 = food [0]; // Stores 'p '
4 char letter2 = food [1]; // Stores 'i '
5 char letter3 = food [2]; // Stores 'z '
6 char letter4 = food [3]; // Stores 'z '
7 char letter5 = food [4]; // Stores 'a '

6. Review questions:
(a) Before a variable can be used, it must be. . .

(b) "LHS" stands for. . .

(c) "RHS" stands for. . .

(d) The "assignment operator" is. . .

(e) A "literal" is. . .

(f ) How do you write a variable declaration?


(g) How do you write a variable initialization?

(h) How do you write a variable assignment?

(i) What does the auto keyword do?

(j) What does marking a variable unsigned mean?

(k) What does case sensitive mean?

103
5.3.3 Introduction to memory addresses and pointer variables

1. Bits and Bytes


When we declare a variable, what we're actually doing is telling the com-
puter to set aside some memory (in RAM) to hold some information.
Depending on what data type we declare, a dierent amount of memory
will need to be reserved for that variable.

Data type Size


boolean 1 byte
character 1 byte
integer 4 bytes
oat 4 bytes
double 8 bytes

A bit is the smallest unit, storing just 0 or 1. A byte is a set of 8 bits.


With a byte, we can store numbers from 0 to 255, for an unsigned number
(only 0 and positive numbers, no negatives).

The minimum possible value for 1 byte is 0.


(Decimal value = 128 · 0 + 64 · 0 + 32 · 0 + 8 · 0 + 4 · 0 + 2 · 0 + 1 · 0)

place 128 64 32 16 8 4 2 1
value 0 0 0 0 0 0 0 0

The maximum possible value for 1 byte is 255.


(Decimal value = 128 · 1 + 64 · 1 + 32 · 1 + 8 · 1 + 4 · 1 + 2 · 1 + 1 · 1)

place 128 64 32 16 8 4 2 1
value 1 1 1 1 1 1 1 1

Some data types, like a Boolean and a Character, use only 1 byte. But oth-
ers, like Integers and Floats, use more. Since an integer uses 4 bytes, that
means it has 8·4 = 32 bits available to store data. 232 = 4, 294, 967, 296,
so oats and integers can store this many dierent values. (Note that this
doesn't mean that an integer goes from 0 to 4,294,967,296, because we
have to account for negative values.)

104
2. Memory addresses
Whenever a variable is declared, we need space to store what its value
is. We have already looked at how many bytes a data type takes up,
but where is the variable's data stored?  In working memory. You can
think of this as the RAM, though the Operating System interacts with
the RAM and gives us a "virtual memory space" to work with. But, to
keep it simple, we will think of this as the RAM.

Each block of space in memory has a memory address, one after an-
other. . .

Bit address 0 1 2 3 4 5 6 7

Though to the computer, it represents these addresses in binary (base 2)


or hexadecimal (base 16):

Address 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07

Hexadecimal goes from 0 to 16, but values from 10 and up are represented
with letters. This is so each "number" in the value only takes 1 character
(10 is two characters: 1 and 0). So, a quick reference for hexadecimal is
like this:

Base 16 (Hex) A B C D E F
Base 10 10 11 12 13 14 15

105
Example: Variable in memory
Let's say we're investigating some blocks of memory.

If we declare a char, which gets 1 byte, it will take up any available


memory where 8 bits are available side-by-side. Some blocks in memory
might already be taken, so whatever is available will be used:

Address Variables (BEFORE) Address Variables (AFTER)


0x0 (used) 0x0 (used)
0x1 (used) 0x1 (used)
0x2 0x2 char1
0x3 0x3 char1
0x4 0x4 char1
0x5 0x5 char1
0x6 0x6 char1
0x7 0x7 char1
0x8 0x8 char1
0x9 0x9 char1
0xA(10) (used) 0xA(10) (used)
0xB(11) (used) 0xB(11) (used)
0xC(12) 0xC(12)
0xD(13) 0xD(13)
0xE(14) (used) 0xE(14) (used)
0xF(15) (used) 0xF(15) (used)

In this case, declaring our variable,

1 char char1 = 'A ';

its data will be placed with its rst bit at address 0x2.

We can use the address-of operator & to see what any variable's address
in memory is:

1 cout << " Value : " << char1 << " \ t " ;
2 cout << " Address : " << & char1 << endl ;

Getting the address-of a variable will return the address of its rst bit, so
the output here would be:

Value : A Address : 0 x2

(Again, keep in mind that the representation of addresses here is simpli-


ed.)

106
Example: Variable value in memory
We can see where the variable is stored at in memory, but let's look at
how it's value will be stored as well. Given the declaration:

1 char char1 = 'A ';

The value of 'A' is stored in 1 byte. Technically, our computer stores the
letter "uppercase A" as the number code 65. This can be converted into
binary: (65)10 = 0100 0001. This is the data that would be stored in
that memory address.

Address Variables Value

0x0 (used)
0x1 (used)
0x2 char1 0
0x3 char1 1
0x4 char1 0
0x5 char1 0
0x6 char1 0
0x7 char1 0
0x8 char1 0
0x9 char1 1
0xA(10) (used)
0xB(11) (used)
0xC(12)
0xD(13)
0xE(14) (used)
0xF(15) (used)

This is just a basic representation, again. One thing you'll learn more
about in future Computer Science courses is endian-ness, such as whether
a number has its most-signicant bit on the left side or the right side.
We're not worrying about that here. :)

107
3. Pointer variables
Pointer variables are another type of variable, but instead of storing a
value like "ABC", 'X', 10.35, or 4, it stores a memory address instead.

(a) Pointer declaration


When we declare a normal variable, we have to specify its data type.
With a pointer variable, we specify the data type of the data it's
pointing to, plus the * character (after the data type) to show that
this is a pointer variable.

Declaration forms

ˆ DATATYPE* PTRNAME;
ˆ DATATYPE * PTRNAME;
ˆ DATATYPE *PTRNAME;
ˆ DATATYPE* PTRNAME = nullptr;
ˆ DATATYPE* PTRNAME{nullptr};

The pointer variable declaration takes the same form as a normal


variable's declaration except we have to put the asterisk * after the
data type. The asterisk can be attached to the data type, the name,
or free-standing, it doesn't really matter, but I prefer keeping it with
the data type.

Safety with pointers!

Remember how variables in C++ store garbage in them ini-


tially? The same is true with pointers - it will store a garbage
memory address. This can cause problems if we try to work with
a pointer while it's storing garbage.

To play it safe, any pointer that is not currently in use should


be initialized to nullptr (or NULL if you're going back to plain
old C language :).

108
(b) Pointer assignment
Once we have a pointer, we can point it to the address of any variable
with a matching data type. To do this, we have to use the address-
of operator to access the variable's address - this is what gets stored
as the pointer's value.

Assignment forms

ˆ Assigning an address during declaration:


int* ptr = &somevariable;
ˆ Assigning an address after declaration:
ptr = &somevariable;

After assigning an address to a pointer, if we cout the pointer it will


display the memory address of thepointed-to variable - just like if we
had used cout to display the address-of that variable.

Example: A variable and a pointer


1 // Declare normal variable
2 int someVariable = 100;
3
4 // Declare pointer variable ,
5 // point to someVariable 's address
6 int * ptr = & someVariable ;
7
8 // Both show someVariable 's address
9 cout << & someVariable ;
10 cout << ptr << endl ;

109
(c) Dereferencing pointers to get values
Once the pointer is pointing to the address of a variable, we can
access that pointed-to variable's value by dereferencing our pointer.
This gives us the ability to read the value stored at that memory
address, or overwrite the value stored at that memory address. We
dereference the pointer by prexing the pointer's name with a * -
again, another symbol being reused but in a dierent context.

Dereference forms

ˆ Displaying pointed-to value:


cout << *ptr;
ˆ Overwriting pointed-to value:
*ptr = 200;
ˆ Overwriting pointed-to value with user input:
cin >> *ptr;

Example: A variable and a pointer


1 // Declare normal variable
2 int someVariable = 100;
3
4 // Declare pointer variable ,
5 // point to someVariable 's address
6 int * ptr = & someVariable ;
7
8 // Both show someVariable 's address
9 cout << & someVariable ;
10 cout << ptr << endl ;
11
12 // Both show someVariable 's value
13 cout << someVariable << endl ;
14 cout << * ptr << endl ;

4. Pointer cheat sheet

Declare a pointer int* ptrInt;


float *ptrFloat;

Assign pointer to address ptrInt = &intVar;


ptrFloat = &floatVar;

Dereference a pointer cout << *ptrChar;


*ptrInt = 100;

Assign to nullptr float *ptrFloat{nullptr};


ptrChar = nullptr;

110
5.3.4 Input and output: Interacting with the user
1. Interactivity and Output in C++
Most programs feature interactivity in some way or another. This can
involve moving a mouse around, clicking on things, tapping on a touch
screen, using a gamepad's joysticks and buttons, but we'll be primarily
interacting with our C++ programs through keyboard input. Feedback
from our C++ programs will come in the form of text output to the screen,
as we are writing terminal programs.

Enter number 1: 1300


Enter number 2: 37

1300 + 37 = 1337

We will also delve into reading from and writing to text les (or other le
formats) later on. But for now, let's focus on the terminal/console.

Terminology

"Terminal", "Console", "Bash", "Command Line" tend to be used


interchangably. A terminal is a text-based interface you can use to
interact with your computer. In order to start simple with introduc-
tory programming, we begin by just thinking about Command Line
Interfaces and writing programs that deal with text.

111
2. Outputting Information with cout
The cout command (pronounced as "c-out" for "console-out") is used
to write information to the screen. This can include outputting a string
literal:

1 cout << " Hello , world ! " << endl ;

or a variable's value:

1 cout << yourName << endl ;

or stringing multiple things together:

1 cout << " Hello , " << yourName << " ! " << endl ;

In C++, we use the output stream operator << to string together


multiple items for our output.

(a) Newlines with endl


The endl command stands for "end-line" and ensures there is a
vertical space between that cout statement and the next one. For
example, if we write two cout statements without endl like this:
1 cout << " Hello " ;
2 cout << " World " ;

the output will be:

HelloWorld

If we want to separate them on two dierent lines, we can write:

1 cout << " Hello " << endl ;


2 cout << " World " ;

And our output will be:

Hello
World

Remember that in C++, a statement ends with a semicolon ;, so you


can split your cout statement across multiple lines, as long as you're
chaining items together with << and only adding a ; on the last line:
1 cout << " Name : " << name
2 << " Age : " << age
3 << " State : " << state << endl ;

112
3. Inputting Information with cin
When we want the user to enter a value for a variable using the keyboard,
we use the cin command (pronounced as "c-in" or "console-in").

For variables like int and oat, you will use this format to store data from
the keyboard into the variable:

(a) Using cin >> for variables


1 cin >> VARIABLENAME ;

You can also chain cin statements together to read multiple values
for multiple variables:

1 cin >> VARIABLENAME1 >> VARIABLENAME2 >> ETC ;

(b) Strings and cin >>


When using cin >> with a string variable, keep in mind that it will
only read until the rst whitespace character, meaning it can't cap-
ture spaces or tabs. For example:

1 string name ;
2 cin >> name ;

If you enter "Rachel Singh", name will contain "Rachel". To capture


spaces, you need to use a dierent function.

(c) Using getline(cin, var); for Strings


You can use the getline function to capture an entire line of text as a
string. This is useful when you want to capture spaces and multiple
words. For example:

1 string name ;
2 getline ( cin , name ) ;

(d) Mixing cin >> var; and getline(cin, var);


If you mix cin >> var; and getline(cin, var);, you might en-
counter issues with the input buer. To avoid this, use cin.ignore();
before getline(cin, var); if you used cin >> var; before it.
1 int number ;
2 string text ;
3
4 cin >> number ;
5 cin . ignore () ;
6 getline ( cin , text );

113
(e) Escape Sequences
There are special characters, called escape sequences, that you can
use in your cout statements:

Character Description
\n newline (equivalent to endl)
\t tab
\" double quote

Example code:

1 cout << " \" hello \ nworld \" " << endl ;

Output:

" hello
world "

Example code:

1 cout << " A \ tB \ tC " << endl ;


2 cout << " 1\ t2 \ t3 " << endl ;

Output:

A B C
1 2 3

Example code:

1 cout << " He said \" Hi !\" to me ! " << endl ;

Output:

He said " Hi !" to me !

4. Review questions:
(a) What is a "console" (aka "terminal")?

(b) What does "cout" stand for?

(c) What does "cin" stand for?

(d) The "endl" command is used for. . .

(e) The \t command is used for. . .

(f ) The \n command is used for. . .

(g) The "getline" function is used for. . .

(h) When do you need to have cin.ignore(); in your code?

114
5.4 Unit 03: C++: Functions

5.4.1 Program Structure

As programs become more sophisticated and oer more features, the size of
the program increases. At some point, it becomes too complicated to keep your
entire program just within main(). (You could certainly do it, but maintaining
it would be a nightmare!)
One of the tools we use to build modular, easier-to-read code is func-
tions. By using functions, we can delegate tasks out to other portions of the
program, passing inputs as data to the function, and receiving some kind of
output as a result.

As a basic example, let's say we need to calculate square footage of a room


in multiple places in a program. By making a float GetArea( float width,
float length ) function. Then, we only have to implement the formula once
and can use the function in every part of the program. Then, we wouldn't be

115
copy-and-pasting the same formula over and over again in the code - which also
means less likelihood of errors, and easier to update later as needed.

1. Program ow and functions


Whenever a function is called, the program ow is redirected into that
function, running from top-to-bottom as normal (with branching and loops
changing that ow). Once the function has completed, it can return some
data, which is received by the call location.
From a design standpoint, this means we can break out dierent parts of
programs into their own sections. Each function has a name, which should
be used to label what the purpose of its code is.

116
5.4.2 Uses of functions
1. Functions for formulas
In algebra, you've seen functions like this:

f (x) = 2x + 3
If you were like me in algebra, you might have thought to yourself, "That's
the same as y = 2x + 3, why did we replace y with f (x)?"
The reason is that we want to write a function in terms of its input, x,
and its output f (x). The equation 2x + 3 is the function body, which
species how we get some output given some input.

We can use functions in programming like with math as well - dening


formulas that we might need a lot - but there's more to functions than
just making computations.

Let's say we want to make our "GetArea" function in math. We would


need two inputs: Width and Length, and the output would end up being
the area, so maybe we would name the function A. It might look like this:

A(w, l) = w · l
In C++, it would look like this:

1 float Area ( float width , float length ) {


2 return width * length ;
3 }

(Luckily we don't have to restrict ourselves to single-letter variable and


function names in C++ :)

2. Functions to validate
Functions can also be handy in validating data and user input, putting
the validation in one place instead of having to re-implement the same
checks over and over.

For example, let's say we want to keep some variable percentage in our
program betwee 0% and 100% - no negative values, nothing over 100%.
We could implement a function that takes the percentage as an input,
and either returns the same percentage, or 0%, or 100% as output. . .
1 int BoundPercent ( int originalPercent ) {
2 if ( originalPercent < 0 ) {
3 return 0;
4 }
5 else if ( originalPercent > 100 ) {
6 return 100;
7 }
8 else {
9 return originalPercent ;
10 }
11 }

117
Then, anywhere in the program, we could use this function to make
sure our percentages are in the right range. . .

1 // in main ()
2 hungerPercent = BoundPercent ( hungerPercent ) ;
3 healthPercent = BoundPercent ( healthPercent ) ;
4 happinessPercent = BoundPercent ( happinessPercent ) ;

3. Functions to get input


Getting user input is a common part of writing software, and we will
usually need to validate what the user is entering prior to doing any
operations on it. Let's say your program is full of numbered menus and
you want to validate the user's menu choices easily. You can use a function
with a while loop in it:

1 int GetUserInput ( int min , int max )


2 {
3 int choice ;
4 cout << " Choice : " ;
5 cin >> choice ;
6
7 while ( choice < min || choice > max )
8 {
9 cout << " Invalid choice , try again : " ;
10 cin >> choice ;
11 }
12
13 return choice ;
14 }

118
You write this function once and then you can reuse it in your entire
program for all menus. . .

1 cout << " 1. Deposit money " << endl


2 << " 2. Withdraw money " << endl
3 << " 3. View balance " << endl ;
4
5 choice = GetUserInput ( 1 , 3 ) ; // 1 , 2 , or 3
6
7 if ( choice == 1 )
8 {
9 cout << " 1. Checking account " << endl
10 << " 2. Savings account " << endl ;
11 choice = GetUserInput ( 1 , 2 ) ; // 1 or 2
12 }

4. Functions to output
Functions aren't required to return data. Sometimes, you just want a
function that is responsible for formatting output or displaying a menu.
In this case, a function's return type can be void.

1 void DisplayStudentInfo ( string name , float gpa )


2 {
3 cout << " Name : " << name
4 << " GPA : " << gpa << endl ;
5 }

You also aren't required to pass input to functions. In this case, the
parameter list between ( ) remains empty, but the () is always required
for functions:

1 void DisplayMainMenu ()
2 {
3 cout << " 1. Deposit " << endl ;
4 cout << " 2. Withdraw " << endl ;
5 cout << " 3. View Balance " << endl ;
6 cout << " 4. Log Out " << endl ;
7 }

5. Other uses
These are just some examples of why you might use functions in your
programs. Anything you write in main() can go inside of a dierent
function as well - it's just another tool for designing clean, maintanable,
and readable code.

119
5.4.3 Anatomy of a function
1. Function Declaration
1 float GetArea ( float width , float height );

Before you start using a function, you have to declare and dene it. . .
A function declaration is similar to a variable declaration - we tell the
program "hey, we want to use this function, here's its name and some info
about it." Declaration statements end with a semi-colon and don't contain
a code block (the function body) because it's just a declaration.

(a) Function Header:


The function header is the rst line of a function, which includes the
following information: return type, function name, and parameter
list.
1 RETURNTYPE FUNCNAME ( PARAM1TYPE PARAM1NAME , ...)

(b) Function Return Type:


The return type of a function species what kind of data is returned
from this function. The return type can be any data type, or it can
be void if nothing is going to be returned.

(c) Function Name:


The function name should describe what the responsibility of the
function is - what it does.

(d) Function Parameters:


The parameters of a function are a list of input variables that are
expected to be passed into the function from elseware. The parameter
list is located between the ( and ) in the function header.

120
2. Function Denition
1 float GetArea ( float width , float height )
2 {
3 return width * height ;
4 }

The function denition is where we actually write what the function does.
It includes the same information as the function declaration, but we in-
clude the function body in a code block.

3. Function Body
The function body is the code block, written between { and }, dening
what logic the function performs.

4. Function Call
1 float room1Sqft = GetArea ( 5 , 10 ) ;
2 float room2Sqft = GetArea ( room2width , room2length ) ;

After a function is dened, we can then call that function to execute its
internal code. If the function has input parameters, we can pass in literal
values (hard-coded data) or variables to provide that input data.

5. Calling a function
Once the function has been dened, you can call it from anywhere in your
program. . .

1 int main ()
2 {
3 float width , height ;
4 cout << " Enter width and height : " ;
5 cin >> width >> height ;
6
7 // Call GetArea
8 float area = GetArea ( width , height ) ;
9
10 cout << " Area : " << area << endl ;
11 }

(a) Function Call:


Calling a function requires the function name, and passing in a
series of inputs that become the function's parameters. In the ex-
ample above, the GetArea function is called, with the values from the
width and height variables being passed in. Once GetArea returns
its output, that output is then stored in the area variable.

121
(b) Arguments:
An argument is the name of the value or variables being passed into
the function during the function call. These arguments become the
values that the function parameters within the function deni-
tion uses.

Here in the function call, 10 and 20 are the arguments:

1 // Call GetArea
2 float area = GetArea ( 10 , 20 ) ;

So the values of 10 and 20 get used as the width and length param-
eters' values:

1 float GetArea ( float width , float height )


2 {
3 return width * height ;
4 }

The arguments of a function call can be hard-coded values, like 10


and 20 above, or you can pass in other variables as arguments. Then,
whatever is stored in those variables is copied over to the parameters.

1 // Call GetArea twice


2 float area1 = GetArea ( room1Width , room1Length ) ;
3 float area2 = GetArea ( room2Width , room2Length ) ;

The arguments passed indo not need to share a name with the
parameters; these are not the same variables. They're only sharing
the data stored within them.

The rst time GetArea is called, whatever is stored within room1Width


is copied from that variable and stored in the parameter variable
width within the function's denition.

122
Common function errors:

When you're declaring/dening a function you specify data


types - the return type and the parameters' data types. When
you're calling a function, you do not include data types!
ˆ YES:

sqft = GetArea( room_width, room_length );


ˆ NO:

sqft = GetArea( float room_width, float room_length );

Functions must have parentheses ()! If you're missing the


parentheses, your program isn't going to call the function!

ˆ YES:

DisplayMenu();
ˆ NO:

DisplayMenu;

If a function contains a return statement, then you must store


the returned data in a variable! If you don't assign the
return anywhere, it will be lost!

ˆ YES:

sqft = GetArea( room_width, room_length );


ˆ NO:

GetArea( room_width, room_length );

5.4.4 Variable scope


Scope refers to the location in the code where a variable exists.

main():
If you declare a variable at the top of the main() function, not inside any
if statements or loops, then that variable is in scope for the entire duration of
main(), starting with the line it was declared on.

1 int main ()
2 {
3 int a;
4 // ... etc ...
5 }

123
Variables declared within if statements and loops:
Variables declared within the code block of an if statement or a loop only
exists within that code block.

1 if ( a == 3 )
2 {
3 int b ; // only exists within this block
4 }
5
6 for ( int i = 0; i < 10; i ++ )
7 {
8 cout << i ; // only exists within this block
9 }

If you try to use these variables somewhere below the code block, your
compiler will give an error, stating that the variable does not exist in that
scope. Once the program leaves the code block, the variable is out of scope.

Functions:
Remember that main() is a function, just like any other functions we write
in our program. Any variables declared within a function are local to that
function, and accessible anywhere from the variable's declaration until the end
of the function.

1 int GetChoice ()
2 {
3 int choice ; // local variable
4 cout << " Choice : " ;
5 cin >> choice ;
6 return choice ;
7 }

Parameters:
Variables declared in the parameter list of a function are also local to that
function and can be used anywhere within the function.

1 int Sum ( int a , int b , int c )


2 {
3 // a , b , and c are local to this function .
4 return a + b + c ;
5 }

124
Same names?
The same name can be reused for dierent variables in dierent scopes.
Even if they share the same name, they are not related in any way.

1 int GetChoice ()
2 {
3 int choice ; // Variable A
4 cout << " Choice : " ;
5 cin >> choice ;
6 return choice ;
7 }
8
9 int main ()
10 {
11 int choice ; // Variable B
12 choice = GetChoice () ;
13 }

5.4.5 Parameters and arguments


1. Pass-by-value
When we have a function declared with a parameter. . .

1 void Example ( int someNumber )


2 {
3 cout << someNumber ;
4 }

. . . and we call that function elseware, passing in another variable as an


argument. . .

1 int main ()
2 {
3 int myNumber = 2;
4 Example ( myNumber ) ;
5 return 0;
6 }

. . . What happens is that the value of the variable myNumber is copied


and passed to the function parameter someNumber. This works the same
as if you simply pass in Example( 10 ), passing in a hard-coded value
instead of using a variable.

125
If you wrote the function to change the value of its parameter, that change
would only be reected within the function and would not aect the
original argument passed as part of the function call.

1 void Example ( int someNumber )


2 {
3 cout << " Example begin : " << someNumber << endl ;
4 someNumber = 100;
5 cout << " Example end : " << someNumber << endl ;
6 }
7
8 int main ()
9 {
10 int myNumber = 2;
11
12 Example ( myNumber ) ;
13
14 cout << " main end : " << myNumber << endl ;
15
16 return 0;
17 }

The output of this program would be:

Example begin : 2
Example end : 100
main end : 2

Even though the value of someNumber from the Example function changes
(which is valid), that change doesn't aect myNumber within main(), be-
cause only the value was copied over.
This is known as pass-by-value.

2. Pass-by-reference
If we wanted to change the value of an argument variable within a function,
we'd have to change the parameter to pass-by-reference. To do this, we
use the symbol = &= in the parameter's declaration, after the data type
and before the variable name.

1 void Example ( int & someNumber )


2 {
3 cout << " Example begin : " << someNumber << endl ;
4 someNumber = 100;
5 cout << " Example end : " << someNumber << endl ;
6 }

The ampersand symbol can go next to the data type (int & blah), next
to the variable name (int &blah), or separate from both (int & blah).
Once we've made the parameter a reference, then when the function is
called, the argument is not copied - a reference to that variable is passed
to the function. Any changes to the reference parameter in the function
also aects the original argument variable.

126
1 int main ()
2 {
3 int myNumber = 2;
4
5 // Calling it looks the same as before
6 Example ( myNumber ) ;
7
8 cout << " main end : " << myNumber << endl ;
9
10 return 0;
11 }

The output of this program would be:

Example begin : 2
Example end : 100
main end : 100

Pass-by-reference instead of return

In some cases, you may need to return multiple pieces of data from a
function - however, you can only return one item from a function with
the return statement (in C++). One option is to set the information you
want "returned" as pass-by-reference parameters of the function.

1 void DoubleTheseNumbers ( int & a , int & b , int & c )


2 {
3 a *= 2;
4 b *= 2;
5 c *= 2;
6 }

Pass-by-reference of large things

We haven't gone over arrays or classes/objects yet, but another reason


we might want to pass something by-reference instead of by-value is when
the parameter is big (which can be the case with arrays and objects).

If we have a large object we need to pass to a function, doing a copy of


the entire thing is inecient - it is much simpler and faster to pass the
large object by-reference.

127
5.4.6 Summary: Ways to pass data to/from functions
The following table illustrates dierent ways we can dene our parameters,
and what the goal is. "RT" means "Return Type", "T" is the "Type" of the
parameter.

Function Read Return Info


1. RT func( T X ) yes no Pass-by-value X
2. RT func( const T& X ) yes no Const pass-by-reference X
3. RT func( T& X ) yes yes Pass-by-reference X

1. X is pass-by-value, which is ne for primitive data types like ints, oats,
chars, and bools.

2. X is passed by const-reference because X is a mose sophisticated data type


like a string or other class-based object. (Longer time to copy if passed
by value.)

3. The function can read from X but also overwrite its value and the change
will be reected back to the argument being passed to the function call.

128
5.4.7 Default parameters
When declaring a function, you can also set default parameters. These are
the default values assigned to the parameters if the user doesn't pass anything
in. The default parameters are only specied in a function declaration -
NOT the denition!

In this example, it could be a function that displays ingredients for a recipe,


and by default the batch is set to 1.0 (one batch).

1 void OutputIngredients ( float eggs , float sugar , float flour


, float batch = 1.0 ) ;

The function could be called without passing in a batch:

1 cout << " Ingredients : " << endl ;


2 OutputIngredients ( 1 , 2.0 , 3.5 ) ;

Or they could pass a batch amount explicitly:

1 cout << " Ingredients : " << endl ;


2 OutputIngredients ( 1 , 2.0 , 3.5 , 0.5 ) ; // half batch

You can have multiple default parameters specied in your function decla-
ration - but all variables with default values must go after any variables without
default values.

5.4.8 Function Overloading


In C++, you can also write multiple functions that have the same name, but
a dierent parameter list. This is known as function overloading.
Let's say you want to be able to sum numbers, and you make a version for
oats and a version for integers:

1 int Sum ( int a , int b )


2 {
3 return a + b ;
4 }
5
6 float Sum ( float a , float b )
7 {
8 return a + b ;
9 }

129
You can write as many versions of the function as you like, so long as the
function headers are uniquely identiable to the compiler, which means:
ˆ The functions have a dierent amount of parameters, or
ˆ The data types of the parameters are dierent, or
ˆ The parameters are in a dierent order (when mixing data types).
These will become much more useful once we cover classes and objects.

5.4.9 Review questions:


1. Build the function signature given the following specs:

ˆ The function is named "GetRectArea".

ˆ The function returns a oat.

ˆ The function takes in a oat for the width and a oat for the length

2. Identify each code snippet (function declaration / denition / call):

ˆ a.

1 float PercentToDecimal ( float percent )


2 {
3 return percent / 100.0;
4 }

ˆ b.

1 float PercentToDecimal ( float percent ) ;

ˆ c.

1 float decimal = PercentToDecimal ( percent ) ;

3. Identify how the following parameters are passed (by value / by reference),
given this function declaration:

1 void SomeFunction ( int & a , int b ) ;

ˆ a is passed. . . (by value / by reference)

ˆ b is passed. . . (by value / by reference)

130
5.5 Unit 04: Tech Literacy: Debugging, testing, and re-
searching
5.5.1 Syntax

What is syntax ?
syntax, noun - The way in which linguistic elements (such as words) are
put together to form constituents (such as phrases or clauses)
From the Merriam-Webster Dictionary.

C++, Java, C#, and other "C-like" languages follow similar syntax rules.

Lines of code:
A code statement ends with a semi-colon. Statements are single commands,
like using cout ("console out") to display text to the screen, assigning a value
to a variable, and other simple operations.

1 string state ; // Variable declaration


2 cout << " Enter state : " ; // Display text to screen
3 cin >> state ; // Getting input from keyboard
4 cout << state << endl ; // Displaying text to the screen

Comments:
Comments are notes left in the code by humans for humans. They can help
us remember what our code was doing later on, or help guide someone else
reading through our code. There are two ways we can write comments in C++.
If we use // then all text afterwards will be a comment. This is a single-line
comment. If we use /* then all text will be a comment, only ending once we
reach a */. This is a multi-line comment.

1 string state ; // Variable declaration


2
3 /*
4 Next we ' re going to search for this state
5 in the list of all states that match xyz criteria ...
6 */

Code blocks:
There are certain types of instructions that contain additional code. If state-
ments, for example, contain a set of instructions to execute only if the con-
dition given evalutes to true. Any time an instruction contains additional
instructions, we use opening and closing curly braces { } to contain this in-
ternal code. Note that an if statement and other structures that contain code
don't end with a semicolon ;.
1 if ( price > 100 )
2 { // Code block begin
3 cout << " Too expensive ... " << endl ;
4 } // Code block end

131
5.5.2 Types of errors
Syntax errors and logic errors

Syntax errors are errors in the language rules of your program code. This
typos, misspellings, or just writing something that
include things like isn't
valid C++ code, such as forgetting a ; at the end of some instructions. Although
they're annoying, syntax errors are probably the "best" type of error because
the program won't build while they're present. Your program won't build if you
have syntax errors.
Logic errors are errors in the programmer's logic. This could be something
like a wrong math formula, a bad condition on an if statement, or other things
where the programmer thinks thing A is going to happen, but thing B happens
instead. These don't lead to build errors, so the program can still be run, but
it may result in the program crashing, or invalid data being generated, or other
problems.

Minimizing bugs and debugging time

ˆ Write a few lines of code and build after every few lines - this will help
you detect syntax errors early.

ˆ DON'T write the "entire program" before ever doing a build or a test -
chances are you've written in some syntax errors, and now you'll have a
long list of errors to sift through!

ˆ If you aren't sure where an error is coming from, try commenting out
large chunks of your program until it's building again. Then, you can
un-comment-out small bits at a time to gure out where the problem is.

132
5.5.3 Testing software
1. Why test?

How do you know that your program actually works?


Sure, you may have manually tested your code, running the program and
typing in test data and checking the output. After a while, manual testing
becomes a chore. Maybe you start entering "asdjhfklq" as the test data
and just make sure nothing breaks while running the program. But are
you sure your program runs, doesn't crash, and gives the correct output
for all reasonable cases?

A skill that is good to develop as a software developer is how to test and


validate your work. You can break down parts of your code into little
transactions of "inputs" and "outputs", and then develop test cases.

ˆ Test case: A test case is a single test. You specify some input(s)
that you will give your program, and the expected output(s) it should
return.

When you run the actual program with your inputs, it will return actual
output(s). Compare the actual output with the expected output to val-
idate whether the program worked as expected. Test cases can be built
without any of the program built so far. In fact, it can be handy to write
your tests ahead of time so you have a better understanding of how things
are supposed to work.

133
2. Writing test cases
Example: Bank withdrawals
In this example, the program keeps track of a bank balance and the amount
the user wants to withdraw, but it shouldn't let the balance fall below 0.

Test Input(s) Expected output Actual out-


case put
1 balance = 100, withdraw = 10 balance is now 90
2 balance = 0, withdraw = 100 can't withdraw!
3 balance = 100, withdraw = 100 balance is now 0

You would make a list of inputs and what should be the result for each
case, and then run your program and check each scenario - does the actual
output match the expected output? If something doesn't match, it
could mean that there's an error in a calculation somewhere, or other
logic in the program. (And yes, sometimes tests can be wrong, too.)

3. Ways to test
Testing is a whole job title in software development. Usually the "devel-
opers" write the new features and maybe add unit tests for their code.
A dedicated QA (Quality Assurance) or SET (Software Engineer in Test)
is then responsible for thoroughly testing developer work. This includes
testing in multiple ways, both the feature itself "in a vacuum", and con-
nected to the entire system as a whole, to make sure that nothing breaks
along the way.

(a) Manual testing


Manually testing is as it sounds - the QA has a list of test cases
in a document or wiki and they follow those test cases to make sure
the program continues working. Often this means navigating the
program's UI from the user's perspective, going through each step to
make sure nothing breaks.

(b) Integration tests


Integration tests test the new feature within the entire system as
a whole, integrated with the rest of the program. Usually companies
will have multiple servers, such as a QA server where the program is
set up like it's ready for the real world, but only used by testers and
lled with test/mock data. This is usually where integration tests
happen - we want to make sure it works before we push to production
(in other words, submit the new feature to the live website or app
that the actual users are using.)

(c) Unit tests


Often the developers who write features are required to also write
unit tests for those features. Unit tests are a way to test "in a vac-
uum", one unit at a time. They're handy for making sure that each
individual component of a feature doesn't break. Unit tests are au-
tomated - you can write something like

134
1 // Inputs for this test case
2 int input_balance = 100;
3 int input_withdraw = 10;
4
5 // What the expected result ( balance ) is
6 int expected_output = 90;
7
8 // Call the function that handles it with the
9 // test case inputs , its output is our " actual
output ".
10 int actual_output = Withdraw ( input_balance ,
expected_output ) ;
11
12 if ( actual_output == expected_output )
13 {
14 // If the actual output matches
15 // the expected output - PASS !
16 cout << " Test passes ! " << endl ;
17 }
18 else
19 {
20 // The actual output didn 't match , so test FAILS .
21 cout << " TEST FAILS ! " << endl ;
22 }

Again, for reference, the rst test case is written out as:

Test Input(s) Expected output


case
1 balance = 100, withdraw = 10 balance is now 90

4. Test driven development


In the book Test-Driven Development by Kent Beck, he highlights
a way of approaching software development where you write your tests
for a new feature rst, before writing any actual code to implement that
feature. By writing tests rst, it helps developers think through the
actual requirements in a quantiable way. You can read more about it on
the Wikipedia page - https://en.wikipedia.org/wiki/Test-driven_
development .

I think it's an interesting way to approach design and development, though


from my experience no company I've ever worked for has used this test-
rst approach. I do nd this a good way to go about designing solutions
during job interview questions! (Plus it gives you stalling time as you ask
your interviewer questions about the requirements, gives you more time
to think through your design, and gives you a way to verify your work
afterwards. ;)

135
5.5.4 Doing research as a programmer
For developers it's a pretty common experience for people to feel like they spend
a lot of their time searching for solutions and scouring Stack Overow posts for
solutions to their troubles. In the professional world you will belearning your
company's codebase, as well as probably learning third party APIs from
other companies as well. While you may be procient in the language you
work in, learning other peoples' code and products will always be part of it. So,
research is part of development.

1. Internal wikis and documentation

Companies often have some kind of internal Wiki (or Conuence, or Share-
point) where employees can post documentation and notes to share with
others. However, developers don't usually do much documentation on
their code or code they've explored, so usually a company's internal doc-
umentation for their own code is pretty bad. (In my experience only the
auto-generated API docs built from code comments are okay.)

136
2. Search engines (and AI?)
Searching on a search engine can come up with tutorials, blogs, API docs,
message board posts, and other resources for reference. Finding help,
documentation, examples, and posts where someone else had the same
problem is a common way of working through problems, as well as asking
coworkers, sketching out the problem on paper, and testing out dierent
approaches.

As Large Language Models ("AI") becomes more popular, it may be


tempting to try to ask it all of your questions. However, there's nointelli-
gence in this LLM-based AI, it's not thinking critically about what you've
said, and it can frequently get things wrong but in a condent manner. I
would suggest that you use it as a starting point, somewhere to get some
ideas, rather than utilizing it as actual documentation.

3. Documentation resources

Figure 10: A screenshot of the documentation page for Canvas' API, listing an
action, inputs, and other information.

When working with third party libraries and APIs that are provided by
another business or organization they will generally have decent documen-
tation explaining the items you can use. Going over API documentation
is a big part of software development. :) So having the patience to read
through docs to nd what you need is important.

If you want to see some examples of API documentation, here are a few.
You can also search "[thing] API docs" to nd documentation for a lot of
things, from meal delivery apps to catalogs of venomous frogs in Australia.

ˆ Canvas API: https://canvas.instructure.com/doc/api/all_resources.


html
ˆ Spotify API: https://developer.spotify.com/documentation/web-api
ˆ Reddit API: https://www.reddit.com/dev/api/

137
4. Stack Overow and message boards
As you do web searches for programming problems (for me, usually build
error messages - what does it mean? :)) often you will see message boards
with archived posts from people with similar problems. These are pretty
common to reference, though can be limited in how helpful they are. Some-
times the poster's problem matches yours, sometimes nobody responded,
sometimes you can't quite nd what you need. But still a common re-
source.

5. Language reference resources

Figure 11: An image of the cover of the book "JavaScript Pocket Reference",
published by O'Reilly.

It's good to keep a reference book about the language you're using as
well. These can usually be college style textbooks about the language, or
maybe a quick reference. There are also books that help you gain a deeper
understanding of the language, frameworks, and tools you use.

There are also often online video lessons that can teach you about tech-
nologies as well. These are usually through websites like Pluralsight or
maybe Coursera or Udemy.

The software/web/mobile development landscape is always changing so


as a developer you will often need to keep up with updates that your
company makes to frameworks and technologies.

138
5.6 Unit 05: C++: Structs
5.6.1 Introduction to objects

Programming paradigms (pronounced "pair-uh-dimes") are ways we can


classify dierent programming styles. Some programming languages support
multiple paradigm styles and some are restricted to one style of coding. Over
the decades dierent paradigms have been developed and evolved over time.
Object Oriented Programming is one of the most common styles of pro-
gramming these days, and is a big part of how C++, C#, and Java-based
programs are designed.

1. What are "Objects"?


Dening classes and structs in our programs are a way that we can
create our own data types for our variables. When we dene our own
structures, we can create them with internal variables and functions
available to them. The variables we create, whose data types come from
a dened class or struct, is known as an object.
Design-wise, the idea is to take real-world objects and nd a way to rep-
resent them in a computer program as an object that has attributes
(variables) and functionality (functions).

2. OOP design ideals


The concept of Object Oriented Programming is creating a design
that is easy to maintain over time. In particular, there are some core
design goals behind OOP, including:

ˆ Encapsulation: Giving the user / other programmers an interface


\ to interact with the objects, hiding the inner-workings within the
class.

139
 Certain functions are made public, which other programmers
can use to interface with the object.

 The other programmers don't need to worry about the inner-


workings of the object in order to use it.

 The developer of the class can modify how the internals work
without breaking the public interface.

 Helps protect the data within the class from being accessed or
modied by external things that shouldn't have access to it.

ˆ Loose coupling: Ideally, dierent objects in a program shouldn't


have their functionality tied to other objects too closely; we wan tto
reduce inter-dependence between objects. When objects are more
independent from each other, we say they are loosely coupled.
ˆ High cohesion: When we design our objects, we shouldn't just
throw everything and the kitchen sink into one object. To design an
object with high cohesion means that everything inside the object
belongs to that object - reduce the clutter.

5.6.2 Separate variables to one struct


Structs are a way we can group related information together into one data
type.
For example, let's say we were writing a program for a restaurant, and an
item on the menu would have a name, a price, a calorie count, and a "is it
vegetarian?" signier. We could declare these all as separate variables:

1 string food1_name ;
2 float food1_price ;
3 int food1_calories ;
4 bool food1_is_veggie ;

But there isn't really anything in the program that says these variables are
related, except that we as humans have given these variables similar prexes
in their names. A better design would be to create a new datatype called
MenuItem (or something similar), and the MenuItem will contain these four
variables within it. We're basically making a variable data type that can contain
multiple variables!

140
First we create the struct, which should go in its own .h le:
MenuItem.h:
1 struct MenuItem
2 {
3 string name ;
4 float price ;
5 int calories ;
6 bool isVeggie ;
7 };

And then we can declare variables of this type in our program:


main.cpp:
1 MenuItem food1 ;
2 food1 . name = " Bean Burrito " ;
3 food1 . price = 1.99;
4 food1 . calories = 350;
5 food1 . isVeggie = true ;
6
7 MenuItem food2 ;
8 food2 . name = " Crunchy Taco " ;
9 food2 . price = 1.99;
10 food2 . calories = 170;
11 food2 . isVeggie = false ;

5.6.3 Multiple les in C++ programs

When creating a struct, we should create a new source code le in our
project. Usually the name of the le will be the same name as the struct, with
a .h at the end. This is a header le and declarations for structs (and functions
and classes later) will go in these types of les.

Something you need to require in your .h les that isn't needed for your .cpp
les are le guards. These prevent the compiler from reading the le more than
once. If it reads it multiple times, it will think you're redeclaring things over
and over again. Your .h les should always look like this:

141
1 # ifndef _MYFILE_H
2 # define _MYFILE_H
3
4 // put code here
5
6 # endif

Where the "_MYFILE_H" should be changed to something unique in each le


- usually, the name of your le.

5.6.4 Creating our own structs


A basic struct declaration is of the form. . .

1 # ifndef _MYFILE_H
2 # define _MYFILE_H
3
4 struct STRUCTNAME
5 {
6 // member variables
7 int MEMBER1 ;
8 string MEMBER2 ;
9 float MEMBER3 ;
10 };
11
12 # endif

Note that the closing curly-brace } must end with a ; otherwise the compiler
will give you errors.
You can name your struct anything you'd please but it has to abide by the
C++ naming rules (no spaces, no keywords, can contain letters, numbers, and
underscores).
Any variables we declare within the struct are known as member variables
- they are members of that struct.
Any new variables you declare whose data type is this struct will have its
own copy of each of these variables.

1. Declaring object variables


A object is a type of variable whose data type is a struct (or class). To
declare a variable whose data type is a struct, it looks like any normal
variable declaration:

1 DATATYPE VARIABLE ;

2. Accessing member variables


Our struct object variables each have their own member variables,
which we access via the dot operator .. We can assign values to it, our
read its value, similar to any normal variable.

142
1 VARIABLE . MEMBER1 = 10;
2 VARIABLE . MEMBER2 = " ASDF " ;
3 VARIABLE . MEMBER3 = 2.99;
4
5 cout << VARIABLE . MEMBER1 << endl ;

3. Example: Fraction struct


First we would declare our Fraction struct within Fraction.h:
1 # ifndef _FRACTION_H
2 # define _FRACTION_H
3
4 struct Fraction
5 {
6 int num ;
7 int denom ;
8 };
9
10 # endif

Within main(), we could then create Fraction variables and work with
them:

main.cpp:
1 # include " Fraction . h "
2
3 int main ()
4 {
5 Fraction frac1 , frac2 , frac3 ;
6
7 cout << " FIRST FRACTION " << endl ;
8 cout << " * Enter numerator : " ;
9 cin >> frac1 . num ;
10 cout << " * Enter denominator : " ;
11 cin >> frac1 . denom ;
12
13 cout << endl ;
14 cout << " SECOND FRACTION " << endl ;
15 cout << " * Enter numerator : " ;
16 cin >> frac2 . num ;
17 cout << " * Enter denominator : " ;
18 cin >> frac2 . denom ;
19
20 frac3 . num = frac1 . num * frac2 . num ;
21 frac3 . denom = frac1 . denom * frac2 . denom ;
22 cout << endl ;
23 cout << " PRODUCT : " << frac3 . num << " / " << frac3 . denom
<< endl ;
24
25 return 0;
26 }

143
5.6.5 Review questions:
1. File guards are needed because. . .

2. What kind of data would be good to represent with a struct?

ˆ A character in a video game including the amount of experience


points they have, their current hit points, and current level

ˆ The tax rate of a city

ˆ The URL of a website you're visiting

ˆ An address, including recipient name, street address, city, state, and


zip code

3. If we declared an object variable likeCourse cs200; , How would we as-


sign "cs" to the department member variable and 200 to the code member
variable?

144
5.7 Unit 06: Tech Literacy: Careers in tech
Here I tried to summarize, or nd text summaries of, descriptions of dierent
common roles in tech. I myself have worked as a Software Engineer and have
worked on teams with QAs, Software Engineers in Test, Business Analysts,
UI/UX Designers, and Database Admins, but most of my rst-hand experience
is the development side of things.
If you're interested in some particular elds, I have added links to YouTube
videos from various people that describe more about the roles. In the PDF le
you should be able to click the links to access them on the web.

5.7.1 Roles in Tech


1. Software Engineer
The software engineering role is probably what most people think of when
they're thinking of software development. They are the people who imple-
ment the features that we use on apps, webpages, and software. This may
include working on the front end code (the user interface code/markup),
back end code (how the processing gets done on the server-side or behind-
the-scenes), database scripts (accessing, updating, and writing data).

Usually a development team will have at least 2 - 3 software engineers


who split the list of tasks to be implemented in the code base, and they
work closely with the UI/UX design, Software Engineers in Test, and the
product managers who decide what is going to get implemented.

ˆ Video: What do I do as a Software Engineer? (4:36):

https://youtu.be/5kas2jBObUY

2. Software Engineer in Test


A software engineer in test role is another type of programming role but
the developer focuses on the testing of features and the code base, rather
than development new features. This can include writing automated tests
to check the program's back-end functionality, automated scripts to test
usability from the GUI side, and even doing manual testing in the program
and with additional tools. It's their job to look for any oversights the
developers may have made while implementing their new feature, and
making sure the new features don't break any existing functionality.

Average teams may have one or two software engineers in test on a team.

ˆ Video: Meet Test Engineers at Google (2:00):

https://www.youtube.com/watch?v=C7OLZf5099Y

ˆ Video: What is automated testing? (6:53):

https://www.youtube.com/watch?v=Nd31XiSGJLw

145
3. Quality Assurance
Colloquially, a person in a Quality Assurance test role with software devel-
opment doesn't do as much coding as a Software Engineer in Test. They
may write basic scripts but sometimes their background isn't even in cod-
ing. A lot of this includes manually testing the software (usually from the
GUI) and documenting the steps on how to test a given feature.

Teams may have both QA testers and software engineers in test, or one,
or the other. It kind of depends on the application itself !

ˆ Video: 7 Roles and responsibilities of software tester (6:54):

https://www.youtube.com/watch?v=t5jJ4bNJ4kw

4. Database Admin
Software and websites need to store data, whether it's all the products
available in a store, or a series of chat messages between users. The
database is its own area that needs specialized people to build and main-
tain, even if software developers occasionally write their own tables and
scripts. Databases also require maintenance of the actual servers where
the database lives, as well as conguration, migration, and more.

ˆ Video: Who is a database administrator? (6:48):

https://www.youtube.com/watch?v=aI8CB60HGoo

5. UX Design
The User Experience Designer is more about the entire experience of using
the product. In a way, think of a person who gures out what kind of
features might be important to a user - is "clicking once to purchase an
item online" a feature that users would desire? UX is somewhat more
about functionality, and they work with UI and developers to gure out
how to create the solution.

ˆ Video: What is UX Design? (5:07):

https://www.youtube.com/watch?v=v6n1i0qojws

6. UI Design
UI Designer is more of a visual, graphical role, creating a pleasant interface
for customers/users who are using the product. It is important to be
able to present information clearly, and to be consistent across the entire
product. Depending on the company, sometimes the UI designer may also
write HTML and CSS, but not always. Still, learning some basic coding
with HTML, CSS, and JavaScript can be a huge asset as a designer.

ˆ Video: 6 Stages of UI Design (8:22):

https://www.youtube.com/watch?v=_6Tl2_eM0DE

146
7. DevOps
DevOps engineers reduce that complexity, closing the gap between actions
needed to quickly change an application, and the tasks that maintain its
reliability.

DevOps is all about the unication and automation of processes, and


DevOps engineers are instrumental in combining code, application main-
tenance, and application management. All of these tasks rely on under-
standing not only development life cycles, but DevOps culture, and its
philosophy, practices, and tools.

ˆ Video: My life as a DevOps Engineer (12:14):

https://www.youtube.com/watch?v=s7E9pMHPRts

8. Business Analyst
Business analysts (BAs) are responsible for bridging the gap
between IT and the business using data analytics to assess pro-
cesses, determine requirements and deliver data-driven recom-
mendations and reports to executives and stakeholders.

BAs engage with business leaders and users to understand how


data-driven changes to process, products, services, software and
hardware can improve eciencies and add value. They must ar-
ticulate those ideas but also balance them against what's tech-
nologically feasible and nancially and functionally reasonable.

(Description from

cio.com/article/276798/project-management-what-do-business-analysts-
actually-do-for-software-implementation-projects.html)

ˆ Video: What Does A Business Analyst Do? SIMPLIFIED! (5:35):

https://www.youtube.com/watch?v=50MooA33nlk

9. IT Specialist
IT is needed anywhere a company has computers. This can include places
that develop software, but also companies that don't develop software and
still need someone to set up and maintain the oce's systems. This may
include the actual computer systems, the network and wi, maintaining in-
building server(s), and otherwise providing tech support for the employees
of the company. Coding in IT can include writing scripts (e.g., UNIX
scripts) to automate conguring many systems, or writing utilities to help
you diagnose issues or otherwise do your job.

ˆ Video: A Day As An IT Specialist (4:18):

https://www.youtube.com/watch?v=1l3kKBEEQIo

10. Product Manager

147
A product manager is the person who identies the customer
need and the larger business objectives that a product or feature
will fulll, articulates what success looks like for a product, and
rallies a team to turn that vision into a reality.

(Description from

atlassian.com/agile/product-management/product-manager)

ˆ Video: What do I do as a Product Manager? (10:05):

https://www.youtube.com/watch?v=pCmh6XaMVxs

11. Information Security


People working in InfoSec or CyberSecurity helps protect a company's as-
sets from bad actors. This can mean anything from teaching a company's
employees about scams and phishing attempts, monitoring network trac
to the application/website and looking for people trying to gain unautho-
rized access or sending bad data, and otherwise evaluate threats.

ˆ Video: How To Become An Information Security Analyst (11:06):

https://www.youtube.com/watch?v=eKM9AGwSPKU

12. Data Scientist, Data Analyst, Data Engineer


Tons of data is passed around everyday, from the way a product
is used to customer data. Many companies collect this data
but with so many data points, what do you even do with it?
Working in Data Science is about interpreting and presenting
the data, or training machines to learn patterns to predict how
the software will be used, or how dierent pieces of data are
related.

(Description from

redhat.com/en/topics/devops/devops-engineer)

ˆ Video: Data Scientist vs Data Analyst vs Data Engineer: What's


the dierence? (6:58):

https://www.youtube.com/watch?v=XW0YptcgZSk

148
5.7.2 Professional development and networking
One of the easiest ways to get your foot in the door at a company is by knowing
somebody who is already working there. This could be somebody that you
went to school with, somebody that you've worked with previously, or even
someone you've met through conferences or via the internet. But, how do you
go about making contacts and keeping in touch? You can build your network of
professionals in various ways throughout the years. Here are some of the ways
that I've met other developers throughout my career. . .

School: One of the easiest ways to meet people right now is meeting your
classmates. For some of us, our style might be go to class, do the work by
myself, don't talk to others (like me, I was a shy youngin'), but making
contacts at school can go a long way.

While in school, being able to discuss assignments, work on homework


together, and give each other tips and tricks for programming can be
helpful, and outside of school you can keep in touch and keep tabs on
where each other is working, share information on good companies to work
for and bad, compare salaries to make sure you're getting compensated
fairly, etc.

School clubs can be a good way to meet others, both inside and outside
your area of study. You can view a list of JCCC clubs and organizations
here:

https://www.jccc.edu/campus-life/student-activities-organizations/
The school may also have events from time-to-time to get you and your
work exposed to local businesses and professionals, such as regular career
fairs and poster symposiums. You may need to keep an eye on campus
news for these! The CSIT department hosts a reverse career fair once a
year so keep an eye out!

Work: As you have jobs (whether they're software development or not), try to
make sure to keep in touch with one or more coworker. With coworkers
especially, they will be able to better vouch for you and how you work if
you end up applying for a job with them at a dierent company as well.

Friends: Your friends have their own professional networks and, even if they're
not in tech, they might know others who are, or know of other companies
that hire tech people.

Conferences and meetups: You can also connect with other professionals at
events and conferences. It could be tech conferences or events for other
topics (you don't exclusively need to keep in touch with just software
developers; knowing non-developers can also be helpful in nding oppor-
tunities!).

I know during the pandemic it can be dicult to do this kind of in-


person networking. Some events have moved to online, and some have
just canceled. If you attend an in-person event or a virtual event, you
could try to connect with people you meet or whose talks you listen to via
LinkedIn or Twitter (a lot of people who talk at conferences will have a
Twitter).

149
Some local conferences:
ˆ KCDC  Kansas City Developer Conference

https://www.kcdc.info/
Yearly conferences that feature developers from Kansas City and elseware
giving talks about various technology, practices, and more. This can be a
good place to learn the basics of a new area and meet with others. They
also have a booth area where you can talk to recruiters and developers
from dierent companies.

ˆ MINK WIC  Missouri/Iowa/Nebraska/Kansas Women in Computing

https://www.minkwic.org/
This is a conference for women in tech in the surrounding area. Each year
the conference is held in a dierent one of the four states and also includes
talks and presentations and company booths.

Some local groups


ˆ Flyover Indies - Gamedev Meetup

https://flyoverindies.party/
Flyover Indies is a group of independent game developers here in the KC
Metro area. There's a co-working afternoon on Sundays, a Ludology club
studying about game development concepts, and more.

ˆ SecKC  Security Meetup

https://www.seckc.org/
SecKC is a meetup of people interested in the security side of tech. They
usually meet monthly.

Other ideas
ˆ Meetup.com - You can nd other meetups for specic areas (e.g., just
Python, just web development, etc.) on Meetup.com. Going to meetings
will help you become acquainted with other developers and learn about
businesses locally, as well as give you a chance to ask questions and get
advice.

ˆ Other conferences - Try searching online for conferences related to your


area of interest in other parts of the country or world! They might have
deals on tickets for students, or have some online component.

ˆ Online communities - Sometimes you can nd Slack or Discord servers for
people in a specic eld (e.g., ".net developers", "women in tech", etc.)
and it can be handy to be a part of these groups.

ˆ Reddit - Some students have suggested that you can network with others
via Reddit as well.

ˆ Discord and IRC chat - Find a group of hobbyists, open source developers,
or other areas and join the community! Even libraries like SFML have
their own community.

150
5.7.3 What about AI?
You don't have to read this if you don't want to, I'm just rambling
here.

All the big tech companies seem to be buying into adding AI into their
products these days, but I see this as repeated history, such as the frenzy about
NFTs in the past ve years, or the dot com bubble of the late 1990s.

Basically, companies make money if their investors are excited about some-
thing. We already saw how many companies announced some kind of "blockchain"
or "NFT" based feature they were going to create, which seems to have some-
what quietly died down in the past year or two. Companies throw something
out there, whether it's an idea they are actually excited about or not, just to
get an inux of cash from investors.

Just like with NFTs and AI, in the 1990s any business touting having a web-
site would get funding, even if the business idea was not viable. Investors were
excited about the potential to make a ton of money o the hot new technology:
the Internet.

Here in 2024, the pumping up of AI technologies seems to be the exact


same thing. From a standpoint of how LLMs work, the layperson seems to have
an idea of what "Articial Intelligence" is from decades of movies and media
presenting it in a certain way, and I think investors tend to be non-technical
people who buy into this idea as well. Tech companies are telling us all they're
integrating AI into their products so that they get more money from investors
and generate more buzz to stay relevant.

But in my mind there is a disconnect: We could use Large Language Models


and "AI" in very useful, helpful ways. We could train these technologies in
an ethical manner and it could help us with real tasks, but that's not what
is even happening here. These companies have basically trained their models
indescriminately on tons of information from random places of the internet, no
specializations and no quality control measures. A Large Language Model is
basically good at predicting which word comes next in a sentence, based on the
patterns it has seen in its training data.

If AI is a danger to your potential future jobs as a software developer, I do


not believe that it is because AI will replace you as a programmer. I think that
the reasons for the current garbage job market is more complex, such as:

ˆ Non-technical bosses and investors think they can save money by using AI
instead of developers, but doing so will create erroneous, awed products.
(Will they be humble enough to backtrack on their decisions in order to
x it? Doubtful.)

ˆ More companies than usual may be using "AI" to try to pair down a pool of
applications, even though this bakes in historical bias into what resumes

151
are brought forward - or the ability to game the system if a candidate
knows how to appeal to the algorithm.

ˆ Companies currently like to inate their prot margins by laying o em-


ployees before the end of a quarter. This is also contributing to lack of
jobs.

ˆ At the same time, it looks good for companies to be "searching for jobs"
by posting jobs online, even without the intention of hiring for those jobs.

There's a lot more to ramble about when it comes to AI (e.g., companies


don't want employees pasting company code into LLMs because company se-
crets, how do you train to be a prompt engineer if we have no control over how
these companies/organizations change their AI models, is it ethical for an AI to
scrap webpages and return a summary of answers rather than sending searchers
to webpages, is it ethical to train AI on art, code, and articles that are publically
available but without the authors' consent, and lots more things), but I'll leave
it at that for now.
(Written May 2024)

152
5.8 Unit 07: C++: Looping
5.8.1 Boolean expressions
In order to start writing questions that a computer can understand, we need to
understand boolean expressions.

A math expression looks like this:

2+3
A boolean expression is a statement that result in either true or false:
"it is daytime."
"the user saved the document"
"the user's age is greater than 12 and less than 20"

if ( i_have_not_been_fed && it_is_6_am ) {


MakeLotsOfNoise();
}

Logic in computer programs are based around these types of questions: some-
thing that can only be true or false. Statements include:

ˆ Is [boolean variable] true?

1 x

ˆ Is [boolean variable] false?

1 !x

ˆ Are two variables equal?

1 x == y

ˆ Are two variables not equal?

153
1 x != y

ˆ Is x less than y?

1 x < y

ˆ Is x less than or equal to y?

1 x <= y

ˆ Is x greater than y?

1 x > y

ˆ Is x greater than or equal to y?

1 x >= y

For the rst two, we can check the value of a boolean variable. The rest
of them, we can use any data type to compare if two values are equal, greater
than, less than, etc. a and b can be replaced with variables and/or values. . .

1 if ( age < 18 ) { ... }


2
3 if ( my_state == your_state ) { ... }
4
5 if ( word1 < word2 ) { ... }
6
7 if ( document_saved == true ) { ... }
8
9 if ( document_saved == false ) { ... }

Note: When using < and > with strings or chars, it will compare them
based on alphabetical order - if they're both the same case (both uppercase or
both lowercase). The code 65 represents 'A', but the code 97 represents 'a',
so items will be "sorted" based on these codes.

154
1. And, Or, and Not operators
We can also combine boolean expressions together to ask more sophisti-
cated questions.

(a) Not operator: ! If we're checking a boolean variable, or a boolean


expression, and we happen to want to execute some code for when
that result isfalse, we can use the not operator. . .
Using with boolean variable documentSaved :
1 // Just checking documentSaved is true
2 if ( documentSaved ) {
3 Quit () ;
4 }
5
6 // Checking if documentSaved is false
7 if ( ! documentSaved ) {
8 Save () ;
9 Quit () ;
10 }

Using with boolean expressions ( age >= 21 ):


1 // If the age is not 21 or over ...
2 if ( !( age >= 21 ) ) {
3 NoBeer () ;
4 }

(b) And operator: &&


When using the and operator, we can check to see if all boolean
variables/expressions are true. The full question of "is this and
this and this true?" only results to true if all boolean variables/-
expressions are true. If even one of them are false, then the entire
statement is false.

1 if ( wantsBeer && isAtLeast21 ) {


2 GiveBeer () ;
3 }

To break it down, the customer would only get beer if they want beer
AND if they are over 21. If they don't want beer but are 21 or over,
they don't get beer. If they want beer but are under 21, then they
don't get beer.

(c) Or operator: ||
For an or operator, we can check to see if at least one boolean
variable/expression is true. If at least one item is true, then the
whole statement is true. The only way for it to be false is when each
boolean variable/expression is false.

1 if ( isBaby || isSenior || isVet )


2 {

155
3 GiveDiscount () ;
4 }

In this case, discounts are given to babies, seniors, and vets. A cus-
tomer wouldn't have to be all three to qualify (and clearly, couldn't
be all three at the same time!). If the customer is not a baby and not
a senior and not a vet, then they don't get the discount - all three
criteria have to be false for the entire expression to be false.

2. Truth tables
We can use truth tables to help us visualize the logic that we're working
with, and to validate if our assumptions are true. Truth tables are for
when we have an expression with more than one variable (usually) and
want to see the result of using ANDs, ORs, and NOTs to combine them.

(a) Truth table for NOT:


On the top-left of the truth table we will have the boolean variables
or expressions written out, and we will write down all its possible
states. With just one variable p, we will only have two states: when
it's true, or when it's false.

On the right-hand side (I put after the double lines) will be the result
of the expression - in this case, "not-p" !p. The not operation simply
takes the value and ips it to the opposite: true → false, and false
→ true.

p !p
T F
F T

(b) Truth table for AND: For a truth table that deals with two vari-
ables, p and q, the total amount of states will be 4:

i. p is true and q is true.


ii. p is true and q is false.

iii. p is false and q is true.

iv. p is false and q is false.

p q p && q
T T T
T F F
F T F
F F F

This is just a generic truth table. We can replace the values with
boolean expressions in C++ to check our logic.

156
(c) Truth table for OR: This also deals with 2 variables, p and q, so
4 total states. If at least one of the two variables are true, then the
entire expression istrue. An expression with an "or" is only false
when all sub-expressions are false.
p q p † q
T T T
T F T
F T T
F F F

(d) Example - AND:


We will only quit the program if the game is saved and the user wants
to quit:

game_saved want_to_quit game_saved && want_to_quit


T T T
T F F
F T F
F F F

The states are:

i. T: gameSaved is true and wantToQuit is true: Quit the game.


ii. F: gameSaved is true and wantToQuit is false: The user
doesn't want to quit; don't quit.

iii. F: gameSaved is false and wantToQuit is true: The user wants


to quit but we haven't saved yet; don't quit.

iv. F: gameSaved is false and wantToQuit is false: The user


doesn't want to quit and the game hasn't been saved; don't quit.

(e) Example - OR:


If the store has cakes OR ice cream, then suggest it to the user that
wants dessert.

hasCake hasIcecream hasCake † hasIceCream


T T T
T F T
F T T
F F F

The states are:

i. T: hasCake is true and hasIcecream is true: The store has


desserts; suggest it to the user.

ii. T: hasCake is true and hasIcecream is false: The store has


cake but no ice cream; suggest it to the user.

157
iii. T: hasCake is false and hasIcecream is true: The store has no
cake but it has ice cream; suggest it to the user.

iv. F: hasCake is false and hasIcecream is false: The store doesn't


have cake and it doesn't have ice cream; don't suggest it to the
user.

3. DeMorgan's Laws
Finally, we need to cover DeMorgan's Laws, which tell us what the opposite
of an expression means.

For example, if we ask the program "is a > 20?" and the result is false,
then what does this imply? If a > 20 is false, then a ≤ 20 is true. . . notice
that the opposite of "greater than" is "less than OR equal to"!

(a) Opposite of a && b


a b a && b !( a && b ) !a † !b
T T T F F
T F F T T
F T F T T
F F F T T

If we're asking "is a true and is b true?" together, and the result is
false, that means either:
i. a is false and b is true, or
ii. a is true and b is false, or

iii. a is false and b is false.

These are the states where the result of a && b is false in the truth
table.

In other words,

!( a && b ) ≡ !a † !b
If a is false, or b is false, or both are false, then the result of a && b
is false.

(b) Opposite of a † b:
a b a † b !( a † b ) !a && !b
T T T F F
T F T F F
F T T F F
F F F T T

158
If we're asking "is a true or b true?", if the result of that is false that
means only one thing:

i. Both a and b were false.

This is the only state where the result of a || b is false.

In other words,

!( a † b ) ≡ !a && !b
a † b is false only if a is false AND b is false.

(c) Summary
In order to be able to write if statements or while loops, you
need to understand how these boolean expressions work. If you're
logic
not familiar with these concepts, they can lead to you writing
errors in your programs, leading to behavior that you didn't want.

159
5.8.2 While loops
While loops look a lot like if statements. . .

1 while ( CONDITION )
2 {
3 // Do stuff repeatedly
4 }

except that they will continue looping while their condition is true.
Once the condition results in false, then the loop will stop and the program
will continue after the while loop's code block.

Warning!:
Because a while loop will keep going until the condition is false, it
is possible to write a program where the condition never becomes false,
resulting in an innite loop!
The while loop's condition is another boolean expression - a statement
that will be true or false.

1. Example: Counting up
The following while loop will increase a variable by 1 each time and display
it to the screen.

1 int num = 1;
2 while ( num < 10 )
3 {
4 cout << num << " \ t " ;
5 num ++; // add 1 to num
6 }

Output:

1 2 3 4 5 6 7 8 9

2. Example: Program loop


In some cases, you'll have a main menu and want to return the user back
to that menu after each operation until they choose to quit. You could
implement this with a basic boolean variable:

1 bool done = false ;


2 while ( ! done )
3 {
4 cout << " Option : " ;
5 cin >> option ;
6 if ( option == " QUIT " )
7 {
8 done = true ;
9 }
10 }
11 cout << " Bye " << endl ;

160
3. Example: Validating user input
Sometimes you want to make sure what the user entered is valid before
continuing on. If you just used an if statement, it would only check the
user's input once, allowing them to enter something invalid the second
time. Use a while loop to make sure that the program doesn't move on
until it has valid data.

1 cout << " Enter a number between 1 and 10: " ;


2 cin >> num ;
3
4 while ( num < 1 || num > 10 ) // out of bounds !
5 {
6 cout << " Invalid number ! Try again : " ;
7 cin >> num ;
8 }
9
10 cout << " Thank you " << endl ;

Output:

Enter a number between 1 and 10: 100


Invalid number ! Try again : -400
Invalid number ! Try again : -5
Invalid number ! Try again : 5
Thank you

Do. . . while loops


A do. . . while loop is just like a while loop, except the condition goes at the
end of the code block, and the code within the code block is always executed
at least one time.
1 do
2 {
3 // Do this at least once
4 } while ( CONDITION ) ;

For example, you might want to always get user input, but if they enter
something invalid you'll repeat that step until they enter something valid.

1 do
2 {
3 cout << " Enter a choice : " ;
4 cin >> choice ;
5 } while ( choice > 0 ) ;

161
Special commands
1. continue
Sometimes you might want to stop the current iteration of the loop,
but you don't want to leave the entire loop. In this case, you can use
continue; to skip the rest of the current iteration and move on to the
next.

1 int counter = 10;


2 while ( counter > 0 )
3 {
4 counter - -;
5 if ( counter % 2 == 0 ) // is an even number ?
6 {
7 continue ; // skip the rest
8 }
9 cout << counter << " odd number " << endl ;
10 }

Output:

9 odd number
7 odd number
5 odd number
3 odd number
1 odd number

2. break
In other cases, maybe you want to leave a loop before its condition has
become false. You can use a break; statement to force a loop to quit.

1 while ( true ) // Infinite loop : o


2 {
3 cout << " Enter QUIT to quit : " ;
4 cin >> userInput ;
5 if ( userInput == " QUIT " )
6 {
7 break ; // stop looping
8 }
9 }

Review questions:
1. A while loop will continue looping while its condition is. . .

2. What does the continue command do?

3. What does the break command do?

162
5.8.3 For loops
A for loop is another type of loop that combines three steps into one line of
code. A for loop looks like this:

1 for ( INIT_CODE ; CONDITION ; UPDATE_ACTION )


2 {
3 }

ˆ INIT CODE: This is some code that is executed before the loop starts.
This is usually where a counter variable is declared.

ˆ CONDITION: This is like a while loop or if statement condition - con-


tinue looping while this condition is true.
ˆ UPDATE ACTION: This code is executed each time one cycle of the
loop is completed. Usually this code adds 1 to the counter variable.

Technically you can use the for loop in a lot of ways, but the most common
use is something like this:

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


2 {
3 // Do something 10 times
4 cout << i << " \t " ;
5 }

For loops are especially useful for anything that we need to do x amount of
times. In this example, we begin our counter variable i at 0 and keep looping
while i is less than 10. If we cout i each time, we will get this:

0 1 2 3 4 5 6 7 8 9

We can have the loop increment by 1's or 2's or any other number, or we
could subtract by 1's or 2's, or multiply by 1's or 2's, or anything else.

1. Example: Count down from 10 to 1 by 1 each time


1 // 10 9 8 7 6 5 4 3 2 1
2 for ( int i = 10; i > 0; i - - )
3 {
4 cout << i << "\ t " ;
5 }

2. Example: Count from 0 to 14 by 2's


1 // 0 2 4 6 8 10 12 14
2 for ( int i = 0; i >= 14; i += 2 )
3 {
4 cout << i << "\ t " ;
5 }

163
3. Example: Count from 1 to 100 by doubling the number each
time
1 // 1 2 4 8 16 32 64
2 for ( int i = 0; i >= 100; i *= 2 )
3 {
4 cout << i << " \t " ;
5 }

For loops will come in even more handy later on once we get to arrays.

Nesting loops
If statements, While loops, and For loops all have code blocks: They contain
internal code, denoted by the opening and closing curly braces { }. Within any
block of code you can continue adding code. You can add if statements in if
statements in if statements, or loops in loops in loops.

Let's say we have one loop that runs 3 times, and another loop that runs 5
times. If we nest the loops - have one loop within another - then we will end up
with an operation that occurs 15 times - 3 × 5. Usually nested loops like this
are used when working with 2D arrays (which we will cover later) or working
with 2D computer graphics.

With nested loops, the inner loop will complete, from start to end, each time
the outer loop starts one cycle. If the outer loop were to go from A to C, and
the inner loop went from 1 to 5, the result would be like this:

A 1 2 3 4 5
B 1 2 3 4 5

Example nested loop:


1 for ( int outer = 0; outer < 3; outer ++ ) {
2 for ( int inner = 0; inner < 3; inner ++ ) {
3 cout << " OUTER : " << outer
4 << " \ t INNER : " << inner << endl ;
5 }
6 }

Output:

OUTER : 0 INNER : 0
OUTER : 0 INNER : 1
OUTER : 0 INNER : 2
OUTER : 1 INNER : 0
OUTER : 1 INNER : 1
OUTER : 1 INNER : 2
OUTER : 2 INNER : 0
OUTER : 2 INNER : 1
OUTER : 2 INNER : 2

164
See how each line, the INNER number goes up each time and the OUTER
number does NOT go up each time. . . it only goes up once the INNER loop
has completed.

Review questions:
1. What are the 3 parts of a for loop?

165
5.9 Unit 08: C++: Arrays and vectors
5.9.1 Traditional C arrays

1. Array basics - what are arrays?


In C++, arrays are a built-in way to store a series of similar data all under
one name.

Before now, if we wanted to store a list of students in a class (or similar


kind of data), we would have to declare a bunch of separate variables and
write the same code over and over to manage it:

1 string student1 , student2 , student3 ;


2
3 cout << " Enter student 1 name : ";
4 cin >> student1 ;
5
6 cout << " Enter student 2 name : ";
7 cin >> student2 ;
8
9 cout << " Enter student 3 name : ";
10 cin >> student3 ;

This would quickly become unmanagable if you were writing a program


with tens, hundreds, or thousands of students stored in it. Instead, we
can make use of arrays to store a series of related data together.

166
1 string students [100];
2 for ( int i = 0; i < 100; i ++ )
3 {
4 cout << " Enter student " << ( i +1) << " name : " ;
5 cin >> student [ i ];
6 }

Arrays allow us to operate on the same name (e.g., student), but address-
ing dierent elements of the array with an index number. This way, we
can write code to act on the data once, just modifying that index to work
with dierent pieces of data.

Example: student array of size 4:

Element Rai Anuj Rebekah Rose


Index 0 1 2 3

Each item in the array has a corresponding index marking its position in
the list, with 0 being the rst value. If an array is of size n, then the valid
indices are 0 through n − 1.
An element is the information stored at that index position, which is
essentially a single variable in an array of variables.

2. Declaring arrays
In C++, we declare an array similarly to how we declare a variable, except
that we need to specify an array size during declaration:
1 // An array of size 100
2 string students [100];

Or, if we already have data to put into it, we can initialize it with an
initializer list. Then the array will be sized at however many items you
give it.

1 // An array of size 4
2 string students [] = { " Rai " , " Anuj " , " Rebekah " , " Rose " };

(a) Size must be known at compile-time


Traditional C-style arrays must have its size be dened during its
declaration and the array cannot be resized during the program's
execution. Because the array size can't change, and because we may
need to know the size of the array throughout the program, we will
generally use a named constant to store the size of the array.

167
1 const int MAX_STUDENTS = 100;
2 string students [ MAX_STUDENTS ];

(b) A variable to store the # of items in the array


Because an array's size cannot be changed after its declaration, it
often becomes necessary to overshoot the amount of spaces we need
in the array so that we always have enough room for our data. Per-
haps a school's classrooms range from 20 to 70 seats, so we would
want to declare the array of the biggest size so that we don't run out
of space. Because of this, not all spaces in the array may be taken
up at any given time.

C++ doesn't have a function to directly get the amount of elements


in an array, so generally when declaring an array we need to also
have an associated variable to track how many items we've stored
in the array.

1 const int MAX_STUDENTS = 100; // total array size


2 int studentCount = 0; // how many elements
3 string students [ MAX_STUDENTS ]; // array declaration
4
5 students [0] = " Rai " ; // setting up first student
6 studentCount ++; // adding 1 to student count

(c) Array data types


Arrays can be declared with any data type. To the computer, we
are just declaring n amount of some variable, and it takes care of
putting all the n variables back-to-back in memory.

(d) Valid indices


As stated earlier, if an array is of size n, then its valid indices are 0
to n − 1. In most computer languages, arrays and lists start at index
0 and go up from there, meaning to count for items we have "0, 1,
2, 3".

Warning!

A common source of program crashes is going outside the


bounds of an array! This happens if you try to access an
invalid index, such as student[-1] or student[100] (for an
array of size 100; valid indices are 0-99).

168
3. Accessing array elements via index After we've declared an array, we
can treat its elements like normal variables, storing data within it and
accessing that data. Each one can be accessed via its index (position in
the array) and the subscript operator: [].

In math, you might be used to these subscripts:

an = an−1 + 2

But with C++, subscripts look like this:

a[n] = a[n-1] + 2

So, declaring an array and accessing its values can look like this:

1 string courses [4];


2 courses [0] = " CS 134 " ;
3 courses [1] = " CS 200 " ;
4 courses [2] = " CS 210 " ;
5 courses [3] = " ASL 120 " ;
6
7 cout << " First course : " << courses [0] << endl ;

Or, with modern C++ (from 2011 and later) you can initialize an array
with an initializer list, {}:
1 string courses [4] = {
2 " CS 134 " ,
3 " CS 200 " ,
4 " CS 210 " ,
5 " ASL 120 "
6 };
7
8 cout << " First course : " << courses [0] << endl ;

Design!

It's common for array names to be plural - it is a structure that


stores multiple items - multiple courses, multiple products, multiple
grades, etc. So, to be clear, it is best to give your arrays plural names:
courses, products, grades, instead of singular.

(a) Accessing indices with variables Since the array index is always
an integer, we could use a variable to determine which item in an
array to modify - such as asking the user which item they want to
edit.

1 cout << " Edit which item ? (0 -9) : " ;


2 cin >> itemIndex ;
3 cout << " Enter price for item : " ;
4 cin >> prices [ itemIndex ];

169
4. Using for loops with arrays
Using for loops is the most common way to iterate over all the data in an
array, setting data or accessing data. Have an array of size n? We want
to iterate from i = 0 to n − 1, going up by 1 each time.

(a) Design pattern: Asking the user to enter all elements


We can iterate over all the items in an array and have the user enter
information for each element by using a loop. Since the rst index
is 0, we sometimes just add +1 to the index for the user's benet,
since people generally aren't used to lists starting at 0.

1 const int TOTAL_ITEMS = 10;


2 float prices [ TOTAL_ITEMS ];
3
4 for ( int i = 0; i < TOTAL_ITEMS ; i ++ )
5 {
6 cout << " Enter price for item " << ( i +1) << " : " ;
7 cin >> prices [ i ];
8 }

(b) Design pattern: Displaying all items in an array


We can display all the elements of an array by using a loop as well,
though we usually don't want to show all elements of the array -
usually just the items we know we're storing data in. Recall that we
usually will have an extra integer variable to count how many items
have actually been stored in the array, which is dierent from the
total array size.

1 const int MAX_STUDENTS = 100;


2 int studentCount = 0;
3 string students [ MAX_STUDENTS ];
4
5 // (... Let 's say 20 students were added here ...)
6
7 // Iterate from index 0 to 19 , since we have stored
8 // 20 students so far .
9 for ( int i = 0; i < studentCount ; i ++ )
10 {
11 cout << " Student " << ( i +1)
12 << " is " << students [ i ] << endl ;
13 }

You can also use a range-based for loop in versions of C++ from
2011 or later:

1 for ( auto & student : students )


2 {
3 cout << student << endl ;
4 }

170
5. Parallel arrays
Let's say we're writing a simple restaurant program where we need a list of
dishes and their prices together. Later on, we will write our own data type
using structs and classes to keep these items together. But for now, we
would implement this relationship by keeping track of two separate arrays
with the data we need.

1 const int MAX_DISHES = 20;


2 int dishCount = 0;
3
4 // Information about a dish
5 string dishNames [ MAX_DISHES ];
6 float dishPrices [ MAX_DISHES ];
7 bool dishVegetarian [ MAX_DISHES ];
8
9 // ... Let 's say we created some dishes here ...
10
11 // Display the menu
12 cout << " What would you like to order ? " << endl ;
13 for ( int i = 0; i < dishCount ; i ++ )
14 {
15 cout << " Dish # " << i << " : " << endl ;
16 cout << " * Name : " << dishNames [ i ] << endl ;
17 cout << " * Price : $ " << dishPrices [ i ] << endl ;
18
19 if ( dishVegetarian [ i ] ) {
20 cout << " * Is vegetarian " << endl ;
21 }
22
23 cout << endl ;
24 }
25
26 // Get the index of dish they want
27 int whichDish ;
28 cout << " Selection : " ;
29 cin >> whichDish ;

171
6. Arrays as arguments
they could potentially take up a lot of memory. Because of this, passing
an array as a pass-by-value parameter would be inecient - remember
that pass-by-value means that the parameter is copied from the caller
argument.

C++ automatically passes arrays around as pass-by-reference instead.


You don't have to inclue the & symbol in your parameter list for an array,
it just happens! But - keep in mind that any problems with pass-by-
reference also apply to arrays. If you want to pass an array to a function
but you don't want the data changed, then you would need to mark
that array parameter asconst.
1 void DisplayAllItems ( const string arr [] , int size )
2 {
3 for ( int i = 0; i < size ; i ++ )
4 {
5 cout << arr [ i ] << endl ;
6 }
7 }

When using an array as a parameter, you don't have to hard-code a size


to it. You can leave the square brackets empty (but you DO need square
brackets to show that it's an array!) and then pass any array (with match-
ing data type) to the function. However, you will also want to have an int
parameter to pass the size of the array as well.

7. Array management functionality


Since arrays require quite a bit of management to work with, you could
implement some basic functions to do this management, instead of having
to re-write the same code over and over. For example. . .

(a) Clear array


Sets all elements of this string array to an empty string and resets
the elementCount to 0 afterwards.

1 void Clear ( string arr [] , int & elementCount )


2 {
3 for ( int i = 0; i < elementCount ; i ++ )
4 {
5 arr [ i ] = " " ;
6 }
7 elementCount = 0;
8 }

172
(b) Display all elements
Shows all the elements of an array.

1 void Display ( const string arr [] , int elementCount )


2 {
3 for ( int i = 0; i < elementCount ; i ++ )
4 {
5 cout << i << " \ t " << arr [ i ] << endl ;
6 }
7 }

(c) Add new element to array


Often in our programs we will only set up one item at a time (perhaps
when selected from a menu). This means we need to get the data
for the array and gure out where in the array it will go.

1 void AddItem ( string arr [] , int & elementCount )


2 {
3 cout << " Enter new element : " ;
4 cin >> arr [ elementCount ];
5 elementCount ++;
6 }

For an array, elementCount starts at 0 when the array is empty.


This also happens to be the index where we will insert our rst
element - at 0.

Element
Index 0 1 2 3

Once we add our rst element, our elementCount will be 1, and the
next index to insert data at will also be 1.

Element Cats
Index 0 1 2 3

Then, elementCount will be 2, and the next index to insert at will


be 2.

Element Cats Dogs


Index 0 1 2 3

Because of this, the elementCount variable both tells us how many


items have been stored in the array and what is the next index to
store new information at.

173
8. Multidimensional arrays
We can also declare multidimensional arrays, such as 2D or 3D arrays. As
with a 1D array, there is just one data type that all the elements share.

1 string spreadsheet [32][32]; // rows and columns


2 int vertices [4][4][4]; // x , y , z

Let's say we wanted to turn a day planner into a program. Perhaps we


originally stored the day plan like this:

Day Time Task


Monday 8:00 Work meeting with Bob
Monday 13:00 Project review
Tuesday 10:00 Customer meeting
Tuesday 12:00 Crying in car
Wednesady 14:00 Sprint Retrospective

We can convert this into a 2D array of strings (the "task"), with one
dimension being for "day of the week" and the other dimension being for
"hour of the day". . .

1 int DAYS_OF_WEEK = 7;
2 int HOURS_IN_DAY = 24;
3 string todo [ DAYS_OF_WEEK ][ HOURS_IN_DAY ];

We could ask the user what day they want to set a task for, and if they
type "Sunday" that could translate to 0, and "Saturday" could translate
to 6 (or however you want to organize your week). . .

Sunday Monday Tuesday Wednesday Thursday Friday Saturday


0 1 2 3 4 5 6

We could ask them next for what hour the task is at, and that can map
to the second index: "0" for midnight, "8" for 8 am, "13" for 1 pm, and
so on to 23.

174
With this information, we can get the user's todo task and store it at the
appropriate indices:

1 int day , hour ;


2
3 cout << " Enter the day : " << endl ;
4 cout << " 0. Sunday \n"
5 << " 1. Monday \n"
6 << " 2. Tuesday \n"
7 << " 3. Wednesday \ n "
8 << " 4. Thursday \ n "
9 << " 5. Friday \n"
10 << " 6. Saturday \ n " ;
11
12 cout << " Day : " ;
13 cin >> day ;
14
15 cout << " Enter the hour (0 to 23) : " ;
16 cin >> hour ;
17
18 cout << " Enter your task : " ;
19 cin >> todo [ day ][ hour ];

With the user's week planned out, you could then display it back to the
user by using a nested for loop: One loop for the day, one loop for the
hour.

1 cout << " YOUR SCHEDULE " << endl ;


2
3 for ( int day = 0; day < DAYS_OF_WEEK ; day ++ )
4 {
5 for ( int hour = 0; hour < HOURS_IN_DAY ; hour ++ )
6 {
7 cout << day << " , "
8 << hour << " : "
9 << todo [ day ][ hour ] << endl ;
10 }
11 }

Though you'd probably want to do some extra formatting; such as deter-


mining that if the day is 0, then write "Sunday" instead of the number
"0".

9. Review questions:

(a) Do all items in an array need to be the same data type in C++?

(b) What is an element of an array?

175
(c) What is an index ?
(d) The subscript operator is. . .

(e) What code would you write to display the item at position 0 in an
array?

(f ) What code would you write to display the item at position 2 in an


array?

(g) Given an array of size n, the valid indices of the array are. . .

(h) How do you iterate over all elements of an array?

176
5.9.2 Dynamic arrays - Memory allocation with pointers
1. Dynamic array
We can use Dynamic Arrays to allocate space for an array at run-time,
without having to know or hard-code the array size in our code. To do
this, we need to allocate memory on the heap via a pointer.

(a) Creating a dynamic array


We don't have to know the size of the array at compile-time, so we
can do things like ask the user to enter a size, or otherwise base its
size o a variable.

1 int size ;
2 cout << " Enter size : " ;
3 cin >> size ;
4 string * products = new string [ size ];

(b) Setting elements of the array


We can access elements of the dynamic array with the subscript
operator, as before. However, we won't know the size of the array
unless we use the size variable, so it'd be better to use a for loop
to assign values instead of this example:

1 products [0] = " Pencil " ;


2 products [1] = " Eraser " ;
3 products [2] = " Pencil case " ;
4 products [3] = " Pencil sharpener ";
5 products [4] = " Ruler " ;

(c) Iterating over the array


Accessing elements of the array and iterating over the array is done
the same way as with a traditional array.

1 for ( unsigned int i = 0; i < size ; i ++ )


2 {
3 cout << i << " . " ; // Display index
4 cout << products [i ] << endl ; // Display element at
that index
5 }

(d) Freeing the memory when done


Before your pointer loses scope we need to make sure to free the
space that we allocated:

1 delete [] products ;

177
(e) "Resizing" the array
When memory is allocated for an array we must know the entire
size at once because all of the array's elements are contiguous in
memory. Because of this, we don't technically "resize" a dynamic
array, instead we allocate more space elseware and copy the data
over to the new array. Here are the steps:

One: Allocate space for a new, bigger array


1 string * newArray = new string [ size + 10 ];

Two: Copy the data from the old array to the new array
1 for ( unsigned int i = 0; i < size ; i ++ )
2 {
3 newArray [ i ] = products [ i ];
4 }

Three: Free the space at the old address


1 delete [] products ;

Four: Update the main array pointer to the new address


1 products = newArray ; // Point to same address

Five: Update your size variable


1 size = size + 10;

2. Review questions:

(a) How do you allocate memory for an array via a pointer?

(b) How do you deallocate memory for a dynamic array?

(c) What are the steps to "resize" a dynamic array?

178
5.9.3 STL array and vector
1. C++ Standard Template Library: Arrays
Documentation: https://cplusplus.com/reference/array/array/

If we put #include <array> at the top of our le, we can use an array
object instead of a traditional array to store data. They are basically
interchangible, ecxept the array object gives us access to the .size()
function, making our job slightly easier. However, the array still can't be
resized.

(a) Creating an STL array


1 array < string , 5 > products ;

(b) Setting elements of the array


1 products [0] = " Pencil " ;
2 products [1] = " Eraser " ;
3 products [2] = " Pencil case " ;
4 products [3] = " Pencil sharpener ";
5 products [4] = " Ruler " ;

(c) Iterating over the array


1 for ( unsigned int i = 0; i < products . size () ; i ++ )
2 {
3 cout << i << " . " ; // Display index
4 cout << products [i ] << endl ; // Display element at
that index
5 }

179
2. C++ Standard Template Library: Vectors
Documentation: https://cplusplus.com/reference/vector/vector/

The C++ Standard Template Library contains a special structure called


a vector. A vector is a class (something we'll learn about later) and it is
implemented on top of a dynamic array (which we will learn about later
with pointers). Basically, it's a resizable array and it has functionality to
make managing data a bit more managable.

Generally, in Computer Science curriculum, we teach you how to build


data structures (structures that store data) like vectors, lists, and other
items because it's important to know how they work (thus why we're
covering arrays), but for your own projects and in the real world, you
would probably use a vector over an array.

(a) Declaring a vector


Vectors are a type of templated object, meaning it can store any
data type - you just have to specify what kind of type the vector
stores. The format of a vector declaration looks like this:

1 // Declaring vectors
2 vector < string > students ;
3 vector < float > prices ;

(b) Adding data


You can add data to a vector by using its push_back function, pass-
ing the data to add as the argument:

1 vector < string > students ;


2 students . push_back ( " Rai " ) ;

(c) Getting the size of the vector


The size function will return the amount of elements currently
stored in the vector.

1 cout << " There are "


2 << students . size () << " students " << endl ;

(d) Clearing the vector


You can erase all the data in a vector with the clear function:

1 students . clear () ;

180
(e) Accessing elements by index
Accessing an element at some index looks just like it does with an
array:

1 cout << " Student : " << students [0] << endl ;

(f ) Iterating over a vector


You can use a for loop to iterate over all the elements of a vector,
similar to an array:

1 cout << " Students :" << endl ;


2
3 for ( int i = 0; i < students . size () ; i ++ )
4 {
5 cout << i << " \ t " << students [i ] << endl ;
6 }

You can also use C++11 style range-based for loop if you don't
need the index. It allows you to iterate over all the elements of
students, using an alias of student for each element.

1 for ( auto & student : students )


2 {
3 cout << student << endl ;
4 }

3. Review questions:

(a) How do you declare an STL array object?

(b) How do you declare an STL vector object?

(c) How do you add new items to a vector object?

181
5.10 Unit 09: C++: Branching
5.10.1 If statements
1. Branching
Branching is one of the core forms of controlling the ow of the pro-
gram. We ask a question, and based on the result we perhaps do this
code over here or maybe that code over there - the program results change
based on variables and data accessible to it.

We will mostly be using if / else if / else statements, though switch


statements have their own use as well. Make sure to get a good under-
standing of how each type of branching mechanism "ows".

(a) If statements If statements (usually the general term encompassing


if / else if / else as well) are a way we can ask a question and respond:
If a is less than b then. . . or if a is greater than c then. . . Otherwise
do this default thing. . .

Let's look at some examples while ironing out how it works.

For a basic if statement, we use the syntax:


1 // Do things 1
2
3 if ( CONDITION )
4 {
5 // Do things 2 -a
6 }
7
8 // Do things 3

The CONDITION will be some boolean expression. If the boolean


expression result is true, then any code within this if statement's
code block (what's between \* and \*) will get executed. If the
result of the expression is false, then the entire if statement's code
block is skipped and the program continues.

Example:

1 cout << " Bank balance : " << balance ;


2
3 if ( balance < 0 )
4 {
5 cout << " ( OVERDRAWN !) " ;
6 }
7
8 cout << " in account # " << accountNumber << endl ;

Output with balance = -50


Bank balance : -50 ( OVERDRAWN !) in account #1234

182
Output with balance = 100
Bank balance : 100 in account #1234

ˆ The special message "OVERDRAWN!" only gets displayed


when the balance is less than 0.

ˆ The following cout that gives the account number is displayed


in all cases.

183
(b) If/Else statements
In some cases, we will have code that we want to execute for the
false result as well. For an if/else statement, either the if code
block will be entered, or the else code block will be.
NOTE: The else statement NEVER has a CONDITION.
1 // Do things 1
2
3 if ( CONDITION )
4 {
5 // Do things 2 -a
6 }
7 else
8 {
9 // Do things 2 -b
10 }
11
12 // Do things 3

The else if check fails. If the CONDI-


block is executed when the
TION is false, we can use DeMorgan's Laws to gure out what
the program's state is during the else.

Example:

1 cout << " Enter your age : " ;


2 cin >> age ;
3
4 if ( age < 18 )
5 {
6 result = " can 't vote " ;
7 }
8 else
9 {
10 result = " can vote " ;
11 }
12
13 cout << " Result : " << result << endl ;

If the age is less than 18, it will set the result variable to "can't
vote". If that boolean expression is false, age is ≥ 18,
that means
and then it will set the result to "can vote". Finally, either way, it
will display "Result: " with the value of the result variable.

(c) If/Else if/Else statements


In some cases, there will be multiple scenarios we want to search for,
each with their own logic. We can add as many else if statements
as we want - there must be a starting if statement, and each else if
statement will have a condition as well.

We can also end with a nal else statement as a catch-all: if none of


the previous if / else if statements are true, then else gets executed
instead. However, the else is not required.

184
1 // Do things 1
2 if ( CONDITION1 )
3 {
4 // Do things 2 - a
5 }
6 else if ( CONDITION2 )
7 {
8 // Do things 2 - b
9 }
10 else if ( CONDITION3 )
11 {
12 // Do things 2 - c
13 }
14 else
15 {
16 // Do things 2 - d
17 }
18 // Do things 3

Example:

1 cout << " Enter grade : " ;


2 cin >> grade ;
3
4 if ( grade >= 90 ) { letterGrade = 'A '; }
5 else if ( grade >= 80 ) { letterGrade = 'B '; }
6 else if ( grade >= 70 ) { letterGrade = 'C '; }
7 else if ( grade >= 60 ) { letterGrade = 'D '; }
8 else { letterGrade = 'F '; }
9
10 cout << " Grade : " << letterGrade << endl ;

With this example, I'm rst checking if the grade is 90 or above. If


it is, then I know the letter grade is 'A'.
However, if it's false, it will go on and check the next else if state-
ment. At this point, I know that since

grade ≥ 90 was FALSE

that means

grade < 90 is TRUE.

Since the next statement checks if

grade ≥ 80

if this one is TRUE, I know that:

grade < 90 AND grade ≥ 80

185
2. Nesting if statements
If statements, While loops, and For loops all have code blocks: They
contain internal code, denoted by the opening and closing curly braces {
}. Within any block of code you can continue adding code. You can add
if statements in if statements in if statements, or loops in loops in loops.

Nesting an if statement within another if statement basically gives you a


boolean expression with an AND.

Example:
1 if ( wantsBeer )
2 {
3 if ( age >= 21 )
4 {
5 GiveBeer () ;
6 }
7 }

Equivalent logic:
1 if ( wantsBeer && age >= 21 )
2 {
3 GiveBeer () ;
4 }

Whether you implement some logic with nested if statements, or with if /


else if statements using AND operations is a matter of design preference-
in some cases, one might be cleaner than the other, but not always.

If you have a statement like this:

1 if ( conditionA )
2 {
3 if ( conditionB )
4 {
5 Operation1 () ;
6 }
7 else
8 {
9 Operation2 () ;
10 }
11 }

It could be equivalently described like this:

1 if ( conditionA && conditionB )


2 {
3 Operation1 () ;
4 }
5 else if ( conditionA && ! conditionB )
6 {
7 Operation2 () ;
8 }

186
5.10.2 Switch statements

1. Switch statements
Switch statements are a special type of branching mechanism that only
checks if the value of a variable is equal to one of several values. Switch
statements can be useful when implementing a menu in a program, or
something else where you only have a few, nite, discrete options.

In C++, switch statements only work with primitive data types, like in-
tegers and chars - not strings.

1 switch ( VARIABLE )
2 {
3 case VALUE1 :
4 // Do thing
5 break ;
6
7 case VALUE2 :
8 // Do thing
9 break ;
10
11 default :
12 // Default code
13 }

With a switch statement, each case is one equivalence expression. The


default case is executed if none of the previous cases are.

1 case VALUE1 : // equivalent to : if ( VARIABLE == VALUE1 )

1 case VALUE2 : // equivalent to : if ( VARIABLE == VALUE2 )

1 default : // equivalent to : else

The default case is not required, just like how the else clause is not
required in an if statement.

187
The break; statement
The end of each case should have a break; statement at the end. If the
break is not there, then it will continue executing each subsequent case's
code until it does hit a break.

This behavior is "ow-through", and it can be used as a feature if it


matches the logic you want to write.

Variables inside cases


If you're declaring a variable within a case statement, you need to
enclose your case with curly braces { }, otherwise you'll get compiler
errors:

1 switch ( operation )
2 {
3 case 'A ':
4 {
5 float result = num1 + num2 ;
6 cout << " Result : " << result << endl ;
7 }
8 break ;
9 }

Calculator example:
Perhaps you are implementing a calculator, and want to get an option
from the user: (A)dd, (S)ubtract, (M)ultiply, or (D)ivide. You could
store their choice in a char variable called operation and then use the
switch statement to decide what kind of computation to do:

1 switch ( operation )
2 {
3 case 'A ': // if ( operation == 'A ' )
4 result = num1 + num2 ;
5 break ;
6
7 case 'S ': // else if ( operation == 'S ' )
8 result = num1 - num2 ;
9 break ;
10
11 case 'M ': // else if ( operation == 'M ' )
12 result = num1 * num2 ;
13 break ;
14
15 case 'D ': // else if ( operation == 'D ' )
16 result = num1 / num2 ;
17 break ;
18 }
19
20 cout << " Result : " << result << endl ;

188
Flow-through example:
Sometimes you want to check if your variable equals a value "x" or "y",
and execute the same code for each. You can use ow-through in this case.
If no break; is given for a specic case, then it will continue to execute
code for the following case until a break; is found.
1 char choice ;
2 cout << " Do you want to quit ? ( Y / N ) : " ;
3 cin >> choice ;
4
5 switch ( choice )
6 {
7 case 'Y ':
8 case 'y ':
9 done = true ;
10 break ;
11
12 case 'N ':
13 case 'n ':
14 done = false ;
15 break ;
16
17 default :
18 cout << " Unknown selection ! " << endl ;
19 }

189
5.11 Unit 10: C++: Searching and sorting
5.11.1 Searching
We're going to keep this section short for now because we're mostly going to be
focusing on sorting algorithms.

1. Linear search
When we're searching for items in an unsorted linear structure there's
not much we can do to speed up the process. We can basically either
start at the beginning and move forward, or start and the end and move
backward, checking each item in the structure for what you're looking for.

1 template < typename T >


2 int LinearSearch ( const vector <T >& arr , T findme )
3 {
4 int size = arr . size () ;
5 for ( int i = 0; i < size ; i ++ )
6 {
7 if ( arr [ i ] == findme )
8 {
9 return i ;
10 }
11 }
12
13 return -1; // not found
14 }

ˆ We begin at the rst index 0 and iterate until we hit the last in-
dex. Within the loop, if the element at index i matches what we're
looking for, we return this index.

ˆ If the loop completes and we haven't returned an index yet that


means we've searched the entire structure and have not found the
item. In this case, it is not in the structure and we can throw an
exception to be dealt with elseware or return something like -1 to
symbolize "no valid index".

This search algorithm's growth rate is O(n)  the more items in the struc-
ture, the time linearly increases to search through it. Not much we can do
about that, which is why we have dierent types of data structures that
sort data as it is inserted - more on those later on.

2. Binary search
OK, but what if the structure is sorted?
We're going to be learning about sorting algorithms, so what if we happen
to have a structure that is sorted? How can we more intelligently look for
some value in the structure?

Let's say we have a simple array like this:

190
Value: "aardvark" "bat" "cat" "dog" "elephant" "fox"
Index: 0 1 2 3 4 5

And we want to see if "dog" is in the array. We could investigate what the
rst item is (Hm, starts with an "a") and the last item ("f"), and realize
that "d" is about halsh way between both values. Maybe we should start
in the middle and move left or right?

ˆ Index 0 is "aardvark". Index 5 is "fox". 0+5


Middle value
2 is 2.5
(or 2, for integer division). What is at position 2?  "cat". If arr[2]
< ndme, move left (investigate arr[1] next) Or if arr[2] > ndme,
move right (investigate arr[3] next).

ˆ "d" is greater than "c" so we'll move right. . . Index 3 gives us "dog"
- we've found the item! Return 3.

In this case, we basically have two iterations of a loop to nd "dog" and
return its index. If we were searching linearly, we would have to go from
0 to 1 to 2 to 3, so four iterations.

This still isn't the most ecient way to search this array - just starting at
the midpoint and moving left or moving right each time. However, we can
build a better search that imitates that rst step: Checking the mid-way
point each time.

Here is the code:

1 template < typename T >


2 int BinarySearch ( vector <T > arr , T findme )
3 {
4 int size = arr . size () ;
5 int left = 0;
6 int right = size - 1;
7
8 while ( left <= right ) {
9 int mid = ( left + right ) / 2;
10
11 if ( arr [ mid ] < findme ) {
12 left = mid + 1;
13 }
14 else if ( arr [ mid ] > findme ) {
15 right = mid - 1;
16 }
17 else if ( arr [ mid ] == findme ) {
18 return mid ;
19 }
20 }
21
22 return -1; // not found
23 }

With the binary search we look at the left-most index, right-most index,
and mid-point. Each iteration of the loop, we look at our search value
findme  is its value greater than the middle or less than the middle?

191
(a) Example: Binary search on a sorted array
Let's say we have this array, and we are searching for 'p'.

Value: 'a' 'c' 'e' 'h' 'i' 'k' 'm' 'o' 'p' 'r'
Index: 0 1 2 3 4 5 6 7 8 9

Step 1: left is at 0, right is at 9, mid is 0+9


2 = 4 (integer division).

Value: 'a' 'c' 'e' 'h' 'i' 'k' 'm' 'o' 'p' 'r'
Index: 0 1 2 3 4 5 6 7 8 9
left mid right

Next we compare i to 'p'. 'p' comes later in the alphabet (so p >
i), so next we're going to change the left value to look at mid+1
and keep right as it is.

Step 2: left is at 5, right is at 9, mid is 5+9


2 = 14
2 = 7.

Value: 'a' 'c' 'e' 'h' 'i' 'k' 'm' 'o' 'p' 'r'
Index: 0 1 2 3 4 5 6 7 8 9
left mid right

Now we compare the item at arr[mid] 'o' to what we're searching


for ('p'). p > o so we adjust our left point again to our current
midpoint.

Step 3: left is at 7, right is at 9, mid is 7+9


2 = 16
2 = 8.

Value: 'a' 'c' 'e' 'h' 'i' 'k' 'm' 'o' 'p' 'r'
Index: 0 1 2 3 4 5 6 7 8 9
left mid right

Now we compare the item at arr[mid] ('p') to what we're searching


for ('p'). The values match! So the result is mid as the index where
we found our item.

Each step through the process we cut out half the search area by
investigating mid and deciding to ignore everything either before it
(like our example) or after it. We do this every iteration, cutting out
half the search region each time, eectively giving us an eciency of
O(log(n)) - the inverse of an exponential increase.

192
5.11.2 Sorting
I'll update the text here later for next semester but I never liked sorting algo-
rithms. I always found the approach to studying them really tedious in uni.
I'm not going to make you have to gure out these algorithms yourself - the
algorithms are online.
I'm just going to give you the code and we can visually step through how
they work. It's possible you'll be asked to implement some sorting algorithms in
a job interview if the company is really annoying, but for the most part you're
going to be using sorting algorithms already implemented in your day-to-day
life rather than implementing these yourself from scratch each time.
You'll nd animations and stu on the class webpage that hopefully illustrate
it better than we could in a typewritten format.

Sorting algorithm eciency (From https://www.bigocheatsheet.com/)


Algorithm Best time Average time Worst time
Bubble Sort Ω(n) Θ(n2 ) O(n2 )
Insertion Sort Ω(n) Θ(n2 ) O(n2 )
Selection Sort Ω(n2 ) Θ(n2 ) O(n2 )
Merge Sort Ω(nlog(n)) Θ(nlog(n)) O(nlog(n))
Quick Sort Ω(nlog(n)) Θ(nlog(n)) O(n2 )

193
1. Bubble Sort
1 template < typename T >
2 void BubbleSort ( vector <T >& arr )
3 {
4 for ( int i = 0; i < arr . size () - 1; i ++ )
5 {
6 for ( int j = 0; j < arr . size () - i - 1; j ++ )
7 {
8 if ( arr [ j ] > arr [ j +1] )
9 {
10 swap ( arr [ j ] , arr [ j +1] ) ;
11 }
12 }
13 }
14 }

194
2. Insertion Sort
1 template < typename T >
2 void InsertionSort ( vector <T >& arr )
3 {
4 size_t arraySize = arr . size () ;
5 size_t i = 1;
6
7 while ( i < arraySize )
8 {
9 int j = i ;
10 while ( j > 0 && arr [j -1] > arr [ j ] )
11 {
12 swap ( arr [ j ] , arr [j -1] ) ;
13 j = j - 1;
14 }
15
16 i = i + 1;
17 }
18 }

195
3. Selection Sort
1 template < typename T >
2 void SelectionSort ( vector <T >& arr )
3 {
4 int arraySize = arr . size () ;
5
6 for ( size_t i = 0; i < arraySize - 1; i ++ )
7 {
8 int minIndex = i ;
9
10 for ( size_t j = i + 1; j < arraySize ; j ++ )
11 {
12 if ( arr [ j ] < arr [ minIndex ] )
13 {
14 minIndex = j ;
15 }
16 }
17
18 if ( minIndex != i )
19 {
20 swap ( arr [ i ] , arr [ minIndex ] ) ;
21 }
22 }
23 }

4. Merge Sort
1 // Declarations
2 template < typename T >
3 void MergeSort ( vector <T >& arr ) ;
4
5 template < typename T >
6 void MergeSort ( vector <T >& arr , int left , int right ) ;
7
8 template < typename T >
9 void Merge ( vector <T >& arr , int left , int mid , int right
);
10
11 // Definitions
12 template < typename T >
13 void MergeSort ( vector <T >& arr )
14 {
15 MergeSort ( arr , 0 , arr . size () - 1 ) ;
16 }
17
18 template < typename T >
19 void MergeSort ( vector <T >& arr , int left , int right )
20 {
21 if ( left < right )
22 {

196
23 int mid = ( left + right ) / 2;
24
25 MergeSort ( arr , left , mid ) ;
26 MergeSort ( arr , mid +1 , right ) ;
27 Merge ( arr , left , mid , right ) ;
28 }
29 }
30
31 template < typename T >
32 void Merge ( vector <T >& arr , int left , int mid , int right
)
33 {
34 const int n1 = mid - left + 1;
35 const int n2 = right - mid ;
36
37 vector <T > leftVec ;
38 vector <T > rightVec ;
39
40 for ( int i = 0; i < n1 ; i ++ )
41 {
42 leftVec . push_back ( arr [ left + i ] ) ;
43 }
44
45 for ( int j = 0; j < n2 ; j ++ )
46 {
47 rightVec . push_back ( arr [ mid + 1 + j ] ) ;
48 }
49
50 int i = 0;
51 int j = 0;
52 int k = left ;
53
54 while ( i < n1 && j < n2 )
55 {
56 if ( leftVec [ i ] <= rightVec [ j ] )
57 {
58 arr [ k ] = leftVec [ i ];
59 i ++;
60 }
61 else
62 {
63 arr [ k ] = rightVec [ j ];
64 j ++;
65 }
66 k ++;
67 }
68
69 while ( i < n1 )
70 {
71 arr [ k ] = leftVec [ i ];
72 i ++;
73 k ++;
74 }
75

197
76 while ( j < n2 )
77 {
78 arr [ k ] = rightVec [ j ];
79 j ++;
80 k ++;
81 }
82 }

5. Quick Sort
1 // Declarations
2 template < typename T >
3 void QuickSort ( vector <T >& arr ) ;
4
5 template < typename T >
6 void QuickSort ( vector <T >& arr , int low , int high ) ;
7
8 template < typename T >
9 int Partition ( vector <T >& arr , int low , int high ) ;
10
11 // Definitions
12 template < typename T >
13 void QuickSort ( vector <T >& arr )
14 {
15 QuickSort ( arr , 0 , arr . size () - 1 ) ;
16 }
17
18 template < typename T >
19 void QuickSort ( vector <T >& arr , int low , int high )
20 {
21 if ( low < high )
22 {
23 int partIndex = Partition ( arr , low , high ) ;
24 QuickSort ( arr , low , partIndex - 1 ) ;
25 QuickSort ( arr , partIndex + 1 , high ) ;
26 }
27 }
28
29 template < typename T >
30 int Partition ( vector <T >& arr , int low , int high )
31 {
32 T pivotValue = arr [ high ];
33 int i = low - 1;
34
35 for ( int j = low ; j <= high - 1; j ++ )
36 {
37 if ( arr [ j ] <= pivotValue )
38 {
39 i ++;
40 swap ( arr [ i ] , arr [ j] ) ;
41 }
42 }
43

198
44 swap ( arr [ i +1] , arr [ high ] ) ;
45 return i + 1;
46 }

199
5.12 Unit 11: Tech Literacy: Current trends in tech
5.12.1 AI
1. What is AI and LLM?
Articial Intelligence itself can refer to so many various things. AI has
been part of our media culture for decades with sci-, but depending on
how you dene articial intelligence, we've been training and utilizing AI
for a while, before this explosion of "everything is AI now".

When utilized properly, "AI" (or, more accurately, algorithms ) has been
utilized to develop technology like:

ˆ Voice recognition on phones

ˆ Text to speech training

ˆ Deciding who to show an ad to, or a video or post on social media


to, or what movies on a platform you might prefer

And even in the past there has been trouble with relying on an un-
supervised algorithm to generate content for the web. (For example,
see: Google apologises for Photos app's racist blunder from BBC (2015):
https://www.bbc.com/news/technology-33347866). Even with early
problems arising, in my opinion it doesn't seem like there's been much at-
tention paid to the early issues - full speed ahead for Silicon Valley, move
fast and break things, at whatever cost.

Large Language Models basically refer to an algorithm trained on


human language, which can imitate sensible, grammatically correct sen-
tences. In a way, it's a big complex "autocomplete".

Pretend that you're a language model being trained and you're given a
bunch of books to learn from. After your training, someone types in a
prompt, "Once upon" - from your training, you might immediately com-
plete the sentence with "a time", because statistically that is the most
likely set of words that come after "Once upon".

The same is true with generative AI, whether that's for code, text,
images, or audio. For a product like GitHub Co-pilot, it has been trained
on open source projects hosted on GitHub. This means code by newbies
and by experienced people. Code from 20+ years ago and code from
recently. The Co-pilot AI doesn't think through a problem and come up
with a solution, it repeats whatever it has seen most often - what it thinks
is statistically likey to be the answer.

2. What's with the explosion of AI products?


Every-so-often there's a new product or feature that we begin getting
excited about. Lots of companies jump on the bandwagon because their

200
investors expect them to chase the trend, and the companies raise money
from their investors by announcing a new product featuring the hot new
thing, and all the companies want to make the next thing that will bring
in all the money.
Some previous bubbles include:

ˆ With the goldrush, people ocked to the west coast in hopes of


striking it big, being the lucky one to

nd a ton of gold and become rich.

ˆ With the dot com bubble the internet was hot and new and well
these companies made a ton of money, so investors began dumping
money into any and every business with a website - whether or not
their product was viable or not. (See also: List of companies aected
https://en.wikipedia.
by the dot-com bubble from Wikipedia:
org/wiki/List_of_companies_affected_by_the_dot-com_bubble)
ˆ More recently, NFTs were the big new thing and many compa-
nies (especially in gaming) felt the pressure to announce NFT-based
projects.

Basically, my perception of the reason there are so many new AI products


announced now, is that there is investor pressure to do so, and that the
non-technical owners and bosses want it done, without really having a
good idea of how it works.

LLMs and AI can be used in an ethical, useful way that creates real results,
but that's not where we're currently at right now.

3. The various ethical concerns


There are various ethical concerns to keep in mind when it comes to using
AI for any works you do. At worst, using obviously AI generated image,
music, text, etc. is seen as tacky, at worst you may be spreading dangerous
information.

(a) Copyright, licensing, and theft


A lot of AI models were being trained before the common person
knew it was happening. Without asking, tons of AI was trained
by scraping content publicly available on the internet. This could
be peoples' art in web-based art galleries, stories and posts online,
videos on YouTube, code repositories online, and other public con-
tent.

The issue here is that, while a person may look at this public content,
perhaps imitate it in their own work, to outright copy parts of those
works is considered plagiarism. But there has been a large feeling

201
that, if we take enough content from around the web and train a
model on it, that's not plagiarism because it's generating something
new.
The dierence between, say, a budding artist and an AI model, how-
ever, is the budding artist is perhaps studying with their eyes, and
are unable to exactly duplicate any given piece of a work in their
own. The AI model, however, doesn't know how to uniquely gen-
erate anything, so its generated content is made up of thousands of
tiny copies from various other sources.

One could argue that making a collage - building a larger image


from clippings of smaller ones - should be fair use and understood as
its own art. I'm not familiar with any sort of discourse on collage,
licensing, and derivative works, but again here the distinction is
that generally the artist has a reason or purpose for utilizing the
elements in the way they are. An AI is mindlessly copying chunks
here and there because that's what seems like the most likely thing
from patterns it has observed in its training.

(b) Condently wrong


Given the way in which LLMs work, asking something like ChatGPT
a question could result in incorrect answers, but stated in a condent
way, without any indication that the AI may be wrong.

Recently, Google has implemented an summarization AI into its


search engine, but the AI has no ability to discern sources. The
"use glue to stick cheese to pizza" result that was passed around
online recently could be from a random internet joke, or perhaps
from an advertising resource where they assemble "food" for use in
commercials (it's not really edible a lot of the time!)

"Eat a small rock every day"? How do we tell an AI what sites are
satirical (theonion.com/geologists-recommend-eating-at-least-one-small-
rock-per-1846655112) and which aren't?

(c) Power consumption


Everything we do with computers costs energy. When we store in-
formation "in the cloud", that's a server somewhere that's up and
running 24/7. When we use an AI service, your request needs
to go back to a server (or servers), work with the LLM, and re-
turn a result. Additionally, there's also the cost associated with
training the model - hours and hours running a system, giving it
data, so it can learn the patterns present. According to this ar-
ticle from The Verge (theverge.com/24066646/ai-electricity-energy-
watts-generative-consumption), "you'd have to watch 1,625,000 hours
to consume the same amount of power it takes to train GPT-3."

With or without AI, everything we do with technology consumes


so much energy, and there doesn't seem to be any action toward

202
alternatives (perhaps just "making things more ecient"), as we
keep nding more and more ways to consume more energy.

(d) Content pollution


In addition to companies wanting AI products to bring in a bunch
of money, you may have also seen "training videos" on YouTube on
how to "make a bunch of money by using AI to generate videos!",
or perhaps even seen AI generated videos that cover history or other
easily-scrapable data, often using videos edited together by an AI,
and a text to speech AI voice. On social media platforms, there are
bots farming engagement by posting, and trying to make money o
that engagement with their posts. Article-based websites can use AI
to generate articles that have no nuance.

Is any of this content worthwhile ? Does anyone want to engage


with. . . nobody? But this sort of synthetic internet content can
be generated so fast that it drowns out all other information. Now
it's not just spam in your text messages, email inbox, mailbox, and
phonecalls, it's everything. Everything generated, trying to aggre-
gate a few cents from every person who clicks a video mistaking it
for something with value.

There's also the threat of a feedback loop - what happens when an


AI generates content, then is trained on that AI generated content?
What it generates will become even more nonsensical and garbage.

4. How AI could be utilized well


Utilizing LLMs can be helpful, but it seems like all these new AI products
are going about it wrong. If you have a specic training data set,
you can train an AI to know one specic domain - perhaps something
like "here's a library of all bird calls", then it can utilize that data set to
gure out what bird you're hearing. Insteat what we seem to be doing is
having a large LLM trained on everything o of the internet, so if you ask
it what bird makes a given noise, it's going to also be cross-referencing
music, sound eects, and voice.

I, personally, would love for an AI to be able to auto-mark everything that


it thinks is spam and marketing content in my email. There is some level
of auto-spam-marking, but my email inbox is still primarily marketing
and it gets hard to nd anything not auto-generated by a company. I've
been late on paying bills or have missed emails from actual people I know
because of the amount of spam - and no amount of hitting "unsubscribe"
on these emails ever seems to lessen the ow of utter garbage.

Technology like using AI to make text-to-speech more realistic could be


used for something good, like giving a personalized voice to people who
must communicate via text-to-speech, rather than utilizing it to steal work
from voice actors.

203
Any tool can be used for good or bad, to construct and to help, or to pillage
and hurt. Being aware of these aspects are an important part of utilizing
technology and being a professional in the tech eld. We shouldn't just
code something because our bosses said to - you will need to be discerning
with what you are and arae not okay with.

5. See also

ˆ Microsoft claims it's okay to train its AI models on your online con-
tent, because it is "fair use" (MSN, June 2024):

msn.com/en-us/news/technology/microsoft-claims-it-s-okay-to-train-
its-ai-models-on-your-online-content-because-it-is-fair-use/ar-BB1p6Dow

ˆ Google's AI Overview can give false, misleading, and dangerous


answers (Ars Technica, May 2024)

arstechnica.com/information-technology/2024/05/googles-ai-overview-
can-give-false-misleading-and-dangerous-answers/

ˆ The Energy Footprint of Humans and Large Language Models (ACM,


June 2024)

cacm.acm.org/blogcacm/the-energy-footprint-of-humans-and-large-language-
models/

ˆ Reddit's licensing deal means Google's AI can soon be trained on the


best humanity has to oer  completely unhinged posts (Business
Insider, Feb 2024):

businessinsider.com/google-train-ai-model-crazy-subreddit-posts-reddit-
licensing-deal-2024-2

ˆ World of Warcraft Subreddit Trolls AI-Generated 'News' Site into


Publishing Fake Article

mmorpg.com/news/world-of-warcraft-subreddit-trolls-ai-generated-news-
site-into-publishing-fake-article-2000128508

ˆ Disability community has long wrestled with `helpful' technologies


 lessons for everyone in dealing with AI

theconversation.com/disability-community-has-long-wrestled-with-helpful-
technologies-lessons-for-everyone-in-dealing-with-ai-227979

5.12.2 Data privacy


Another important area that is always relevant is privacy and security, especially
with our data. Here's what's been on my mind lately.

204
1. Microsoft Recall
Microsoft has announced their own AI-powered product: Microsoft Recall.
In an attempt to make recalling what you did on your copmuter previously
more easy, this AI product screenshots your PC screen as you work on it,
using OCR to convert images to text, and storing the archive locally.
Since its announcement, there has been massive outcry among security
experts on how this could go wrong. A local database isn't enough for
security - a system can still be compromised, and that data can still be
pulled to other computers. This raises concerns with privacy laws like
HIPAA (Health Insurance Portability and Accountability Act)  even if
you're not using Recall, a person you're working with might be, opening
up all your data to being stolen.

See also:

ˆ Windows AI feature that screenshots everything labeled a security


`disaster' (The Verge, June 2024)

theverge.com/2024/6/3/24170305/microsoft-windows-recall-ai-screenshots-
security-privacy-issues

ˆ This Hacker Tool Extracts All the Data Collected by Windows' New
Recall AI (Wired, June 2024)

wired.com/story/total-recall-windows-recall-ai/

2. Miscellaneous rambling
Our computer systems and our phones these days collect data as we
move about the world and cyberspace. When you visit websites, loads
of Javascript widgets are loaded on, which report back to ad services or
metrics services, analysing how you search and how you purchase. Apps
may ask for GPS access and utilize your data there.

Whatever data we generate with our behaviors, data brokers are inter-
ested in buying and selling that information, so that they can analyze our
behavior patterns and gure out how best to advertise to us.

And yet, the modern world has been shaped based on the assumption that
you're using this technology. My six year old phone nally died this past
May. I've tried two phones as an alternative: a ip phone with an old
version of Android, and my Pinephone Pro running Mobian OS (a variant
of Debian). Multiple things kept coming up while trying to live with either
of these devices:

ˆ Denitely no 'Android Auto" - and no ability to update the Android


OS to enable it.

ˆ Certain apps only being available for iOS and Android, but not PC
(Microsoft Authenticator, which I need for work).

205
ˆ Mobile websites not allowing me to view the "Desktop Page" and in-
sisting I "download the app" instead from my Linux phone, meaning
that service was unaccessible without further tweaking.

ˆ Various other apps not being compatible with low-resolution screens,


even on an Android device. (UI elements overlapping, buttons o
the side of the screen and unaccessible, etc.)

There's an assumption that we all have access to the internet and have
a smartphone, though not everybody has access to internet at home, not
everybody has access to smartphones, and perhaps people would prefer to
not have these.

Shopping around for phones, many phone providers oer a set amount of
years of security updates and OS update support.

Computers no longer feel like something you own and can decide how to
use and maintain, it feels like another service that can be discontinued at
any time, that some outside company gets to make the decisions for the
devices you use and how you use them.

OK I'm tiring of writing this rambley part but the last note: it seems
like User Interface design has also gone downhill since the days of desktop
software and I hate it. I'm tired of using bad software.

206
5.13 Unit 12: Tech Literacy: Object Oriented Program-
ming

5.13.1 Programming paradigms


Programming paradigms (pronounced "pair-uh-dimes") are ways we can classify
dierent programming languages based on features they have available or the
style programs are written. Dierent paradigms have popped up over the life of
computers as programming languages grow and evolve.

ˆ Machine code: At the beginning, computers were programmed with


machine code, where you work directly with instructions supported by
the hardware - for example, add, sub, storing data in registers, and other
relatively simple commands.

ˆ Procedural Languages: Eventually, those commands were abstracted


into higher-level languages, where one command in, say, C, could "trans-
late" to several machine-code instructions. Languages like C, Fortran, Al-
gol, BASIC, and C are known as Procedural Languages, where these
programs would describe a procedure to follow and instructions are exe-
cuted one-at-a-time in a specic order (top-to-bottom, or calling a function
and returning).

ˆ Object Oriented Programming: Languages like C supported our basic


control ow and using functions, but did not include classes - a way to
make more sophisticated data types. A class is a structure that can store
its own member variables and member functions. A variable whose
data type is from some dened class is known as an object.

There are other programming paradigms, but we are going to focus on Object
Oriented Programming (OOP) now since it's a large part of using C++ and
other languages like Java, C#, and Python.

207
5.13.2 Introduction to Object Oriented Programming

Object Oriented Programming (or "OOP") is probably one of the most pop-
ular ways to design and implement software these days. In programming, an
object is some sort of structure that stores its own data (variables) and func-
tionality (functions). We try to design our programs as a collection of objects
that interact with each other to get some job done.
In C++ and many other languages functions always end with parentheses
( ), which is how you can quickly identify them. Sometimes, there is data in
the parentheses - these are input parameters. Functions can also return data as
well, so each interaction between objects can pass inputs between objects, and
return data between objects.

1. Design ideals
Designing programs in an OOP style helps us pursue certain design goals:

ˆ Abstraction: Hiding complexity in the design, creating an "inter-


face" for the user, generalizing functionality to a more "digestible"
form. Think of a button on any device: If you open up the device,
there's a lot actually going on, but we just see the simple button
and don't have to worry about the rest.

 Certain functions are made public that other programmers


can use to interface with the object.

 The other programmers don't need to worry about the inner-


workings of the object in order to use it.

 The developer of the class can modify how the internals work
without breaking the public interface.

208
 Helps protect the data within the class from being accessed or
modied by things it shouldn't.

ˆ Encapsulation: Also goes along with creating an "interface", though


in this regard we are encapsulating related pieces together. We can
store data (variables) with the functions that operate on that data
(functions) all within a class object.

ˆ Loose coupling: Ideally, dierent objects in a program shouldn't


have their functionality tied to other objects too closely; we want to
reduce inter-dependence between objects. When objects are more
independent from each other, they are loosely coupled.
ˆ High cohesion: When we design our objects, we shouldn't just
throw everything and the kitchen sink into one object. To design an
object with high cohesion means that everything inside the object
belongs in that object. Reduce the clutter.

2. Inheritance and composition

Sometimes we have multiple objects that are similar but still have dierent
sets of data (member variables) - think of a File, how we might have an
Image File, Sound File, Video File. . . Each le has a name, le extension,
and size, but the actual le contents are dierent.

209
And sometimes we have an object that is best represented by being "in-
side" another object - think of a House with an array of Room objects.

These are the two ideas betweeninheritance, an "is-a" relationship, and


composition, a "has-a" relationship.
With inheritance:

ˆ Variables and functions from a class can be inherited by child classes.


This means that the child class will have these same variables and
functions, without having to re-write it all.

ˆ We use this to create specialized versions of some generic object, like


a GameObject, PlayerObject, and NPCObject, or a Shape, Square,
and Circle.

With composition:

ˆ One class is a member variable of another class, and is generally a


private member.

ˆ Often this means that the internal class can't be accessed by outside
functions, and the "containing" class needs to have some kind of
interface layer to allow interactions with that internal item.

ˆ Some people argue that you should prefer using composition over in-
heritance because the act of composing another class keeps it "mod-
ularized"; that class' features are encapsulated within a variable,
and not more inherited variables added onto the pile-o-variables a
class has.

3. Accessibility levels
When we're designing our objects we don't want to give unrestricted ac-
cess to every part of the program. We generally create a class and it
is responsible for certain things, including modifying its own data. This
helps us protect the integrity of the data. Each member variable and func-
tion belonging to a class can be marked as one of these three accessibility
levels:

public: Any part of the program can access these members. This is usu-
ally used for the member functions of a class.

private: These members can only be accessed by the class itself, from
within its functions.

protected: Similar to private except that classes that inherit from the
class we're dening will also have access to protected members. More
on this when we cover inheritance.

210
5.13.3 Modeling C++ classes using UML
UML (Unied Modeling Language) is a way to diagram classes, their member
variables and functions (methods), and relationships between those classes. It is
meant as a language-agnostic way to describe your codebase or how something
should be designed.

1. Describing a single object


A UML diagram for a single class looks like this:

Player
- x : int
- y : int
- image : Texture
+ Setup() : void
+ Move(velX: float, velY: float): void
+ BeginJump() : void
+ BeginAttack() : void
+ Draw(screen:Window) : void

Here's how to read it:

ˆ The TOP region is the name of the class.

ˆ The MIDDLE region is its member variables.

ˆ The BOTTOM region is its member methods/functions.

ˆ The - minus sign signies private accessibility level, which means


these members can only be accessed by this class' functions.

ˆ The + plus sign signies public accessibility level, which means these
members can be accessed by this class' functions or any functions
external to it (like belonging to another class, or in main()).
ˆ A # pound sign signies protected accessibility level (used with
inheritance, which we will cover more later).

211
2. Describing relationships between objects
UML diagrams are also used to show the relationship between classes.

In a diagram that shows a relationship between objects you will see arrows
going between classes.

ˆ A line coming FROM a class and ending in a triangle arrow to


another class shows an inheritance relationship, with the former
inheriting from the latter.
ˆ A line coming FROM a class and ending in a diamond shape to
composition
another class shows a relationship, with the former
being contained within the latter.

Using UML diagrams can be (relatively) quick to write out and to read,
compared to just giving someone a .h header le or all the code itself.
Often, companies will have some kind of global UML diagram of all of
the components in their codebase and how they interact - developers are
expected to update this diagram as they add/remove classes or members
of classes.

212
5.14 Unit 13: C++: Classes and Inheritance
5.14.1 Classes
1. Structs
(a) Structs vs. Classes
Structs in C++ have all the same functionality of a Class, but are
generally used design-wise to group a few variables together, maybe
some functions, into a simple structure. A class, on the other hand,
is usually used for much bigger and more complex objects.

In C++, the only dierence between Structs and Classes are default
accessibility - if you don't specify the accessibility of your variables/-
functions within a struct, they are public by default. This means
that anything in the program can access those variables/functions.
For Classes, everything is private by default - only that Class itself
can use the variables/functions.

(b) Declaring a struct


Struct declarations go in header (.h) les. Usually the le name
should reect the name of the struct itself, and the le guard labels
should also match.

1 # ifndef _STRUCTNAME
2 # define _STRUCTNAME
3
4 struct STRUCTNAME
5 {
6 int var ;
7 void Func () ;
8 };
9
10 # endif

Design-wise, structs should only contain a small amount of data.


While structs can contain functions, it is generally better to create
a class if you nd yourself needing functions.

An example of a small struct would be grouping x and y coordinates


together in a Coordinate Pair. . .

1 struct CoordinatePair
2 {
3 float x , y ;
4 };

Sometimes we need to group some basic variables together. Structs


are great for this.

1 struct Rectangle
2 {
3 float left , right , top , bottom ;
4 };

213
(c) Declaring object variables
Once a struct has been declared in a program, you can then create
a variable with that data type. To access the internal variables of
the struct, you use the variable's name followed by the dot operator
. and then the name of the member variable.

1 // Declare two variables


2 CoordinatePair point1 , point2 ;
3
4 cout << " Enter the x y coordinates for the first
point : " ;
5 cin >> point1 . x >> point1 . y ;
6
7 cout << " Enter the x y coordinates for the second
point : " ;
8 cin >> point2 . x >> point2 . y ;
9
10 float slope = ( point2 .y - point1 . y ) / ( point2 . x -
point1 . x ) ;
11 cout << " The slope is : " << slope << endl ;

We will have more examples during the section on Classes, since


that's mostly what we will be using. Again, structs are useful for
combining a small amount of member variables together under one
name, usually used for structures for math (coordinates, rectangles,
etc.) but more sophisticated objects ought to be created with a
class.

2. Classes
Traditionally, a struct is used to create small objects that join a few
variables together. Classes are much more heavily used in C++ and is
the back-bone of Object Oriented Programming. There is a lot we can do
with classes, but for now we are just going to look at the basics.

A class declaration looks just like a struct declaration except that we use
the keyword class. Take note that with a struct and class declaration,
we must end the closing curly brace with a semi-colon.

1 class Player
2 {
3 public :
4 void SetPosition ( int newX , int newY ) ;
5 void Move () ;
6
7 private :
8 int x , y ;
9 };

(a) Accessibility

214
We can dene our member variables and functions with three dif-
ferent levels of accessibility, dictating where these members can be
accessed throughout the program:

public: Any part of the program can access these members. This
is usually used for the member functions of a class.

private: These members can only be accessed by the class itself,


from within its functions.

protected: Similar to private except that classes that inherit from


the class we're dening will also have access to protected mem-
bers. More on this when we cover inheritance.

(b) Header and Source les


When we are creating a class, we generally will put the class decla-
ration within its own header le. Header les end with .h or .hpp
- I tend to use .hpp since we're using C++ and I like to explicitly
state this is a "C++ header"; the .h extension was also used in C.
However, the C++ Core Guidelines document says to:

NL.27: Use a .cpp sux for code les and .h for interface
les

Reason It's a longstanding convention. But consistency


is more important, so if your project uses something else,
follow that.

(From https://github.com/isocpp/CppCoreGuidelines/
blob/master/CppCoreGuidelines.md#reason-451)

Class declaration goes in Rectangle.h (or Rectangle.hpp):


1 # ifndef _RECTANGLE_H
2 # define _RECTANGLE_H
3
4 class Rectangle
5 {
6 public :
7 void SetPosition ( int newX , int newY ) ;
8 void SetDimensions ( int newWidth , int newHeight ) ;
9
10 private :
11 int x , int y , int width , int height ;
12 };
13
14 # endif

Class function denitions go in Rectangle.cpp:

215
1 # include " Rectangle . h "
2
3 void Rectangle :: SetPosition ( int newX , int newY )
4 {
5 x = newX ;
6 y = newY ;
7 }
8
9 void Rectangle :: SetDimensions ( int newWidth ,
10 int newHeight )
11 {
12 width = newWidth ;
13 height = newHeight ;
14 }

In our source le (.cpp), we need to make sure to include the header
that goes with our class so it knows about the class declaration.
Then, we can dene the member functions here.
Note that when we're dening the functions outside of the class
declaration, we must prex the function name with the class name,
followed by the scope resolution operator ::. . .
1 void Rectangle :: SetPosition ( int newX , int newY )

This is the standard way C++ les are organized - for each class we
create, we create a header and a source le for it.

(c) Additional context with classes

ˆ What is #ifndef?

 In C++, when we #include "Rectangle.h" in a dier-


ent source le, the compiler essentially copy-pastes the
code from the included le into the includer le. Because
of this, if multiple les are #include "Rectangle.h"-ing
(or any other header), the same code in that header gets
copied multiple times, making the compiler think you've
declared the same class over and over.

 #ifndef, #define, and #endif are preprocessor com-


mands used by the compiler. We are essentially saying
"if-not-dened _RECTANGLE_H, dene _RECTANGLE_H, ...
... end-if.", preventing the compiler from copying the
same le twice.

ˆ Dening member functions inside the class declaration

 It is completely possible to dene our member functions


inside the class declaration, getting rid of the need for
the .cpp le. However, this does end up being treated
dierently by the compiler - writing our class this way

216
makes the functions inline. . . Basically, instead of hav-
ing a separate function that the compiler will mark as
"call this", it will copy the contents of the inlined function
to the function call, basically replacing the call with the
contents of the function. I haven't written much about
how the compiler works since that's a more specialized
topic and we don't need to worry about it at this stage
of learning C++. This is just here for your own info.

ˆ Should you dene functions in the .h or the .cpp?

 It is standard to put class declarations and function


declarations in .h les, and the function/method def-
initions in the .cpp les. You should follow this best
practice.

ˆ What is a Function vs. Method?

 A method is a word that means "member function". In


Java and C#, the term method is used instead of function,
since you physically cannot have functions dened outside
of a class in those languages.

 I tend to stick with the term "member function", but if


I write "method", it means that, whereas a "function"
would be a standalone function elseware in the program.

(d) Getters and Setters


In Object Oriented Programming, we generally want to hide the
inner-workings of a class from the outside world (other functions
and other classes). If everything were exposed, then other parts of
the program could make changes to our class and it could be dicult
to track down all those modifying locations (this, in particular, is a
nightmare at a job with a large codebase).

We generally write all our member variables as private - accessible


only to the class' member functions themseves - and use public
member functions to interface with those variables as needed.

For example, in our Rectangle class, we might have a function to set


up the entire Rectangle all at once. . .

1 void Rectangle :: Setup ( int newX , int newY , int


newWidth , int newHeight )
2 {
3 x = newX ;
4 y = newY ;
5 width = newWidth ;
6 height = newHeight ;
7 }

. . . or just a couple things at a time . . .

217
1 void Rectangle :: SetPosition ( int newX , int newY )
2 {
3 x = newX ;
4 y = newY ;
5 }

Setters: Or, we might want to just set one member variable's value.

In this case, we write a member function called a setter (aka mu-


tator) that is responsible for setting a member variable's value:
1 void Rectangle :: SetX ( int newX )
2 {
3 x = newX ;
4 }

The good thing about having setters instead of directly updating


the x variable is that we can add error checks in our setter. Say,
perhaps, that we don't want x to be negative, so we validate the
input before changing it. . .

1 void Rectangle :: SetX ( int newX )


2 {
3 if ( newX >= 0 )
4 {
5 x = newX ;
6 }
7 }

If somewhere else in the program tries to set a negative value for the
x variable, it will just ignore that command. (We could also throw
an exception or display an error message or set a default value - it's
up to your design.)

Getters: Likewise, sometimes we want to access

those member variables to see what values they store. In this case,
we write Getter member functions that are responsible for returning
a copy of the data (or, in some cases, a reference to it - but that's a
design decision).

1 int Rectangle :: GetX ()


2 {
3 return x ;
4 }

Getters are also handy for formatting output prior to returning


it, or doing some other operation before returning something. Let's
say we have a member function for a Student class, and a GetName
function is going to combine their names and return it together:

218
1 int Student :: GetFullName ()
2 {
3 return lastName + " , " + firstName ;
4 }

To summarize. . .

ˆ Setters: Sets the value of a member variable. Generally, re-


void and there is one paramete for the new value.
turn type is
void SetThing( int newValue );

ˆ Getters: Returns the value of a member variable. Generally,


return type matches that variable, and there are no parame-
ters. =int GetThing(); =

(e) Constructors and Destructors


Constructors and Destructors are special types of member functions
in a class.

ˆ Constructor:

 Runs automatically as soon as a new object is declared.

 Can declare more than one constructor.

 No return type

 Constructor name must match name of the class.

ˆ Destructor:

 Runs automatically as soon as a new object is destroyed.

 Can only have one destructor.

 No return type

 Destructor name =must= match name of the class, pre-


xed with a tilde \~.

Example: Text le wrapper


Let's say we're writing a class that works with a text le.

When the object is created, the constructor will open the le and
get it ready to write to. With various member functions we can write
to that text le as the program is running. Then, when the program
ends and the object is destroyed, it will automatically close the
text le for us.

Class declaration:

219
1 class Logger
2 {
3 public :
4 // constructors
5 Logger ( string filename ) ;
6 Logger () ;
7
8 // destructor
9 ~ Logger () ;
10
11 // other method
12 void Write ( string text ) ;
13
14 private :
15 ofstream m_output ;
16 };

We have two constructors: one where we pass in a lename for a


le to open, and one where we don't. In the second case, we can use
a default le name.

Context: Why "m_" with the variable?

In some places, it is standard to prex private member variables


with an underscore (_output) or (m_output). I tend to use the
latter when writing private member variables of a class. The
"m" stands for "member".

The constructor denitions could look like this:

1 Logger :: Logger ( string filename )


2 {
3 m_output . open ( filename ) ;
4 }
5
6 Logger :: Logger ()
7 {
8 m_output . open ( " log . txt " ) ;
9 }

The Write function could be used to write information to that text


le, and could be implemented like this:

1 void Logger :: Write ( string text )


2 {
3 m_output << text << endl ;
4 }

And then the destructor would be used to close up the le at the
end:

1 Logger ::~ Logger ()


2 {

220
3 m_output . close () ;
4 }

Now, we don't have to manually deal with le operations since this
class wraps that functionality and deals with it for us.
To use the program, we just declare the object variable:

1 # include " Logger . hpp "


2
3 int main ()
4 {
5 // At this point ,
6 // a constructor is called automatically
7 Logger log ( " logfile . txt " ) ;
8
9 // Writing to the text file
10 log . Write ( " Hello ! " ) ;
11 log . Write ( " How are you ? " ) ;
12
13 // Program ends here . The destructor
14 // is called automatically when the log variable
15 // goes out of scope and is destroyed .
16 return 0;
17 }

It can often be handy to overload our constructors so that we can


initialize our objects in several dierent ways.

221
i. Types of constructors
A. Default Constructors
A default constructor is a constructor with no parameters
in it. This will be called when a variable of this class type
is declared with no constructor explicitly called.

Usually, a default constructor would be used to initial-


ize variables to default values, and if your class contains
pointers, this constructor should initialize those pointers
to point to nullptr.
1 class MyClass
2 {
3 public :
4 MyClass () // Default constructor
5 {
6 m_value = 0;
7 }
8
9 private :
10 int m_value ;
11 };

When we create a new object of this type like this, the


default constructor will be called:

1 MyClass classVar ;

B. Parameterized Constructors
Parameterized Constructors take in one or more parame-
ters to help initialize the member variables of the object.
We can have 0, one, or multiple parameterized construc-
tors for our class.

1 class MyClass
2 {
3 public :
4 MyClass () { // Default
5 m_value = 0;
6 }
7
8 MyClass ( int value ) { //
Parameterized
9 m_value = value ;
10 }
11
12 // etc
13 };

When we instantiate our object, we can pass in argu-


ment(s) in order to call the parameterized version of the
constructor:

222
1 MyClass classVar ( 100 ) ;

If you declare a parameterized constructor but not a de-


fault constructor, then the C++ compiler will assume
that you don't want an object to be declared with the
default constructor. This means, you would only be able
to declare the variable with an explicit call to the con-
structor and with arguments.

If this isn't the desired design, make sure to include a


default constructor, even if you just leave it blank.

C. Copy Constructors
A copy constructor takes in another object of the same
type as its parameter and uses this to copy over members
from the parameter to the new object.

1 class MyClass
2 {
3 public :
4 MyClass () // Default
5 {
6 m_value = 0;
7 }
8
9 MyClass ( int value ) // Parameterized
10 {
11 m_value = value ;
12 }
13
14 MyClass ( const MyClass & other ) // Copy
15 {
16 m_value = other . m_value ;
17 }
18
19 private :
20 int m_value ;
21 };

In this case, we might already have an object of this type


available, and when we are creating a new object, we want
to make a copy of the old object:

1 MyClass classVar ( 100 ) ;


2 MyClass anotherOne ( classVar ) ; // Copy

ˆ Design: When a class has multiple member vari-


ables, it is up to us to decide which variables get
copied over during this operation. There could be
some design cases where all information is copied over
except certain elds (maybe a unique customerID or
a name).

223
ˆ Default copy constructor: If you don't explicitly
declare a copy constructor, the C++ compiler will
provide one for the class behind-the-scenes. This im-
plicit copy constructor will only do shallow copies.

Ways to copy:
ˆ A Shallow Copy is where values of variables are
copied over. This is generally ne for any sort of
non-pointer-based variables. If the class contains a
pointer that is pointing to some address, the shallow-
copy of the pointer will point to the same address.

ˆ A Deep Copy is where values are copied over like


with a shallow copy, but also will allocate new mem-
ory for a dynamic array (if the class has one) in order
to copy over values of the element of the array to the
new class copy.

Example of a shallow copy:

With the implicit copy constructor, any pointers in the


copied version will be pointing to the same address as in
the original. If the class contains a dynamic array, both
the copy and the original will end up pointing to the same
address of the array in memory.

224
Example of a deep copy:

A new block of memory has been allocated for the int


* numArr. The values from InstanceA's numArr would
be copied to InstanceB's numArr via a for loop during
construction.

3. Additional class concepts

(a) Const member methods


When we declare a class' member function as const, we are saying
that this function should not ever change any values of any member
variables of this class. This can be handy for methods like a Dis-
play() where we just want to output member variables but should
never change them.

1 class Coordinates
2 {
3 public :
4 int GetX () const ; // Can 't change m_x or m_y
5 int GetY () const ; // Can 't change m_x or m_y
6
7 void SetX ( int val ) ;
8 void SetY ( int val ) ;
9
10 private :
11 int m_x , m_y ;
12 };

225
The function denition will also need to have this const marked at
the end of the function header as well.

1 int Coordinates :: GetX () const


2 {
3 return m_x ;
4 }

(b) this Within our class methods, we can explicitly refer to the object
we are currently working with as this. this is a pointer, so it is
pointing to a memory address. Any member of the class can also be
accessed via the this pointer:

1 class MyClass
2 {
3 public :
4 void A ()
5 {
6 cout << " Hello ! " << endl ;
7 }
8
9 void B ()
10 {
11 this - > A () ;
12 cout << this - > var << endl ;
13 }
14
15 void C ()
16 {
17 A () ;
18 cout << var << endl ;
19 }
20
21 private :
22 int var ;
23 };

In this example, methods B() and C() do the same thing, but B()
explicitly uses this.

4. Review questions:

(a) True or false: A class can have member variables and functions
(methods).

(b) Class declarations go in what kind of le?

(c) Class function (method) denitions go in what kind of le?

(d) A class' public members can be accessed by. . .

226
(e) A class' protected members can be accessed by. . .

(f ) A class' private members can be accessed by. . .

(g) When dening a function that is a member of a class, the function


name needs to be prexed with. . .

(h) What does a getter (accessor) function do?

(i) What does a setter (mutator) function do?

(j) When does a constructor function run?

(k) When does a destructor function run?

(l) The constructor and destructor name must match what?

5.14.2 Inheritance

Inheritance is where one class inherits some or all member variables and
functions from some parent class. Certain "traits" are passed on, and the child
class can have additional member variables and functions dened, making it a
more specialized version of the parent class.

1. Reusing functionality
Let's say we're designing an operating system that will store les. We can
think about what all les have in common, and we can gure out what
is dierent between dierent types of les. Any commonality could go in
a base class (aka parent class).
So, a generic File class might have contain variables and functions like:

227
File
- m_filename : string
- m_extension : string
- m_fileSize : size_t
- m_creationDate : DateTime
+ CreateFile(...) : void
+ RenameFile(...) : void
+ GetSize() : size_t
+ GetPath() : string

Then we could have specialized le classes that inherit from the original
File, such as TextFile, ImageFile, SoundFile, and so on. These would
inherit all the common attributes of its parent (File), but each would
have additional variables and methods that are suited specically to its
own specialization.

ˆ TextFile: m_textContent, Print()


ˆ ImageFile: m_pixels[][], Draw(), EditPixel( x, y )
ˆ SoundFile: m_audioSample, m_length, Play(), Pause(), Stop()

2. Example: The iostream and fstream family

Part of the ios family. You can see the full library's family tree at http:
//www.cplusplus.com/reference/ios/
One family we've already been using are our console input/output streams,
cin and cout, and our le input/output streams, ifstream and ofstream.
Working with each of these works largely the same way.

When we overload the << and >> stream operators, we use a base type
ofistream and ostream so that our class can handle cin / cout AND
ifstream / ofstream, as well as any other streams in that family tree.

228
3. Inheritance (Is-A) vs. Composition (Has-A) Another way we think
about inheritance is that one class "is-a" type of other class.

Car is-a vehicle:

1 class Car : public Vehicle


2 {
3 // etc .
4 };

Whereas Composition, where one class contains another class as a member


variable object, is known as a "has-a" relationship.

Car has-an engine:

1 class Car
2 {
3 private :
4 Engine engine ;
5 };

When is composition more appropriate than inheritance? This is a design


question and it can really depend on how the designer feels about each
one.

4. Example: Game objects


For example, when writing a game, I nd inheritance handy for creating
game objects. A BaseObject can contain everything that's in common
between all objects (characters, items, tiles, etc.), such as:

Any items that don't animate, don't move, and just sit there in the level
could be instantiated as a simple BaseObject and it would be ne.

229
BaseObject
# m_position : Coordinate
# m_sprite : Sprite
# m_name : string
+ Setup(...)
+ SetTexture(...)
+ Update(...)
+ SetPosition(...)
+ Draw(...)

Then, let's say we want to build a 2D game level and each level is made
up of a 2D array of tiles. Tiles will be very similar to objects, but maybe
we want more information stored in a tile. We could then inherit from
the BaseObject. . .

The Tile class would have all the public and protected members from
its parent, plus any new member variables and methods we declare within
this class.

Tile Inherits from BaseObject


- m_isSolid : bool
- m_doesDamage : bool

For the game characters, there would be two dierent types usually: char-
acters that the players control and characters that the computer controls.
Character could be its own base-class as well, implementing anything a
character can do, with a Player and NPC (non-player-character) classes
inheriting from Character.

Character Inherits from BaseObject


# m_speed : int
# m_direction : Direction
# m_animFrame : float
# m_maxFrames : float
+ Move(...)
+ Animate(...)

230
Player Inherits from Character
- m_score : int
- m_experience : int
- m_level : int
+ HandleKeyboard(...)
+ LevelUp(...)

The Player class would be a specialized type of Character that can be


controled via the keyboard (or some other input device), as well as have
information that a non-player-character generally has, such as a score or
a level.

NPC Inherits from Character


- m_difficulty : int
- m_isFriendly : bool
+ SetGoal(...)
+ DecideNextAction(...)

Likewise, the NPC class is a specialization of Character as well, but with


special functionality and attributes of a character in the game controlled
by the computer itself. This could include some form of AI to help the
NPC decide how to behave.

231
Game object family:

With this family of game objects, we could also write functions that work
on all types of game objects, such as checking if there's a collision between
items, because they all have a common parent.

5. Implementing inheritance
In C++ a class can inherit from one or more other classes. Note that
Java and C# do not support multiple inheritance directly, if you end up
switching to those languages. Design-wise, however, it can be messy to
inherit from more than one parent and as an alternative, you might nd
a composition (has-a) approach a better design.

232
6. Inheriting from one parent
To inherit from one other class in C++, all you need to do is add ":
public OTHERCLASS" after the "class CLASSNAME" at the beginning of
your class declaration. With a public inheritance (the most common
kind), the child class will inherit all public and protected members of
the parent class.

1 // File is the parent


2 class File
3 {
4 protected :
5 string name ;
6 string extension ;
7 size_t filesize ;
8 };
9
10 // TextDocument is the child
11 class TextDocument : public File
12 {
13 protected :
14 string textContents ;
15 /* Also inherits these members from File :
16 string name ;
17 string extension ;
18 size_t filesize ;
19 , */
20 };

Context: The Parent Class is often known as the superclass and the
Child Class is often known as the subclass, particularly from the Java
perspective.

7. Inheriting from multiple parents


You can also have a class inherit from multiple parents, bringing in pub-
lic/protected members from all parent classes, but again this can muddle
your program's design somewhat and is generally pretty uncommon.

1 class AnimationObject // Parent A


2 {
3 public :
4 void Animate () ;
5
6 protected :
7 int totalFrames ;
8 int currentFrame ;
9 };
10
11 class PhysicsObject // Parent B
12 {
13 public :
14 void Fall () ;

233
15 void Accelerate () ;
16
17 protected :
18 float velocity ;
19 float acceleration ;
20 };
21
22 class PlayerCharacter : public AnimationObject ,
23 public PhysicsObject
24 {
25 public :
26 void HandleKeyboard () ;
27
28 protected :
29 string name ;
30 };

8. Private, Public, and Protected

Member access

Remember that we can declare our member variables and methods as


private and public, but we can also make items protected. Protected
members are similar to private, except that protected members will be
inherited by child classes - private members do not get inherited.

Access Class' methods Childrens' methods Outside functions


public Accessible Accessible Accessible
protected Accessible Accessible Not accessible
private Accessible Not accessible Not accessible

Inheritance style You can also use public, protected, and private when
inheriting other classes. You probably won't need to ever do a pro-
tected or private inheritance.

ˆ public inheritance: Child class inherits public and pro-


tected members from the parent.

ˆ protected inheritance: Child class inheirits public and


protected members and turns them into protected mem-
bers.

ˆ private inheritance:
Child class inherits public and pro-
tected members and turns them into private members.

234
This could be used if, for some reason, you want a child class to inherit
certain members but don't want "grandchildren" to have access to those
members as well.

9. Function Overriding
When a child class inherits from a parent class, the parent class' public
and protected methods are passed down to the child and these functions
are still callable for objects of the child type.

If we would like, the child class can also override any methods from the
parent. This means that we write a new version of the function with the
same return type and parameter list, and when that function is called
from the child class, the child class' version will be called instead of the
parents'.

Let's say we're writing a quizzer program that will support diernet ques-
tion types. We can write a base "Question" class with whatever would be
in common between all Questions:

1 class Question
2 {
3 public :
4 Question ( string q , string a ) {
5 question = q ;
6 answer = a ;
7 }
8
9 void AskQuestion () {
10 cout << question << endl ;
11 string playerAnswer ;
12 cin >> playerAnswer ;
13
14 if ( playerAnswer == answer ) {
15 cout << " Right ! " << endl ;
16 } else {
17 cout << " Wrong . " << endl ;
18 }
19 }
20
21 protected :
22 string question ;
23 string answer ;
24 };

We can then inherit from our Question class to make dierent types of
quiz questions: Multiple choice, true/false, and so on. Adding additional
functionality means that we might want to rewrite how AskQuestion()
works - so we can.

This also means that everything in our Question family has a similar
interface - create a question, set it up, and then call AskQuestion() no
matter what kind of question it is.

235
1 class MultipleChoiceQuestion : public Question
2 {
3 public :
4 void DisplayQuestion ()
5 {
6 cout << question << endl ;
7 for ( int i = 0; i < 4; i ++ )
8 {
9 cout << i << " . "
10 << answerChoices [ i ] << endl ;
11 }
12 int playerAnswer ;
13 cin >> playerAnswer ;
14
15 if ( answerChoices [ playerAnswer ] == answer ) {
16 cout << " Right ! " << endl ;
17 } else {
18 cout << " Wrong . " << endl ;
19 }
20 }
21
22 protected :
23 string answerChoices [4];
24 };

10. Calling the parents' version of a method


In some cases, perhaps the parent version of a method has some common
functionality we will need no matter what version in the family we're using,
but the child versions of the methods add on to that functionality. We
can directly call the parent's version of some method from within a child's
method by explicitly calling the method with the parent class name and
the scope resolution operator ::.
1 class Lion
2 {
3 public :
4 void Activities ()
5 {
6 cout << " Hunt " << endl ;
7 cout << " Eat " << endl ;
8 cout << " Sleep " << endl ;
9 }
10 };
11
12 class HouseCat : public Lion
13 {
14 public :
15 void Activities ()
16 {
17 Lion :: Activities () ;

236
18 cout << " Talk to human " << endl ;
19 cout << " Use catbox " << endl ;
20 }
21 };

For this example, the HouseCat does everything the Lion does and adds
a few activities to the list. We don't have to re-write the same Activities
from Lion - we can just call the parent's version of the method directly
with Lion::Activities();.

11. Constructors and Destructors in the family


We often use constructors to initialize member variables for a class, and
when a child is inheriting its parents' member variables, we want to make
sure we're not forgetting to still initialize those variables.

We can call the parent's constructor from the child's constructor as well,
but we do it via the initializer list of a constructor - a little bit of
code after the constructor's function header that can be used to initialize
variables and call the parent constructor.

1 class Person
2 {
3 public :
4 Person ( string name )
5 {
6 m_name = name ;
7 }
8
9 protected :
10 string m_name ;
11 };
12
13 class Student : public Person
14 {
15 public :
16 Student ( string name , string major )
17 : Person ( name ) // Calling the parent ctor
18 {
19 m_major = major ;
20 }
21
22 protected :
23 string m_major ;
24 };

(Note: "ctor" is short for "constructor")

We can also initialize variables through the initializer list as well:

1 class Student : public Person


2 {
3 public :

237
4 Student ( string name , string major )
5 : Person ( name ) , m_major ( major )
6 {
7 // nothing else to do now !
8 }
9
10 protected :
11 string m_major ;
12 };

238
5.15 Unit 14: C++: Strings and File I/O
5.15.1 Strings

A string is a special data type that really is just an array of char variables.
A string has a lot going on behind-the-scenes, and it also has a set of functions
you can use to do some common operations on a string - nding text, getting a
letter at some position, and more.
Note that everything with strings is case-sensitive. A computer considers
the letter 'a' and 'A' dierent, since they are represented by dierent number
codes. Keep that in mind for each of the string's functions.

Strings as arrays
When we declare a string like this:

1 string str = " pizza " ;

what we have behind-the-scenes is an array like this:

Value: 'p' 'i' 'z' 'z' 'a'


Index: 0 1 2 3 4

Declaring a string actually gives us an array of char variables. We can


access the string as a whole by using the string variable's name (str), or access
one char at a time by treating str like an array.

1. Subscript operator - get one char with [ ]


We can access each letter of the string directly with the subscript oper-
ator, just like an array:
1 cout << str [0] << endl ; // Outputs p
2 cout << str [1] << endl ; // Outputs i
3 cout << str [2] << endl ; // Outputs z
4 cout << str [3] << endl ; // Outputs z
5 cout << str [4] << endl ; // Outputs a

Because we can act on a string like an array, this means we can also use
a variable to access an arbitrary index of a character in the array. . .
1 int i ;
2 cout << " Get which letter ? " ;
3 cin >> i ;
4 cout << str [ i ];

239
Or even iterate over the string with a for loop. . .
1 for ( int i = 0; i < str . size () ; i ++ )
2 {
3 cout << i << " = " << str [ i ] << endl ;
4 }

Additionally, strings have a set of functions that we can use to manipu-


late, search, and otherwise work with them.

String functionality
2. Size of the string

size_t size() const;


The string's size() function will return the size of the string
- how many characters are stored in the string. The size_t
data type is just a type of integer - an unsigned integer, because
sizes cannot be negative amounts.

Documentation: https://www.cplusplus.com/reference/string/
string/size/

Example: Outputting a string's length Let's write a little program


that asks the user to enter some text, and then outputs the length
of the string:

1 string text ;
2 cout << " Enter some text : " ;
3 getline ( cin , text ) ;
4 cout << " That string is " << text . size ()
5 << " characters long ! " << endl ;

When the user enters a line of text, it will count all characters (including
spaces) in the string, so the text "cats dogs" would be 9 characters long.
Enter some text : cats dogs
That string is 9 characters long !

240
Example: Counting z's If we wanted to use a for loop to iterate over
all the letters of an array, we could! Perhaps we want to count the
amount of z's that show up:

1 string text ;
2 int zCount = 0;
3
4 cout << " Enter some text : " ;
5 getline ( cin , text ) ;
6
7 // Iterate from i =0 to the size of the string ( not -
inclusive )
8 for ( unsigned int i = 0; i < text . size () ; i ++ )
9 {
10 // If this letter is a lower - case z or upper - case Z
11 if ( text [ i ] == 'z ' || text [ i ] == 'Z ' )
12 {
13 // Add one to z count
14 zCount ++;
15 }
16 }
17
18 // Display the result
19 cout << " There were " << zCount
20 << " z ( s ) in the string ! " << endl ;

Enter some text : The wizard fought a zombie lizard


There were 3 z ( s ) in the string !

3. Concatenating strings with +


We can use the + operator to add strings together as well. This is called
concatenation.
Let's say we have two strings we want to combine - favoriteColor and
petName, we can use the concatenation operator + to build a new string,
superSecurePassword.
1 string favoriteColor = " purple " ;
2 string petName = " Luna " ;
3 string superSecurePassword = favoriteColor + petName ;
4 cout << superSecurePassword << endl ; // = purpleLuna

241
We can also add onto strings by using the += operator. Let's say you're
building a string over time in a program, and want to append parts
separately.

1 string pizzaToppings = " " ;


2
3 // Later on ...
4 pizzaToppings += " Buffalo sauce , " ;
5
6 // Later on ...
7 pizzaToppings += " Cheese , " ;
8
9 // Later on ...
10 pizzaToppings += " Pineapple ";
11
12 // Later on ...
13 cout << pizzaToppings << endl ;

At the end of the program, the value of pizzaToppings would be:

"Buffalo sauce, Cheese, Pineapple"

4. Finding text with nd()

size_t find (const string& str, size_t pos = 0 ) const;


The nd function can be used to look for a substring in a
bigger string. If the substring is found, its position is returned.
Otherwise, the value of string::npos is found.

When a starting pos is included, it only begins the search at


that position. If left o, it defaults to 0 (the start of the string).

Documentation: https://www.cplusplus.com/reference/string/
string/find/

So when we want to search a string for some text, we can call it like
bigString.find( findMeString ), and that function call will return an
unsigned integer: the location of the findMeString within bigString, or
the value of string::npos when it is not found.

1 string str = " this was written during the 2021 winter
storm make it stop please . " ;
2
3 string findMe = " winter " ;

242
4
5 size_t position = str . find ( findMe ) ;
6
7 cout << " The text \" " << findMe
8 << " \" was found at position " << position << endl ;

The text " winter " was found at position 33

5. Finding substrings with substr()

string substr (size_t pos = 0, size_t len = npos) const;


Returns a string within the string, starting at the position pos
provided, and with a length of len.
Documentation: https://www.cplusplus.com/reference/string/
string/substr/

With the substr() function, we can pull part of a string out, using a
starting point and a length.

1 string text = " Name : Bob " ;


2
3 int start = 6;
4 int length = 3;
5
6 string name = text . substr ( start , length ) ;
7
8 cout << " Extracted \" " << name << " \". " << endl ;

Extracted " Bob ".

6. Comparing text with compare()

243
int compare (const string& str) const;
This compares the string with str and returns an integer:

ˆ 0 is returned if both strings are the same.

ˆ <1 (a negative number) is returned if the caller string


is "less-than" the str string.

ˆ >1 (a positive number) is returned if the caller string is


"greater-than" the str string.

One character is "less than" another if it comes before, and


it is "greater than" if it comes after, alphabetically.
(Remember that lower-case and upper-case letters are consid-
ered separate, so comparing 'a' to 'A' would actually return
a positive number.)

Documentation:https://www.cplusplus.com/reference/string/
string/compare/

1 string first ;
2 string second ;
3
4 cout << " Enter first string : " ;
5 cin >> first ;
6
7 cout << " Enter second string : " ;
8 cin >> second ;
9
10 int order = first . compare ( second ) ;
11
12 cout << endl << " Result : " << order << endl ;

Enter first string : apple


Enter second string : banana

Result : -1

7. Inserting text into a string with insert()

= string& insert (sizet pos, const string& str);=


This function will take the calling string and modify it by
inserting the string str at the position pos.
Documentation: https://www.cplusplus.com/reference/string/
string/insert/

244
1 string text = " helloworld " ;
2
3 cout << " Original text : " << text << endl ;
4
5 int start ;
6 string insertText ;
7
8 cout << " Enter text to insert : " ;
9 getline ( cin , insertText ) ;
10
11 cout << " Enter position to insert : " ;
12 cin >> start ;
13
14 text = text . insert ( start , insertText ) ;
15
16 cout << endl << " String is now : " << text << endl ;

Original text : helloworld


Enter text to insert : - to the -
Enter position to insert : 5

String is now : hello - to the - world

8. Erasing a chunk of text with erase()

string& erase (size_t pos = 0, size_t len = npos);


This function will return a string with a portion erased, start-
ing at position pos and pulling out a length of len.
Documentation: https://www.cplusplus.com/reference/string/
string/erase/

1 string text = " helloworld " ;


2
3 cout << " Original text : " << text << endl ;
4
5 int start ;
6 int length ;
7
8 cout << " Enter position to begin erasing : " ;
9 cin >> start ;
10
11 cout << " Enter length of text to erase : " ;
12 cin >> length ;
13
14 text = text . erase ( start , length );
15 cout << endl << " String is now : " << text << endl ;

245
Original text : helloworld
Enter position to begin erasing : 2
Enter length of text to erase : 5

String is now : herld

9. Replacing a region of text with replace()

string& replace (size_t pos, size_t len, const string&


str);
This function is similar to erase, except it will insert the string
str in place of the erased text.

Documentation:https://www.cplusplus.com/reference/string/
string/replace/

1 string text = " helloworld " ;


2
3 cout << " Original text : " << text << endl ;
4
5 int start ;
6 int length ;
7 string replaceWith ;
8
9 cout << " Enter string to replace with : " ;
10 getline ( cin , replaceWith ) ;
11
12 cout << " Enter position to begin replacing : " ;
13 cin >> start ;
14
15 cout << " Enter length of text to replacing : " ;
16 cin >> length ;
17
18 text = text . replace ( start , length , replaceWith ) ;
19 cout << endl << " String is now : " << text << endl ;

Original text : helloworld


Enter string to replace with : BYE
Enter position to begin replacing : 2
Enter length of text to replacing : 5

String is now : heBYErld

Review questions:
1. A string is technically an array of. . .

2. How would you output the letter at position 0 in a string? At position 2?

246
3. What function is used to get the amount of characters in a string?

4. What operator is used to combine (concatenate) two strings together?

5. What does the nd() function return if the searched-for substring is not
found?

5.15.2 File I/O

1. Output streams
In C++ we've been using cout to stream information to the console win-
dow in our programs. Using cout requires including the iostream library.
1 cout << " Hello , " << location << " ! " << endl ;

Writing out to a text le works in a very similar way. We will need to
include the fstream library in order to get access to the ofstream (output-
le-stream) object. Streaming out to a le works in the same way as with
cout, except that we need to declare a ofstream variable and use it t
open a text le.

1 # include < iostream > // Console streams


2 # include < fstream > // File streams
3 using namespace std ;
4
5 int main ()
6 {
7 // Console output
8 cout << " Hello , world ! " << endl ;
9
10 // File output

247
11 ofstream outputFile ( " file . txt " ) ;
12 outputFile << " Hello , world ! " << endl ;
13 outputFile . close () ;
14 }

<< to continue chaining to-


You can use the output stream operator
endl=s, string literals in double quotes,
gether dierent items -
variable values, etc. just like with your =cout statements.
Once the le is closed, you will see the le on your computer, usually the
same directory as your .cpp les.
Dierent le types. . . Any le type that is a plaintext le can be built
as well - .html les, .csv les, heck, even .cpp les. However, gener-
ally if you wanted to write a program to output a dierent le type,
you'd use a library to properly convert the data.

Outputting html data:

1 # include < fstream >


2 using namespace std ;
3
4 int main ()
5 {
6 ofstream outputFile ( " page . html " ) ;
7 outputFile << " < body > " << endl ;
8 outputFile << " <h1 > This is a webpage </ h1 > " << endl ;
9 outputFile << " <p > Hello , world ! </p > " << endl ;
10 outputFile << " </ body > " << endl ;
11 outputFile . close () ;
12 }

Outputting csv data:

1 # include < fstream >


2 using namespace std ;
3
4 int main ()
5 {
6 ofstream outputFile ( " spreadsheet . csv " ) ;
7 outputFile << " COLUMN1 , COLUMN2 , COLUMN3 " << endl ;
8 outputFile << " cell1 , cell2 , cell3 " << endl ; // row 1
9 outputFile << " cell1 , cell2 , cell3 " << endl ; // row 2
10 outputFile << " cell1 , cell2 , cell3 " << endl ; // row 3
11 outputFile . close () ;
12 }

2. Input streams
File input streams work just line console input streams. You will need to
create a ifstream (input-le-stream) object and open a le, and then you
can read in the contents of that le. Files to be read should generally be
placed in the same path as your .cpp le, though the working directory
on your system may vary.

248
1 # include < fstream > // File streams
2 # include < string > // Strings
3 using namespace std ;
4
5 int main ()
6 {
7 string data1 , data2 ;
8
9 // File input
10 ifstream inputFile ( " file . txt " ) ;
11 inputFile >> data1 ; // Read one word
12 inputFile . ignore () ; // Clear buffer
13 getline ( inputFile , data2 ) ; // Read one line
14 inputFile . close () ;
15 }

Just like with using cin, you can use the input stream operator (>>) and
the getline() function with the le streams to get text. You will also
need one or more variable to store the text read in.

(a) Reading an entire le

Reading chunks of data: Let's say you have a le full of data to
read in. For this example, the le will be a list of numbers
that we want to add together. The le might look something
like. . . .

Data.txt:

9 15 16 0 10 13 5 16 1 9 2 17 3 3 8

In our program, we want to read all the numbers, but to do this, we


need to use a loop and read in one number at a time. We can keep
a running total variable to keep adding data to the sum as we go. We
can use a loop to continue reading while it is successful, using this as
the condition: input >> readNumber. This will stop the loop once
there's nothing else to read, and it updates the readNumber variable
with the input each cycle.

1 ifstream input ( " data . txt " ) ;


2
3 int sum = 0; // Sum variable
4 int readNumber ; // Buffer to store what we read in
5
6 // Keep reading while it 's possible
7 while ( input >> readNumber )
8 {
9 sum += readNumber ; // Add on to the sum
10
11 // Output what we did
12 cout << " Read number " << readNumber
13 << " ,\ t sum is now " << sum << endl ;

249
14 }
15
16 cout << " FINAL SUM : " << sum << endl ;

The output of this program would look like this:

Read number 9, sum is now 9


Read number 15 , sum is now 24
(... etc ...)
Read number 3, sum is now 119
Read number 8, sum is now 127
FINAL SUM : 127

Reading lines of data: In other cases, maybe you're reading in


text data from a le and want to read in a full line at a time.
We can use a while loop with the getline() function as well
to make sure we read each line of a text le:

1 ifstream input ( " story . txt " ) ;


2
3 string line ;
4
5 while ( getline ( input , line ) )
6 {
7 cout << line << endl ;
8 }

The output of this program would look like this:

CHAPTER I.
Down the Rabbit - Hole

Alice was beginning to get very tired of sitting by her


sister on the bank , and of having nothing to do : once or
twice she had peeped into the book her sister was
reading , but it had no pictures or conversations in it ,
" and what is the use of a book ," thought Alice " without
pictures or conversations ?"

3. Saving and loading data

(a) Parsing les Reading in data from a le is one thing, but making
sense of what was read in is another. Are you storing saved data
from the last session of the program? Are you trying to parse data
to crunch? How do you read that data in logically?

First, if your program is going to be saving output that will need to


be read in and made sense of later on, how do you organize the data
that's output? It's up to you to make sure to structure the output
save data in a consistent and readable way. . .

250
SAVEGAME RachelsGame
LEVEL 5
GOLD 1000
LOCATION RegnierCenter

If every save le from the program is formatted in the same way,
then when reading the le we can make assumptions. . .

ˆ First word: "SAVEGAME" - not important (human readable)

ˆ Second word: Save game name - store in gameFileName

ˆ Third word: "LEVEL" - not important (human readable)

ˆ Fourth word: Player's level - store in level

. . . And so on. This could work, but we could also take advantage of
those human-readable labels that were added into the le.

ˆ Read firstWord.

ˆ IffirstWord is "SAVEGAME", then read the next word into


gameFileName.

ˆ Else if firstWord is "LEVEL", then read the next word into


level.

So, let's say we have our four variables for a save game:

Name Data type


gameFileName string
level int
gold int
location string

When we go to save our game le, it would be a simple output like


this:

1 // Save the game


2 ofstream output ( " save . txt " ) ;
3 output << " SAVEGAME " << gameFileName << endl ;
4 output << " LEVEL " << level << endl ;
5 output << " GOLD " << gold << endl ;
6 output << " LOCATION " << location << endl ;

Giving us a save le like:

SAVEGAME MyGame
LEVEL 1
GOLD 10
LOCATION OCB

251
Then to read it, we could approach it in a couple of dierent ways.
If we assume that the le will always have exactly four lines of data
saved and will always be in the same order, we could read it like:

1 // Load the game


2 string buffer ;
3 ifstream input ( " save . txt " ) ;
4 input >> buffer ; // ignore SAVEGAME
5 input >> gameFileName ;
6
7 input >> buffer ; // ignore LEVEL
8 input >> level ;
9
10 input >> buffer ; // ignore GOLD
11 input >> gold ;
12
13 input >> buffer ; // ignore LOCATION
14 input >> location ;

Or, if we weren't sure that order these would show up in, we could
store the rst item read into buffer each time, and based on what
that label was ("SAVEGAME", "LEVEL", etc.) we would know
what to read next . . .
1 string buffer ;
2 ifstream input ( " save . txt " ) ;
3
4 while ( input >> buffer )
5 {
6 if ( buffer == " SAVEGAME " )
7 input >> gameFileName ;
8
9 else if ( buffer == " LEVEL " )
10 input >> level ;
11
12 else if ( buffer == " GOLD " )
13 input >> gold ;
14
15 else if ( buffer == " LOCATION " )
16 input >> location ;
17 }

If we stepped through this, buffer is always going to store one of


the data labels, because after buer is read, we immediately read
the second item in the line of text. Once the second item is read,
the next thing to be read will be the next label.

Review questions:
1. What library is required in order to use le I/O in C++?

2. What data type is used to create a le that inputs (reads in) text from
an outside le?

252
3. What data type is used to create a le that outputs (writes out) text to
an outside le?

4. How do you write out the string literal "Hello world" to an output le?

5. How do you write out the value of a variable to an output le?

6. How do you read in one word from an input le?


7. How do you read in one line from an input le?

253
5.16 Unit 15: Tech Literacy: Ethics in tech
Software is made by people and it is used by people. We have a responsibility
to design and test software to avoid doing harm to people. While designing
software it can be dicult to think of how people who aren't like us will be
aected, which is why we should have our work reviewed by others with dierent
backgrounds and experiences to try to catch issues ahead of time.

Some examples of problematic designs are:

ˆ A social media platform giving you reminders of what happened a year


ago, when a user happened to experience a tragedy at that time.

ˆ Writing scripts to "validate" peoples' names, which mark certain names


as invalid, whether because too short / has a space / has punctuation,
and so on. (Names generally shouldn't be validated! Also, not everyone
has just 2 names!)

ˆ A medical machine whose software hasn't been properly tested to pre-


vent invalid inputs, causing over-radiation of cancer patients, resulting in
numerous deaths.

ˆ A video platform being designed so that videos that keep eyeballs the
longest generate the most prot, leading to exploitative video creation
tactics (content farms, content designed to exploit childrens' attention
spans) with no motivation to curb these practices aside from pressure
from users of the platform.

And as we use more and more algorithms to crunch data and try to make
decisions, the topic of algorithmic bias also comes up - what should we allow
a machine to make decisions on, and what should it not have the ability to
control? How do we hold a machine accountable for decisions it makes, when
its whole algorithm is a black-box, even to its developers?

Here are a few items I want you to look at for the discussion board post:

ˆ Data scientist Cathy O'Neil on the cold destructiveness of big data:

qz.com/819245/data-scientist-cathy-oneil-on-the-cold-destructiveness-of-big-
data

ˆ How tech's lack of diversity aects its products: An interview with Sara
Wachter-Boettcher (Podcast/transcript)

uxpod.com/episodes/how-techs-lack-of-diversity-aects-its-products-an-interview-
with-sara-watchter-boettcher.html

ˆ How I'm ghting bias in algorithms | Joy Buolamwini:

https://www.youtube.com/watch?v=UG_X_7g63rY
ˆ Facebook showed this ad to 95% women. Is that a problem?:

https://www.youtube.com/watch?v=2wVPyiyukQc

254
5.17 Unit 16: C++: Intro to recursion

5.17.1 Examples of recursion in math


Recursion is a manner of solving a problem by breaking it down into smaller
pieces - and those smaller pieces are solved in the same way as the big-picture
version.

1. Summation:
A summation can be broken down into smaller chunks but using the same
structure as the original.

Let's say we have


6
X
i=1+2+3+4+5+6
i=1

The summation can be redened recursively:

6
X 5
X
i=6+ i
i=1 i=1

The summation from i = 1 to 6 is equivalent to whatever the sum is at


i = 6, plus the sum from i = 1 to 5.
P1
We can continue this way until we get to a case that we know (e.g., i=1 i).

P6 P5
ˆ i=1 i=6+ i=1 i
P5 P4
ˆ i=1 i=5+ i=1 i
P4 P3
ˆ i=1 i=4+ i=1 i
P3 P2
ˆ i=1 i=3+ i=1 i

255
P2 P1
ˆ i=1 i=2+ i=1 i

P1
ˆ We know that i=1 i = 1, then we move back up to sub out this
value.

Recursive problem
P6 P5 P5
A. i = 6 + i=1 i But what is i ?
P5i=1 P4 P4i=1
B. i = 5 + i=1 i But what is i ?
Pi=1
4 P3 Pi=1
3
C. i=1 i = 4 + i=1 i But what is i ?
P3 P2 P2i=1
D. i = 3 + i=1 i But what is i ?
P2i=1 P1 P1i=1
E. i = 2 + i=1 i But what is i=1 i ?
P1i=1
F. i=1 = 1
i

Now we start substituting this value back for each step. . .

Finding the solution


P2 P1
G. i= 2 + i= 2 + 1 = 3
P3i=1 Pi=1
2
H. i = 3 + i= 3 + 3 = 6
P4i=1 Pi=1
3
I. i= 4 + i= 4 + 6 = 10
Pi=1
5 Pi=1
4
J. i=1 i =P 5 +
Pi=1
i= 5 + 10 = 15
6 5
K. DONE! i=1 i = 6 + i=1 i = 6 + 15 = 21

2. Factorials:
With a factorial of n, written n! the formula to solve this is:

n! = n · (n − 1) · ... · 3 · 2 · 1

So,

ˆ 2! is 2 · 1,

ˆ 3! is 3 · 2 · 1,

ˆ 4! is 4 · 3 · 2 · 1, and so on.

Additionally, we can break down each of these equations: 3! is equivalent


to 3 · 2! 4! is equivalent to 4 · 3! ... n! is equivalent to n · (n − 1)!
Thinking of breaking down the problem here in this way is looking at it
recursively.

256
5.17.2 Recursion in programming
In programming, we usually approach problems iteratively, using a for-loop or
a while-loop:

1 // Iterative solution
2 int Sum ( int n )
3 {
4 int result = 0;
5 for ( int i = 1; i <= n ; i ++ )
6 {
7 result += i ;
8 }
9 return result ;
10 }

Which solves this summation:

n
X
i
i=1
But some types of problems lend themselves better to a recursive solution.
To be fair, though, many problems are better solved iteratively. So how do we
know which method is better?

1. Recursion basics
When dening a problem recursively in programming, we need two things:

(a) A terminating case: A case that ends our recursing. Often, this
is some known data, something hard-coded. For example with our
summation, the terminating case would be that

1
X
i=1
i=1

257
or for a factorial, 1! = 1 and 0! = 1.
(b) A recursive case: A recursive case is what happens otherwise - if
we're not to a solution yet (via the terminating case), we call the
same function again, but with updated arguments. For example:

ˆ Factorial( 4 ) = 4 * Factorial( 3 )

ˆ Factorial( 3 ) = 3 * Factorial( 2 )

ˆ Factorial( 2 ) = 2 * Factorial( 1 )

ˆ Factorial( 1 ) = 1

We can solve these basic math operations both iteratively and recursively:

1 // Iterative solution
2 int FactorialI ( int n )
3 {
4 int result = 1;
5 for ( int i = 1; i <= n ; i ++ )
6 {
7 result *= i ;
8 }
9 return result ;
10 }

1 // Recursive solution
2 int FactorialR ( int n )
3 {
4 if ( n == 1 || n == 0 ) { return 1; }
5 return n * FactorialR ( n -1 ) ;
6 }

258
2. Breaking down problems into recursive solutions

One of the most challenging parts of recursion, at least for me, is trying to
break away from thinking of something in terms of "looping" and guring
out how to think of it "recursively". It's not as natural-feeling, so don't
worry if it's confusing at rst.

Let's tackle some basic design problems to practice.

Summation: Try to convert the Summation function to be recursive.


Think about what the terminating case would be and the recur-
sive case. Use the Factorial function for reference.

1 int SumI ( int n )


2 {
3 int result = 0;
4 for ( int i = 1; i <= n ; i ++ )
5 {
6 result += i ;
7 }
8 return result ;
9 }

1 int SumR ( int n )


2 {
3 // Terminating case ?
4 // Recursive case ?
5 }

Solution for recursive summation:

1 int SumR ( int n )


2 {
3 if ( n == 1 ) { return 1; } // Terminating case
4 return n + SumR ( n -1 ) ; // Recursive case
5 }

259
Draw a line: Now let's make a function that will draw a line of symbols,
with a parameter being the length. Iteratively, it could look like
this:

1 void DrawLineI ( int amount )


2 {
3 for ( int i = 0; i < amount ; i ++ )
4 {
5 cout << " -" ;
6 }
7 }

How would we repeat this behavior recursively? How do we have a "count


up" sort of functionality? What would be the terminating case?

We're going to think of it a little dierently: The recursive function will


only output one "-" before it recurses. Each time it recurses, it draws one
more dash. . .

1 void DrawLine_Recursive ( int amount )


2 {
3 cout << " -" ;
4 // Recursive case
5 DrawLineR ( amount ) ;
6 }

However, we don't have a terminating case. . . it will continue looping,


but it won't go forever like a bad while loop. We will eventually run out
of stack space and the program will encounter a stack overow and
end.

So what would the terminating case be? How do we adjust the amount
each time? Since amount is the one parameter we have, let's have the
recursion stop once it is 0. Each time we recurse, we can pass in amount-1
to the next call. . .

1 void DrawLine_Recursive ( int amount )


2 {
3 cout << " -" ;
4
5 // Terminating case
6 if ( amount == 0 ) { return ; }
7
8 // Recursive case
9 DrawLineR ( amount - 1 ) ;
10 }

260
Counting Up: How can we write a function that takes a start and end
integer, and outputs each number between them (including the start
and end)?

Iteratively, it could look like this:

1 void CountUpI ( int start , int end )


2 {
3 for ( int i = start ; i <= end ; i ++ )
4 {
5 cout << i << "\ t " ;
6 }
7 }

Try to ll in this function to build a recursive solution:

1 void CountUpR ( int start , int end )


2 {
3 }

Solution for recursive count up:

1 void CountUpR ( int start , int end )


2 {
3 cout << start << " \ t " ;
4
5 // Terminating case
6 if ( start == end ) { return ; }
7
8 // recursive case
9 CountUp_Recursive ( start +1 , end ) ;
10 }

3. A case for recursion


Although there are a lot of problems we could convert from an iterative
solution to a recursive solution, there are some types of problems that
really are better suited to recursion.

(a) Searching a File System

261
On a harddrive, we generally have les and folders. Folders can
contain les, but they will also contain subfolders as well. And
subfolders can each contain their own subfolders.

When you don't know the exact layout of the lesystem, how would
you even begin to iteratively search for a specic le?

Instead, it is good to think of it recursively. For example, say we're


searching for a folder where you store your Recursion homework.
We will begin searching at the top-most folder of the computer. The
algorithm would then run like. . .

Let's say we have a recursive function, Find( FOLDERNAME, currentFolder


).
For this functionality, terminating cases would be:

i. Have we found the item? Return it.

ii. Are we out of places to search? Return nothing.

And the recursive case would be:

i. Has a subfolder? Call Find() on that folder.

262
Example lesystem:

C:
games
DOOM
school
cs210
cs235
recursion
work
TPSreports

So steps to locate the "Recursion" folder would look like this:

Find( "recursion", "C:" )


Does "C:" have the recursion folder? NO...
Does it have subfolders? YES... OK, Recurse.
|
| Find( "recursion", "C:\games" )
| Does "C:\games" have the recursion folder? NO...
| Does it have subfolders? YES... OK, Recurse.
| |
| | Find( "recursion", "C:\games\DOOM" )
| | Does "C:\games\DOOM" have the recursion folder? NO...
| | Does it have subfolders? NO... Return.
| |
| Does "C:\games" have any more subfolders? NO... Return.
|
Does "C:" have any more subfolders? YES... OK, Recurse.
|
| Find( "recursion", "C:\school" )
| Does "C:\school" have the recursion folder? NO...
| Does it have subfolders? YES... OK, Recurse.
| |
| | Find( "recursion", "C:\school\cs210" )
| | Does "C:\school\cs210" have the recursion folder?
| | NO... Does it have subfolders? NO... Return.
| |
| Does "C:\school" have any more subfolders? YES... OK, Recurse.
| |
| | Find( "recursion", "C:\school\cs235" )
| | Does "C:\school\cs235" have the recursion folder? *YES*...
| | OK, return this path.
| |
| "C:\school\cs235" path was returned, continue returning it.
|
"C:\school\cs235" path was returned, continue returning it.

And the result for nding the recursion folder is "C:\school\cs235".

263
(b) Solving a maze

Solving a maze can be approached from a recursive standpoint much


easier than an iterative one.

Terminating cases:

i. If we get to the end of the maze, SUCCESS.

ii. If we hit a dead-end, GO BACK (return).

Recursive case: Explore each available direction, except the direc-


tion you came from.

i. Try to go NORTH

ii. Try to go EAST

iii. Try to go SOUTH

iv. Try to go WEST

264
Example step-through, going from A to B (@) is current location.

######## Path so far:


### ## # Recursive case: Can't go NORTH, can go EAST...
A @ ## Z
### #
########

######## Path so far: E


### ## # Recursive case: Can't go NORTH, can go EAST...
A @ ## Z
### #
########

######## Path so far: E E


### ## # Recursive case: Can't go NORTH, can go EAST...
A @ ## Z
### #
########

######## Path so far: E E E


### ## # Recursive case: Can go NORTH...
A @## Z
### #
########

######## Path so far: E E E N


###@## # Recursive case: Can't go NORTH, can't go EAST,
A ## Z can't go WEST...
### # Return to previous location...
########

######## Path so far: E E E


### ## # Recursive case: Already went NORTH.
A @## Z Can't go EAST... Can go SOUTH...
### #
########

######## Path so far: E E E S


### ## # Recursive case: Can go EAST...
A ## Z
###@ #
########

######## Path so far: E E E S E


### ## # Recursive case: Can go EAST...
A ## Z
### @ #
########

265
######## Path so far: E E E S E E
### ## # Recursive case: Can go EAST...
A ## Z
### @ #
########

######## Path so far: E E E S E E E


### ## # Recursive case: Can go NORTH...
A ## Z
### @#
########

######## Path so far: E E E S E E E N


### ## # Recursive case: Can go NORTH...
A ##@ Z
### #
########

######## Path so far: E E E S E E E N N


### ##@# Recursive case: Can't go NORTH, can't go EAST,
A ## Z can't go WEST.
### # Return to previous location...
########

######## Path so far: E E E S E E E N


### ## # Recursive case: Can go EAST...
A ##@ Z
### #
########

######## Path so far: E E E S E E E N E


### ## # Made it to the end!
A ## @Z Return "EEESEEENE" as the solution!
### #
########

266
5.18 End of the semester
Let me know if you have any additional suggestions! :)

5.18.1 Ways to practice

5.18.2 Articles to read


ˆ Martin Fowler's blog

 Diversity Imbalance: https://martinfowler.com/bliki/DiversityImbalance.


html

 https://martinfowler.com/bliki/
Diversity Mediocrity Illusion:
DiversityMediocrityIllusion.html

 Alienating Atmosphere: https://martinfowler.com/bliki/AlienatingAtmosphere.


html

 Born for it: https://martinfowler.com/articles/born-for-it.


html

5.18.3 Podcasts to listen to


ˆ Hanselminutes

 Innovation in Accessibility with Fable's Kate Kalcevich: https://


hanselminutes.com/942/innovation-in-accessibility-with-fables-kate-kalcevich

 Indigenous cultural robots with Danielle Boyer: https://hanselminutes.


com/916/indigenous-cultural-robots-with-danielle-boyer

 Documentation as a path to Open Source with Sarah Rainsberger:


https://hanselminutes.com/911/documentation-as-a-path-to-open-source-with-sarah-rains

267
5.18.4 Books to read
Software development:

ˆ Eective C++ by Scott Meyers (Repository with overview: https://


github.com/henrytien/effective-cpp-3rd?tab=readme-ov-file#chapter-1-accustoming-
ˆ The Pragmatic Programmer by David Thomas and Andrew Hunt:
https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edit
ˆ Test-Driven Development By Example by Kent Beck: https://www.
oreilly.com/library/view/test-driven-development/0321146530/
ˆ Object-Oriented Analysis and Design with Applications by Grady
Booch: https://www.oreilly.com/library/view/object-oriented-analysis-and/
9780201895513/
Bias and equity in tech:

ˆ Weapons of Math Destruction by Cathy O'Neil: https://weaponsofmathdestructionbook.


com/
ˆ Technically Wrong by Sara Wachter-Boettcher: https://wwnorton.
com/books/Technically-Wrong/
ˆ Automating Inequality by Virginia Eubanks: https://virginia-eubanks.
com/
ˆ Invisible Women by Caroline Criado Perez: https://www.abramsbooks.
com/product/invisible-women_9781419729072/
The Enshittication of tech:

ˆ DEF CON 31 - An Audacious Plan to Halt the Internet's En-


shittication - Cory Doctorow: https://www.youtube.com/watch?
v=q118B_QdP2k

5.18.5 Things to watch


ˆ Coded Bias: https://www.pbs.org/independentlens/documentaries/
coded-bias/
ˆ The Secret Rules of Modern Living: Algorithms:

 https://connect.open.ac.uk/science-technology-engineering-and-maths/
the-secret-rules-of-modern-living-algorithms
 https://tv.apple.com/gb/movie/algorithms-secret-rules-of-modern-living/
umc.cmc.2wz39wxhneinbbd78kfsf7yrn ?

268
ˆ YouTube channels:

 https://www.youtube.com/@MayaBello/featured
 https://www.youtube.com/@TheCherno

269
6 Nonogram puzzles

How to play: Each cell in the grid of squares can either have a X (or blank)
or be lled in. The lled in boxes create the pixels of an image. Each row and
each column have one or more numbers. This species how many pixels are in
that row/column. The number given is how many unbroken pixels will show up
together. Two numbers separated by a space, e.g., "1 1", will have at least one
empty spot between them.
Look for rows/columns with "0"s and x out the entire region, do the same
for rows/columns with the same # as the width/length, but ll in the entire
region.

Figure 12: A 5x5 grid. Column labels: 1. 4. 2, 1. 4. 1. Row labels: 0. 3. 3. 1,


1. 5. The 5 row has been lled in.

Look for overlaps, continue started lines, and continue analyzing and lling
things out until you solve the puzzle. Check YouTube videos for step-by-step
solutions to other Nonogram (aka Picross) puzzles.

Figure 13: The same puzzle as above. The 4 columns and the 2, 1 column has
been lled in.

270
6.1 Puzzle A
6.1.1 Hint: Among Us

Figure 14: A 5x5 grid. Column labels: 0. 5. 1, 2. 5. 0. Row labels: 3. 1, 1. 3.


3. 1, 1.

6.1.2 Hint: Star

Figure 15: A 5x5 grid. Column labels: 1. 3. 4. 3. 1. Row labels: 1. 1. 5. 3. 1,


1.

271
6.2 Puzzle B
6.2.1 Hint: Happy

Figure 16: A 5x5 grid. Column labels: 2. 2, 1. 1. 2, 1. 2. Row labels: 1, 1. 1,


1. 0. 1, 1. 5.

6.2.2 Hint: Cat

Figure 17: A 5x5 grid. Column labels: 2. 2, 2. 4. 2, 2. 2. Row labels: 1, 1. 3.


1, 1, 1. 5. 3.

272
6.3 Puzzle C
6.3.1 Hint: Love

Figure 18: A 5x5 grid. Column labels: 2. 4. 4. 4. 2. Row labels: 1, 1. 5. 5. 3.


1.

6.3.2 Hint: :P

Figure 19: A 5x5 grid. Column labels: 1. 1, 2. 1, 1. 1, 1, 1. 2. Row labels: 1,


1. 0. 5. 1, 1. 2.

273
6.4 Puzzle D
6.4.1 Hint: Tree

Figure 20: A 5x5 grid. Column labels: 1. 3, 1. 5. 3, 1. 1. Row labels: 3. 3. 3.


1. 5.

6.4.2 Hint: Chocolate chip cookie

Figure 21: A 5x5 grid. Column labels: 3. 1, 1, 1. 1, 2. 2, 1. 3. Row labels: 3.


1, 2. 2, 1. 1, 1, 1. 3.

274
6.5 Puzzle E
6.5.1 Hint: Burger

Figure 22: A 10x10 grid. Column labels: 1. 2, 2. 1, 3, 1. 1, 1, 1, 1. 1, 3, 1. 2,


2. 1. Row labels: 3. 1, 1. 5. 1, 1, 1, 1. 5. 1, 1. 3.

275
6.6 Puzzle F
6.6.1 Hint: Bunny

Figure 23: A 10x10 grid. Column labels: 3. 2, 1. 1, 1, 1. 2, 1. 1, 1, 1. 2, 1. 3.


Row labels: 1, 1. 1, 1, 1. 1, 1, 1. 1, 1. 1, 1, 1, 1. 1, 1. 5.

276

You might also like