Moosadee Gitlab Io Courses 202401 Spring Book Oopcpp HTML
Moosadee Gitlab Io Courses 202401 Spring Book Oopcpp HTML
Table of Contents
WEEK 1 - JAN 16
📊
UNIT 00: Welcome & setup
Presentation - Set up (U00.PRES)
🧑🔬
📖️Reading - Welcome (U00.READ)
Lab - Set up (U00.LAB)
📊
UNIT 01: Exploring software design
Presentation - Exploring software design (U01.PRES)
🧠
📖️Reading - Exploring software design (U01.READ)
Tech Literacy - Exploring software design (U01.TEC)
📊
UNIT 02: CS 200 Review - Basics
Presentation - CS 200 Review: Basics (U02.PRES)
🧑🔬
📖️
🧠
Reading - CS 200 review: Basics (U02.READ)
Lab - CS 200 review: Basics (U02.LAB)
Tech Literacy - Command Line programs (U02.TEC)
WEEK 2 - JAN 22
📊
UNIT 03: CS 200 Review - Functions and classes
Presentation - CS 200 Review - Functions and classes (U03.PRES)
🧑🔬
📖️
🏋️
Reading - CS 200 Review - Functions and classes (U03.READ)
Lab - CS 200 review: Functions and classes (U03.LAB)
Exercise - Debugging functions and classes (U03.EXE)
📊
UNIT 04: Debugging and testing
Presentation - Debugging and testing (U04.PRES.202401CS250)
🧑🔬
📖️
🧠
Reading - Debugging and testing (U04.READ.202401CS250)
Lab - Debugging and testing (U04.LAB)
Tech Literacy - Git (U04.TEC)
📊
UNIT 05: Algorithm efficiency
Presentation - Algorithm efficiency (U05.PRES)
🧠
📖️Reading - Algorithm efficiency (U05.READ.202401CS250)
Tech Literacy - Algorithm efficiency (U05.TEC)
WEEK 3 - JAN 29
📊
UNIT 06: CS 200 Review - Pointers
Presentation - Pointers and memory (U06.PRES)
🧑🔬
📖️Reading - Pointers and memory (U06.READ)
Lab - CS 200 Review - Pointers (U06.LAB)
📊
UNIT 07: The Standard Template Library
Presentation - The Standard Template Library (U07.PRES)
🧑🔬
📖️Reading - The Standard Template Library (U07.READ)
Lab - The Standard Template Library (U07.LAB)
WEEK 4 - FEB 5
📊
UNIT 08: Recursion
Presentation - Recursion (U08.PRES)
🧑🔬
📖️
🏋️
Reading - Recursion (U08.READ)
Lab - Recursion (U08.LAB.202401CS250)
Exercise - Debugging arrays and pointers (U08.EXE)
📊
UNIT 09: Searching and sorting
Presentation - Searching and sorting (U09.PRES)
🧑🔬
📖️
🧠
Reading - Searching and sorting (U09.READ)
Lab - Searching and sorting (U09.LAB.202401CS250)
Tech Literacy - Problem solving (U09.TEC)
WEEK 5 - FEB 12
📊
UNIT 10: Templates
📖️
Presentation - Templates (UX.PRES) - WORK IN PROGRESS
Reading - Templates (U10.READ)
📊
UNIT 11: Exceptions
Presentation - Exceptions (U10.PRES) - WORK IN PROGRESS
🧑🔬
📖️Reading - Exceptions (U11.READ)
Lab - Templates and exceptions (U10.LABh)
WEEK 6 - FEB 19
📊
UNIT 12: Overloading functions and constructors
📖️
Presentation - Overloading functions (U12.PRES)
Reading - Overloading functions (U12.READ)
📊
UNIT 13: Default parameters
Presentation - Default parameters (U13.PRES)
🧑🔬
📖️Reading - Default parameters (U13.READ)
Lab - Overloading functions, default parameters (U13.LAB)
WEEK 7 - FEB 26
📊
UNIT 14: Static members
📖️
Presentation - Static (U14.PRES)
Reading - Static members (U14.READ)
UNIT 15: Friends
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
📊 Presentation - Friends (U15.PRES)
🧑🔬
📖️
😺
Reading - Friends (U15.READ)
Lab - Static members and friends (U15.LAB)
Unit 14/15 Status Update - Static members & friends (U15.SUP)
WEEK 8 - MAR 4
UNIT 16: Anonymous functions
🔎
📖️ Reading - Anonymous functions (U16.READ)
Unit 16 Concept Intro - Anonymous functions (U16.CIN)
UNIT 17: Polymorphism
🔎
📖️ Reading - Polymorphism (U17.READ)
Unit 17 Concept Intro - Polymorphism (U17.CIN)
WEEK 9 - MAR 11 - SPRING BREAK
WEEK 10 - MAR 18
📊
UNIT 18: Operator overloading
Presentation - Operator overloading (U18.PRES)
🧑🔬
📖️ Reading - Operator overloading (U18.READ)
Lab - Operator overloading (U18.LAB)
📊
UNIT 19: Third party libraries
Presentation - Third party libraries (U19.PRES)
🧑🔬
📖️ Reading - Third party libraries (U19.READ)
Lab - Third party libraries (U19.LAB)
WEEK 11 - MAR 25 - SEMESTER PROJECT PART 1
Project v1
WEEK 12 - APR 1 - R.W. COURSE BREAK
WEEK 13 - APR 8 - SEMESTER PROJECT PART 2
Project v2
WEEK 14 - APR 15 - R.W. COURSE BREAK
WEEK 15 - APR 22 - SEMESTER PROJECT PART 3
Project v3
WEEK 16 - APR 29 - LAST WEEK OF CLASS / R.W. COURSE BREAK
WEEK 17 - MAY 7 - MAY 13 - FINALS WEEK
Additional
About
About this book
About this course
About the author
Reference
Basic Computer Skills
Code and UI Style Guide
C++ Quick Reference
Common C++ issues
Git guide
Terminal - Building and running
VS Code - Open projects, building, and running
Setting up and using third party libraries
Archive - Video links
Syllabus
Course information
Course policies
Additional information
Course catalog info
Rachel Wil Sha Singh's Object Oriented Programming Course © 2024 by Rachel Wil Sha Singh is licensed under CC BY 4.0. To view a copy of this license, visit
http://creativecommons.org/licenses/by/4.0/
These course documents are written in emacs orgmode and the files can be found here: https://gitlab.com/moosadee/courses
Dedicated to a better world, and those who work to try to create one.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This section contains each of the units we will be covering in the class, including the reading material, review, and assignment documentation. Add your own notes
and highlight things as you go through!
WEEK 1 - JAN 16
📖️
Reading - Welcome (U00.READ)
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.)
Belonging
Unfortunately there is a lot of bias in STEM fields 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 fit this description can be hesitant 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
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
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 different degree. I know developers who are into all sorts of sports, or into photography, or into fashion. There is no specific "type" of
programmer. You can be any religion, any gender, any color, from any country, and be a programmer.
Figure 1: Don't be like Gatekeeper Baby. You can begin coding at any age!
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 figure out this program and I had to get it done!!
All developers struggle. Software is a really unique field. It's very intangible, 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.
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.
Learning
My teaching style is influenced on all my experiences throughout my learning career, my software engineer career, and my teaching career.
I have personally met teachers who have tried to scare me away from computers, 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 independently 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 development 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.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
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!"
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?)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
How do you design a solution given just some requirements?
How do you network in the tech field?
How do you find jobs?
What are some issues facing tech fields 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 field is about "how do computers work?", not about "how do I write software good?" but I still find 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.
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 content to emacs orgmode documents, which allows me to export the course
content to HTML and PDF files. I have a few goals with this:
I know a lot of text can be intimidating at first, but hopefully it will be less intimidating as the semester goes and we learn our way around this page.
In CS 200 you learn about many of the core, basic features of C++. We work on basic assignments but there are some topics missing: Building bigger
programs, and additional C++ language features and techniques that help with building those bigger programs while reducing duplicate code.
In this class, we're going to continue learning about features of C++ as well as how programs are often structured using Object Oriented
Programming for maintainability and scalability. I try to add as much context from my real-world software development experience in this course to
help you learn about software development as a whole, to hopefully better prepare you for working as a software developer.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Object Oriented Programming is just one paradigm (or style) of designing software. It is probably the most popular way to structure most types of
software you think of - a grocery store website, bank accounts, social media, etc. - but it's not the only style of programming. Here's a bit of
background information for context.
Early programming
Early programming in Assembly or Machine Code didn't have the concepts of "classes", and at a very basic level, even "functions" aren't a
feature. Programs were built mostly of instructions that flow from top-down, utilizing variables with branching (if statements) and looping.
Structured programming
Early programming languages built on top of the basic commands to add more functionality, such as subroutines (basically, functions), but
were still without classes and objects.
Object-oriented programming
Object oriented programming relies on classes to create objects that interact with each other. This helps us conceptualize each working part of a
program as a discrete "thing" with its own attributes and functionality, that interacts with other "things".
Others
You can get an overview about other Programming Paradigms on Wikipedia: https://en.wikipedia.org/wiki/Programming_paradigm
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
It might help to investigate how we might design a system around OOP. Let's say we have a video game, since that's a visual example.
In a video game, usually you have different types of objects on the screen, with different types of behaviors. Some of those behaviors are in common,
and we would use inheritance or composition to reduce duplicate code by having them share these aspects. Otherwise, each type of "object" defines
the attributes and functionality that it requires.
Character:
Attributes (variables):
x, y coordinates - where is the character on the screen?
width, height - what is the size of the character?
image - What image file is used to represent the character?
healthPoints - How much remaining health the character has.
Functions:
Move() - move the character along the x axis (left/right) or y axis (up/down).
IsHit() - Checks if character is hit by projectile, affect health.
PlayerCharacter might inherit from Character, inheriting its variables and functions. Then we add onto it:
score - A variable to store player score.
GetInput() - Check for keyboard input, such as arrow keys to tell the player to move.
NonPlayerCharacter might inherit from Character, and have its own special functions:
DecideMovement() - Instead of input from the keyboard, the NPC would use its "AI" to figure out where to go.
If you were working somewhere that created software that dealt with food delivery, the classes defined in the code base might look something like
this:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Inheritance:
Driver and Customer inherit from Person (anything in common goes in the "Person" class)
Composition:
A Restaurant has an array of FoodItem s offered.
An Order contains an array of FoodItem s ordered.
A driver has a single Order they're currently delivering. (Though this might be an array in modern apps.)
A customer has an array of Order s that make up their order history.
This is just a really basic example that highlights the objects (classes) and their attributes (variables), but I've left off functionality here for
simplicity. The core idea here is that we think of real world items, such as a "Restaurant", and that can be modeled as an object. OOP code bases are
built up around this concept, of interconnected objects working together.
Review questions:
Answer these questions in your notes, then check your work by completing the related Concept Intro assignment on Canvas.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Create a GitLab account
Set up git software on your computer
Clone a repository
Make changes to a repository
Deal with merge conflicts
Create branches and merge requests
Turn-in:
❓
1. Tell me what your GitLab username is using the " Unit 00 Setup - GitLab Username" assignment on Canvas.
Then I can give you access to your repository for the semester.
🧑🔬
2. Turn in a URL to a merge request in the " Unit 00 Lab - Set up (U00.LAB.202401CS250)" assignment on
Canvas.
Should contain an example program and your project files.
Installing an IDE
Download and install an IDE (Integrated Development Environment) on your system. Here are some suggested ones, but you can use whatever tools
you'd like.
We'll use our IDE more once we set up git and clone our repository…
Installing git
Starting off, you will need to install the git program to your computer. Go to https://git-scm.com/ and select Download for your OS. Make sure to read
through the setup settings here to prevent headaches in the future. (In particular, not setting Vim as the default text editor… unless that's something
you want.)
Configuring git
After git is installed, we will need to do a one-time configuration. Open up Git Bash (in Windows) or use git from your terminal (Linux/Mac).
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Replace "[email protected]" with your email (such as your student email).
Replace "Your Name" with your name, which is what will show up when you submit code file edits.
Finally, we're setting up a default merge resolution scheme, which you don't really need to worry about the details right now:
1. Go to the sign up page: Start by going to https://gitlab.com/users/sign_up and fill out the form to create your account.
Fill out your first and last name, a username, email address, and password. Note that if you want to maintain your privacy you might use an
alternative email/name, but make sure to let the instructor know who you are!
2. Navigate to your profile page: After registering, going to https://gitlab.com/ should take you to a "Projects" page. You will be able to view your
repositories here later on. On the right-hand sidebar, click on your profile image (it might be some default picture), then click on the top section to go
to your profile.
3. Bookmark your profile page: Once you're on your profile page, the URL will look something like this:
https://gitlab.com/YOURUSERNAME Take note of this URL and bookmark this page. You may also need to give this link to the instructor for
further setup.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Make sure the instructor knows your GitLab username
Post your GitLab username in the " ❓ Unit 00 Setup - GitLab Username" assignment. Once you have access to your repository, you can continue.
Your operating system: Navigate to the folder where you're storing your class projects. From here, right-click in the empty space and select Git Bash
Here to open Git Bash.
Repository webpage: On the repository webpage (gitlab.com) click on the blue Clone button and copy the URL listed under the Clone with HTTPS
header. (You can use SSH if you know how to set it up, but we aren't going to cover that here.)
Git Bash: Use the git clone URL command in Git Bash. This will clone the repository within the folder you opened Git Bash in. (Windows: To
use PASTE, right-click in Git Bash… CTRL+V will not work here.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
Now that the folder is on your computer, you will need to change directory into the folder. Use cd FOLDERNAME (in the example above, the folder
name would be YOURSSO-cs235 or YOURSSO-cs250 ) to enter the repository folder in Git Bash.
Creating a branch
Command Description
git branch View available branches
git checkout -b BRANCHNAME Create a new branch with the given BRANCHNAME
git checkout BRANCHNAME Checkout an existing branch whose name matches the BRANCHNAME
When working on an assignment, you will need to create a new branch each time.
$ git branch
* main
To create a new branch, use the git checkout -b BRANCHNAME command. The branch name needs to be unique. I suggest putting the Unit # in
the branch name at least.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
$ git checkout -b u00_setup
Switched to a new branch 'u00_setup'
Now if you type in git branch again you will see two branches with the asterisk marking which branch you're currently on:
$ git branch
main
* u00_setup
Each branch basically has its own code space. If you have work-in-progress code happening on separate branches, they will only be available on that
specific branch. If you switch to another branch you'll only see code for that branch, but you can always keep switching between to get the code back.
(When starting a new assignment, make sure to go back to the main branch and use git pull to grab latest code before then creating a new
branch. I'll try to put a reminder in future assignments.)
If you want to switch between existing branches, use git checkout BRANCHNAME :
(Note: The main branch might be named "master" so if your git branch shows "master" instead of "main", use that.)
Command Description
ls List out the files and folders in the current directory
touch FILENAME Create a new file
echo "text" >> FILENAME Append text to a file
git status View files that have changed
git add FILENAME Add a specific file to the changeset
git add *.cpp Add all files that end with ".cpp" to the changeset
git add . Add all changed files to the changeset
git commit Create a snapshot of currently added changes
git commit -m "text" Create a snapshot of currently added changes, setting commit message at the same time
git push -u origin BRANCHNAME Push the changes in the branch to the server
Starting off, your repository may only have a README file in the folder:
$ ls
README.md
In Windows you can create a new text file in here by opening notepad and saving a new file in this directory.
In Git Bash you can create a file by using the touch command: Use the touch FILENAME command to create a new file. Name your file
YOURNAME.txt . You can open the file from your OS and edit the text, or you can use the following command to put the text "Hello, I'm NAME!" in
place:
Next, use the git status command to view the changed file:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
$ git status
On branch u00_setup
Untracked files:
(use "git add <file>..." to include in what will be committed)
u00_hello.txt
nothing added to commit but untracked files present (use "git add" to track
We need to use the git add FILENAME command to mark the file for the changeset.
Next, we use the git commit -m "COMMIT MESSAGE" command to make a snapshot of the file's changes at this point:
Finally, use the git push -u origin BRANCHNAME command to push your changes to the GitLab server:
Command Description
git pull Pull latest changes from the server
GitLab webpage: On the webpage your branch will now show up in the dropdown menu.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Select your branch and you'll be able to see the last commit and your file here:
Open up your text file here and click the blue Edit button and select an editor. Add another line to the text file, then click the Commit changes button
at the bottom of the page.
Git Bash: Use the git pull command here to pull all changes, which will grab the changes that you just made from the server.
$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 517 bytes | 517.00 KiB/s, done.
From gitlab.com:(URL)
9eb8e5c..90394af u00_setup -> origin/u00_setup
Updating 9eb8e5c..90394af
Fast-forward
u00_hello.txt | 2 ++
1 file changed, 2 insertions(+)
When you open the text file in Notepad or a text editor, you will now see the second line of text.
This time we're going to purposefully create a merge conflict. This happens when changes are made to the same file from different locations (such as
on your computer and the web, or between different developers) and git can't figure out how to automatically merge the changes together. It can be
intimidating to deal with, but it isn't too bad.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Computer: Edit your text file to add some text in the middle. Then use git add FILENAME , git commit -m "Edited file" , but don't
push yet.
GitLab: Edit your text file to add a different line of text in the middle.
Git Bash: Now that you have two sets of changes, try to push your changes to the server. It will be rejected:
$ git push
To gitlab.com:(URL).git
! [rejected] u00_welcome -> u00_welcome (fetch first)
error: failed to push some refs to '[email protected]:(URL).git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
It gives you a hint - you need to use git pull to grab any latest changes from the server:
$ git push
To gitlab.com:(URL).git
! [rejected] u00_welcome -> u00_welcome (non-fast-forward)
error: failed to push some refs to '[email protected]:(URL).git'
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.
Use git pull , which will work, but result in a merge conflict:
$ git pull
Auto-merging u00_welcome.txt
CONFLICT (content): Merge conflict in u00_welcome.txt
Automatic merge failed; fix conflicts and then commit the result.
Open the text file in your editor and you'll see some additions to the file:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
There are two regions, and we need to manually decide how we want to merge the text. You could just remove the markers if you wanted both
changes. Make the update and save the file:
Then do your add, commit, and push to push the merged updates to the server.
$ git add . && git commit -m "manual merge" && git push
GitLab: On the website, you can select the "Commits" link under the "Code" section to view all the changes you've made to the code:
Lastly we're going to create a basic C++ project and make sure everything builds correctly. The project and code you create here should be stored
within your repository.
If you're using VS Code, please check the reference portion of the book for the section labeled VS Code - Open projects, building, and
running.
If you're using another code editor and wish to build from the terminal using the Makefile, look in the reference portion of the book for
the section labeled Terminal - Building and running
Visual Studio
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Select "Empty project" and click "Next".
3. Set your Project name. Make sure to set the project Location to somewhere within your repository directory.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
4. Right-click on your empty project and select Add then New item…
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
5. Type in "main.cpp" then click "Add".
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
7. Go to the "Build" dropdown menu and select "Build Solution".
9. Then, click the "(play) Local Windows Debugger" button to run the program.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
10. Your program text will show up in a console.
11. Your files will be in the location you set up. The .cpp file is your source code, and the .vcxproj is the project file.
Code::Blocks
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
3. Set your Project name. Make sure to set the project Location to somewhere within your repository directory.
4. Go to the "File" dropdown menu and select "New", then "Empty file".
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
5. It will ask you to save the file first, name it main.cpp. Default options are fine.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
8. The program should build without any errors.
11. Your files will be in the location you set up. The .cpp file is your source code and the .cbp file is the project file.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Afterwards, add, commit, and push your changes:
git add .
git commit -m "Example project"
git push -u origin u00_setup
Once changes are made, you'll create a merge request. This is how you can have your code reviewed, and the instructor will sign off on it and merge it
to the main branch, where all the code will live together. This is similar to in software development, where everybody will work on their own features
on their own branches, create a merge request, get their code reviewed, then a senior developer will merge the code into the main project.
GitLab: On the main repository page you will see a message saying that there are changes in your branch, with a button "Create merge request":
You can mostly leave the defaults unless you want to add notes. Scroll down and click the blue "Create merge request" button.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The URL of this page is what you will usually turn in as your Lab assignments
Once you've created a merge request, copy the URL of the merge request on the GitLab.com webpage:
Back on the Canvas page, locate the assignment and click the link:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Then click on "Start Assignment":
Paste in the URL to your Merge Request in the "Website URL:" textbox, then click "Submit Assignment" to finish the turn in.
📖️
Reading - Exploring software design (U01.READ)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Figure 2: Screenshot of VisiCalc running on an Apple II computer, by Gortu, CC0, File:Visicalc.png
Software on computers have come a long way over the decades. Desktop software, mobile apps, and websites handle so much more data and have
much more functionality than what was around 20 or more years ago. As a code base expands in scope, software architects try to structure the
software they work on to be scalable, efficient, and maintainable (though businesses often don't prioritize code maintenance so often times corporate
code bases are big and messy and terrible. :)
If you get a job as a software developer, chances are the code base you join will be designed around the object oriented programming paradigm. An
interconnected network of objects that have attributes (variables) and functionality, and which interact with other objects across the code base.
Many objects represent data that will get stored in a database, some objects' purpose may be to facilitate interactions between other objects. With
languages like Java and C#, everything must be built into a class, though C++ makes this optional, allowing for different styles of coding as well.
In this section we will look at some example designs for apps and websites you may commonly use.
Example: Spotify
We can get some kind of idea of the underlying structure of a system by looking at the API (Application Programming Interface) that it exposes to the
outside world. Many modern websites offer APIs in order to allow third parties to create helper programs and services that work with the data stored
by the original service.
Looking at the Spotify API documentation (https://developer.spotify.com/documentation/web-api), we can see several main "objects" it provides:
1. Albums
2. Artists
3. Audiobooks
4. Categories
5. Chapters
6. Episodes
7. Genres
8. Markets
9. Player
10. Playlists
11. Search
12. Shows
13. Tracks
14. Users
If you click on one of the objects, it will show an example of requests that an external program can call, such as Get Album, Get Album Tracks,
Save Albums for Current User, and so on.
Clicking on a request type will also show a Response Sample, which shows what kind of information may be returned with a call, such as Get
Album:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
{
"album_type": "compilation",
"total_tracks": 9,
"available_markets": [
"CA",
"BR",
"IT"
],
"id": "2up3OPMp9Tb4dAKM2erWXQ",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c82
"height": 300,
"width": 300
}
],
"release_date": "1981-12",
"type": "album",
"artists": [
{
"id": "string",
"name": "string",
}
],
"tracks": {
"total": 4,
"href": "https://api.spotify.com/v1/me/shows?offset=0&limit=20",
"next": "https://api.spotify.com/v1/me/shows?offset=1&limit=1",
"previous": "https://api.spotify.com/v1/me/shows?offset=1&limit=1"
},
"copyrights": [
{
"text": "string",
"type": "string"
}
],
"genres": [
"Egg punk",
"Noise rock"
],
"popularity": 0
}
The data and the form it's returned in via API response isn't necessarily how the data is stored in the database itself, or how the data is stored in objects
when worked on by the Spotify servers themselves. Usually, API systems pulls data from multiple sources and bundles it together to return as a
response. But, this can at least give us some idea of how the actual system may be organized.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This is just a small example, containing a "Music" section (Artist, Album, Track) and a "User" section (User, Playlist). The arrows show relationships
between the objects. But this diagram is also lacking any of the back-end functionality that helps everything actually do something. On their own, it's
just data stored somewhere. A program has to be written around it.
Software layers
Software is built in layers. The architecture itself may change over time, so we're going to keep this pretty general. Basically, you'll have a front-end,
which is the interface the user sees when working with the program. The user isn't exposed to all of the complexity of the program itself - we give
them some kind of nice interface to work with, and they don't care how anything actually works.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The front-end is hooked into the program back-end, which handles logic. This may also read from or write to storage, or a database.
A lot of utilities we use these days are websites, not desktop software, so the server we're contacting has the back-end and all its logic, as well as
access to its databases. It then sends webpages or other forms of information to our computer (the client), which will be displayed - such as rendered
by a web browser.
Again, architecture can change quickly. At the moment, microservices are a popular way to architect websites. We aren't going to go into depth into
this, however, since we're going to just be working with console-based desktop software in this course.
Here's an example of how we can may design programs in this course for larger projects. I have a "database" labeled but data saving and loading for
us will just be via text documents or CSV files. (We're not going to set up database stuff because everyone's platforms are different and we don't have
time for that. ;)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In the yellow, BankTellerProgram and CustomerATMProgram are two different, separate programs. One would theoretically be used by a
bank employee, and they have access to more sensitive information as part of their job. The customer's ATM might only have some basic features like
checking balance, depositing, and withdrawing. For us, these act as the "interface layer".
We have basic objects like BankAccount and Customer , which are more obvious instances of turning real-world concepts into objects (classes)
in C++.
Then we have the Manager objects, which contain all of the data for whatever they manage ( BankAccountManager has a
vector<BankAccount> , CustomerManager has a vector<Customer> ) and interfaces to allow other parts of programs to access the data.
This way, we're not cluttering up the Programs themselves with the logic needed to manage Bank Accounts or Customers.
How does this design "flow"? Here's an example diagram of the process for a bank teller to add a new account:
When the program begins, we enter main() , but we don't put much program logic in there - we just create and run a
BankTellerProgram .
It starts at the main menu, and then the bank teller would select an option from the list.
We're adding a new account, so it calls Menu_AddNewAccount() in the BankTellerProgram .
Within this function, it will display a list of all customers by calling CustomerManager 's GetAllCustomers() function (or perhaps we
could add a Display function).
Next, it asks the bank teller to enter the ID of the customer we're creating an account for.
Then, we create a new BankAccount object and set up its initial information.
After that's done, we call the BankAccountManager 's AddAccount function, passing in the new account object we created.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
At the end of the Menu_AddNewAccount() function, it returns the teller back to the main menu so they can select the next operation that
they'll perform.
🧠
Utilize this example for the " Unit 01 Tech Literacy - Exploring software design (U01.TEC.202401CS235)" assignment, where you will come
up with some example objects.
Example software:
1. A Door Dash style food delivery app where a Customer can place an Order for some Food items from a Restaraunt, a Driver might pick up the
items.
2. A Social Media style app where Users can make friends, create Posts, and mark Posts as favorites.
3. A Class Learning Management System where Teachers and Students can access a course, Assignments can be created/accessed, Grades can be
saved.
You can come up with your own example program to post about as well.
📖️
Reading - CS 200 review: Basics (U02.READ)
Make sure to also view the "C++ Quick Reference" part of this textbook for a reference guide on basic C++ syntax.
Includes
Include Features
#include <iostream> Use of cout (console output), cin (console input), getline
#include <string> Use of the string data type and its functions
#include <fstream> Use of ofstream (output file stream), ifstream (input file stream), and related functions
#include <array> Use of array from the Standard Template Library
#include <vector> Use of vector from the Standard Template Library
#include <cstdlib> C standard libraries, usually used for rand() .
#include <ctime> C time libraries, usually used for srand( time( NULL ) ); to seed random # generator
#include <cmath> C math libraries, such as sqrt , trig functions, etc.
#include "file.h Use "" to include .h files within your own project. DON'T USE INCLUDE ON .cpp FILES!!
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The using namespace std; command states that we're using the std namespace. If this is left off, then we need to prefix any C++
types and functions with std:: , such as std::cout << "Hello!" << std::endl;
Best practices:
If your program ONLY uses C++ standard library includes, use using namespace std; for brevity.
If your program uses MULTIPLE LIBRARIES, avoid using namespace std; and prefix each type/function with the library it
belongs to (e.g., std::string from the STD library, sf::vector2f from the SFML library)
Without arguments:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello, world!" << endl;
return 0;
}
With arguments:
#include <string>
#include <iostream>
using namespace std;
return 0;
}
(There's a different command to use the Visual Studio compiler to build from command line.)
./PROGRAMNAME.out
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Running a program with arguments:
Variable declaration
1. Declaring a variable: DATATYPE VARIABLENAME;
2. Declaring a variable and assigning a value: DATATYPE VARIABLENAME = VALUE;
3. Declaring and assigning a named constant: const DATATYPE NAME = VALUE;
4. Assigning a new value to an existing variable: VARIABLENAME = VALUE;
5. Copying a value from one variable to another: UPDATEDVAR = COPYME;
Increment/Decrement statements:
a++ , a--
++a , --a
a+=5; , a-=5;
a = a + 5; , a = a - 5;
Notes:
LHS = RHS; copies FROM RHS TO LHS ; make sure you have the right order!
A hard-coded value, like "Hello" , is known as a literal.
Notes:
The << operator is called the output stream operator and is used on cout statements.
The >> operator is called the input stream operator and is used on cin statements.
endl is only to be used with cout statements, not cin !
getline can only be used with strings!! Use cin >> for other data types.
You need a cin.ignore() ONLY in between cin >> ... and getline( cin, ... ) .
If your program is skipping an input then you're missing a cin.ignore(); .
If your program is getting input but not storing the first letter then you have too many cin.ignore(); statements / they're in the
wrong place.
Boolean expressions
AND ( && )
Expression is TRUE if all sub-expressions are TRUE
Expression is FALSE if at least one sub-expression is FALSE
OR ( || )
Expression is TRUE if at least one sub-expression is TRUE
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Expression is FALSE if all sub-expressions are FALSE
NOT ( ! )
Expression is TRUE if sub-expression is FALSE
Expression is FALSE if sub-expression is TRUE
a b a AND b a OR b
T T T T
T F F T
F T F T
F F F F
a NOT a
T F
F T
If statements
if statement:
if ( CONDITION_A )
{
// Action A
}
if/else statement:
if ( CONDITION_A )
{
// Action A
}
else
{
// Action Z
}
if/else if statement:
if ( CONDITION_A )
{
// Action A
}
else if ( CONDITION_B )
{
// Action B
}
else if ( CONDITION_C )
{
// Action C
}
if ( CONDITION_A )
{
// Action A
}
else if ( CONDITION_B )
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
{
// Action B
}
else if ( CONDITION_C )
{
// Action C
}
else
{
// Action Z
}
Or a boolean expression:
int a = 10, b = 5;
if ( a > b )
{
cout << "a is bigger!" << endl;
}
Notes:
Switch statements
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;
}
Notes:
You can leave off break; from a case statement. In this case, fallthrough occurs, where the following case's code will be executed, up until it
hits a break; statement.
Switch statements like the one above can be replaced with if (myNumber = 1)=, else if (myNumber = 2)=.
In C++, switch doesn't work with string , only primitive data types like int , float , char .
Fallthrough example:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
char choice;
cout << "Enter a choice: (y/n): ";
cin >> choice;
switch( choice )
{
case 'y':
case 'Y':
cout << "YES" << endl;
break;
case 'n':
case 'N':
cout << "NO" << endl;
break;
default:
cout << "INVALID INPUT!" << endl;
}
While loops
while ( CONDITION ) { }
while ( a < b )
{
cout << a << endl;
a++;
}
Notes:
For loops
Notes:
When using STL arrays or vectors, size_t or unsigned int should be used instead of int for i . This will remove the warning relating
to testing .size() (which returns size_t ) against a signed integer.
In versions of C++ past C++98 (from 1998) you can use range-based for loops to iterate over a range of items:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
vector<int> myVec = { 1, 2, 3, 4 };
for ( int element : myVec )
{
cout << element << endl;
}
Notes:
// C-style array:
for ( int i = 0; i < TOTAL_STUDENTS; 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 I/O
ofstream output;
output.open( "file.txt" );
ifstream input;
input.open( "file.txt" );
if ( input.fail() )
{
cout << "ERROR: could not load file.txt!" << endl;
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
string buffer;
// read a word
input >> buffer;
// read a line
getline( input, buffer );
Notes:
An ifstream open will fail if the file requested does not exist or cannot be found. Use if ( input.fail() ) to check for a failure
scenario.
An ofstream open will create a file if it doesn't already exist.
The default path where files are written to or read from is wherever your project file is (.vcxproj for Visual Studio, .cbp for Code::Blocks). You
can also set a default working directory in your project settings.
Mac users may need to specify an absolute path, like " ~/myfile.txt" , which will put the file in your home directory. I don't know
how to use XCode but we can work through it together if you need help.
Review questions:
Answer these questions in your notes, then check your work by completing the related Concept Intro assignment on Canvas.
Goals:
Turn-in:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
First, Open up Git Bash (Windows) or your Terminal (Linux/Mac) from within your repository directory. Make sure you're inside the repository
folder, which should be named something like YOURSSO-CLASS .
Next, create a new branch in the repository with the checkout command: git checkout -b u02_review
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Now your folder is on the new branch and you can start working on the assignment.
Download the following starter code and unzip it to your repository folder.
shared/labs/starter-code/u02_Review_CPPBasics.zip
.
├── INFO.h
├── main.cpp
├── Project_CodeBlocks
│ ├── CPPReviewBasics.cbp
│ ├── CPPReviewBasics.depend
│ └── CPPReviewBasics.layout
├── Project_Makefile
│ └── Makefile
├── Project_VisualStudio
│ ├── CPPBasicsReview.sln
│ ├── CPPBasicsReview.vcxproj
│ ├── CPPBasicsReview.vcxproj.filters
│ ├── results.txt
│ ├── test1.txt
│ └── test2.txt
└── u02_Review_CPPBasics
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
├── P1_variables
│ └── U02_P1_PizzaSlices.cpp
├── P2_branching
│ └── U02_P2_LetterGrade.cpp
├── P3_looping
│ └── U02_P3_SalaryRaise.cpp
├── P4_vector
│ └── U02_P4_GPA.cpp
├── P5_ofstream
│ └── U02_P5_SalaryRaise.cpp
├── P6_ifstream
│ ├── lyricsB.txt
│ └── U02_P6_Lyrics.cpp
├── U02_Headers.cpp
└── U02_Headers.h
Open the Project_VisualStudio folder and open the CPPBasicsReview.sln file to get started.
Code::Blocks users:
Open the Project_CodeBlocks folder and open the CPPReviewBasics.cbp file to get started.
In the Project_Makefile directory you'll find a makefile you can use to build the project. Use the command make in the directory, and it will
generate an executable file that you can run like this: ./CPPReviewBasics_out
(These are not steps to do yet, just background information on the program. Instructions continue below.)
Once you run the program, you will see two options: Run the AUTOMATED TESTS or run the PROGRAMS manually.
You can use the AUTOMATED TESTS to verify your work. Tests will either be marked as PASS or FAIL, and show the input passed in and the
expected result:
You can also MANUALLY RUN THE PROGRAMS to test them yourself:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Program 1: Pizza slices
Program 2: Letter grade
Program 3: Salary raise v1
Program 4: GPA
Program 5: Salary raise v2
Program 6: Lyrics
Run program #: 4
Enter another letter grade (A, B, C, D, F) or X to stop: A
Enter another letter grade (A, B, C, D, F) or X to stop: B
Enter another letter grade (A, B, C, D, F) or X to stop: C
Enter another letter grade (A, B, C, D, F) or X to stop: X
Your GPA is: 3
To begin with, the functionality won't work properly - you will need to implement the functions themselves. We will step through that in a moment.
File: INFO.h
This file contains a string constant. Replace "Your Name" with your actual name. This is to help me with grading.
As you work through the coding assignments, if you have any questions or get stuck, feel free to ask for hints from the instructor.
File: U02_P1_PizzaSlices.cpp
You will be editing the function int U02_Program1_Function( int guest_count, int pizza_slices ) for this program.
Input parameters:
1. guest_count , the amount of guests attending the party
2. pizza_slices , the total amount of pizza slices at the party
Return output: The amount of slices of pizza each guest gets
Requirements: In this function, calculate the slices per person. You can add cout statements to display each piece of information, or you can
also just do the calculation and return it at the end.
Math: Given s total slices and g total guests, slices per person p is
s
p =
g
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
File: U02_P2_LetterGrade.cpp
GRADE INFORMATION
My score ......... 75
Points possible ...65
Grade % ...........115.385
Letter grade ......A
You will be editing the function char U02_Program2_Function( float points_possible, float my_score ) for this program.
Input parameters:
1. points_possible , the amount of total points an assignment is worth
2. my_score , the amount of points the student earned on the assignment
Return output: The letter grade they received on the assignment
Requirements: Calculate the percent result the student earned on the assignment
Math: Given p points possible and s score earned, the percentage grade the student earned g is:
s
g = ⋅ 100
p
Letter grade: Use the following criteria to decide which grade the student receives.
Letter Range
'A' 89.5% and above
'B' 79.5% - 89.5%
'C' 69.5% - 79.5%
'D' 59.5% - 69.5%
'F' Below 59.5%
File: U02_P3_SalaryRaise.cpp
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
You will be editing the function float U02_Program3_Function( float starting_salary, float raise_per_year, int
years ) for this program.
Input parameters:
1. starting_salary , the salary the user starts out with
2. raise_per_year the decimal value of the raise per year (e.g., 0.05 instead of 5%)
3. years , how many years of raises they want to calculate
Return output: The salary after years amount of years.
Requirements: Use a loop to calculate and display the updated salary each year.
Math: Given the last year's salary s and the decimal raise per year d, the updated salary for the year u is:
u = s + sd
File: U02_P4_GPA.cpp
You will be editing the function float U02_Program4_Function( std::vector<char> course_grades ) for this program.
Input parameters:
1. course_grades , a vector of letter grades
Return output: The GPA the student received
Requirements: Calculate the decimal equivalent of each letter grade, then use that to calculate the GPA.
Math: Given n total decimal scores s , s , …, s , the GPA is:
1 2 n
s 1 + s 2 +. . . +s n
File: U02_P5_SalaryRaise.cpp
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Year: 2, Salary: $44100
Year: 3, Salary: $46305
Year: 4, Salary: $48620.2
Year: 5, Salary: $51051.3
You will be editing the function float U02_Program5_Function( float starting_salary, float raise_per_year, int
years ) for this program.
Input parameters:
1. starting_salary , the salary the user starts out with
2. raise_per_year the decimal value of the raise per year (e.g., 0.05 instead of 5%)
3. years , how many years of raises they want to calculate
Return output: The salary after years amount of years.
Requirements: Besides calculating the updated salary, create an ofstream output file and store the following data to the text file:
The starting salary
In the loop, each year and the updated salary.
File: U02_P6_Lyrics.cpp
You will be editing the function std::string U02_Program6_Function( std::string filename, int line_number ) for this
program.
Input parameters:
1. filename , the file of lyrics to open
2. line_number , which line # of the song to display
Return output: The lyric at the given line_number
Requirements: Use an ifstream object to open the filename given. Read each line of the input file until you hit the correct line number,
return the string read in at that line number.
Error check: If opening the file fails, then display an error message and return an empty string, "" .
Default: If the loop completes and we haven't hit the line_number requested (i.e., the file is fewer than that many lines), then return
an empty string. "" .
You can read one line of the file at a time with the getline function:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Once you're done with the assignment, you need to add, commit, and push your changes to the server.
1. Open git bash from within your repository folder on your harddrive.
2. Use git status to review what files have changed since your last commit.
3. Use git add . to add all changed files to a changeset.
4. Use git commit -m "MESSAGE" to create a snapshot of your current changes. (Replace "MESSAGE" with something more descriptive.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
5. Use git push -u origin u02_review to push all your commits to the GitLab server, on the u02_review branch.
You can continue making changes and do additional add , commit , and push commands as well.
1. Use git checkout main to change back to the main branch to prepare for the next assignment. (You can always use git checkout
u02_review to return to this branch and code.)
2. Use git pull to pull latest from the server. (This might happen if the instructor adds new starter code or makes modifications.)
After pushing your changes to your branch, the GitLab webpage will show an update:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Give your Merge Request a descriptive name, such as the unit the assignment belongs to.
At the bottom of the page, click on the blue "Create merge request" button.
Your merge request will now be created. You don't need to do anything further on this page.
Approve button: The instructor may mark the merge request as approved.
Merge button: You won't be able to press the Merge button; the instructor will merge the code once they've reviewed your work and approved
it.
Once you've created a merge request, copy the URL of the merge request on the GitLab.com webpage:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Back on the Canvas page, locate the assignment and click the link:
Paste in the URL to your Merge Request in the "Website URL:" textbox, then click "Submit Assignment" to finish the turn in.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
🧠 Tech Literacy - Command Line programs (U02.TEC)
A brief history of interfacing with computers
Early computers were a shared resource, with one mainframe computer shared by many people at a university, business, or elseware. People often
wrote programs on paper punchcards using dedicated hardware separate from the computer itself. (See: 1964 IBM 029 Keypunch Card Punching
Demonstration (CuriousMarc))
Similarly, early computers didn't necessarily utilize video screens or monitors for output. Since the computer was shared, you might drop off your
batch of cards for your program and come back later for the result output. If you think about it, a paper-based printout was probably the most cost-
effective way for this. (See: YouTube: The IBM 1401 Mainframe Computer Wishes you a Merry Christmas (CuriousMarc) - Feeding a mainframe
punchcards and getting printed output)
Even when video monitors were available for these mainframe computers, the computers were still a shared resource being used by multiple people
sharing computer time. In cases like these, users would work at a terminal. These look like what we think of as computers, with a video display and a
keyboard, but they don't do any processing on their own. These terminals were connected to the mainframe computer, allowing users in other locations
to interact with it via a simple text interface.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Figure 4: By IBM - https://digitaltmuseum.no/011015240147/22-0-ibm-modell-360-370, CC BY-SA 4.0,
https://commons.wikimedia.org/w/index.php?curid=113477774
Even as Personal Computers began taking root in households in the 1980s, only rudimentary graphics were available (if any), such as drawing large
blocks with some basic colors, or drawing pixels at specific positions on a low resolution screen. For daily use, typed commands were still largely
how people interacted with the operating system of their computer, and for many of their programs as well.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Figure 5: A photo of a Vic-20 BASIC program displayed on a CRT television.
If a program did offer some kind of graphical user interface, at the time there were no standards and programs by different developers would often
have wildly different interfaces, keyboard shortcuts, and styles.
Who uses command line programs these days?
In a way, there are still challenges around different types of interfaces. We have computers running different operating systems like Windows, Mac
OS, Linux, and Unix, we have smartphones running their own operating systems as well. Beyond that, people might install different types of software
or configure their personal computers differently. Under the surface, however, there is still some form of command line, though the commands may
differ between a Windows PowerShell and a Linux/UNIX Bash system. So, what do these non-GUIs offer in utility?
Consistency
Sometimes I try to help out a person on a Mac computer, though I have almost no experience with that operating system. Often, I find it more
comfortable to navigate through the Mac Terminal to utilize the UNIX-like commands that are in common with Linux - such as ls to list files
and folders in a directory. Rather than have to learn a GUI for a system I'll never use on my own, I can interact with it with a "common tongue"
- the command line. :)
Scriptability
Think of the effort it takes to automate doing anything with a GUI - you'll need some kind of program or library that allows moving the mouse
to some (x,y) position, hit mouse clicks, type keys, etc. And even then, windows in a GUI might move around. It's much easier to write a
program script to automate running commands from a command line instead - it's just text commands!
Speed
Command lines generally can be more responsive than a GUI. I find that even on computers that aren't too old, Windows slogs along. Command
lines don't necessarily use your computer's graphics card to make the windows semi-transparent and animate when they perform some
operation. And in some cases it can be faster to type something like mkdir cs200 cs235 cs250 to create three folders than to go through
the steps to move mouse to "File", move mouse to "New Folder", click, type "cs200", repeat twice more.
Portability
Being able to navigate a command line also makes it much easier to access remote computers. While you can run a computer remotely and work
with the graphical operating system, it's still usually pretty sluggish. Instead, you could SSH into a computer and work with it from the
command line and quickly perform some operations that you need, which could be remotely launching a build, restarting a server, or even
writing some notes.
Most average computer users aren't using the command line in their personal lives, but it is still a hugely useful tool for people who work in IT and
software. With IT, imagine you have to configure 20 computers per classroom, for all the classrooms in a building - would it be easier to manually go
configure those computers from their GUIs, or to write a script and run that script on each computer?
If you're on Windows open up the PowerShell. If you're on Mac open up the Terminal. If you're on Linux open up your favorite Terminal emulator
or whatever. :) Let's look at some basic programs that might be useful.
ping URL - The ping program allows us to send multiple packets to some URL. I usually just use this to see if my internet has gone down
or if a site is just down. I still, by habit, use ping yahoo.com even though I haven't used Yahoo in years. (FYI: Use CTRL+C to end a
command line program if it continues looping.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
rachelwil@rachelwil-GF63-Thin-9SC:~$ ping yahoo.com
PING yahoo.com (98.137.11.163) 56(84) bytes of data.
64 bytes from media-router-fp74.prod.media.vip.gq1.yahoo.com (98.137.11.163
64 bytes from media-router-fp74.prod.media.vip.gq1.yahoo.com (98.137.11.163
64 bytes from media-router-fp74.prod.media.vip.gq1.yahoo.com (98.137.11.163
64 bytes from media-router-fp74.prod.media.vip.gq1.yahoo.com (98.137.11.163
^C
--- yahoo.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
mkdir FOLDER1 FOLDER2 FOLDER3 - The mkdir (make-directory) program allows you to create 1 or more folders within the directory
that you're currently in.
ls - The ls (list) program shows you all the files and folders in the directory that you're currently in.
pwd - The pwd (present working directory) program shows you the path of the directory that you're currently in.
rachelwil@rachelwil-GF63-Thin-9SC:~/test-folder$ ls
folderA folderB folderC
rachelwil@rachelwil-GF63-Thin-9SC:~/test-folder$ pwd
/home/rachelwil/test-folder
Commands that you can use from the terminal can also be called from C++ by using the system() function.
See also
YouTube: Tomorrow's World: Home Computer Terminal 20 September 1967 (BBC) - Using a teletype terminal to communicate with a remote
computer
YouTube: What are Dumb Terminals? (The 8-Bit Guy)
WEEK 2 - JAN 22
UNIT 03: CS 200 Review - Functions and classes
📊 Presentation - CS 200 Review - Functions and classes (U03.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235cs250-unit03-cs200review_classes.html
📖️
Reading - CS 200 Review - Functions and classes (U03.READ)
Make sure to also view the "C++ Quick Reference" part of this textbook for a reference guide on basic C++ syntax.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Functions
Function headers
The return type is the type of data returned (like an int ), or void for functions that don't need to return any data.
The function name follows the same naming rules as a variable - letters, numbers, and underscores allowed, no spaces or other special
characters.
The parameter list is a series of variable declarations to be used within the function. These parameters are assigned values during the
function call, when arguments are provided.
Function declarations
Function declarations should go in .h files. A function declaration is the function header, with a semicolon at the end:
Function definitions
Function definitions should go in .cpp files. A function definition is the function header, plus a code block, starting and ending with curly braces
{} :
void DisplayMenu()
{
cout << "1. Add items" << endl;
cout << "2. Subtract items" << endl;
cout << "3. Quit" << endl;
}
Function calls
Function calls will happen within other functions. A function call includes the function's name, input arguments to be passed in, and the return
data will need to be stored in a variable, if applicable.
int main()
{
DisplayMenu(); // Function call
int choice;
cin >> choice;
if ( choice == 1 )
{
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
int num1, num2, result;
cout << "Enter num1: ";
cin >> num1;
cout << "Enter num2: ";
cin >> num2;
return 0;
}
Header files
Header files must have file guards, this prevents the .h file from being "copied" into multiple files, which will cause a "duplicate code" build
error.
#ifndef _FILENAME_H
#define _FILENAME_H
#endif
For the file guard, a label like _FILENAME_H is used. This must be unique for each file!
Visual Studio supports using #pragma once for .h files, but this is not cross platform, so you should use these preprocessor file guards!
Source files
Any file that utilizes your function must include the .h file:
#include "MyFunctions.h"
Note that something like #include <iostream> is used for including libraries that are not inside the project. Using "" is for including
files that are in your project.
Function overloading
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Multiple functions can have the same name as long as their function signatures are different. This means that two functions with the same name
either need a different number of parameters, or different parameter data types, so that they can be unambiguously identified.
AMBIGUOUS:
UNAMBIGUOUS:
We can specify accessibility levels for struct and class members. This information dictates where a struct/class' internal contents can be accessed
from:
Structs are usually used to store very basic structures, often with just variable data and no functions.
struct Coordinate
{
float x, y;
};
Struct declarations should go in their own .h file, usually the filename will match the name of the class, such as "Coordinate.h".
Also note that at the closing curly brace } of the struct declaration there is a semicolon - this is required!
Classes
class CLASSNAME
{
public:
// Public members
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
protected:
// Protected members
private:
// Private members
};
Class declarations should go in their own .h file, and class function definitions should go in a corresponding .cpp file!
It is best practice to make member variables of a class private , and only provide indirect access to this data via functions.
Example: Product.h
#include <string>
using namespace std;
class Product
{
public:
// Constructors:
Product();
Product( string newName, float newPrice );
// Destructor:
~Product();
// Setters:
void SetName( string newName );
void SetPrice( float newPrice );
// Getters:
string GetName() const;
float GetPrice() const;
private:
string m_name;
float m_price;
}
#endif
Example: Product.cpp
#include "Product.h"
// Constructors:
Product::Product()
{
m_name = "unset";
m_price = 0;
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
// Destructor:
Product::~Product()
{
cout << "Bye." << endl;
}
// Setters:
void Product::SetName( string newName )
{
m_name = newName;
}
// Getters:
string Product::GetName() const
{
return m_name;
}
Accessor/Getter functions:
Mutator/Setter functions:
Constructor functions:
Destructor functions:
Once we've declared a class we can then declare variables whose data types are that class:
PlayerCharacter bario;
NonPlayerCharacter boomba;
In this example, bario is a PlayerCharacter object, aka an "instantiation of the PlayerCharacter object".
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Class inheritance
A class (called a subclass or a child class) can inherit from another class (called a superclass or a parent class). Doing this means that any
protected and public members are inherited by the child class. This can be useful for creating more "specialized" versions of something,
storing the shared attributes of a set of items in a common "parent" class.
Example:
class Character
{
void SetPosition( float x, float y );
void Move( float xAmount, float yAmount );
protected:
float x, y;
};
private:
int totalLives;
};
private:
bool attackPlayer;
};
Class composition
Class composition is where a class contains class objects as member variables. This is another form of object oriented design where a class
might "contain" traits that could be inherited, but instead encapsulates them into a sub-object.
Example:
class MovableObject
{
void SetPosition( float x, float y );
void Move( float xAmount, float yAmount );
private:
float x, y;
};
class PlayerCharacter
{
public:
void GetKeyboardInput();
private:
int totalLives;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
MovableObject mover;
};
Review questions:
int Pet::XYZ()
{
return m_age;
}
10. This kind of class function will be called automatically when an object of that class type is instantiated…
11. This kind of class function will be called automatically when an object of that class type is destroyed…
After reading, do the quiz to check your notes: 🔎 Unit 03 Concept Intro - CS 200 review: Functions and classes (U03.CIN)
Goals:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Turn-in:
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
First, Open up Git Bash (Windows) or your Terminal (Linux/Mac) from within your repository directory. Make sure you're inside the repository
folder, which should be named something like YOURSSO-CLASS .
Next, create a new branch in the repository with the checkout command: git checkout -b u03_review
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Now your folder is on the new branch and you can start working on the assignment.
Download the following starter code and unzip it to your repository folder.
shared/labs/starter-code/u03_Review_FuncClass.zip
.
├── INFO.h
├── main.cpp
├── Project_CodeBlocks
│ ├── FunctionsClasses.cbp
│ ├── FunctionsClasses.depend
│ └── FunctionsClasses.layout
├── Project_Makefile
│ └── Makefile
├── Project_VisualStudio
│ ├── FunctionsAndClasses.sln
│ ├── FunctionsAndClasses.vcxproj
│ └── FunctionsAndClasses.vcxproj.filters
├── u03_Review_FuncClass
│ ├── P1_functions
│ │ └── U03_P1_Sale.cpp
│ ├── P2_struct
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
│ │ └── U03_P2_Room.cpp
│ ├── P3_class
│ │ └── U03_P3_Employee.cpp
│ ├── U03_Headers.cpp
│ └── U03_Headers.h
└── Utilities
├── Colors.hpp
├── Helper.cpp
└── Helper.hpp
Open the Project_VisualStudio folder and open the FunctionsAndClasses.sln file to get started.
Code::Blocks users:
Open the Project_CodeBlocks folder and open the FunctionsClasses.cbp file to get started.
In the Project_Makefile directory you'll find a makefile you can use to build the project. Use the command make in the directory, and it will
generate an executable file that you can run like this: ./CPPReviewClasses_out
Once you run the program, you will see two options: Run the AUTOMATED TESTS or run the PROGRAMS manually.
You can use the AUTOMATED TESTS to verify your work. Tests will either be marked as PASS or FAIL.
Note that the first "automated" test in the set requires user input once the program is implemented. The test text will describe what inputs it
is expecting, the user can set those prices, and then use checkout to finish the test.
You can also MANUALLY RUN THE PROGRAMS to test them yourself:
EMPLOYEE LOOKUP
INDEX ID NAME WAGE
---------------------------------------------------------------------------
0 123 Ochoa 16.65
1 234 Bakalar 16.65
2 353 Grubb 16.65
To begin with, the functionality won't work properly - you will need to implement the functions themselves. We will step through that in a moment.
File: INFO.h
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This file contains a string constant. Replace "Your Name" with your actual name. This is to help me with grading.
As you work through the coding assignments, if you have any questions or get stuck, feel free to ask for hints from the instructor.
File: U03_P1_Sale.cpp
########################################
MAIN MENU
########################################
RECEIPT
The U03_P1_Sale.cpp file contains several functions that you'll implement for this program.
void DisplayMenu()
This function is responsible for showing the numbered menu, with 1 for "Add item" and 2 for "Checkout".
This function does not get any input! Just use cout statements here.
This function takes in the price and formats it as USD. You can set up the precision like this first: std::cout << std::fixed <<
std::setprecision( 2 );
Afterwards, use cout to display "$" and then the price .
float GetTaxPercent()
This function only returns the tax percent. Return a value of 9.61 .
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Math: Given original price o and tax percent t, the new price p is: p = o + (o ⋅ t)
float GetNewPrice()
This function needs to ask theuser to enter the price of a new item. Use cout and cin statements here, and return the new price they entered
afterwards.
This function should ask the user to enter a number between min and max .
Get the user's input, then use a while loop to check for invalid input: While input is invalid, display an error and have the user enter their
choice again.
Input is invalid if user_choice < min OR user_choice > max .
After the while loop we know the user's input is valid, so we return that value.
float SaleProgram()
Note that your program output does not need to perfectly match mine. The important thing is the correct information, and readability.
########################################
MAIN MENU
########################################
RECEIPT
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The "automated tests" for this one will require that you manually input information. It will tell you what inputs it is expecting, and then tell you if it
passes or not.
Enter prices: 2.25, 4.00, 5.30 <<<<<<<<< This tells you what to ente
Expected output: 12.66
File: U03_P2_Room.cpp
ROOM BUILDER
Enter room length: 15
Enter room width: 20
RESULT:
* width: 20
* length: 15
* area: 300
* perimeter: 70
struct Room
{
float width;
float length;
float area;
float perimeter;
};
In this function, set the newRoom 's member variables, utilizing the input parameters.
Make sure the newRoom is being returned at the end of the function.
void U03_Program2_Program()
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In this function ask the user to enter a room length and a room width. Store their inputs in float variables. Call the BuildRoom function, passing in
the data, and storing the returned result in a new Room variable. Finally, use cout to display all of the Room's information.
File: U03_P3_Employee.cpp
EMPLOYEE LOOKUP
INDEX ID NAME WAGE
---------------------------------------------------------------------------
0 123 Ochoa 16.65
1 234 Bakalar 16.65
2 353 Grubb 16.65
This program has a list of employees, each with an employee_id , name , and hourly_wage . The user can enter in an employee_id in this
program, and the associated array index will be returned.
Within the file is a class Employee declaration and empty member functions. You will implement these and the basic GetEmployeeIndex
search function.
Note: I have all the class functions declared here inside the class declaration, for program simplicity. When implementing class functions, generally
the class declaration goes in a .h file and the function definitions go in a .cpp file, and look like int Employee::GetId() const .
This is the constructor function for the Employee class. Within this function, initialize each of the private member variables ( employee_id ,
name , hourly_wage ) to the values passed in as input parameters ( new_id , etc.)
Within this function return the value of the private member variable, employee_id .
Note that this function is const , which means that changes to member variables are not permitted within.
Within this function return the value of the private member variable, name .
Within this function return the value of the private member variable, hourly_wage .
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
int GetEmployeeIndex( std::vector<Employee> employee_list, int lookup_id )
std::vector<Employee> employee_list Input parameter The list of all employees to search through
int lookup_id Input parameter The employee ID of the person we're looking for
int Return output The associated index of the employee with the matching ID.
Within this function use a for loop to iterate over all the elements of the employee_list , using the index as the looping variable. Within the
loop:
If the employee at this index's ID matches the lookup_id , then return the current index.
At the end of the function, after the for loop, if nothing has been returned yet that means there's no matches - return a -1 here.
To access a certain element of the array: employee_list[index] , then you can also call its functions: employee_list[index].GetId()
Once you're done with the assignment, you need to add, commit, and push your changes to the server.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
1. Open git bash from within your repository folder on your harddrive.
2. Use git status to review what files have changed since your last commit.
4. Use git commit -m "MESSAGE" to create a snapshot of your current changes. (Replace "MESSAGE" with something more descriptive.)
5. Use git push -u origin u03_review to push all your commits to the GitLab server, on the u03_review branch.
You can continue making changes and do additional add , commit , and push commands as well.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
1. Use git checkout main to change back to the main branch to prepare for the next assignment. (You can always use git checkout
u03_review to return to this branch and code.)
2. Use git pull to pull latest from the server. (This might happen if the instructor adds new starter code or makes modifications.)
After pushing your changes to your branch, the GitLab webpage will show an update:
Give your Merge Request a descriptive name, such as the unit the assignment belongs to.
At the bottom of the page, click on the blue "Create merge request" button.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Your merge request will now be created. You don't need to do anything further on this page.
Approve button: The instructor may mark the merge request as approved.
Merge button: You won't be able to press the Merge button; the instructor will merge the code once they've reviewed your work and approved
it.
Once you've created a merge request, copy the URL of the merge request on the GitLab.com webpage:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Back on the Canvas page, locate the assignment and click the link:
Paste in the URL to your Merge Request in the "Website URL:" textbox, then click "Submit Assignment" to finish the turn in.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
"What happens if I make mistakes?"
If you make mistakes, I will be able to mark certain lines of code in the merge request and add a comment as to what isn't correct, similar to how your
coworkers would also review your code on the job.
After receiving feedback, you can go back and make updates to your code and resubmit it. You will need to do the following:
1. Check out the branch you made the changes on: git checkout BRANCHNAME
2. Make the fixes to the code.
3. Make a new add/commit/push:
1. git add .
2. git commit -m "MESSAGE"
3. git push -u origin BRANCHNAME
4. The merge request automatically gets updated; re-submit the merge request link in Canvas to mark it as ready to be re-graded.
1. It's important to know what I'm talking about when I use certain terms. Please identify what each of these pieces of code are called. Identify
whether each of the following is a function declaration, function definition, or a function call.
void DisplayMenu()
{
cout << "1. Save" << endl;
cout << "2. Load" << endl;
}
DisplayMenu();
void DisplayMenu();
When trying to build the program, we get compile errors: expected primary-expression before 'int'. It points to the " int
result = Sum( int num1, int num2 ); " line. The error isn't very descriptive, but it's complaining about an "int" keyword. What is
the error with the highlighted line of code?
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
return a + b;
}
And is used elseware in the program. But when building, we get an error: error: call of overloaded ‘Sum(int&, float&)’
is ambiguous| What is causing this error to occur?
#include <iostream>
using namespace std;
struct Vector
{
float x, y;
}
int main()
{
Vector my_vec;
return 0;
}
But even at this early point, there is a build error: error: expected ‘;’ after struct definition| What is the cause of this
build error?
class Student
{
public:
void Setup( string newName );
private:
string m_name;
};
However, a build error occurs: In function ‘void Setup(std::string)’:| error: ‘m_name’ was not declared in
this scope; did you mean ‘tzname’?| Ignore the "tzname" part of the error message, it doesn't help us. There is something
missing from the code which is causing this build error. What is it?
📖️
Reading - Debugging and testing (U04.READ.202401CS250)
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 validate
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.
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.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Test case Input(s) Expected output Actual output
1 balance = 100, withdraw = 10 balance is now 90 (enter after testing)
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. 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.)
Companies that write big software products will often have multiple types of testing that they do to ensure the validity of their software.
QA (Quality Assurance) people generally will be responsible for writing test cases and running through *manual tests to validate the
software works as intended. They might also write test scripts that automate going through the UI of the software, or automate other parts of
testing.
Software Engineers will regularly need to be able to write unit tests along with whatever features they're working on in order to validate that
their new feature works as intended and they will run older unit tests to ensure that their new feature doesn't break anything already there.
Testing is an important part of software development and, from a student perspective, it is also a handy tool in ensuring that your programming
projects work as intended before turning them in.
Designing tests
Test cases
When writing out test cases, it's important to try to think of valid inputs and invalid inputs that could be entered in, and account for how the
program will respond to that input.
By comparing the expected result with the actual result, you can validate whether your program is working as intended. If they match - the
test passes. If they don't match - the test failed.
If a test fails, you can investigate the expected output and the actual output to help you get an idea of perhaps where it went wrong - perhaps a
formula is wrong somewhere.
Example: Calculate price plus tax When ringing up a product at a store, there will be a price for that product and a sales tax that gets added
onto it. Using a test case can help us make sure that the program's calculations are correct.
Let's say that the programmer implemented the formula like this: total = price + tax
We could validate the program's actual output vs. the expected output, and see that there's an error.
What is the problem with the formula? Well, we don't just add tax as a flat number; "0.09" is supposed to represent 9%, not 9 cents!
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The correct formula would be: total = price + (price * tax)
Manual testing
You can manually test your program effectively by documenting your test cases and running through each of them each time you decide to test
your program. Of course it can take a while, but by using your test cases instead of entering in gibberish or only testing one scenario, you make
sure your program works, even as you keep adding onto it.
Our test cases can be a handy roadmap to follow when running through your program's various features and validating it all works manually, but
you can speed up the process by letting the computer do these checks for you.
After all, when you manually validate outputs yourself, you're basically asking yourself,
"If the actual output DOES NOT match the expected output, then the test failed."
A test that only validates one function is known as a unit test, testing the smallest possible unit of a program. You could also write automated
tests that checks several functions, but unit tests are good to validate each function on its own, independently of the rest.
I was told this at a job interview once. I didn't take the job.
At companies that maintain tests, the software engineers will usually write unit tests to validate their work as they're adding in new
functionality or making modifications to the existing code.
This means that ideally each feature of the program has one or more test to validate that it works.
This also means that, when adding or modifying features, you can run the entire test suite to make sure that all features still work.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Many software companies have something called Continuous Integration (CI), which is an automated system that kicks off a build of
the software and runs all the tests each time a developer commits code to the repository.
Example: Area function Let's say we have a function with the header
and we don't necessarily know what's in it (we don't need that to test). We can write a series of test cases with inputs we specify and
outputs we know to be correct in order to check the logic of the Area function…
…and so on.
We could use this to manually test by calling Area and checking the output it gives you, but you could also write a function to validate
it for us…
Here's some example code of a function that tests Area() for us.
void Test_Area()
{
// Variables used for each test
int width, length;
int expectedOutput;
int actualOutput;
// Test 1
width = 10;
length = 20;
expectedOutput = 200;
actualOutput = Area( width, length );
if ( actualOutput != expectedOutput ) {
cout << "Test failed!"
<< "\n width: " << width
<< "\n length: " << length
<< "\n expected output: " << expectedOutput
<< "\n actual output: " << actualOutput
<< endl;
}
else {
cout << "Test 1 passed" << endl;
}
}
You can add as many tests as you'd like inside one function, testing different permutations of inputs against outputs to make sure that any
reasonable scenarios are covered. To test, just call the function in your program, and check the output:
Test failed!
width: 10
length: 20
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
expected output: 200
actual output: 30
If the test fails, you can cout your variables' values to help you figure out what might be wrong with the logic.
Other automated tests
(It should be the smallest "unit", if your function is really long you should probably split it up!)
There are other types of automated tests as well, and software tools to help developers create and run those tests.
An integration test is when you test multiple units together. A unit might work fine on its own, but when multiple units are put together,
the resulting system may not work as intended.
(Look up "integration test unit test" online for some good gif examples. :))
Tests can also be written to test user interfaces of a program, running a script to drive the cursor around the screen, or defining text that
should be typed into fields, running through features of the program from the user's perspective, and validating that data updates and is
displayed when some action is performed from the UI.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Utilizing debugging tools are an important part of software development. Especially as you begin working in large codebases on the job, being able to
step through the execution of a program to find variable values, how the program flows, and where exceptions are thrown is something you will have
to do frequently.
The lab contains more of the steps for learning these tools with your IDE, but here is some general information for now.
Breakpoints
A breakpoint can be toggled in your code by clicking to the left of the code screen. The exact placement differs between IDEs, but usually a red circle
pops up once clicked to show that the program execution will stop here once we reach it.
You can set breakpoints in your program at various places to begin stepping through to see where the program goes, if it's "flowing" the way you
expect it to, and to navigate into other function calls as they're hit.
The "next line" or "step over" button will let you move to the next line of code execution. If your pause line is at a function call, it will not enter the
function, and just continue on the next line after the function call is done.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The "step into" button will take you to inside a function if you're currently paused on a line that is a function call.
Watch/Local/Auto window
Watch, Local, and Auto windows do similar things - they all display a variable's name and its current value (while paused in the program execution).
Visual Studio has (and other IDEs may have) an auto view, which shows variables that are around the current statement we're paused on. The locals
view shows variables that are currently in scope. (Information from https://learn.microsoft.com/en-us/visualstudio/debugger/autos-and-locals-
windows?view=vs-2022)
Call stack
The call stack will show you all the functions that have been called, leading up until the point where you are currently paused at. The current function
is listed on the top, with the function immediately below it being the one that made the call to the function you're in. The function listed at the bottom
is the "oldest" function, or the first one called, usually main() .
Review questions:
1. Given some input and expected output defined, a test would pass if…
2. Let's say I've written a program that takes in two numbers as inputs and returns the sum as the output. For our first test case,
let's say the inputs are 2 and 3. What would the expected output be?
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
3. Let's say you need to write a program that will update a person's account balance after they deposit some money. What might
be the input(s) / output(s)?
4. Let's say your program is crashing somewhere. How might setting breakpoints be useful?
int a = 10;
int b = 20;
int result = Sum( a, b ); << Break here
cout << result << endl;
If we hit the step over button, what will the next line the debugger is paused at be?
int a = 10;
int b = 20;
int result = Sum( a, b ); << Break here
cout << result << endl;
If we hit the step into button, what will the next line the debugger is paused at be?
Product::GetPrice()
Store::PurchaseProduct()
Store::MainMenu()
main()
Product::GetPrice()
Store::PurchaseProduct()
Store::MainMenu()
main()
Once the current function returns, which function will then be at the top of the call stack?
After reading, do the quiz to check your notes: 🔎 Unit 04 Concept Intro - Debugging and testing (U04.CIN)
Goals:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Practice writing unit tests
Turn-in:
1. For the DEBUG assignment you'll be creating a text document to log your findings. (You can save it in your repository to
submit via the merge request as well.)
2. You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
Download the following starter code and unzip it to your repository folder.
shared/labs/starter-code/u04_DebuggingAndTesting.zip
.
├── Part1_Debug
│ ├── engine
│ │ ├── Helper.cpp
│ │ ├── Helper.h
│ │ ├── Log.cpp
│ │ ├── Log.h
│ │ ├── PpmImage.cpp
│ │ ├── PpmImage.h
│ │ ├── ScreenDrawer.cpp
│ │ └── ScreenDrawer.h
│ ├── Game.cpp
│ ├── Game.h
│ ├── images
│ │ ├── food.ppm
│ │ ├── kansascity.ppm
│ │ ├── medical.ppm
│ │ ├── olathe.ppm
│ │ ├── overlandpark.ppm
│ │ ├── raytown.ppm
│ │ ├── safehouse.ppm
│ │ ├── scavenger.ppm
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
│ │ ├── zombie1.ppm
│ │ └── zombie2.ppm
│ ├── main.cpp
│ ├── Player.cpp
│ ├── Player.h
│ ├── Project_CodeBlocks
│ │ ├── log.txt
│ │ ├── ZombieApoc.cbp
│ │ ├── ZombieApoc.depend
│ │ └── ZombieApoc.layout
│ ├── Project_Makefile
│ │ └── Makefile
│ └── Project_VisualStudio
│ ├── log.txt
│ ├── ZombieApoc.sln
│ ├── ZombieApoc.vcxproj
│ └── ZombieApoc.vcxproj.filters
└── Part2_Test
├── Functions.cpp
├── Functions.h
├── Project_CodeBlocks
│ ├── WritingTests.cbp
│ ├── WritingTests.depend
│ └── WritingTests.layout
├── Project_Makefile
│ └── Makefile
└── Project_VisualStudio
├── WritingTests.sln
├── WritingTests.vcxproj
└── WritingTests.vcxproj.filters
Please use the provided Visual Studio or Code::Blocks project files, don't make your own!
If you want to build the code from the terminal, go to the Project_Makefile directory and use the command make to generate an out file.
Part 1: Debug
For this assignment you'll run an existing program. You don't need to do any programming - you will be utilizing the debugging
tools of your IDE to answer the questions. You will need to create a text document (a MS Word / LibreOffice Write / Google
Docs document).
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Run the game as-is and play a few rounds of it. You can choose to scavenge in the area you're currently at, or travel to another location. For this
step, you're just getting used to how the game controls.
Task:
1. Set breakpoints at the start of Player::Player() in Player.cpp, and at the start of Game::Game() in
Game.cpp.
2. In the watch window, add the following (for the Player class):
1. food
2. maxHealth
3. health
4. location
3. In the watch windwo, add the following (for the Game class):
1. m_done
2. m_day
Observe the current values of those variables. Refer to the following documentation on the steps to do this.
Video: https://youtu.be/BNaTN9KWmu4
Player::Player()
{
food = 5;
Game::Game()
{
m_day = 1;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
To set a breakpoint, you can locate a line of code and click on a region in your editor next to the line number that will enable a breakpoint.
A breakpoint is a debugging tool that will cause the program execution to pause when that line of code is reached. While the program is
paused, you can investigate values and step through the program flow one line at a time.
Depending on your IDE you might need to click before or after the line number to set the breakpoint. You can also toggle breakpoints
through the menu or keyboard shortcuts:
XCode
Code::Blocks F8
XCode
The program will build (if it hasn't already) and start running the program. When the program starts, it will hit the breakpoint and pause
execution. Go back to your IDE to view where your program has paused.
Opening the variable investigation panes:
At the bottom of your screen should be some debug panels. If they don't show up, you can usually open these under the Debug drop down
menu.
IDE Steps
Visual Studio Debug, Windows, Watch window
Code::Blocks Debug, Debugging wnidows, Watches
XCode View, Debug area, Activate console
Now you should have the watch windows open, which is a table that displays a Name (variable name) column and a Value column.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Enter the names of the variables we want to track:
While the program is still paused, we will use the step features to step through each line of code one at a time and watch the variables as
they're assigned values.
Use the Step Over or Next Line to step down one line at a time until you get to the end of the function. As you go down each line, notice
how the variable value changes in the watch window once its declaration line is finished.
Task: Set a breakpoint at the start of Game::Menu_Scavenge() and then use the Continue button to resume program
execution. (Or if you closed the program, run it again and enter a name.)
Select the "1. Scavenge here" option in the game and make sure the program execution pauses within this function.
void Game::Menu_Scavenge()
{
bool actionSuccessful = true;
int random = rand() % 5;
RandomEvent_Scavenging( random );
}
Use the Stepover/Next line button to move the cursor to the line with RandomEvent_Scavenging( random ); Take note of the value
of the random variable.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
We are now sitting at a function call. We can go into the function call using the Step into option.
int mod;
if ( event == 0 )
{
mod = rand() % 3 + 2;
ScreenDrawer::Set( 3, 4, "You find a stash of food.", "green", "
// ... etc ...
This function takes the event variable and figures out what kind of event to make happen in the game.
Use the Step Over / Next Line button to see which if/else if statement is executed: event = 0=? event = 1=? And so on…
Don't stop the program execution, we are going to keep working with where we've paused.
Another important debugging tool is the Call Stack, which tells you the order of functions called to get to where the program is currently at.
Task: Use the Call Stack to take note of what functions were called leading up to your
Game::RandomEvent_Scavenging breakpoint.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
If the call stack pane isn't showing up, you can open them through the menus:
IDE Menu
Visual Studio Debug, Windows, Call Stack
Code::Blocks Debug, Debugging windows, Call Stack
The top-most function displayed is the one currently running, and all functions below it are functions that were active previously. If you step all
the way down, you can trace all the functions that were called to get to where we're at.
Task: Set a breakpoint in the Game::EndOfDayStats() function and use the Call Stack to take note of what functions
were called leading up to it.
Task: Set a breakpoint in the Player::Player() function (in Player.cpp) and use the Call Stack to take note of what
functions were called leading up to it. You will probably have to close and restart the game to hit this breakpoint.
Debugging tools are extremely helpful and the better you get at utilizing them to diagnose your programs' issues, the more well prepared you
will be for software development in the "real world".
Don’t close the zombie game yet – now we’re going to use various IDE features in this project.
Take a screenshot once you've completed each one and paste it into your document.
In most IDEs you can click-and-drag a code window (via its tab) to another part of the screen, allowing to have a side-by-side view of two (or
more) different code files at once.
Visual Studio:
Click and drag the tab to the center of the screen. Then, a placement box will show up. Drag the tab to one of these 5 options for different views.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Code::Blocks:
Click and drag the tab to an edge of the code window. A slight highlight will appear in the place where it will be placed. Let go of the mouse
button to place the tab to the side.
Go to definition
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Go to the .h file and right-click on one of the functions, then select the Go to definition (VS) or Go to implementation (CB) to go directly to
the definition of that function.
Go to declaration
Right-click on a function call somewhere, and select Go to declaration to go to where the function is declared.
Find references of
Right-click on any function and select Find references of and you will get a search result with every place where the function is used
throughout the program, including function calls.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Indenting/unindenting chunks of code
Highlight a chunk of code and use "tab" to indent it all forward, or "shift+tab" to un-indent it all backward.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Autoformatting
When your indentation gets messed up you can have the IDE automatically format it for you.
IDE Steps
Visual Studio Edit, Advanced, Format Document
Code::Blocks Right-click in the code window, select Format use AStyle
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Highlight a section of code. You can comment out a whole block at once, or uncomment out a block, in the following ways:
Part 3: Test
This program contains four simple functions and four test functions:
We are going to approach this from a Test Driven Development standpoint where we will write our TESTS before implementing the functionality.
This way, we ensure our tests "work" because they first fail - then, when we implement the functionaltiy, the tests passing should be how we verify
our logic is correct.
These functions contain placeholder information being returned. They return data because some C++ compilers will complain if a non-void
function doesn't have a return statement. Before you implement the function itself, we will be implementing the unit tests for each function
first.
Task: Implement void Test_GetArea() and void Test_GetStringLength() first, then implement int
GetArea( int width, int length ) and int GetStringLength( string text );
GetArea
First off we need to come up with test cases - at least two for these simple functions that just do computations. Why two? Because if you
only have one test that checks "The area of a 2x5 yard is 10", then implementing the function as return 10 would cause it to pass…
we need at least two tests to make sure the function has proper logic.
We have two inputs and an expected output, and in the program itself we will have an actual output. We can create variables to
represent each of these pieces of information:
int input_width = 5;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
int input_height = 3;
int expected_result = 15;
int actual_result;
To get a value for the actual_result , we just call the function itself, passing in our inputs:
We can tell if the test passed if the actual_result matches the expected_result . Or, the test failed if they do not match.
It would be useful to output the results to the console as well, so we can write out something like this:
If you run the program now, we should get a nice print out of the test result:
Once they're both implemented, you can now implement the int GetArea( int width, int height ) function. To calculate
the area of a rectangle, we use the formula:
Implement the function and once run the tests should now pass. Here's how I've formatted my tests:
---------------------------------------------------------------------
Test_GetArea
---------------------------------------------------------------------
[PASS] GetArea - pass in 5 and 3 and should get 15 back
* input_width: 5
* input_height: 3
* expectedResult: 15
* actualResult: 15
GetStringLength
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Once the tests are implemented and they fail when you run the program, now implement the GetStringLength function. (Hint: You
can get the length of the text string with text.size() .)
These functions have already been implemented, but with incorrect logic. You're going to write unit tests before doing any fixes to help ensure
that your fixes are valid once implemented.
Task: Implement void Test_GetPerimeter() and void Test_Withdraw() first, then fix the functions -int
GetPerimeter( int width, int length ) and float Withdraw( float balance, float amount
)
GetPerimeter
For this function, come up with your own TWO test cases and implement them as unit tests. After implementing the unit tests, fix the
function logic.
Withdraw
For this function, come up with your own TWO test cases and implement them as unit tests. After implementing the unit tests, fix the
function logic.
Once you're done with the assignment, you need to add, commit, and push your changes to the server.
1. Open git bash from within your repository folder on your harddrive.
2. Use git status to review what files have changed since your last commit.
3. Use git add . to add all changed files to a changeset.
4. Use git commit -m "MESSAGE" to create a snapshot of your current changes. (Replace "MESSAGE" with something more descriptive.)
5. Use git push -u origin u04_debugtest to push all your commits to the GitLab server, on the u04_debugtest branch.
You can continue making changes and do additional add , commit , and push commands as well.
1. Use git checkout main to change back to the main branch to prepare for the next assignment. (You can always use git checkout
u04_debugtest to return to this branch and code.)
2. Use git pull to pull latest from the server. (This might happen if the instructor adds new starter code or makes modifications.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
5. Find the assignment on Canvas. Click "Start Assignment".
6. Paste in the Merge Request URL here. Click "Submit Assignment".
Let's imagine a workplace that doesn't use any source control software. Multiple people have shared files on a network drive and can edit them at any
time. Two different users are working on a file at the same time, but what happens when they save?
If User A saves their file first and then User B saves their file second, the network file will only be the last saved version - User B's version. It won't
automatically merge the files together, meaning User A's work gets lost. Imagine working on a lot of code and having this happen - making sure work
doesn't get overwritten would be a nightmare to manage manually.
Various source control systems have been developed over the years to help manage versioning, storing, and merging source code. There are pros and
cons to each one, but the most common ones these days are probably Git and TFS (Team Foundation Server). Others you might hear about are SVN
(Subversion) and Mercurial. We will be specifically talking about Git here.
Basics of Git
There are two main parts of source control: The Server, where the code is all brought together and stored, and the Clients - or, the user PCs. A person,
company, or other organization can set up a Server on their own computers or they can utilize a service like GitLab, GitHub, SourceForge,
Bitbucket, or other services to host their code for them.
Either way, for a project, a repository is created on the server. This is basically a folder, except the Git program is told that it is a special Git folder,
and the Git software knows how to process different commands to help users add, update, and manage the code stored within.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The clone command
When a new developer joins the team, or a new project is created to work on, the repository will be created and then each teammate on that
project can use the clone command, which looks like this:
This command tells the Git program to access the git URL given and download the repository folder. Git handles the download and setting up
the folder and files within, and on the user's local computer they'll see a folder with the repository name. The clone command only needs to be
done once per computer.
Branches
In our project repository, by default there will be a main branch (Note: sometimes the default is a master branch). The main branch
should represent the current, stable version of the program. The goal is to make sure the code on main can build.
When somebody wants to add a new feature or is working on a bug, they will create a new branch to work on. This starts at the main
branch, but gives the user their own workspace. They can make many backups of their code on their own branch without affecting the main
branch, and without breaking code on other peoples' machines.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The checkout command is used with the -b flag to create a new branch:
Even if you're on a different branch, you can switch back to main, or other branches, any time with git checkout BRANCHNAME . On your
local computer you may see files disappear and changes be undone, but those changes will come back once you're on the branch where you
created those files/changes.
While working on a branch you can use the git status command to see a list of files that you've added, removed, and changed since the
last commit. Items marked in red haven't yet been marked as "to back up", and items marked in green are ready to be backed up by using the
commit command. To mark a file as "ready to backup", we use the add command.
git status
When you're ready to make a backup of your work, you can use a git add command to add your files. Sometimes you only want to add one
or two files, sometimes you want to add only a certain type of files, and sometimes you want to add everything that has been updated.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
git add *.cpp
git add .
After using the add command, we "bundle" all the changes together in one commit. We use the commit command, and a message is
required - this is to help us keep track of what we changed where. Try to add a descriptive message so you can track your changes later if you
need to.
Commits are initially only stored on your own computer, they won't be shown on the repository server until you push everything.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
After you have one or more commits ready to go, you can use the push command to send your changes to the server under your branch. This
will allow others to view the changes you've made, while still keeping your code separate from the main branch… for now. The overall goal is
to eventually get it merged into the main branch, but we aren't doing that quite yet.
Besides just pushing your own changes to the server, you will periodically want to use the pull command to get any changes from the server -
such as completed features from other developers, or merged in code.
The pull will grab the latest version of files, so you want to make sure to first add and commit your changes before using pull .
Merge requests
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The Merge Request is the final part of a work-in-progress feature's life. You create a merge request, and it will show a list of all changes you've
made under the changes tab. Usually, you would send this Merge Request to other developers to review your work, but for this class you'll
submit your Merge Request as your assignment turn-ins.
Other developers can leave comments on specific lines of code in the merge request. Those reviewing your merge request should look out for
obvious potential errors, typos, logical fallacies, and so on. If comments are left asking you to fix something, you can go back to your computer,
make changes, then add/commit/push again and ask others to re-review your updates.
Finally, once it has been approved, the code can be merged to the main branch. In this class, the instructor will merge the code. In the work
world, someone like the system architect or your team lead might handle this step.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
UNIT 05: Algorithm efficiency
📊 Presentation - Algorithm efficiency (U05.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235cs250-unit05-algorithmefficiency.html
📖️
Reading - Algorithm efficiency (U05.READ.202401CS250)
Introduction: Algorithm Efficiency (and why we care)
Processing power continues increasing as time moves forward. Many things process so quickly that we barely notice it, if at all. That doesn't mean
we can just write code as inefficiently as possible and just let it run because "computers are fast enough, right?" - as technology evolves, we crunch
more and more data, and as "big data" becomes a bigger field, we need to work with this data efficiently - because it doesn't matter how powerful a
machine is, processing large quantities of data with an inefficient algorithm can still take a long time.
And some computers today are slow. Not usually the computers that the average person is using (Even though it might feel that way if they're running
Windows). Some computers that handle systems are pretty basic, or they're small, and don't have the luxury of having great specs. Fitness trackers,
dedicated GPS devices, a thermostat, etc. For systems like these, processing efficiency is important.
Let's say our algorithm's time to execute increases quadratically. That means, as we increase the amount of items to process (n), the time to process
that data goes up quadratically.
For processing 1 piece of data, it takes 1 unit of time (we aren't focused so much on the actual unit of time, since each machine runs at different
speeds) - that's fine. Processing 2 pieces of data? 4 units of time. 8 pieces of data? 64 units of time. We don't just double the amount of time it takes
when we double the data - we square it.
How much data do you think is generated every day on a social media website that has millions of users? Now imagine the processing time for an
algorithm with a quadratic increase…
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Data n Time units
4 16
5 25
… …
100 10,000
1,000 1,000,000
10,000 100,000,000
1,000,000 1,000,000,000,000
From a design standpoint we also need to know what the efficiency of different algorithms are (such as the algorithm to find data in a Linked List or
the algorithm to resize a dynamic array) in order to make design decisions on what is the best option for our software.
As an example, you shouldn't use a recursive algorithm to generate a Fibonacci sequence (Each number F in the sequence is equal to the sum of the
n
The most efficient way to do this would be with an iterative approach using a loop. However, we could also figure it out with a recursive approach,
though the recursive approach is much less efficient.
int GetFib_Iterative(int n)
{
if (n == 0 || n == 1) { return 1; }
int n_prev = 1;
int n_prevprev = 1;
int result = 0;
return result;
}
This algorithm has a simple loop that iterates n times to find a given number of the Fibonacci sequence. The amount of time the loop iterates based
on n is:
n 3 4 5 6 7 8 9 10 … 20
iterations 2 3 4 5 6 7 8 9 … 19
int GetFib_Recursive(int n)
{
if (n == 0 || n == 1) { return 1; }
The way this version is written, any time we call this function with any value n, it has to compute the Fibonacci number for F ib(n − 1),
F ib(n − 2), F ib(n − 3), … F ib(1), F ib(0) … twice. This produces duplicate work b ecause it effectively doesn't "remember" what F ib(3) was
after it computes it, so for F ib(n) it has to recompute F ib(n − 1) and F ib(n − 2) each time…
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
n 3 4 5 6 7 8 9 10 … 20
iterations 2 4 7 12 20 33 54 88 … 10,945
The growth rate of the iterative version ends up being linear: As n rises linearly, the amount of iterations also goes up linearly.
The growth rate of the recursive function is exponential: As n rises linearly, the amount of iterations goes up exponentially.
For small amounts this might not be too bad. However, if we were generating a Fibonacci number further in the list, it would continue getting even
slower…
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Red/solid: Recursive growth rate
Blue/dashed: Iterative growth rate
Y scale from 0 to 11,000 (the 11,000th Fibonacci number to generate).
If we are trying to generate the 11,000th item in the sequence, the iterative approach requires 11,000 iterations in a loop. That linear increase is still
much faster than each F ib(n) calling F ib(n − 1) and F ib(n − 2) recursively.
For the most part, we don't care much about the exact amount of times a loop runs. After all, while the program is running, n could be changing
depending on user input, or how much data is stored, or other scenarios. Instead, we are more interested in looking at the big picture: the generalized
growth rate of the algorithm.
We use something called "Big-O notation" to indicate the growth rate of an algorithm. Some of the rates we care about are:
2 3 n
O(1) O(log(n)) O(n) O(n ) O(n ) O(2 )
a = b + c
will take the same amount of computing time no matter what the values of a, b, and c are.
int F(int x)
{
return 3 * x + 2;
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Logarithmic time, O(log(n))
Having an algorithm that halves its range each iteration of the loop will result in a logarithmic growth rate.
Having a single loop that iterates over a range will be a linear time increase.
If there is some scenario that causes the loop to halve its range each time, then its growth rate would be less than linear: as O(log(n)).
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Quadratic time comes into play when you have one loop iterating n times nested within an other loop that also iterates n times. For example, if we
were writing out times tables from 1 to 10 (n = 10), then we would need 10 rows and 10 columns, giving us 10 = 100 cells.
2
void TimesTables(int n)
{
for (int y=1; y<=n; y++)
{
for (int x=1; x<=n; x++)
{
cout << x << "*"
<< y << "="
<< x*y << "\t";
}
cout << endl;
}
}
Just like nesting two loops iterating n times each gives us a n result, having three nested loops iterating n times each gives us a O(n
2 3
) growth rate.
void CubicThing(int n)
{
for (int z=1; z<=n; z++)
{
for (int y=1; y<=n; y++)
{
for (int x=1; x<=n; x+
{
cout << x << " "
<< y << " "
<< z << endl
}
}
}
}
With an exponential function, each step increases the complexity of the operation. The Fibonacci example is a good illustration: Figuring out
Fib(0) and Fib(1) are constant, but Fib(2) requires calling Fib(0) and Fib(1) , and Fib(3) calls Fib(1) and Fib(2) , with
Fib(2) calling Fib(0) and Fib(1) , and each iteration adds that many more operations.
int Fib(int n)
{
if (n == 0 || n == 1)
return 1;
return
Exponential_Fib(n-2)
+ Exponential_Fib(n-1);
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Growth rate comparisons:
Review questions:
1. Let's say an algorithm's time complexity is constant. For this example algorithm we can model the efficiency like this:
T (n) = 5
T (n) = 2n
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
1. Processing 1 item would cost how many time units?
2. Processing 10 items would cost how many time units?
3. Processing 100 items would cost how many time units?
3. Let's say an algorithm's time complexity is quadratic. For this example algorithm we can model the efficiency like this:
2
T (n) = n
1. n = 1 ?
2. n = 10 ?
3. n = 100 ?
if ( n > 100 )
return n+100; // +1 command, or
else if ( n > 10 )
return n+10; // +1 command, or
else
return n; // +1 command
}
1. n = 1 ?
2. n = 10 ?
3. n = 100 ?
1. n = 1 ?
2. n = 10 ?
3. n = 100 ?
4. The increase is… (constant/linear/quadratic?)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
void Func( int n )
{
int iterations = 0; // Don't count me
for ( int i = 0; i < n; i++ )
{
for ( int j = 0; j < n; j++ )
{
cout << i << "," << j << endl; // +1 command each iterat
iterations++; // Don't count me
}
}
cout << "Iterations: " << iterations << endl; // Don't count
}
1. n = 1 ?
2. n = 10 ?
3. n = 100 ?
4. The increase is… (constant/linear/quadratic?)
After reading, do the quiz to check your notes: 🔎 Unit 05 Concept Intro - Algorithm efficiency (U05.CIN)
WEEK 3 - JAN 29
UNIT 06: CS 200 Review - Pointers
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
📊 Presentation - Pointers and memory (U06.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235cs250-unit06-reviewpointers.html
📖️
Reading - Pointers and memory (U06.READ)
Memory addresses
When we declare a variable, what we're actually doing is telling the computer to set aside some memory (in RAM) to hold some information.
Depending on what data type we declare, a different amount of memory will need to be reserved for that variable.
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).
Minimum value, 0
place 128 64 32 16 8 4 2 1
value 0 0 0 0 0 0 0 0
place 128 64 32 16 8 4 2 1
value 1 1 1 1 1 1 1 1
A char only needs one byte to store a single letter because we represent letters with the ASCII or UTF8 codes 65 - 90 for upper-case, and 97 - 122
for lower-case.
A B C D E F G H I J K L M
65 66 67 68 69 70 71 72 73 74 75 76 77
N O P Q R S T U V W X Y Z
78 79 80 81 82 83 84 85 86 87 88 89 90
a b c d e f g h i j k l m
97 98 99 100 101 102 103 104 105 106 107 108 109
n o p q r s t u v w x y z
110 111 112 113 114 115 116 117 118 119 120 121 122
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Any of these numbers can be stored with 8 bits:
A = 65…
place 128 64 32 16 8 4 2 1
value 0 1 0 0 0 0 0 1
z = 122…
place 128 64 32 16 8 4 2 1
value 0 1 1 1 1 0 1 0
So when we declare a variable, the computer finds an available space in memory and reserves the appropriate amount of bytes in memory. For
example, our char could be assigned the memory address 0xabc008 in memory, and its value being stored would look like this:
…007 …008 …009 …00a …00b …00c …00d …00e …00f …010
… 0 1 1 1 1 0 1 0 …
We can view the addresses of variables in our program by using the address-of operator & . Note that we have used the ampersand symbol before to
declare pass-by-reference parameters, but this is a different symbol used in a different context.
#include <iostream>
using namespace std;
int main()
{
int number1 = 10;
int number2 = 20;
return 0;
}
Running the program, it would display the memory addresses for these two variables. Notice that they're 4 bytes apart in memory (one is at …70 and
one is at …74):
0x7ffd3a24cc70 0x7ffd3a24cc74
Each time we run the program, we will get different memory addresses, since the operating system reclaims that memory when the program ends, and
gives us new memory spaces to allocate next time we run the program.
0x7ffe0e708a80 0x7ffe0e708a84
When we declare an array of integers of size n, the program asks for n × 4 bytes of memory to work with. The two variables above didn't have to be
side-by-side in memory; they just happened to be because they were declared close together. With an array, however, all elements of the array will be
contiguous (side-by-side) in memory.
int arr[3];
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
cout << &arr[i] << "\t";
}
Because the elements of an array must be contiguous in memory, we cannot resize a normal array. After our array is declared, chances are the memory
addresses right after it will be put to use elseware on the computer and will be unavailable to our program and our array.
But, after we learn about pointers, we will learn how we can dynamically allocate as much memory as we need at any time during our program's
execution - giving us the ability to "resize" arrays by allocating space for a new array, copying the data over to the larger chunk of memory, and
deallocating the old chunk of memory from the smaller array.
Pointers
Creating pointer variables
We can declare special variables that store memory addresses rather than storing an int or float or char value. These variables are called
pointers.
We can declare a pointer like this: int* ptrNumber; Or like this: int * ptrNumber; Or like this: int *ptrNumber;
But note that doing this declares one pointer and several integers: int * ptrNumber, notAPointer1, notAPointer2; To avoid
confusion, \underline{declare multiple pointers on separate lines}.
If we declare a pointer as an int* type, then it will only be able to point to the addresses of integer variables, and likewise for any other data
type.
Remember how variables in C++ store garbage in them initially? 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 NULL or nullptr .
#include <iostream>
using namespace std;
int main()
{
int * ptr = nullptr;
return 0;
}
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.
After assigning an address to a pointer, if we cout the pointer it will display the memory address of the pointed-to variable - just like if we had
used cout to display the address-of that variable.
Here's a simple program that has an integer var with a value of 10, and a pointer ptr that points to var 's address.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
#include <iostream>
using namespace std;
int main()
{
int * ptr;
int var = 10;
ptr = &var;
return 0;
}
c2_u08_ptrmemory.png
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 prefixing the pointer's name with a * - again, another symbol being reused but in a different context.
In this code, we point ptr to the address of var . Outputting ptr will give us var 's address, and outputting *ptr (ptr dereferenced) will
give us the value stored at var 's address.
int * ptr;
int var = 10;
ptr = &var;
Output:
Then, we could also overwrite the value stored at var 's address by again dereferencing the pointer and writing an assignment statement:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
*ptr = 20;
When we output the value that var is storing, either directly through var or through the ptr , we can see that the value of var has been
overwritten:
var value: 20
*ptr value: 20
Remember that when you declare a variable in C++, it will initially store garbage. This is true of pointers as well. When you declare a pointer without
initializing it to nullptr , it will be storing random garbage that it will try to interpret as a memory address. If you dereference a pointer that is
pointing to garbage, your program is going to run into a problem - a segmentation fault.
int main()
{
int * bob;
cout << *bob << endl;
return 0;
}
Program output:
In short, we can't check if an address stored in a pointer is valid. This is why we initialize our pointers to nullptr when they're not in use - we
know nullptr means that the pointer is not pointing to anything.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
One handy use of pointers is to point at the addresses of other variables that were already declared. However, there is a second main use of pointers:
To dynamically allocate memory any time we need new variables that we don't have to pre-write in the program.
Dynamic variables
At the moment, dynamic variables might seem pointless, but they are really handy for linked data structures - a type of structure you can use
to store a series of data in that is an alternative to an array.
We use the new keyword to allocate memory for the size of one variable data type (as opposed to an array of the variables), and delete to
free up that memory.
Once we've allocated memory through the pointer, we can use the pointer as normal. The only difference is that we're now accessing an
address that was allocated differently from the address of a "normal" variable.
int main()
{
int * myNumber; // Declare pointer
return 0;
}
Dynamic arrays
For our normal arrays, we are unable to resize them during the program's run time because an array requires that all elements of the array are
contiguous (side-by-side) in memory.
However, if we can allocate and deallocate memory any time we want with pointers, we can create a dynamic array. If we ever need to resize
it, we allocate a new array of a bigger size and copy the data from the old array to the new one.
When we're allocating space for an array of items, we use a slightly different set of keywords:
Example program that lets the user specify how big the array will be.
int main()
{
int arraySize;
float * pricesArray;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
pricesArray = new float[arraySize]; // Allocate mem
return 0;
}
When you've used a pointer to allocate space for an array, you will access items in the dynamic array the same way you would do for a
normal array. In other words, you would use the subscript operator [ ] to access elements at particular indices, and you don't need to prefix
the pointer with the dereference operator * .
Let's say we're writing a program that stores the user's library of movies they own. It saves a file so they can run the program any time,
add or delete movies, close the program and open it again sometime later.
We can't realistically predict how many movies a person would own - some people might be collectors and have tons of movies. At the
same time, if we were to over-estimate and make an array with, say, 10,000 elements, it would be a huge waste of memory if we had such
a big array for someone who only had a few dozen movies.
A dynamic array would work perfectly here because we can initially create an array that's fairly small - maybe 10 items - and if the array
fills up, we can then allocate more memory and copy the movies to the new array and deallocating the old array. If it fills up again, we
just repeat the process, allocating more memory, copying the data over, and freeing the old array's memory.
Resizing steps
Normally, you would store a dynamic array inside of a class that acts as the interface for adding and removing data, where it will check if
there's enough space before adding new information and resizing the array if not.
void MovieLibrary::Resize()
{
// Allocate more memory
int newSize = m_arraySize + 10;
string * newArray = new string[newSize];
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Dynamic array example: Movie Library
Here's a small example of a class that contains a dynamic array, that allows users to add additional information, and handles checking for
a full array and resizing.
MovieLibrary.h:
#ifndef _MOVIE_LIBRARY_HPP
#define _MOVIE_LIBRARY_HPP
#include <string>
using namespace std;
class MovieLibrary
{
public:
MovieLibrary();
~MovieLibrary();
private:
bool IsFull();
void Resize();
string * m_movieArray;
int m_arraySize;
int m_itemsStored;
};
#endif
The methods IsFull() and Resize() are set as private because outside users don't need to know anything about how the data is
stored. The outside users shouldn't be able to recall Resize whenever they want.
MovieLibrary.cpp:
Constructor:
MovieLibrary::MovieLibrary()
{
m_arraySize = 10;
m_movieArray = new string[m_arraySize];
m_itemsStored = 0;
}
In the constructor, we initialize our m_movieArray member pointer variable by allocating some memory to start with.
If we weren't going to allocate memory in the constructor, then we should initialize m_movieArray by setting it to nullptr .
We also have two separate size variables - m_arraySize keeps track of how many spaces are available in the array, and
m_itemsStored keeps track of how many items the user has added to the array.
Destructor:
MovieLibrary::~MovieLibrary()
{
if ( m_movieArray != nullptr )
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
{
delete [] m_movieArray;
}
}
Before the MovieLibrary item is destroyed (e.g., when the program ends and it goes out of scope), we need to make sure to *free the
memory that we allocated}. First, we need to check if the pointer m_movieArray is pointing to nullptr - if it is, we can assume it's
not in use and there's nothing to do. But, if m_movieArray is pointing to some address, we assume that memory has been allocated
here. In this case, we free that memory.
ViewAllMovies:
This is just a simple for loop that goes from index 0 to m_itemsStored - 1, displaying each element to the screen.
We aren't iterating until i < m_arraySize because if our array size is 10 and the user has only stored 5 movies, we don't need to
display 5 empty slots.
ClearAllMovies:
void MovieLibrary::ClearAllMovies()
{
delete [] m_movieArray;
m_movieArray = nullptr;
m_arraySize = 0;
m_itemsStored = 0;
}
If the user decides to clear out their movie array, we could just deallocate all memory reserved for the movie list and reset our size
variables. We just need to make sure we're checking to make sure the array is allocated before we try to access elements from it or add to
it.
IsFull:
bool MovieLibrary::IsFull()
{
return m_itemsStored == m_arraySize;
}
The array is full if the amount of items the user has stored, m_itemsStored is equal to the amount of spaces we have allocated for the
array, m_arraySize .
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
AddMovie:
Before we add a movie, we need to make sure m_movieArray is set up and ready.
Finally, once those two checks have been done and the array has been prepared, we can add a new item to the array and increase hte
m_itemsStored count.
Resize:
void MovieLibrary::Resize()
{
int newSize = m_arraySize + 10;
string * newArray = new string[newSize];
delete [] m_movieArray;
m_movieArray = newArray;
m_arraySize = newSize;
}
This is the same Resize() method as was shown before as an example of resizing a dynamic array.
Memory Management
Types of memory errors
Working with pointers and dealing with memory can lead to writing code that can mess up our program or even slow down our computer (until
the next reboot).
Invalid memory access happens when a pointer isn't set to nullptr when it's no longer in use. If this doesn't happen, the memory address it's
pointing to could be invalid, such as if delete was used on the pointer, or if the pointer were declared and not initialized.
An invalid memory access would cause a problem once you try to dereference the pointer pointing to an invalid address - causing a segfault
and your program to crash.
Memory leak:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
A memory leak occurs when you've allocated memory (via the new command) but you never deallocate it. C++ won't automatically deallocate
this memory for you, and what happens is that chunk of memory ends up being "called for" even after the program has finished running. This
memory block will be unavailable to all programs until the user restarts their computer.
If you had many items allocating memory but never freeing them, the resulting memory leaks could cause your computer to slow down over
time (until the next reboot).
Missing allocation:
Missing allocation occurs if you try to delete memory that has already previously been freed. If this happens, the progrma will crash.
int myNum;
Well, there are different types of memory, and each is stored in a different space.
The Stack:
All of our non-dynamic variables we have been declaring, including function parameters and class member variables, get allocated to the Stack.
The Stack part of memory has a fixed size, and it contains a sequence of memory addresses. The Stack automatically handles the memory
management for these variables - when we declare a int count; variable, it will be pushed onto the Stack, and when it's not in use anymore
(when it goes out of scope), it will be removed from (popped off) the Stack.
A "stack overflow" error occurs when so many variables have been declared that the Stack runs out of room. This usually occurs while writing
recursive functions that have a logic error, causing them to repeat until we run out of Stack space.
The Heap:
The heap is where dynamically allocated data gets stored. The Heap does not automatically take care of memory management for us, so that is
why we have to deal with new and delete ourselves (unless we're using a smart pointer). Any data in the Heap must be accessed via a pointer.
There is no size restriction for the Heap.
Smart Pointers
In modern versions of C++ we have access to smart pointers, which allow us to utilize pointer functionality but without having to worry about the
memory management side of things. It's important to see both the original style of pointers and the smart pointers so that you're acquainted with both
in case you experience them in other classes or on the job.
shared_ptr
Documentation: https://cplusplus.com/reference/memory/shared_ptr/
Shared pointers are meant for spaces in memory that will be pointed to by multiple pointers. The memory allocated at that address stays active
up until the last pointer is destroyed - that triggers the deallocation of the memory once nobody is pointing to it anymore.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
struct City
{
City( string value )
{
name = value;
}
string name;
shared_ptr<City> west_neighbor;
shared_ptr<City> east_neighbor;
shared_ptr<City> south_neighbor;
shared_ptr<City> north_neighbor;
};
Each City can have a north, south, east, and/or west neighbor City. Instead of using a City* traditional pointer, we're using the
shared_ptr object that's part of the <memory> C++ library.
Within our main program, we can create some cities. Instead of our dynamic variable allocation like City lenexa = new City(
"Lenexa" ); , it will look like this:
For each of these shared pointers, this is the first reference to its memory address. When we set up neighbors for each city, we create additional
references:
// Set up neighbors
lenexa->east_neighbor = overland_park;
overland_park->west_neighbor = lenexa;
lenexa->south_neighbor = olathe;
olathe->north_neighbor = lenexa;
lenexa->north_neighbor = shawnee;
shawnee->north_neighbor = lenexa;
If these were traditional pointers, the syntax would look the same.
The shared_ptr class gives us access to a function called use_count() , which we can use to see how many shared pointers are currently
pointing to a given memory address. (https://cplusplus.com/reference/memory/shared_ptr/) Using this, we can build out a table that displays
each city, its address, and how many references are going to that address:
At the end of the program we don't have to include code like delete lenexa; to free the allocated memory. Since the shared_ptr is a
class, the actual pointer is stored within that class, and utilizing the destructor, it will take care of cleaning up the memory for us.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
unique_ptr
Documentation: https://cplusplus.com/reference/memory/unique_ptr/
With a unique_ptr , we create a pointer that is the only "owner" of the memory block it points to. We can move around "ownership" of that
address, but only one pointer may point to it. When the owning unique_ptr goes out of scope and is destroyed, it will automatically free the
space allocated at the memory address it owns.
This can be useful for creating a dynamic array but without having to deal with the memory management. Instead of allocating memory in the
traditional way like: string* arr = new string[ array_size ]; , we can use the unique_ptr :
or you could use the auto keyword to make this a little nicer looking:
Otherwise, we use this dynamic array similar to with traditional pointers, but we don't need the delete [] arr; at the end of the program:
If you need to change who owns the pointed-to address, the move command can be used:
// Previously declared:
// auto arr = unique_ptr<string[]>( new string[3] );
// auto biggerArray = unique_ptr<string[]>( new string[ newSize ] );
arr = move( biggerArray );
Review questions:
1. Given the variable declaration: int num = 10; What kind of memory is the num variable stored in?
2. Given the variable declaration: int* num = new int; What kind of memory is the num variable stored in?
3. How do you declare a pointer?
4. How do you access the address of a variable?
5. How do you assign the address of a variable to a pointer?
6. How do you dereference a pointer to display the value of the address it's pointing to?
7. How do you dereference a pointer to store a new value in the memory block pointed to?
8. When a pointer is not currently in use, it should be initialized to…
After reading, do the quiz to check your notes: 🔎 Unit 06 Concept Intro - CS 200 review: Pointers (U06.CIN)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Goals:
Turn-in:
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
For this assignment, I've already added the code to your repository.
.
├── graded_program
│ ├── Array.cpp
│ ├── Array.h
│ ├── INFO.h
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
│ ├── main.cpp
│ ├── Project_CodeBlocks
│ │ ├── DynamicArray.cbp
│ │ ├── DynamicArray.depend
│ │ └── DynamicArray.layout
│ ├── Project_Makefile
│ │ └── Makefile
│ └── Project_VisualStudio2022
│ ├── DynamicArray
│ │ ├── DynamicArray.vcxproj
│ │ └── DynamicArray.vcxproj.filters
│ └── DynamicArray.sln
├── practice1_addresses
│ └── u06_p1_addresses.cpp
├── practice2_pointers
│ └── u06_p2_pointers.cpp
├── practice3_dynamic_variables
│ └── u06_p3_dynvars.cpp
├── practice4_dynamic_arrays
│ └── u06_p4_dynarr.cpp
├── practice5_unique_pointers
│ └── u06_p5_uniqueptr.cpp
└── practice6_shared_pointers
└── u06_p6_sharedptr.cpp
I have only provided a Visual Studio and Code::Blocks project for the graded assignment. For the practice assignments you will need to create a
project and add the file to that project. You can follow the steps in this video:
practice1_addresses
EXPLORING ADDRESSES
Original Variables!
VARIABLE ADDRESS VALUE
---------------------------------------------------------------------------
num1 0x7ffd286acffc 10
num2 0x7ffd286ad000 15
num3 0x7ffd286ad004 -5
Pointer!
Address: 0
Don't dereference the nullptr!!
Changed Variables!
VARIABLE ADDRESS VALUE
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
---------------------------------------------------------------------------
num1 0x7ffd286acffc 500
num2 0x7ffd286ad000 200
num3 0x7ffd286ad004 300
THE END
Look out for the comment lines in the code that give instructions on what to do.
You will need to create an integer pointer and assign it to various addresses throughout the program. Once finished, the output should look similar to
the above one.
practice2_pointers
PRODUCTS:
0 Pencil 1.59
1 Markers 2.39
2 Eraser 0.59
Enter # of product to modify: 0
Enter new price: $9.99
Enter new name: Super Pencil
UPDATED PRODUCTS:
0 Super Pencil 9.99
1 Markers 2.39
2 Eraser 0.59
THE END
Look out for the comment lines in the code that give instructions on what to do.
This program will use pointers to objects, so you will need to also access member variables of the given class. Use the -> operator to access
members of an object, when it's being pointed to via a pointer.
practice3_dynamic_variables
LINKED NODES
FREE MEMORY:
* Delete firstNode->ptrNext->ptrNext
* Delete firstNode->ptrNext
* Delete firstNode
Look out for the comment lines in the code that give instructions on what to do.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
practice4_dynamic_arrays
----------------------------------------
ARRAY SIZE: 3, ITEM COUNT: 0
ARRAY CONTENTS:
----------------------------------------
ARRAY SIZE: 3, ITEM COUNT: 1
ARRAY CONTENTS:
0. cat
----------------------------------------
ARRAY SIZE: 3, ITEM COUNT: 2
ARRAY CONTENTS:
0. cat
1. dog
----------------------------------------
ARRAY SIZE: 6, ITEM COUNT: 3
ARRAY CONTENTS:
0. cat
1. dog
2. rat
----------------------------------------
ARRAY SIZE: 6, ITEM COUNT: 4
ARRAY CONTENTS:
0. cat
1. dog
2. rat
3. panda
THE END
Look out for the comment lines in the code that give instructions on what to do.
Follow along with the instructions to implement the core functionality of a dynamic array, which will also be part of the graded program.
practice5_unique_pointers
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
UNIQUE POINTERS
----------------------------------------
ARRAY SIZE: 3, ITEM COUNT: 0
ARRAY CONTENTS:
----------------------------------------
ARRAY SIZE: 3, ITEM COUNT: 1
ARRAY CONTENTS:
0: eggs
----------------------------------------
ARRAY SIZE: 3, ITEM COUNT: 2
ARRAY CONTENTS:
0: eggs
1: bagels
----------------------------------------
ARRAY SIZE: 6, ITEM COUNT: 3
ARRAY CONTENTS:
0: eggs
1: bagels
2: cereal
THE END
Look out for the comment lines in the code that give instructions on what to do.
Follow along to practice with unique pointers. This program is similar to the dynamic array program except without the memory management.
practice6_shared_pointers
SHARED POINTERS
1. Lemon 2. Lime
RESULTS:
OPTION 1: Lemon, USE COUNT: 2
OPTION 2: Lime, USE COUNT: 3
THE END
Look out for the comment lines in the code that give instructions on what to do.
The shared pointers vote1 , vote2 , and vote3 will point to either option1 or option2 . At the end of the program, we check their
use_count() s to see the total amount of references to each address.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
graded_program
DYNAMIC ARRAY
1. Create array
2. Allocate space
AllocateSpace
3. Add items to array, trigger resize
AddItem
AddItem
AddItem
AddItem
ResizeArray
AddItem
4. Display array
0: BASIC
1: COBOL
2: Java
3: C#
4: C++
5. Deallocate space
DeallocateSpace
DeallocateSpace
For this program you will be implementing a dynamic array inside the Array.cpp file.
class Array
{
public:
Array();
Array( int arraySize );
~Array();
void ResizeArray();
void AddItem( string value );
void Display();
private:
int m_arraySize = 3;
int m_itemCount = 0;
string * m_ptr = nullptr;
You can ignore the friend functions - these are used with the unit tests. Basically, marking a function as a friend gives that function access to
the private member variables of a class, which helps me with implementing the unit tests.
The functions of the Array will need to be implemented. You will only need to update Array.cpp.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Array::Array()
Initialize the m_ptr pointer to nullptr for safety and call the AllocateSpace function, passing in the arraySize .
Array::~Array()
If m_ptr is NOT pointing to nullptr this means that it is currently in use. Display an error message and return early (you can leave void
functions with return; .)
Otherwise, allocate space for a new array via the m_ptr pointer - we are creating a dynamic array. Use the arraySize given.
Make sure to also initialize m_arraySize to the arraySize and initialize m_itemCount to 0.
void Array::DeallocateSpace()
If m_ptr is NOT pointing to nullptr then we need to free the memory. delete the array at the m_ptr address, then assign nullptr
to the m_ptr for safety.
delete [] m_ptr;
m_ptr = nullptr;
void Array::ResizeArray()
1. Create a new dynamic array with a larger array size. Let's call this newArray .
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Copy the data from the old array ( m_ptr ) to the new array ( newArray ). You'll use a for loop, and iterate from i=0 to the
m_itemCount (not-inclusive).
3. After copying the data over, free the memory at the m_ptr location using the delete command.
4. Update the m_ptr pointer to point to the same address as newArray .
5. Update the value of the m_arraySize to the new array size.
❓❓ HINT (Hover to view)
QUESTION: How do I create a new dynamic array with a larger size?
delete [] m_ptr;
m_ptr = newArray;
If the array is full ( m_itemCount = marraySize=) then call the ResizeArray function and then continue on.
Assign the element of m_ptr at the index m_itemCount to the value given.
m_ptr[INDEX] = value;
m_ptr[m_itemCount] = value;
void Array::Display()
Use a for loop to iterate over all the elements of the m_ptr array. Display each item's index and element value.
The index is the position of an element in the array. The lowest valid index is 0, and for an array of size size, the
highest valid index is size-1.
for ( int i = 0; i < m_itemCount; i++ ) { cout << i << ". " <<
m_ptr[i] << endl; }
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Once everything is implemented, all the tests should pass. You can also run the program itself to see your dynamic array in use.
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
📖️
Reading - The Standard Template Library (U07.READ)
C++ comes with a bunch of data structures we can use to store sets of data. Each of these have different uses and work better for different designs.
They all have documentation available online so you can learn more about how these structures work there as well.
One of the first ways you may have learned to store a sequence of data is with a traditional array in C++. These aren't "smart" at all, cannot be
resized, and you either have to manually keep track of the size of the array or do a calculation whenever you want to find the size.
Declaration
The ARRAY_SIZE named constant and the itemCount variable are optional, however, we have to manually keep track of the size of the array and
how many items are stored within it - it won't take care of that for us.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
cout << "Enter a number: ";
cin >> myArray[ 0 ];
cout << "Item #0 is " << myArray[0] << endl;
And iterating through it requires, again, keeping track of the amount of items we've stored in the array with some kind of variable:
We can create dynamic arrays by using pointers. This allows us to define the size of the array at runtime, instead of defining the size at compile-time
like with our traditional fixed-length array. The downside is manually managing the memory - making sure to free whatever we have allocated.
Declaration
int itemCount = 0;
int arraySize;
Reading and writing values to the array is the same as with the traditional array. We just have to make sure to free the memory before the program
ends:
Freeing memory
You need to free the memory you allocate before its pointer loses scope - if this happens, you lose the address and that memory is now taken up and
cannot be freed.
delete [] myArray;
STL std::array
Documentation: https://cplusplus.com/reference/array/array/
he array from the STL is basically a class wrapping our traditional array. It allows us to use the array as an object with basic functions, so that we
don't have to keep track of as much.
Declaration
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Accessing the size
Accessing elements
STL std::vector
Documentation: https://cplusplus.com/reference/vector/vector/
Vectors are dynamic arrays so you can add items to it and it will resize - no worries on your part regarding resizing and managing memory.
Declaration
vector<int> myVector;
Accessing elements
Because you're generally not pre-allocating space for a vector, you need to use the push_back function to add additional items to the end of the
vector's internal array.
STL std::list
Documentation: https://cplusplus.com/reference/list/list/
The list is similar to a vector in that you can store any amount of items in it, however you can only ever access the front and the back of the list - not
random items in the middle. You can still iterate over all the items, though.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Declaration
list<int> myList;
Adding data
Accessing data
Removing data
myList.pop_front();
myList.pop_back();
STL std::stack
Documentation: https://cplusplus.com/reference/stack/stack/
A stack is a type of restricted-access data type. It can store a series of items, but you can only add and remove items from the top.
Declaration
stack<char> myStack;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
cout << "Size: " << myStack.size();
Adding data
myStack.push( 'A' );
myStack.push( 'B' );
myStack.push( 'C' );
Accessing data
cout << "Top item is: " << myStack.top() << endl;
Removing data
STL std::queue
Documentation: https://cplusplus.com/reference/queue/queue/
A queue is another type of restricted-access data type. It stores a series of items, with items being added at the back of the queue, and being removed
from the front of the queue, similar to waiting in line at the store.
Declaration
queue<char> myQueue;
Adding data
myQueue.push( 'A' );
myQueue.push( 'B' );
myQueue.push( 'C' );
Accessing data
cout << "The front item is: " << myQueue.front() << endl;
Removing data
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
myQueue.pop(); // Remove front item
STL std::map
Documentation: https://cplusplus.com/reference/map/map/
Our traditional arrays have index numbers (0, 1, 2, …) and elements stored at that position in the array.
With a map, we can have any data type as a unique identifier for an element. This could be an integer, but it doesn't have to be 0, 1, 2, and so on - it
could be an employee ID, a phone number, etc., but the data type of the identifier (called a key) can be any data type.
Declaration
Adding data
Accessing data
int key;
cout << "Enter an area code: ";
cin >> key;
cout << "The region for that is: " << area_codes[ key ];
Review questions:
1. Identify what "type" each of the following is… (traditional array / traditional dynamic array / array object / vector object)
1. vector<int> arr;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. int * arr = new int[100];
3. array<int, 100> arr;
4. int arr[100];
2. Which of these std data types can be resized (store any amount of data after declaration)? (array / vector / list)
3. You can only add items to the … of a stack, and you can only remove items from the … of a stack.
4. You can only add items to the … of a queue, and you can only remove items from the … of a queue.
5. True or false: A map can use any data type for its unique key item.
After reading, do the quiz to check your notes: 🔎 Unit 07 Concept Intro - The Standard Template Library (U07.CIN)
Goals:
Turn-in:
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
For this assignment, I've already added the code to your repository.
.
├── examples
│ ├── array_example.cpp
│ ├── list_example.cpp
│ ├── map_example.cpp
│ ├── queue_example.cpp
│ ├── stack_example.cpp
│ └── vector_example.cpp
├── graded_program
│ ├── Customer.h
│ ├── events.txt
│ ├── GroceryStoreProgram.cpp
│ ├── GroceryStoreProgram.h
│ ├── INFO.h
│ ├── main.cpp
│ ├── Product.h
│ ├── Project_CodeBlocks
│ │ ├── STL.cbp
│ │ ├── STL.depend
│ │ └── STL.layout
│ ├── Project_Makefile
│ │ └── Makefile
│ ├── Project_VisualStudio2022
│ │ ├── StandardTemplateLibraryProject.sln
│ │ ├── StandardTemplateLibraryProject.vcxproj
│ │ └── StandardTemplateLibraryProject.vcxproj.filters
│ └── Tester.cpp
├── practice1_array
│ └── u07_p1_array.cpp
├── practice2_vector
│ └── u07_p2_vector.cpp
├── practice3_list
│ └── u07_p3_list.cpp
├── practice4_map
│ └── u07_p4_map.cpp
├── practice5_stack
│ └── u07_p5_stack.cpp
└── practice6_queue
└── u07_p6_queue.cpp
The examples folder contains examples of each of the Standard Template Library items we're using in this assignment.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
practice1_array
ARRAY PROGRAM
COURSES:
0: CS 134
1: CS 200
2: CS 235
3: CS 250
THE END
Look out for the comment lines in the code that give instructions on what to do.
Utilize the STL array class (https://cplusplus.com/reference/array/array/) for this program. Set the array's size and fill it up with items, then iterate
over the array, displaying each index and element value.
practice2_vector
VECTOR PROGRAM
Enter a new course, or STOP to finish: CS134
Enter a new course, or STOP to finish: CS200
Enter a new course, or STOP to finish: CS235
Enter a new course, or STOP to finish: STOP
COURSES:
0: CS134
1: CS200
2: CS235
THE END
Look out for the comment lines in the code that give instructions on what to do.
Utilize the STL vector class (https://cplusplus.com/reference/vector/vector/) for this program. Use the push_back function to add new items to
the vector, and use a normal for loop to display each index and element value.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Within the loop example above, VECTORNAME[i] is the element.
practice3_list
LIST PROGRAM
COURSES:
F
F
B
B
THE END
Look out for the comment lines in the code that give instructions on what to do.
Utilize the STL list class (https://cplusplus.com/reference/list/list/) for this program. As you add items to the list, the user can choose to put the
new item at the FRONT or the BACK of the list. Afterwards, use a range-based for loop to iterate over all the items in the list to display each one.
practice4_map
MAP PROGRAM
THE END
Look out for the comment lines in the code that give instructions on what to do.
Utilize the STL map class (https://cplusplus.com/reference/map/map/) for this program. You'll add items to the map, access items via their keys, and
utilize a range-based for loop to iterate over all the items in the map.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
for ( auto& item : product_prices ) for the loop, then you can use item.first to get
item.second to get the value.
the key, and
practice5_stack
STACK PROGRAM
--------------------------------------------------
STACK IS EMPTY
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 1
Enter new text to push on stack: A
--------------------------------------------------
TOP ITEM IN STACK: A
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 1
Enter new text to push on stack: B
--------------------------------------------------
TOP ITEM IN STACK: B
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 1
Enter new text to push on stack: C
--------------------------------------------------
TOP ITEM IN STACK: C
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 2
Popped top item off stack
--------------------------------------------------
TOP ITEM IN STACK: B
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 0
--------------------------------------------------
TOP OF STACK: B
TOP OF STACK: A
THE END
Look out for the comment lines in the code that give instructions on what to do.
Utilize the STL stack class (https://cplusplus.com/reference/stack/stack/) for this program. You'll create a stack, use push , pop , and top
functions to interface with it.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
practice6_queue
QUEUE PROGRAM
--------------------------------------------------
QUEUE IS EMPTY
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 1
Enter new text to push on queue: A
--------------------------------------------------
FRONT ITEM IN QUEUE: A
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 1
Enter new text to push on queue: B
--------------------------------------------------
FRONT ITEM IN QUEUE: A
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 1
Enter new text to push on queue: C
--------------------------------------------------
FRONT ITEM IN QUEUE: A
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 2
Popped top item off queue
--------------------------------------------------
FRONT ITEM IN QUEUE: B
--------------------------------------------------
0. Quit
1. PUSH item
2. POP item
>> 0
--------------------------------------------------
FRONT OF QUEUE: B
FRONT OF QUEUE: C
THE END
Look out for the comment lines in the code that give instructions on what to do.
Utilize the STL queue class (https://cplusplus.com/reference/queue/queue/) for this program. You'll create a queue, use push , pop , and front
functions to interface with it.
graded_program
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
(8:10) Added banana @ $0.24 to shelves.
(8:15) Added watermelon @ $12.59 to shelves.
(8:20) Customer Maribel entered store.
(8:25) Customer Maribel adds apple to their cart.
(8:30) Customer Maribel adds apple to their cart.
(8:35) Customer Maribel decides to put apple back.
(8:40) Customer Maribel adds watermelon to their cart.
(8:45) Customer Sara entered store.
(8:50) Customer Sara adds apple to their cart.
(8:55) Customer Sara queues up in the checkout line.
(9:00) Customer Cody entered store.
(9:05) Customer Cody adds watermelon to their cart.
(9:10) Customer Cody adds watermelon to their cart.
(9:15) Customer Cody adds watermelon to their cart.
(9:20) Customer Cody decides to put watermelon back.
(9:25) Customer Cody queues up in the checkout line.
(9:30) Customer Rai entered store.
(9:35) Customer Rai adds avocado to their cart.
(9:40) Customer Rai adds apple to their cart.
(9:45) Customer Rai adds watermelon to their cart.
(9:50) Customer Maribel queues up in the checkout line.
(9:55) Customer Rai queues up in the checkout line.
(10:00) Customer Sara is at the register.
(10:05) >> apple ($0.76) is their next item.
(10:10) >> Checkout done. Total: $0.76... Customer Sara leaves.
(10:15) Customer Cody is at the register.
(10:20) >> watermelon ($12.59) is their next item.
(10:25) >> watermelon ($12.59) is their next item.
(10:30) >> Checkout done. Total: $25.18... Customer Cody leaves.
(10:35) Customer Maribel is at the register.
(10:40) >> watermelon ($12.59) is their next item.
(10:45) >> apple ($0.76) is their next item.
(10:50) >> Checkout done. Total: $13.35... Customer Maribel leaves.
(10:55) Customer Rai is at the register.
(11:00) >> watermelon ($12.59) is their next item.
(11:05) >> apple ($0.76) is their next item.
(11:10) >> avocado ($2.14) is their next item.
(11:15) >> Checkout done. Total: $15.49... Customer Rai leaves.
(11:20) Done processing line!
This program simulates events in a grocery store. The events.txt contains a series of commands, though you don't have to worry about parsing
the file. You only need to implement functionality in the GroceryStoreProgram.cpp file.
You will need to keep in mind these structures as you work on your class:
Product.h:
struct Product
{
string name;
float price;
};
Customer.h: Each Customer has a name and a stack of products_in_cart . Sometimes, customers will put something in their cart and then
change their mind. When this happens, the item at the top of the stack will be popped to be removed.
struct Customer
{
string name;
stack<string> products_in_cart;
};
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
GroceryStoreProgram.h:
class GroceryStoreProgram
{
public:
GroceryStoreProgram();
private:
queue<Customer> checkout_queue;
map<string, float> product_prices;
map<string, Customer> customers_in_store;
int minutes, hours;
queue<Customer> checkout_queue is the queue of customers in line waiting to check out. The customer at the front of the line gets
helped first.
map<string, float> product_prices is a map of product names -> product prices. This can be used to look up the price of a
product.
map<string, Customer> customers_in_store is a map of all customers in the store. The customer's name is the key, and then a
Customer object is the value.
Use the product as the key and the price as the value, adding the data to the product_prices map.
Use the customer as the key for a new item in the customers_in_store map.
Access the customer at the customer key. The Customer object contains a products_in_cart stack, push the new product onto that
stack.
Access the customer at the customer key. The Customer object contains a products_in_cart stack, use the pop function to remove the
last-added item from their cart.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
void GroceryStoreProgram::CustomerLineup( string customer )
Access the customer at the customer key in the customers_in_store map. Push this customer into the checkout_queue .
void GroceryStoreProgram::Process()
Hints:
Once everything is implemented, all the tests should pass. You can also run the program itself to see the "simulation" run.
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
WEEK 4 - FEB 5
UNIT 08: Recursion
📊 Presentation - Recursion (U08.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235cs250-unit08-recursion.html
📖️
Reading - Recursion (U08.READ)
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.
Summation:
A summation can be broken down into smaller chunks but using the same structure as the original.
∑i = 1 + 2 + 3 + 4 + 5 + 6
i=1
6 5
∑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. We can continue this way until we
get to a case that we know (e.g., ∑ i).
1i=1
∑ i = 6 + ∑ i
6i=1 5i=1
∑ i = 5 + ∑ i
5i=1 4i=1
∑ i = 4 + ∑ i
4i=1 3i=1
∑ i = 3 + ∑ i
3i=1 2i=1
∑ i = 2 + ∑ i
2i=1 1i=1
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
We know that ∑ 1i=1
i = 1 , then we move back up to sub out this value.
∑i = 6 + ∑i ∑ i = 6 + ∑ i = 6 + 15 = 21
B. J. ↑
5 4 5 4
∑i = 5 + ∑i ∑ i = 5 + ∑ i = 5 + 10 = 15
C. I. ↑
4 3 4 3
∑i = 4 + ∑i ∑ i = 4 + ∑ i = 4 + 6 = 10
D. H. ↑
3 2 3 2
∑i = 3 + ∑i ∑i = 3 + ∑i = 3 + 3 = 6
E. G. ↑
2 1 2 1
∑i = 2 + ∑i ∑i = 2 + ∑i = 2 + 1 = 3
F. ↑
∑i = 1
i=1
Factorials:
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.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Recursion in programming
// Iterative solution
int Sum( int n )
{
int result = 0;
for ( int i = 1; i <= n; i++ )
{
result += i;
}
return result;
}
∑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?
Recursion basics
1. 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
∑i = 1
i=1
We can solve these basic math operations both iteratively and recursively:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
// Iterative solution
int FactorialI( int n )
{
int result = 1;
for ( int i = 1; i <= n; i++ )
{
result *= i;
}
return result;
}
// Recursive solution
int FactorialR( int n )
{
if ( n == 1 || n == 0 ) { return 1; }
return n * FactorialR( n-1 );
}
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
figuring out how to think of it "recursively". It's not as natural-feeling, so don't worry if it's confusing at first.
Summation:
Try to convert the Summation function to be recursive. Think about what the terminating case would be and the recursive case. Use the
Factorial function for reference.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Solution for recursive summation:
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:
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 differently: The recursive function will only output one "-" before it recurses. Each time it recurses, it draws
one more dash…
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 overflow 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…
// Terminating case
if ( amount == 0 ) { return; }
// Recursive case
DrawLineR( amount - 1 );
}
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)?
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
void CountUpI( int start, int end )
{
for ( int i = start; i <= end; i++ )
{
cout << i << "\t";
}
}
// Terminating case
if ( start == end ) { return; }
// recursive case
CountUp_Recursive( start+1, end );
}
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.
On a harddrive, we generally have files and folders. Folders can contain files, 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 filesystem, how would you even begin to iteratively search for a specific file?
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…
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
1. folder = "C:", 2. folder = "work", 3. folder = "C:"
Is this "Recursion"? No. Is this "Recursion"? No. Are there subfolders? Yes.
Are there subfolders? Yes. Are there subfolders? No. Then, search next subfolder.
Then, search first subfolder. Return.
4. folder = "school" 5. folder = "cs210" 6. folder = "school"
Is this "Recursion"? No. Is this "Recursion"? No. Are there subfolders? Yes.
Are there subfolders? Yes. Are there subfolders? No. Then, search next subfolder.
Then, search next subfolder. Return.
7. folder = "cs235" 8. 9.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
And the recursive case would be:
Review questions:
Goals:
Turn-in:
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Continue scrolling down in the documentation and see if you're missing anything.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
For this assignment, I've already added the code to your repository.
.
├── graded_program
│ ├── FilesystemNode.h
│ ├── Functions.cpp
│ ├── Functions.h
│ ├── INFO.h
│ ├── main.cpp
│ ├── Project_CodeBlocks
│ │ ├── FilesystemProject.cbp
│ │ ├── FilesystemProject.depend
│ │ └── FilesystemProject.layout
│ ├── Project_Makefile
│ │ └── Makefile
│ └── Project_VisualStudio2022
│ ├── FilesystemProject.sln
│ ├── FilesystemProject.vcxproj
│ └── FilesystemProject.vcxproj.filters
├── practice1_countup
│ └── countup.cpp
├── practice2_abc
│ └── abc.cpp
├── practice3_countletter
│ └── countletter.cpp
└── practice4_factorial
└── factorial.cpp
practice1_countup
I've already implemented the iterative solution to this using a for loop. You'll be implementing the recursive solution.
This program doesn't have any unit tests, but the program itself is a manual test - you can visually check if the Recursive output matches the Iterative
output.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
CountUp_Iterative( 2, 5 ): 2 3 4 5
CountUp_Recursive( 2, 5 ): 2 3 4 5
CountUp_Iterative( 10, 20 ): 10 11 12 13 14 15 16 17 18 19 20
CountUp_Recursive( 10, 20 ): 10 11 12 13 14 15 16 17 18 19 20
Iterative version:
We use a for loop to start a counter i at the start position, loop while i is less than or equal to the end position, and add 1 to i each time.
Within the loop, we display the current value of i to the screen.
Recursive version:
and so on until finally the start value is past the end value, then
we're done - we terminate.
practice2_abc
MANUAL TESTS:
Abc_Iterative( 'A', 'G' ): ABCDEFG
Abc_Recursive( 'A', 'G' ): ABCDEFG
AUTOMATED TESTS:
[PASS] TEST 1, Abc_Recursive(a, f, "") = [abcdef]
[PASS] TEST 2, Abc_Recursive(C, G, "") = [CDEFG]
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This function takes in a start , end , and a built_string .
The function is responsible for filling the built_string with
the letters from start to end (inclusive). A char can be treated
like an integer, where adding 1 to a letter (like 'a' ) will give you
the next letter.
practice3_countletter
MANUAL TESTS:
CountLetter_Iterative( "Hello dello!", 'e' ): 2
CountLetter_Recursive( "Hello dello!", 'e' ): 2
AUTOMATED TESTS:
[PASS] TEST 1, CountLetter_Recursive("aabbcc", 'a', 0) = [2]
[PASS] TEST 2, CountLetter_Recursive("onethree", 'e', 0) = [3]
[PASS] TEST 3, CountLetter_Recursive("xyz", 'X', 0) = [0]
This function takes in a line of text and has a letter_to_count . When it finds that letter in the string, it will add one to the result. The i
variable is used as a counter, the current letter we're looking at in the text string.
Terminating case: If i is greater than or equal to text.size() , then we're done with the string. Return 0 in this case.
Recursive case:
a. If text[i] is equal to the letter_to_count , then return 1, plus another call to the function, passing in text , letter , and
i+1 .
b. Otherwise, ( text[i] is not equal to the letter_to_count ) return the function call, passing in text , letter , and i+1 . (I
like to put a 0 + at the start to mirror the other case and to be explicit that no additional letter is being counted, but the 0 + is not
required. I just think it helps readability.)
practice4_factorial
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
MANUAL TESTS:
Factorial_Iterative( 0 ): 1
Factorial_Recursive( 0 ): 1
Factorial_Iterative( 1 ): 1
Factorial_Recursive( 1 ): 1
Factorial_Iterative( 3 ): 6
Factorial_Recursive( 3 ): 6
Factorial_Iterative( 5 ): 120
Factorial_Recursive( 5 ): 120
AUTOMATED TESTS:
[PASS] TEST 1, Factorial_Recursive(0) = [1]
[PASS] TEST 2, Factorial_Recursive(1) = [1]
[PASS] TEST 3, Factorial_Recursive(3) = [6]
[PASS] TEST 4, Factorial_Recursive(5) = [120]
n! = n ⋅ (n − 1) ⋅ (n − 2)⋅. . . ⋅3 ⋅ 2 ⋅ 1
Graded program
/
home/
school/
english/
essay1.txt
essay2.txt
compsci/
homeworkA.cpp
homeworkB.cpp
projects/
my_game/
game.cpp
This program creates a representation of a filesystem on your computer. I've created a FilesystemNode object, which contains the following:
struct FilesystemNode
{
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
FilesystemNode() { }
FilesystemNode( string new_name, NodeType new_node_type )
{
name = new_name;
node_type = new_node_type;
}
Within Functions.cpp, a basic filesystem is created like what is shown in the example output above.
The program displays the filesystem using a recursive function, void DisplayContents( shared_ptr<FilesystemNode>
current_node, int tab ) , which I've already implemented.
The program will also allow the user to search the filesystem for a folder or file that matches the search text they enter. This function is also recursive,
and you will be implementing it.
Returns the path to the file/folder we're searching for, uses recursion.
1. If the current node's name has a partial match with the find_me parameter, then RETURN this current node's name as the result. To do a
partial string match:
2. Afterwards, use a loop to iterate over all of the current node's contents. Within the loop: RECURSE to the FindFile function, passing in this
CHILD node and the find_me data. STORE the result in a string variable. IF the result is NOT an empty string "", then we've found the file:
Return current_node->name + result
3. After the for loop, this means nothing was found in this recursive branch. In this case, just return an empty string "".
Once finished, run the Automated tests to verify that your function works properly. You can also run the Program itself to test the functionality
manually.
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
🏋️ Exercise - Debugging arrays and pointers (U08.EXE)
Do this assignment on Canvas: https://canvas.jccc.edu/courses/68318/modules/items/3910962
📖️
Reading - Searching and sorting (U09.READ)
Introduction to searching and sorting
Searching and sorting algorithms are things that we'll study in college, and perhaps see during job interviews, but for the most part in the daily life of
an average developer we may not be implementing these algorithms from scratch.
Like data structures, these algorithms have already been implemented and are available in various forms, usually already tested and optimized by
someone else, and you can use them in your programs by adding in third party libraries.
I'm just saying this because a some of this functionality of sorting algorithms may not make "intuitive" sense, and I find the code pretty ugly for a lot
of these, but you won't have to worry about these in the real world.
Searching algorithms
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
When we're working with structures of data - such as an array - we often need to find information stored within. Perhaps we know the element or a
piece of data we want to find, but we need to get the positional index of where it's located in the array. This is where our search algorithms come in
handy.
Linear search
Pseudocode:
LinearSearch (
Inputs: array, findme
Outputs: index of found item, or -1 if not found
)
begin function:
for i begins at 0, loop while i < array size, update i++ each loop
if array[i] matches findme, return i
end for
return -1
end function
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 checking each item in the structure for what you're looking for.
We begin at the first index 0 and iterate until we hit the last index. 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 structure, the time linearly increases to search through it. Not much we can
do about that, which is why we have different types of data structures that sort data as it is inserted - more on those later on.
Binary search
Pseudocode:
BinarySearch (
Inputs: array, findme
Outputs: index of found item, or -1 if not found
Note: array MUST BE SORTED
)
begin function:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
left = 0
right = array size - 1
return -1
end function
A binary search allows for a faster search - if the array passed in is sorted (otherwise it won't work!). The binary search cuts its search range in
half each iteration through the loop, thus giving us a log(n) growth rate.
Sorting algorithms
Selection sort
Pseudocode:
SelectionSort (
Inputs: array
Outputs: void
)
begin function:
for i begins at 0, loop while i < array size - 1, update i++ each loop
minindex = i
for j begins at i+1, loop while j < array size, update j++ each loop
if ( array[j] < array[minindex] ): minindex = j
end for
end for
end function
Bubble sort
Pseudocode:
BubbleSort (
Inputs: array
Outputs: void
)
begin function:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
for i begins at 0, loop while i < array size - 1, update i++ each loop
for j begins at 0, loop while j < array size - i - 1, update j++ eac
if ( array[j] > array[j+1] ): swap( array[j], array[j+1] )
end for
end for
end function
Insertion sort
Pseudocode:
InsertionSort (
Inputs: array
Outputs: void
)
begin function:
i = 1
while ( i < array size ):
j = i
i++;
end while
end function
Quick sort
Pseudocode:
Partition (
Inputs: array, lowindex, highindex
Outputs: an index value
)
begin function:
pivotvalue = array[high]
i = low - 1
for j begins at low, loop while j <= high - 1, update j++ each loop:
if ( array[j] <= pivotvalue ) then:
i++
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
swap( array[i], array[j] )
end if
end for
end function
------------------------------------------------------
QuickSort_Recursive (
Inputs: array, lowindex, highindex
Outputs: void
)
begin function:
end function
------------------------------------------------------
QuickSort (
Inputs: array
Outputs: void
)
begin function:
end function
Merge sort
MergeParts (
Inputs: array, left, mid, right
Outputs: void
)
begin function:
n1 = mid - left + 1
n2 = right - mid
for i begins at 0, loops while i < n1, updates i++ each loop:
leftarr push array[ left + i ]
end for
for j begins at 0, loops while j < n2, updates j++ each loop:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
rightarr push array[ mid + 1 + j ]
end for
i = 0
j = 0
k = left
k++
end while
while ( i < n1 ):
array[k] = leftarr[i]
i++
k++
end while
while ( j < n2 ):
array[k] = rightarr[j]
j++
k++
end while
end function
------------------------------------------------------
MergeSort_Recursive (
Inputs: array, left, right
Outputs: void
)
begin function:
end function
------------------------------------------------------
MergeSort (
Inputs: array
Outputs: void
)
begin function:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
end function
Heap sort
LeftChildIndex (
Inputs: index
Outputs: where this index's left child is
)
begin function:
return 2 * index + 1
end function
------------------------------------------------------
RightChildIndex (
Inputs: index
Outputs: where this index's right child is
)
begin function:
return 2 * index + 2
end function
------------------------------------------------------
ParentIndex (
Inputs: index
Outputs: where this index's parent is
)
begin function:
return floor( ( index - 1 ) / 2 )
end function
------------------------------------------------------
SiftDown (
Inputs: array, root, end
Outputs: void
)
begin function:
end while
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
end function
------------------------------------------------------
Heapify (
Inputs: array, end
Outputs: void
)
begin function:
end function
------------------------------------------------------
HeapSort (
Inputs: array
Outputs: void
)
begin function:
end function
Radix sort
CountSort (
Inputs: array, n, exp
Outputs: void
)
begin function:
output is an int array of size n (create as dynamic array)
count is an int array of size 10
count[0] = 0
for i starts at 1, loops while i < 10, updates i++ each loop:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
count[i] += count[i-1]
end for
for i starts at n-1, loops while i >= 0, updates i-- each loop:
output[ count[ ( array[i] / exp ) % 10 ] - 1 ] = array[i]
count[ ( array[i] / exp ) % 10 ]--
end for
------------------------------------------------------
GetMax (
Inputs: array
Outputs: the value of the largest item in the array
)
begin function:
maxvalue = array[0]
for i starts at 1, loops while i < array size, updates i++ each loop:
if ( array[i] > maxvalue ): maxvalue = array[i]
end for
return maxvalue
end function
------------------------------------------------------
RadixSort (
Inputs: array
Outputs: void
)
begin function:
for exp starts at 1, loop while maxvalue / exp > 0, update exp *= 10 e
CountSort( array, array size, exp )
end for
end function
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Goals:
Turn-in:
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
For this assignment, I've already added the code to your repository.
.
├── graded_program
│ ├── Functions.cpp
│ ├── Functions.h
│ ├── INFO.h
│ ├── main.cpp
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
│ ├── Project_CodeBlocks
│ │ ├── SearchSortProject.cbp
│ │ ├── SearchSortProject.depend
│ │ ├── SearchSortProject_exe
│ │ └── SearchSortProject.layout
│ ├── Project_Makefile
│ │ └── Makefile
│ ├── Searching
│ │ ├── BinarySearch.cpp
│ │ └── LinearSearch.cpp
│ ├── SearchSortProject
│ │ ├── SearchSortProject.sln
│ │ ├── SearchSortProject.vcxproj
│ │ └── SearchSortProject.vcxproj.filters
│ └── Sorting
│ ├── HeapSort.cpp
│ ├── MergeSort.cpp
│ ├── QuickSort.cpp
│ ├── RadixSort.cpp
│ └── SelectionSort.cpp
├── practice1_linearsearch
│ └── linearsearch.cpp
├── practice2_selectionsort
│ └── selectionsort.cpp
├── practice3_bubblesort
│ └── bubblesort.cpp
└── practice4_insertionsort
└── insertionsort.cpp
practice1_linearsearch
MANUAL TESTS:
Array: { 0="ice cream", 1="cake", 2="cookies", 3="pie" }
Search for "cookies": 2
Search for "rasgulla": -1
AUTOMATED TESTS:
[PASS] TEST 1, LinearSearch( { 0="dog", 1="rat", 2="cat" }, "cat" ) = 2
[PASS] TEST 2, LinearSearch( { 0="Anuj", 1="Rai", 2="Asha" }, "Rai" ) = 1
[PASS] TEST 3, LinearSearch( { 0="One", 1="Two", 2="Three" }, "Four" ) = -1
A linear search is a simple search. Use a loop to iterate over all the letters of the arr vector. For each element, check to see if arr[i] is equal to
find_me . If it matches, return i , the index it was found at. (No ELSE case is needed INSIDE the for loop!)
If the for loop finishes, that means we searched the entire vector and no match was found. In this case, before the function ends, return -1 to
represent "not found".
practice2_selectionsort
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
MANUAL TESTS:
Original: { 0="ice cream", 1="cake", 2="cookies", 3="pie" }
AUTOMATED TESTS:
[PASS] TEST 1, SelectionSort( { 0="c", 1="a", 2="t" } ) =
{ 0="a", 1="c", 2="t" }
[PASS] TEST 2, SelectionSort( { 0="h", 1="e", 2="l", 3="l", 4="o" } ) =
{ 0="e", 1="h", 2="l", 3="l", 4="o" }
Pseudocode:
SelectionSort (
Inputs: array
Outputs: void
)
begin function:
for i begins at 0, loop while i < array size - 1, update i++ each loop:
minindex = i
for j begins at i+1, loop while j < array size, update j++ each loop:
if ( array[j] < array[minindex] ): minindex = j
end for
end for
end function
Translate the pseudocode into C++. You can also view other implementations of each sorting algorithm for reference.
practice3_bubblesort
MANUAL TESTS:
Original: { 0="ice cream", 1="cake", 2="cookies", 3="pie" }
AUTOMATED TESTS:
[PASS] TEST 1, BubbleSort( { 0="c", 1="a", 2="t" } ) =
{ 0="a", 1="c", 2="t" }
[PASS] TEST 2, BubbleSort( { 0="h", 1="e", 2="l", 3="l", 4="o" } ) =
{ 0="e", 1="h", 2="l", 3="l", 4="o" }
Pseudocode:
BubbleSort (
Inputs: array
Outputs: void
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
)
begin function:
for i begins at 0, loop while i < array size - 1, update i++ each loop:
for j begins at 0, loop while j < array size - i - 1, update j++ each lo
if ( array[j] > array[j+1] ): swap( array[j], array[j+1] )
end for
end for
end function
practice4_insertionsort
MANUAL TESTS:
Original: { 0="ice cream", 1="cake", 2="cookies", 3="pie" }
AUTOMATED TESTS:
[PASS] TEST 1, InsertionSort( { 0="c", 1="a", 2="t" } ) =
{ 0="a", 1="c", 2="t" }
[PASS] TEST 2, InsertionSort( { 0="h", 1="e", 2="l", 3="l", 4="o" } ) =
{ 0="e", 1="h", 2="l", 3="l", 4="o" }
Pseudocode:
InsertionSort (
Inputs: array
Outputs: void
)
begin function:
i = 1
while ( i < array size ):
j = i
i++;
end while
end function
Graded program
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Run PROGRAMS
>> 2
Generating 100000 pieces of data... 4 milliseconds
This program creates a bunch of data to sort and running it will show you how long each algorithm takes to complete. Every computer will have
different results. You can also use the automated tests to verify your function implementations as well.
Sorting/
HeapSort.cpp
MergeSort.cpp
QuickSort.cpp
RadixSort.cpp
Searching/
BinarySearch.cpp
Some sorting algorithms contain multiple functions for different steps of the process. Pseudocode will be provided for each.
(You do NOT need to have these algorithms memorized or really to understand them. You might encounter them later on in other bachelors level CS
classes so it's good to be familiar with them. You can look these algorithms up anywhere, it's not like they're secret knowledge.)
QuickSort
Pseudocode:
Partition (
Inputs: array, lowindex, highindex
Outputs: an index value
)
begin function:
pivotvalue = array[high]
i = low - 1
for j begins at low, loop while j <= high-1, update j++ each loop:
if ( array[j] <= pivotvalue ) then:
i++
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
swap( array[i], array[j] )
end if
end for
end function
------------------------------------------------------
QuickSort_Recursive (
Inputs: array, lowindex, highindex
Outputs: void
)
begin function:
end function
------------------------------------------------------
QuickSort (
Inputs: array
Outputs: void
)
begin function:
end function
MergeSort
MergeParts (
Inputs: array, left, mid, right
Outputs: void
)
begin function:
n1 = mid - left + 1
n2 = right - mid
for i begins at 0, loops while i < n1, updates i++ each loop:
leftarr push array[ left + i ]
end for
for j begins at 0, loops while j < n2, updates j++ each loop:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
rightarr push array[ mid + 1 + j ]
end for
i = 0
j = 0
k = left
k++
end while
while ( i < n1 ):
array[k] = leftarr[i]
i++
k++
end while
while ( j < n2 ):
array[k] = rightarr[j]
j++
k++
end while
end function
------------------------------------------------------
MergeSort_Recursive (
Inputs: array, left, right
Outputs: void
)
begin function:
end function
------------------------------------------------------
MergeSort (
Inputs: array
Outputs: void
)
begin function:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
end function
HeapSort
LeftChildIndex (
Inputs: index
Outputs: where this index's left child is
)
begin function:
return 2 * index + 1
end function
------------------------------------------------------
RightChildIndex (
Inputs: index
Outputs: where this index's right child is
)
begin function:
return 2 * index + 2
end function
------------------------------------------------------
ParentIndex (
Inputs: index
Outputs: where this index's parent is
)
begin function:
return floor( ( index - 1 ) / 2 )
end function
------------------------------------------------------
SiftDown (
Inputs: array, root, end
Outputs: void
)
begin function:
end while
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
end function
------------------------------------------------------
Heapify (
Inputs: array, end
Outputs: void
)
begin function:
end function
------------------------------------------------------
HeapSort (
Inputs: array
Outputs: void
)
begin function:
end function
RadixSort
Radix sort
CountSort (
Inputs: array, n, exp
Outputs: void
)
begin function:
output is an int array of size n (might need to be a dynamic array)
count is an int array of size 10
count[0] = 0
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
for i starts at 1, loops while i < 10, updates i++ each loop:
count[i] += count[i-1]
end for
for i starts at n-1, loops while i >= 0, updates i-- each loop:
output[ count[ ( array[i] / exp ) % 10 ] - 1 ] = array[i]
count[ ( array[i] / exp ) % 10 ]--
end for
------------------------------------------------------
GetMax (
Inputs: array
Outputs: the value of the largest item in the array
)
begin function:
maxvalue = array[0]
for i starts at 1, loops while i < array size, updates i++ each loop:
if ( array[i] > maxvalue ): maxvalue = array[i]
end for
return maxvalue
end function
------------------------------------------------------
RadixSort (
Inputs: array
Outputs: void
)
begin function:
for exp starts at 1, loop while maxvalue / exp > 0, update exp *= 10 e
CountSort( array, array size, exp )
end for
end function
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
Here are a few ways that I approach challenges to help me figure out a solution:
1. Sketch it on paper - Diagramming parts of a program, or writing down data, or otherwise organizing my thoughts on paper help me visualize
the problem. It can also be helpful to step through the code and writing down the values of each variable on paper as you go, to help you figure
out the program flow and variable values.
2. Ask myself "What is the program doing that it shouldn't be doing… or… what is the program not doing that I want it to do?" - Being
able to define what exactly is wrong with your program will help you in solving it, or at least talking to someone else to get ideas for how to
solve it.
3. Rubber duck debugging - This is a technique where you talk through the issue with an object, a pet, or another person. Sometimes, just talking
through the problem can help you figure out a solution.
4. Step away - When you feel like you're hitting your head against a wall and just can't think through anything it is time to step away. Your brain is
done and you won't come up with any solutions, but even a half hour break can help you come back with a new perspective. Don't try to force
yourself through this kind of roadblock - give yourself a break.
5. Write out the steps in pseudocode - When trying to design something, I will usually write down the items it needs to accomplish as
pseudocode, or as a series of function calls or actions that need to occur. Implementation details can come later once I know where I need to go.
Locate the 🧠 Tech Literacy - Problem solving assignment and add to the discussion!
WEEK 5 - FEB 12
UNIT 10: Templates
📊 Presentation - Templates (UX.PRES) - WORK IN PROGRESS
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235cs250-unit10-templates.html
📖️
Reading - Templates (U10.READ)
Before Templates
Templates don't exist in C++'s precursor, C. Because of this, if you had a function like - for example - SumTwoNumbers
that you wanted to work with different data types, you would have to define different functions for each version. C also doesn't have function
overloading, so they would have to have different names as well.
glVertex2f( 0, 0 );
glVertex3f( 0, 0, 0 );
With C++ and other languages like C# and Java, we can now use Templates with our functions and classes. A Template allows us to specify a
placeholder for a data type which will be filled in later.
In the C++ Standard Template Library, there are objects like the vector that is essentially a dynamic array, but it can store any data type - we just have
to tell it what it's storing when we declare a vector object:
vector<int> listOfQuantities;
vector<float> listOfPrices;
vector<string> listOfNames;
We can also define our own functions and even classes with templated functions and member variables ourselves, leading to much more reusable
code.
Templated functions
We can write a standalone function with templated parameters or a templated return type or both. For example, here's a simple function to add
two items together:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
return numA + numB;
}
This function can be called with any data type, so long as the data type has the + operator defined for it - so, if it were a custom class you
wrote, you would have to overload the operator+ function.
What this means is that we can call Sum with integers and floats, but also with someting like a string, since strings use the + operator to
combine two strings together.
int main()
{
int intA = 4, intB = 6;
float floatA = 3.9, floatB = 2.5;
string strA = "alpha", strB = "bet";
Program output:
4 + 6 = 10
3.9 + 2.5 = 6.4
alpha + bet = alphabet
Templated classes
More frequently, you will be using templates to create classes for data structures that can store any kind of data. The C++ Standard Template
Library has data structures like vector, list, and map, but we can also write our own.
When creating our templated class, there are a few things to keep in mind:
1. We need to use template <typename T> at the beginning of the class declaration.
2. Method definitions must be in the header file - in this case, we won't be putting the method definitions in a separate .cpp file. You can
either define the functions inside the class declaration, or immediately after it.
3. Method definitions also need to be prefixed with template <typename T> .
If you try to create a "TemplatedArray.h" file and a "TemplatedArray.cpp" file and put your method definitions in the .cpp file, then you're going
to get compile errors:
You might think, "Well, that's weird." - and yes, it is. C++ is a strange language with weird behaviors. In this case in particular, you can read
about why this is for templates here: https://isocpp.org/wiki/faq/templates%5C#templates-defn-vs-decl
In short, the template command is used to generate classes, and while our class declaration looks normal, this is actually special code that is just
telling the compiler how it's going to generate a family of classes. Because of this, the compiler needs to see the function definitions as well.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Example TemplatedArray (Full):
This is all in one file - TemplatedArray.hpp. I have the class declaration on top, with all the definitions below.
#ifndef _TEMPLATED_ARRAY
#define _TEMPLATED_ARRAY
#include <stdexcept>
using namespace std;
bool IsFull();
bool IsEmpty();
void Display();
int Size();
private:
void AllocateMemory( int size );
void DeallocateMemory();
int m_arraySize;
int m_storedItems;
T* m_array;
};
// Constructors/Destructor
template <typename T>
TemplatedArray<T>::TemplatedArray()
{
m_arraySize = 0;
m_storedItems = 0;
// Be safe: Initialize pointers to nullptr.
m_array = nullptr;
}
// Other functionality
template <typename T>
void TemplatedArray<T>::PushToBack( T item )
{
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
if ( IsFull() )
{
throw runtime_error( "Array is full!" );
}
if ( m_array == nullptr )
{
AllocateMemory( 10 );
}
// Lazy deletion
m_storedItems--;
}
// Private methods
template <typename T>
void TemplatedArray<T>::AllocateMemory( int size )
{
// Clear out any memory currently stored
DeallocateMemory();
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
template <typename T>
void TemplatedArray<T>::DeallocateMemory()
{
// Free the memory allocated
if ( m_array != nullptr )
{
delete [] m_array;
m_array = nullptr;
m_arraySize = 0;
m_storedItems = 0;
}
}
#endif
This basic templated data structure is now ready to store any kind of data. In this case, the only requirement is that the object being stored has the
ostream<< operator function overloaded, since it is used in the Display() function.
#include "TemplatedArray.hpp"
#include <iostream>
using namespace std;
int main()
{
TemplatedArray<string> myList( 10 );
myList.PushToBack( "cat" );
myList.PushToBack( "rat" );
myList.PushToBack( "bat" );
myList.Display();
myList.RemoveFromBack();
myList.Display();
return 0;
}
Review questions:
1. A templated standalone function that uses the template placeholder type T as a parameter looks like…
2. The declaration of a templated class looks like…
3. The definition of a templated class' member function looks like…
4. Declaring an object whose data type is a templated class will look like…
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
UNIT 11: Exceptions
📊 Presentation - Exceptions (U10.PRES) - WORK IN PROGRESS
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235cs250-unit11-exceptions.html
📖️
Reading - Exceptions (U11.READ)
As a software developer, you will often be writing software that other developers will be using. This could be other developers at the company
working on the same software product, or perhaps you might write a library that gets licensed out to other companies, or anything else. Your code will
need to have checks in place for errors and be able to manage those errors gracefully, allowing the software to continue running instead of letting the
program crash and restart.
A long time ago, lots of developers used numeric error codes to track errors. If you've ever seen something like "Error 12943" with no other useful
information, that is an example of these error codes - useless for the end-user, but meant so that the programmer can search the code for that number
and find where it broke. This is also why we use return 0 at the end of our C++ programs - technically, you could return anything else, but
returning 0 is meant to show that there were no errors. If you ran into an error, you /could return 1 or 2 or 3 instead to mark errors.
Modern languages have exception handling built in, usually working with a try/catch style. You write in logic to check for errors, and when you find
a problem you throw an exception, and that exception can be caught elseware in the code.
C++ has an exception family of objects that we can use when trying to classify what kind of exception has happened. If none of the existing
exception objects is appropriate, you can also create your own exception type.
You can find documentation for the exception object here: http://www.cplusplus.com/reference/exception/exception/
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Exception class Description
bad_alloc Exception thrown on failure allocating memory
bad_cast Exception thrown on failure to dynamic cast
bad_exception Exception thrown by unexpected handler
bad_function_call Exception thrown on bad call
bad_typeid Exception thrown on typeid of null pointer
bad_weak_ptr Bad weak pointer
ios_base::failure Base class for stream exceptions
logic_error Logic error exception
runtime_error Runtime error exception
domain_error Domain error exception
future_error Future error exception
invalid_argument Invalid argument exception
length_error Length error exception
out_of_range Out-of-range exception
overflow_error Overflow error exception
range_error Range error exception
system_error System error exception\
underflow_error Underflow error exception
bad_array_new_length Exception on bad array length
The first step of dealing with exceptions is identifying a place where an error may occur - such as a place where we might end up dividing by
zero. We write an if statement to check for the error case, and then throw an exception. We choose an exception type and we can also pass an
error message as a string.
Now we know that the function ShareCookies could possibly throw an exception. Any time we call that function, we need to listen
for any thrown exceptions by using try.
try
{
// Calling the function
cookiesPerKid = ShareCookies( c, k );
}
Immediately following the try, we can write one or more catch blocks for different types of exceptions and then decide how we want to
handle it.
try
{
// Calling the function
cookiesPerKid = ShareCookies( c, k );
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
}
catch( runtime_error ex )
{
// Display the error message
cout << "Error: " << ex.what() << endl;
cout << "The kids get " << cookiesPerKid << " each" << endl;
A function could possibly throw different types of exceptions for different errors, and you can have multiple catch blocks for each type.
Handling the error: Once you catch an error, it's up to you to decide what to do with it. For example, you could…
Coding with others' code: While writing software and utilizing others' code, you will want to pay attention to which functions you're
calling that could throw exceptions. Often code libraries will contain documentation that specify possible exceptions thrown.
A common error I see students make is to put the try, catch, and throw statements all in one function. This defeats the point of even using
exceptions.
Don't do this:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Remember that the throw belongs within a function that could cause an error, and the try/catch belongs with the location that calls the
potentially exception-causing function.
int main()
{
float n, d;
cout << "Enter num: ";
cin >> n;
float result = 0;
try
{
// CALLING "IFFY" FUNCTION - Wrap the CALL in try/catch
result = Divide( n, d );
}
catch( Exception& ex )
{
cout << "ERROR OCCURRED!" << endl;
return 1234;
}
return 0;
}
Review questions:
Turn-in:
You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Dual enrollment: If you are in both my CS 235 and CS 250 this semester, these instructions are the same. You
only need to implement it once and upload it to one repository, then turn in the link for the one merge request. Please turn in on
both Canvas assignments so they're marked done.
For this assignment, I've already added the code to your repository.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
.
├── graded_program
│ ├── DataStructure
│ │ └── SmartFixedArray.h
│ ├── Exception
│ │ ├── InvalidIndexException.h
│ │ ├── ItemNotFoundException.h
│ │ ├── NotImplementedException.h
│ │ ├── StructureEmptyException.h
│ │ └── StructureFullException.h
│ ├── main.cpp
│ ├── Project_CodeBlocks
│ │ ├── TemplateProgram.cbp
│ │ ├── TemplateProgram.depend
│ │ └── TemplateProgram.layout
│ ├── Project_Makefile
│ │ └── Makefile
│ ├── Project_VisualStudio2022
│ │ ├── TemplateProgram.sln
│ │ ├── TemplateProgram.vcxproj
│ │ └── TemplateProgram.vcxproj.filters
│ └── Tester
│ ├── SmartFixedArrayTester.cpp
│ └── SmartFixedArrayTester.h
├── practice1_functions
│ └── templfunctions.cpp
├── practice2_structs
│ └── templstruct.cpp
├── practice3_stdexcept
│ └── stdexcept.cpp
└── practice4_customexcept
└── customexcept.cpp
practice1_functions
FIELD DATA
---------------------------------------------------------------------------
product USB-C cable pack
price 9.99
quantity 5
sold_out 0
For this practice program we are looking at templated functions. Starting off, we have three functions for three different data types, even though they
do basically the same thing:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
cout << setw( 20 ) << variable_name << setw( 20 ) << variable_value << end
}
Convert one of these functions into a templated function so that the variable_value can be any data type T . Remove the other two duplicates.
The code in main() should continue working as usual, and you can add more variables with different data types and display their values now, too.
practice2_structs
This program starts with a Node class that can only contain string data:
struct Node
{
Node()
{
ptr_next = nullptr;
ptr_prev = nullptr;
}
string data;
Node* ptr_next;
Node* ptr_prev;
};
As well as a PrintTable function that only works with this sort of Node:
Update the Node struct to be a templated struct. Change the string data to a T data type.
You'll also have to update the PrintTable to support templated Nodes as its parameters.
Further below in main() , update the set of Nodes already created to be Node<string> types. For additional practice, create another set of Nodes
with a different data type and see that everything still works for the other data type as well.
practice3_stdexcept
---------------------------------------------------------------------------
DIVISION EXAMPLE
Enter a numerator and denominator, separated by a space: 5 0
invalid_argument Exception: Division by 0 not allowed!
---------------------------------------------------------------------------
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
DISPLAY EXAMPLE
Enter an index between 0 and 4: 600
out_of_range Exception: Invalid index!
---------------------------------------------------------------------------
POINTER EXAMPLE
Display good_ptr...
Item being pointed to is: 600
Display bad_pointer...
invalid_argument Exception: ptr is null!
For this program we have a few "risky functions" that could encounter errors. Currently, they have no error checking, and main() is not listening
for any errors, either.
For the Divide , Display , and PtrDisplay functions, add if statements to check for certain error scenarios and throw the appropriate
exception if found:
When throwing an exception, add a message string in the constructor so that the exception has a description to help programmers figure out waht went
wrong…
Down in main() , I've marked certain functions as "!! Risky function call !!". These functions need to be surrounded in a try {} block (one try
for each function), and then have a catch statement following, listening for the type of exception that the risky function might throw - so when
calling Divide, use catch( const invalid_argument& ex ) , and so on.
When an exception is caught, use cout to display the exception information ( ex.what() ).
practice4_customexcept
---------------------------------------------------------------------------
PIZZA PARTY
How many pizza slices at pizza party? 50
How many friends at party? 0
For this program, we're going to inherit from an exception class and create our own exception.
Custom exceptions:
Replace "EXCEPTIONTYPE" with the name of the exception you're creating. This is just creating a new class, inheriting from runtime_error ,
and setting up its constructor. The : std::runtime_error(message) line is calling the parent class' constructor, passing in the message .
The parent class will handle dealing with the message, but we could add additional functionality in our constructor if needed. In this case, I just have
an additional message for this exception type.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
SlicesPerPerson function:
main():
In main, wrap the "risky function call" ( SlicesPerPerson( friendCount, pizzaSliceCount ) ) with a try {} block. Create two
catch blocks afterwards, one listening for the NotEnoughFriendsException exception, and one listening for the
NotEnoughPizzaException exception. Display each exception's error message ( ex.what() ) within each catch statement.
Graded program
For the graded program there are only automated tests and no program right now. We will be editing the SmartFixedArray class, located within
the DataStructure folder.
The SmartFixedArray class is a templated class that stores a fixed-length array within it. We are sort of implementing part of the STL array
class, just fewer features.
Keep in mind the member variables that belong to this class, which will be important as you implement the SmartFixedArray's functionality:
Custom exceptions:
These exceptions are provided already, and you will use them in various functions:
Exception Description
InvalidIndexException
ItemNotFoundException Thrown by Search when an item requested is not found
NotImplementedException All the functions have this by default to mark them as incomplete
StructureEmptyException Thrown when trying to Pop or Get data from an empty array
StructureFullException Thrown when trying to Push data to an array that is full
Automated testing: Make sure to run the automated tests to verify that your data structure fully works!
SmartFixedArray<T>::SmartFixedArray()
When we start off, we mark the array as empty. To do this, we just set this->item_count to 0.
Even though the amount of memory allocated doesn't get changed throughout the lifetime of our array, we marked "filled in" spaces by
adjusting the item count.
SmartFixedArray<T>::Clear()
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
This function "deletes" all the items in the array… however, we're going to do lazy deletion. Basically, by setting this->item_count to 0,
we effectively say "there's nothing in this array!". All the old data will be overwritten sooner or later when new data is added.
SmartFixedArray<T>::Size() const
Return
The current amount of items stored in the array
This function is responsible for telling us how many pieces of data are currently stored in the array. This is reflected by the this-
>item_count variable (NOT the total this->ARRAY_SIZE , which marks the maximum capacity of the array!)
SmartFixedArray<T>::IsFull() const
Return
true if the array is full, or false otherwise.
This function will tell us if the array is currently full. The maximum capacity of the array is stored in this->ARRAY_SIZE , so if this-
>item_count matches that, then it means we've filled up all possible spaces.
SmartFixedArray<T>::IsEmpty() const
Return
true if the array is empty, or false otherwise.
The this->item_count represents how many items are currently stored in the array, so if it is 0, then that means the array is empty.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
SmartFixedArray<T>::Search( T item ) const
Parameters
item , the data we're searching for.
Return
Returns the index of the item found
Exception
If the item is not found in the array, then throw a ItemNotFoundException .
Use a basic Linear Search to iterate over all the used elements of the array (0 to this->item_count ), looking at each item. If the item
asked for is found within your loop, then return the index of this item (usually i in a for loop).
After the for loop is over, this means the item wasn't found, so in this case throw the ItemNotFoundException . (Don't throw this INSIDE
THE FOR LOOP! Logic error…)
Parameters
index , all items to the right of this index value will be shifted to the left.
Exception
If the index is invalid then throw an InvalidIndexException . The index is invalid if index is less than 0 or greater than or
equal to this->item_count , as we want to keep our items contiguous in the array.
Use a for loop to shift everything to the right of the index position to the left.
(Note: DON'T adjust the item count here! This is just a helper function and the function that calls it will handle adjusting item count as needed.)
With an assignment statement, you can move things over from its neighbor: this->data[i] = this-
>data[i+1]
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Parameters
index , all items to the right of this index value will be shifted to the left.
Exception
If the index is invalid then throw an InvalidIndexException . The index is invalid if index is less than 0 or greater than or
equal to this->item_count , as we want to keep our items contiguous in the array.
If the array is full (call IsFull() to check) then throw a StructureFullException , as there is no more space in the array.
Use a for loop to take everything at index position and to its right and shift these items further to the right.
(Note: DON'T adjust the item count here! This is just a helper function and the function that calls it will handle adjusting item count as needed.)
With an assignment statement, you can move things over from its neighbor: this->data[i] = this-
>data[i-1] . You'll want to make sure to start your loop at the end of the range and go towards the index.
SmartFixedArray<T>::PushBack( T newItem )
Parameters
newItem is a new piece of data to eb added to the back (end) of the array.
Exception
If the array is full (call IsFull() to check) then throw a StructureFullException .
The this->item_count contains the amount of items that are currently stored in the array, but this number ALSO corresponds to the next
location where you need to add your data.
Insert the newItem into your this->data array at the this->item_count position, then make sure to increment this-
>item_count .
SmartFixedArray<T>::PopBack()
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Exception
If the array is empty (call IsEmpty() to check) then throw StructureEmptyException .
This function "deletes" the item at the current end of hte items in the array. However, we just do a "lazy deletion" here by decrementing this-
>item_count . We don't need to do anything with the data itself, because it will be overwritten by the next Push call.
SmartFixedArray<T>::GetBack()
Exception
If the array is empty (call IsEmpty() to check) then throw StructureEmptyException .
Return
Return the element of this->data[] at the this->item_count-1 position.
This function returns the last item in the contiguous list of elements in the array… Basically, whatever is at size-1, or this->item_count-
1.
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
4. Click "Submit assignment" to finish.
WEEK 6 - FEB 19
UNIT 12: Overloading functions and constructors
📊 Presentation - Overloading functions (U12.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235-unit12-overloadfunc.html
📖️
Reading - Overloading functions (U12.READ)
Function overloading
In C++, you can also write multiple functions that have the same name, but a different 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 floats and a version for integers:
You can write as many versions of the function as you like, so long as the function headers are uniquely identifiable to the compiler, which means:
The return type doesn't factor into the function's uniqueness, so make sure that you're changing up the parameter list.
Here we have a program that uses a ConfigManager class to deal with saving and loading program settings to a file. While the program runs, we
probably want to be able to update settings, and those settings will be stored as a key, value pair of some kind.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Some settings, like " screen_width ", might be an integer, while other settings, like " last_save_game " might be a string. Within the
ConfigManager, we provide two different functions to be able to update either type of option:
class ConfigManager
{
public:
void Load( std::ifstream& input );
void Save();
To call the function, let's say we have a ConfigManager config; variable declared and set up. We could call the Set function in either of these
ways:
Here is a MenuManager that stores things like UILabel objects and other elements. These elements go on separate layers and each element has a
unit name .
The GetLabel function can be overloaded so that when we call it, we don't necessarily need the layer name - that version of the function does a
search. Or, we can call the version and provide the layer name, and the element can be accessed directly and much more quickly.
class MenuManager
{
public:
UILabel& GetLabel( const std::string& layer, const std::string
UILabel& GetLabel( const std::string& name );
// ... etc ...
private:
std::map< std::string, UILayer > m_layers;
// ... etc ...
};
To call the function, let's say we have a MenuManager menuManager; variable declared and set up. We could call the GetLabel function in either
of these ways:
// Slow version
UILabel& currentLabel = menuManager.GetLabel( "filename" );
// Fast version
UILabel& currentLabel = menuManager.GetLabel( "file_info", "filename" );
Constructor overloading
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Class constructors are special functions that are called automatically when a new object (of that class type) is instantiated. (In other words, when
you declare a new variable and the data type is that class.)
There are three main types of constructors we can write, each of them overloaded.
Default constructor
The default constructor has no parameters and is called automatically when we declare a class object variable like this:
MyClass variablename;
Default constructors are usually used to initialize an object to get it ready for usage. This can include:
MyClass.h MyClass.cpp
private:
int m_memberVariable;
};
Many programs have some kind of Logger that writes out events while the program is running to a external text file (or other format). This
can help diagnose issues if errors occur.
If we were creating a Logger class, it would be useful to open the log file automatically when the Logger object is created, and close the log
file automatically when the object is destroyed.
Logger.h Logger.cpp
Elseware in the program, the Logger will be created, and that log file will be opened automatically:
Logger logger;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Parameterized constructor
A parameterized constructor is when we have one or more parameter in the constructor's parameter list. These are values that will be passed
into the object as it's being instantiated, and these values can be used to set values to the object's member variables immediately.
MyClass.h MyClass.cpp
private:
int m_memberVariable;
};
Similarly to the default constructor example, but maybe there is a time where we want to specify what that logger file is. Perhaps the
parameterized constructor will be called most of the time, but if we don't know what file to use we lean back on the default constructor.
Logger.h Logger.cpp
Elseware in the program, the Logger will be created, and that log file will be opened automatically:
Copy constructor
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
With a copy constructor the idea is that we want to copy information from one object to another object - to make a copy of that original object.
In some cases, maybe we want to copy all of the member variable values over. In other cases, perhaps we don't want to copy over all the data -
such as if the class has a pointer to a memory address.
MyClass.h MyClass.cpp
private:
int m_memberVariable;
int* m_pointer;
};
For this constructor, we need another object of the same type declared already, and we pass in that other object to make a copy of it.
MyClass original;
MyClass copied( original );
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Example of a deep copy:
A program might have some sort of data that you might want to make a copy of to do work on but not potentially mess up the original data set.
This can be good if you want to sort the data or perform operations on the data.
Additional notes
If no constructors are declared, a default parameter is generated automatically at compile-time.
If a parameterized or copy constructor is declared but not a default parameter, then no default constructor will be generated at compile-
time.
📖️
Reading - Default parameters (U13.READ)
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 specified in a function declaration - NOT the definition!
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).
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
void OutputIngredients( float eggs, float sugar, float flour, float batch =
You can have multiple default parameters specified in your function declaration - but all variables with default values must go after any variables
without default values.
In the Overloaded Functions part we showed having a Logger class with multiple constructors. With this particular example, it would actually be
better to use a default parameter instead of overloading!
Logger.h Logger.cpp
Elseware in the program, the Logger will be created, and that log file will be opened automatically. We can specify a file or not, and both will use the
same constructor:
Logger logger();
Logger logger( "log-sept-28.txt" );
Additional notes
According to the C++ Core Guidelines: "F.51: Where there is a choice, prefer default arguments over overloading"
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#reason-67
Turn-in:
1. You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Start this assignment by checking out main , pulling latest to get the files, and creating a new branch…
PRACTICE PROGRAMS: Practice programs for this lab are located in the u12u13_Overloading_DefaultParams folder in your
repository.
.
├── practice1_overload_functions
│ └── overloadfx.cpp
├── practice2_default_params
│ └── defaultparams.cpp
└── practice3_in_classes
├── File.cpp
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
├── File.h
├── fileout
└── main.cpp
GRADED PROGRAM: For this and future assignents we will be using the cs235_application for graded assignments.
.
├── Filesystem
│ ├── File.cpp
│ ├── File.h
│ ├── FileTester.cpp
│ └── FileTester.h
├── main.cpp
├── Namespace_Utilities
│ ├── ScreenDrawer.cpp
│ └── ScreenDrawer.hpp
├── Program
│ ├── Program.cpp
│ └── Program.h
├── Project_CodeBlocks
│ ├── cs235_program.cbp
│ ├── cs235_program.depend
│ └── cs235_program.layout
├── Project_Makefile
│ └── Makefile
└── Project_VisualStudio2022
├── CS235_Application.sln
├── CS235_Application.vcxproj
└── CS235_Application.vcxproj.filters
Practice programs
SPRING 2024 NOTE: I accidentally added the "solution" version of all the practice programs to everybody's repositories and I
don't feel like fixing this so you can look over these to learn from if you want, or you can erase the code and implement them for
practice.
practice1_overload_functions
For this program, we're going to create 3 overloaded standalone functions that will format data in a table:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
cout << string( 80, '-' ) << endl;
The "Name" column gets 40 spaces, the "Price" column gets 20 spaces, and the "In stock" column gets 20 spaces.
Within each of the overloaded DisplayProduct functions, follow this example to write out whatever data is available (e.g., just name, or
name and price, or name and price and quantity).
practice2_default_params
This is the same program as practice1, except we create ONE DisplayProduct function, and set default parameters for the price and
quantity parameters.
Note that usually you'd be putting your function declaration in a separate .h file:
And the function definition goes in a .cpp file, and does not have the default parameter values in the parameter list:
practice3_in_classes
This program has a File class that will use overloaded functions and default parameters. It is similar to the graded program, but it is not
exactly the same, so don't get confused by the differences!
UML Diagram:
File
- name : string
- ext : string
+ File()
The CreateFile function should use default parameters, setting ext to "txt" and text to "hello" if nothing is given.
Function implementation:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Write the text to the ofstream object.
Close the ofstream object.
Context: Using the this-> pointer refers back to the class object that you're currently within. this-> can be used to access its
own member variables and functions. It is optional, but can be used for clarity.
Within main() , test the various ways to create a file like this:
#include <iostream>
using namespace std;
#include "File.h"
int main()
{
File fileA;
return 0;
}
After building and running the program, your text files will be created in the fileout folder:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Open them up and make sure they have the proper contents within.
Graded program
FYI: cs235 application
For this set of units and future units the graded part of the labs will be in the cs235_application .
At the moment, the menus are here but the program won't work until you implement the File class. These screenshots show a finished
version.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Here, you select what type of document to create.
Then you enter in lines of text to the file, then type :q and hit ENTER to finish.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Back at the main menu, if you select View documents, the documents you've created will show up. You can select a document and it will show
the contents of the file:
At the moment, no actual files are created on your computer, these are just abstractions within the File class.
Note: You can also run the automated tests from the main menu with the "11" option.
The File class declaration has already been declared, and you will be implementing its functions. Please take note of the File class and its
member variables to help you with your implementation.
UML Diagram:
File Notes
- path : string
- name : string
- ext : string
- contents : vector<string>
+ File()
+ OpenFile( path: string, name: string, ext: string ) : void ext defaults to "txt"
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
File Notes
+ Display() : void
+ GetFullname() : string
+ GetContents() : vector<string>
File::File()
Call the OpenFile function, passing in default values (like "NOTSET") for all the arguments.
Call the OpenFile function, passing the path, and name to that function.
Call the OpenFile function, passing the path, name, and ext to that function.
Call the OpenFile function, passing in the other object's path, name plus " (copy)", and extension. Afterwards, set this->contents to
the other object's contents.
Set the member variables this->path , this->name , and this->ext to the values passed in as the parameters.
Iterate over all the lines in the file, displaying each one on its own line. Also display the file's path, name, and extention.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
std::vector<std::string> File::GetContents() const
Run the automated tester by selecting option 11 from the main menu. All tests should pass.
You can also manually test the program by choosing option 1 to create a document or two, and selecting option 2 to view the documents and
view their contents.
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
WEEK 7 - FEB 26
UNIT 14: Static members
📊 Presentation - Static (U14.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235-unit14-static.html
📖️
Reading - Static members (U14.READ)
Static Variables and Functions
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Static variables are a special type of variable in a class where all instances of the class share the same member. Another term you might hear is a
Class Variable, whereas a normal member variable of a class would be an Instance Variable.
Let's say we are going to declare a Cat class, and each cat has its own name, but we also want a counter to keep track of how many Cats there are. The
Cat counter could be a static variable and we could write a static method to return that variable's value.
class Cat
{
public:
Cat()
{
catCount++;
}
private:
string m_name;
static int catCount;
};
Within a source file, we will need to initialize this static member. This may go in the class' .cpp file outside of any of the function definitions.
And then any time we create a new Cat object, that variable will automatically add up, and every instance of the Cat will share that variable and its
value.
int main()
{
Cat catA, catB, catC;
return 0;
}
Beyond accessing a static method or member directly through an instantiated object, we can also access it through the class name itself, like this:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Example usage: Manager class
In my game engine I use static member variables and functions for my Manager classes. These Managers are meant to manage parts of the game,
such as the Texture library, Audio library, Inputs, Menus, and so on. Throughout the entire game, I don't create multiple instances of the
TextureManager . Because the functions and data are static , I can use this class across the entire project directly.
class TextureManager
{
public:
static std::string CLASSNAME;
private:
static std::map<std::string, sf::Texture> m_assets;
};
// ...etc...
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
sf::Sprite m_player;
m_player.setTexture( chalo::TextureManager::Get( "moose" ) );
Further, we can use the Singleton pattern to create a class that can only have one instance.
Context: A "Design Pattern" is kind of like a blueprint for a way to implement a structure. These are structures that people have figured out how
to build that end up being useful in a lot of scenarios.
You can learn more about the Singleton pattern here: https://en.wikipedia.org/wiki/Singleton_pattern .
📖️
Reading - Friends (U15.READ)
Friends
Remember that when member variables and functions of a class are set to public they can be accessed by anything and when they are set to private
these members can only be accessed from within the class itself.
We can make an exception to this rule by declaring some external function or other class as a friend of the class we're creating. A friend function or
class has access to any private or protected members of the class.
Friend function The friend function will be declared within the class' declaration:
class MyClass
{
public:
void Hi();
private:
int name;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
And then it can be defined in a source (.cpp) file elsewhere:
Friend class A friend class is the same sort of thing except that any member function of our friend class has access to any private members of the
other class.
class ClassWithAFriend
{
private:
int name;
That other class would be declared elsewhere, and any functions it has can access our ClassWithAFriend's members.
class FriendlyClass
{
public:
void Display( const ClassWithAFriend& myFriend )
{
cout << myFriend.name << endl;
}
};
However - it doesn't go both ways. Keep in mind that if classA declares that classB is its friend, this means that classB has access to classA's
members. However, this does not mean that classA has access to classB's members - we would have to explicitly state "classA is a friend" within the
classB class.
Using friend is usually considered poor design as you're exposing variables to be modified outside of the class itself. I tend to only use friend
for creating a set of unit tests for a given class:
private:
/* Private member variables */
T m_array[100];
const size_t ARRAY_SIZE;
size_t m_itemCount;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
friend class SmartFixedArrayTester; // << To make testing easier
};
Then, my unit tests can directly access the private member variables in order to be able to test one function at a time. For example, this test checks the
PushAt function, then directly accesses the array to check that the right values are at the right positions, instead of relying on a function like
GetAt to see those values. Unit Tests are meant to test one "unit" at a time.
SmartFixedArray<std::string> arr;
arr.m_array[0] = "a";
arr.m_array[1] = "b";
arr.m_array[2] = "c";
arr.m_itemCount = 3;
arr.PushAt( 1, "z" );
if ( arr.m_array == nullptr )
else if ( !Set_Outputs( "m_itemCount", 4, arr.m_itemCount ) )
else if ( !Set_Outputs( "m_array[0]", std::string( "a" ), arr.m_array[0] )
else if ( !Set_Outputs( "m_array[1]", std::string( "z" ), arr.m_array[1] )
else if ( !Set_Outputs( "m_array[2]", std::string( "b" ), arr.m_array[2] )
else if ( !Set_Outputs( "m_array[3]", std::string( "c" ), arr.m_array[3] )
else
Goals:
Implement the functionality of a Static manager class, which also has "friend" access to the Account class.
Turn-in:
1. You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment contains several "practice" program folders, and a "graded" program folder. Only the "graded" program is
required.
The practice programs are there to help you practice with the topics before tackling the larger graded program. If you feel
confident in the topic already, you may go ahead and work on the graded program. If you feel like you need additional
practice first, that's what the practice assignments are for.
The graded program assignment contains unit tests to help verify your code.
You can score up to 100% turning in just the graded program assignment.
You can turn in the practice assignments for extra credit points.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
If you're stuck on the graded program, try the practice programs first.
Start this assignment by checking out main , pulling latest to get the files, and creating a new branch…
Practice programs
practice1_static
Total students: 0
Total students: 1
Total students: 2
Total students: 3
Total students: 4
Total students: 4
Student
- name : string
+ Student( name:string )
First, with static variables, we need to initialize them at the top of the .cpp file, OUTSIDE OF ALL FUNCTIONS. Here is the shell .cpp file:
#include "Student.h"
// Member function
Student::Student( string name )
{
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
// Class function
int Student::GetTotalStudents()
{
}
Student constructor:
GetTotalStudents function:
This is a static function but you don't need any static markers in the definition. For this function, just return the total_students .
main:
int main()
{
cout << "Total students: " << Student::GetTotalStudents() << endl;
vector<Student> student_list;
student_list.push_back( Student( "A" ) );
cout << "Total students: " << student_list[0].GetTotalStudents() <<
return 0;
}
Note that we can access the static function GetTotalStudents either through an instanced object, like
student_list[0].GetTotalStudents() , or through the class name itself, like Student::GetTotalStudents() .
practice2_friend
LAUNCH PRICES
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
------------------------------------------------------------------------
0 PlayStation 299.00 1995
1 PlayStation 2 299.00 2000
2 PlayStation 3 499.00 2006
3 PlayStation 4 399.00 2013
4 PlayStation 5 499.00 2020
Product.h: Declare the function void Display( const vector<Product>& products ); as a friend of the Product class.
Afterwards, the program will build and the Display function (within main.cpp) will be able to access the Product's member variables.
practice3_staticmanager
LAUNCH PRICES
Make sure to take a peek at both classes. Notice that ProductManager has static variables and functions.
ProductManager::Display();
Graded program
Remember that the program is located under the cs235_application folder. Open the existing project provided in either
Project_CodeBlocks , Project_VisualStudio2022 , or use the Project_Makefile to build from a console.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
I've updated the program to have an Account and AccountManager class. Account is done but you will implement some of the functionality
for the AccountManager.
Additional automated tests are provided to ensure that things are working as intended.
Account class
Keep note of the members of the Account class, which will be needed while implementing the AccountManager class.
Account
- id : size_t
- username : string
- password_hash : size_t
+ GetID() : size_t
+ GetUsername() : string
AccountManager class
AccountManager Notes
- save_path : string
- accounts : vector<Account>
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
AccountManager Notes
Functionality:
1. Create a new Account, set its ID to 1000 plus the current size of the `accounts` vector.
2. Set the new account's username to the corresponding parameter.
3. Set the new account's password hash to the corresponding parameter.
4. Push the new account into the `accounts` vector.
5. Return the ID of the account you just created (NOT the index).
Functionality:
1. Iterate over all the elements of the `accounts` vector using a for loop.
Inspect each element's ID. If its ID matches the `id` passed in, then return this index (`i`).
2. After the for loop, at this point nothing has been found. In this case, throw an `outofrange` exception because no matching ID was found.
Functionality:
1. Use the `GetIndexOfAccount` function to get the index of the account that has the `id` given.
2. Use the `accounts` vector's `erase` function to remove this item.
Refer to the vector documentation for how to use the erase function: https://cplusplus.com/reference/vector/vector/erase/
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Turning in the assignment
Screenshot: Before finishing up, run the automated tests and take a screenshot of all of your tests passing. Save the file somewhere as a .png.
Back up your code: Open Git Bash in the base directory of your repository folder.
1. Use git status to view all the changed items (in red).
2. Use git add . to add all current changed items.
3. Use git commit -m "INFO" to commit your changes, change "INFO" to a more descriptive message.
4. Use git push -u origin BRANCHNAME to push your changes to the server.
5. On GitLab.com, go to your repository webpage. There should be a button to Create a new Merge Request. You can leave the default settings
and create the merge request.
6. Copy the URL of your merge request.
Turn in on Canvas:
WEEK 8 - MAR 4
UNIT 16: Anonymous functions
📖️
Reading - Anonymous functions (U16.READ)
What are anonymous functions?
Anonymous functions are functions we can define in-line in our code, without giving that function a name. In C#, the LINQ framework allows us to
use Lambda functions, and in JavaScript and with JQuery we see anonymous functions used a lot as the result of other functions completing, or a
function passed around as a parameter to some other function.
This can be confusing to read without seeing it. In software development, I've usually used these in C# to sort through or search through data to get
returned data based on some criteria - without having to write a totally new function. In JQuery, it's common to make a function as a "do this once this
other function is done".
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
};
So, for example, if you need to sum two numbers but only inside a specific scope:
For these next examples, let's say we have a vector<Restaurant> all_data to look through, and a string find_me as the search term.
The anonymous functions we define would be inside another function, so let's use a shell function like this:
Empty capture
By doing an empty capture, denoted by empty square brackets [] , this means the internal (anonymous) function does not take any variables in
the current scope. In this case, it doesn't automatically gain access to all_data or find_me . Instead, we have to specify input parameters
as the parameter list and At the end of the anonymous function specification is the function call, where we have to pass in the arguments.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
return matchedData; // The matched results will be returne
Usually these would be written out much more concisely to take up less space in the code. An example of how this might look in an actual codebase
are:
Review questions:
So much of the design tricks and features we utilize in C++ and other object-oriented programming languages all stem from the concept of "do not
repeat yourself". If you're writing the same set of code in multiple places, there is a chance that we could design the program so that we only need to
write that code once.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Polymorphism is a way that we can utilize pointers and something called vtables to have a family of classes (related by inheritance) and be able to
write one set of code to handle interfacing with all of those family members. We have a family tree of classes, and we can write our program to treat all
the objects as the parent class, but the program will decide which set of functions to call at run time.
myPtr->Display();
delete myPtr;
Let's say we are writing a quiz program and there are different types of questions: True/false questions, multiple choice, and fill-in-the-blank. They all
have a common question string, but how they store their answers is different…
# m_correct : int
How would you store a series of inter-mixed quiz questions in a program? Without polymorphism, you might think to just have separate vectors or
arrays for all the questions:
vector<TrueFalseQuestion> tfQuestions;
vector<MultipleChoiceQuestion> mcQuestions;
vector<FillInQuestion> fiQuestions;
Utilizing polymorphism in C++, we could simply store an array of pointers of the parent type:
vector<Question*> questions;
And then initialize the question as the type we want during creation:
questions.push_back(new TrueFalseQuestion);
questions.push_back(new MultipleChoiceQuestion);
questions.push_back(new FillInQuestion);
Since we are using the `new` keyword here, we would also need to make sure to `delete` these items at the end of the program:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
delete question;
}
When we're working with polymorphism in this way, we need to be able to treat each child as its parent, from a "calling functions" perspective. Each
child can have its own unique member functions and variables, but when we're making calls to functions via a pointer to the parent type, the parent
only knows about functions that it, itself, has.
Let's say that the `Question` class has a `DisplayQuestion()` function. Since all its children use `mquestion` in the same way and inherit this function, it
will be fine to call it via the pointer.
ptrQuestion->DisplayQuestion(); // ok
But with a function that belongs to a child - not the parent's interface - we wouldn't be able to call that function via the pointer without casting.
ptrQuestion->ListAllAnswers(); // not ok
(static_cast<MultipleChoiceQuestion*>(ptrQuestion))->ListAllAnswers(); ; ok
You could, however, still call that `ListAllAnswers` function from within `MultipleChoiceQuestion`'s `DisplayQuestion` function, and that would still
work fine…
bool MultipleChoiceQuestion::AskQuestion()
{
DisplayQuestion();
ListAllAnswers();
// etc.
}
Still fuzzy? That's OK, this is just an overview; we're going to step into how all this works more in-depth next.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Review: Pointers to class objects
You can declare a pointer to point to the address of an existing object, or use the pointer to allocate memory for one or more new instances of
that class…
Then, to access a member of that object via the pointer, we use the -> operator, which is equivalent to dereferencing the pointer and then
accessing a member:
Question* ptr;
ptr = &q1; ; ok
ptr = &q2; ; ok
ptr = &mc1; ; ok?
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
And, any functions that the Question class and the MultipleChoiceQuestion class could be called from this pointer…
ptr->DisplayQuestion();
This is fine for any member methods not overridden by the child class. But, which version of the function is called if we used an overridden
method?
ptr->AskQuestion();
Question:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
class Question
{
public:
bool AskQuestion();
// etc.
};
MultipleChoiceQuestion:
Here are the outputs we could have from using pointers in different ways:
"Well, how is that useful at all? The function called matches the pointer data type!" - true, but we're missing one piece that allows us to call any
child's version of the method from a pointer of the parent type…
Question:
class Question
{
public:
virtual bool AskQuestion();
// etc.
};
MultipleChoiceQuestion:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
// etc.
};
Here are the outputs we could have from using pointers in different ways:
With this, we can now store a list of Question* objects, and each question can be a different child class, but we can write one set of code to
interact with each one of them.
By using the virtual keyword, something happens with our functions - it allows the pointer-to-the-parent class to figure out which version of the
method to actually call, instead of just defaulting to the parent class' version. But how does this work?
The virtual keyword tells the compiler that the function called will be figured out later. By marking a function as virtual, it then is added to
something called a virtual table - or vtable.
The vtable stores special pointers to functions. If a class contains at least one virtual function, then it will have its own vtable.
With the Question class, it isn't inheriting any methods from anywhere else so the vtable reflects the same methods it has. But, we also have the child
class that inherits DisplayQuestion() and overrides AskQuestion().
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Because of these vtables, we can then have our pointers reference this vtable when figuring out which version of a method to call. Doing this is called
late binding or dynamic binding.
If you're working with inheritance. By making your destructor virtual for each class in the family, you are ensuring that the correct destructor
will be called when the object is destroyed or goes out of scope. If you don't make it virtual and utilize polymorphism, the correct destructor
may not be called (i.e., Question 's instead of MultipleChoiceQuestion 's).
When the object is instantiated (e.g., ptr = new MultipleChoiceQuestion; ) that class' constructor will be called already.
It's all about design. Though generally, if you always want the parent's version of a method to be called, you wouldn't override that method in
the child class anyway.
Polymorphism works best if you're designing a family of classes around some sort of interface that they will all share. In the C# language, there
is an interface type that is available to you, but that's not here in C++, so we implement it via classes.
What is an Interface?
When we're designing a class to be an interface, the idea is that the user (or other programmers) will just see a set of functions it will interface
with - none of the behind-the-scenes, how-it-works stuff.
Most of the devices we use have some sort of interface, hiding the more complicated specifics of how it actually works within a case. For
example, a calculator has a simple interface of buttons, but if you opened it up you would be able to see its hardware and how everything is
hooked up.
We use the same idea with writing software, where we expose some interface (in the form of the class' public methods) as how the "user"
interacts with our class.
A common design practice is to write the first base (parent) class to be a specification of this sort of interface that all its children will adhere
to, and to ensure that each child class must follow the interface by using something that the compiler will enforce itself: pure virtual functions.
When working with our Quiz program idea, our base class is Question, which would define the interface for all other types of Questions.
Generally, our base interface class would never be instantiated - it is not complete in and of itself (i.e., a Question with no types of Answers) -
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
but is merely used to outline a common interface for its family members.
Here is a blank diagram with just the member variables defined, but not yet any functionality, so that we can begin to step through thinking
about an interface:
Thinking in terms of implementing a program that could edit questions (such as the teacher's view of the quiz), as well as that could ask
questions (such as the student's view), we can try to think of what kind of functionality we would need from a question…
But, the specifics of how each of these question types stores the correct answer (and what data type it is) and validates it differ between each of
them…
We could design our Questions so that they have functionality that interacts with the user directly (e.g., a bool function that asks the user to
enter their response and returns true if they got it right and false if not) rather than writing functions around returning the actual answer (which
would be more difficult because they have different data types).
Set up question
Run question
Declarations:
We can set up a simple interface for our Questions with these functions. They've been marked as virtual , which allows us to use
polymorphism, and they've also been marked with = 0 at the end, marking them as pure virtual - this tells the compiler that child classes
must implement their own version of these methods. A function that contains pure virtual methods is called an abstract class.
class Question
{
public:
virtual void Setup() = 0;
virtual bool Run() = 0;
protected:
string m_question;
};
Now our child classes can inherit from Question . They will be required to override Setup() and Run() , and we can also have additional
functions as needed for that implementation:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
class MultipleChoiceQuestion : public Question
{
public:
virtual void Setup();
virtual bool Run();
void ListAllAnswers();
protected:
string m_options[4];
int m_answer;
};
Definitions:
Each class will have its own implementation of these interface functions, but since they're part of an interface, when we build a program around
these classes later we can call all of them the same way.
Question: TrueFalseQuestion:
MultipleChoiceQuestion: FillInQuestion:
Function calls:
Now, no matter what kind of question subclass we're using, we can utilize the same interface - and the same code.
// Allocate memory
if ( choice == "true-false" )
{
ptr = new TrueFalseQuestion();
}
else if ( choice == "multiple-choice" )
{
ptr = new MultipleChoiceQuestion();
}
else if ( choice == "fill-in" )
{
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
ptr = new FillInQuestion();
}
And, utilizing this interface, we could then store a vector<Question*> and set up each question as any question subclass without any
duplicate code.
Let's say we have created a family tree of game objects, starting at the most basic object that has an (x, y) coordinate and dimensions:
class GameObject
{
public:
GameObject();
protected:
sf::Vector2f m_position;
std::string m_name;
sf::Sprite m_sprite;
sf::IntRect m_textureCoordinates;
// ... etc ...
};
Then we might have something like an unanimated item in the world, but maybe it has physics so it needs the ability to update:
protected:
ObjectType m_objectType;
int m_imageCode;
// ... etc ...
};
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
But then our player and NPC characters also have animated sprites and the ability to move with keyboard input or rudimentary AI:
void Update();
void Draw();
const sf::Sprite& GetSprite() const;
GravityHandler gravity;
void ForceSpriteUpdate();
void Animate();
void RestrictMovement();
void SetRestrictMovement( bool value );
sf::IntRect GetValidPositionRegion() const;
void SetValidPositionRegion( sf::IntRect rect );
protected:
void MoveClipping( Direction direction );
void BeginAttack();
void EndAttack();
Direction m_direction;
int m_speed;
float m_animationFrame;
float m_maxFrames;
float m_animationSpeed;
SheetAction m_sheetAction;
float m_sheetActionTimer;
Action m_stateAction;
CharacterType m_characterType;
sf::IntRect m_validPositionRegion;
bool m_restrictMovement;
};
If we didn't use polymorphism, we would have to store all objects in their own vector:
vector<Character> m_npcList;
vector<Item> m_pickups;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
vector<GameObject> m_decor;
But utilizing polymorphism, we can store one vector of GameObject* objects initialized on the heap, and any common functionality they have
(Update, Draw, etc.) could be accessed via that pointer.
// Our storage
vector<GameObject*> m_entities;
// Accessing it later
for ( auto& entity : entities )
{
entity->Update();
}
Review questions:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
WEEK 10 - MAR 18
UNIT 18: Operator overloading
📊 Presentation - Operator overloading (U18.PRES)
https://rachels-courses.gitlab.io/webpage/semester/2024-01/presentations/cs235-unit18-operatoroverloading.html
📖️
Reading - Operator overloading (U18.READ)
Overloading operators
When creating our own classes, we may want to make certain operators mean certain things when used with our class. By default, we can't use math
operators ( + , - , / , * ), stream operators ( << , >> ), relational operators ( < , <= , > , >= , == , != ), the subscript operator [] , and the
assignment operator ( = ) with the classes we create. In order to do so, we would have to use operator overloading to define our own functions and
how these operators work on our class.
For example, we could define our own Fraction class, without overloaded arithmetic operators we would have to do math like this:
Arithmetic operators
Arithmetic operators will be friend functions of our class. This is because it will take two objects and return a third, so it doesn't "neatly" fit
inside one class as a member function.
class MyClass
{
public:
friend MyClass operator+( const MyClass& item1,
const MyClass& item2 );
friend MyClass operator-( const MyClass& item1,
const MyClass& item2 );
friend MyClass operator/( const MyClass& item1,
const MyClass& item2 );
friend MyClass operator*( const MyClass& item1,
const MyClass& item2 );
};
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Then the function definition would go in a source file (it could go in MyClass.cpp as well, but it's not a member function so don't prefix
MyClass:: on these functions).
Relational operators
Relational operators also operate on two objects so these are also friend functions.
class MyClass
{
public:
friend bool operator==( const MyClass& item1,
const MyClass& item2 );
friend bool operator!=( const MyClass& item1,
const MyClass& item2 );
friend bool operator<( const MyClass& item1,
const MyClass& item2 );
friend bool operator<=( const MyClass& item1,
const MyClass& item2 );
friend bool operator>( const MyClass& item1,
const MyClass& item2 );
friend bool operator>=( const MyClass& item1,
const MyClass& item2 );
};
Function definition:
Stream operators
Stream operators will take in a stream reference and the object to input or output and return the stream reference of the modified stream. These
are also friend functions. We use the ostream and istream classes as the return type and parameter since this is the parent class of
cout/cin and ofstream/ifstream , as well as other stream types.
class MyClass
{
public:
friend ostream& operator<<( ostream& out,
MyClass& item );
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
friend istream& operator>>( istream& in,
MyClass& item );
};
Function definition:
You can output or input multiple items in these functions so that you can get input for all class members, or output all class members, in one
statement.
Subscript operator
The subscript operator is usually used when creating a type of list structure so that we can access an element at some position. This function is a
member function of the class.
class MyClass
{
public:
string& operator[] ( const int index );
private:
string m_data[100];
};
Function definition:
Assignment operator
The assignment operator is similar to the copy constructor in that we are telling our class how it will copy the data from another object of the
same class. It's up to us to decide which members to copy over as part of this process.
class MyClass
{
public:
MyClass& operator=( const MyClass& other );
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
private:
int a;
float b;
};
Function definition:
a = other.a;
b = other.b;
return *this;
}
Note the if statement in our assignment operator. This is checking to see if the memory address of "this" class is the same as the "other" class
being passed in. We don't want to make a copy if these are actually the same object, so in that case we return "this" (but it must be de-
referenced).
Otherwise, we can copy whichever member variables we would like, and make sure to return "this" at the end (also de-referenced).
Goals:
Turn-in:
1. You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
This assignment only has the graded program; no additional practice programs
Continue scrolling down in the documentation and see if you're missing anything.
Try skimming through the entire assignment before getting started, to get a high-level overview of what we're going to be
doing.
If you're stuck on a practice program, try working on a different one and come back to it later.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
If you're stuck on the graded program, try the practice programs first.
Start this assignment by checking out main , pulling latest to get the files, and creating a new branch…
---------------------------------------------------------------------------
| MAIN MENU |
-------------
OPTIONS
0. Quit program
1. Run unit tests
2. Initialize fraction
3. Arithmetic
4. Relational
This program allows the user to set two fractions and then utilize the arithmetic and relational operators on those fractions. From the main menu, you
can also run option #1 to run the unit tests. These will be used to help you verify that your code works properly.
Once the Fraction is implemented, you’ll be able to run various functionality to test manually:
---------------------------------------------------------------------------
| INITIALIZATION |
------------------
------------------------------- -------------------------------
| ARITHMETIC | | RELATIONAL |
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
-------------- --------------
0. Go back 0. Go back
1. Add 1/2 + 4/5 1. Is 1/2 == 4/5?
2. Subtract 1/2 - 4/5 2. Is 1/2 != 4/5?
3. Multiply 1/2 * 4/5 3. Is 1/2 <= 4/5?
4. Divide 1/2 / 4/5 4. Is 1/2 >= 4/5?
Perform which operation? 3. Is 1/2 < 4/5?
4. Is 1/2 > 4/5?
>> 1
Perform which operation?
1/2 + 4/5 = 13/10
>> 1
After running the unit tests view the testresult.html file that is located wherever your project file is – such as vcxproj for Visual Studio or cbp for
Code::Blocks.
After implementing each function in the Fraction class, you should be running the unit tests to verify your work for that item.
Test driven development is a style of software development where tests are created and implemented before the thing it's testing is implemented.
There are some benefits to writing tests first:
Ever write an essay and try to proof read it and miss mistakes because your brain fills it in? Well if you write the Fraction class first, your
brain will do this while you're writing the tests - you'll forget certain things to look for.
Writing test cases first helps you think of what are the requirements for the functionality and helps you document that before doing any coding.
(That being said, none of the companies I've worked at have used TDD, though most places I've worked have required programmers to write unit tests
to test their code after the fact.)
In the Tester class, there is a function to test each of the functions available in the Fraction class. We will implement tests for all functionality to ensure
we have complete coverage to validate the Fraction class.
class Fraction
{
public:
Fraction();
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Fraction CommonDenominatorize( const Fraction& other ) const;
// Operator overloading
// Assignment operator
Fraction& operator=( const Fraction& other );
// Arithmetic operators
friend Fraction operator+( const Fraction& left, const Fraction& right );
friend Fraction operator-( const Fraction& left, const Fraction& right );
friend Fraction operator*( const Fraction& left, const Fraction& right );
friend Fraction operator/( const Fraction& left, const Fraction& right );
// Relational operators
friend bool operator==( const Fraction& left, const Fraction& right );
friend bool operator!=( const Fraction& left, const Fraction& right );
friend bool operator<=( const Fraction& left, const Fraction& right );
friend bool operator>=( const Fraction& left, const Fraction& right );
friend bool operator<( const Fraction& left, const Fraction& right );
friend bool operator>( const Fraction& left, const Fraction& right );
// Stream operators
friend ostream& operator<<( ostream& out, const Fraction& fraction );
friend istream& operator>>( istream& in, Fraction& fraction );
private:
int m_num;
int m_denom;
};
The Fraction class contains a m_num and m_denom as member variables. Beyond that it’s all functionality. The assignment operator = is used to
assign a value from one Fraction to the local (" this ") Fraction. It is the only operator that we will be implementing that belongs to the class itself.
Arithmetic operators allow us to add, subtract, multiply, and divide two fractions together, the relational operators allow us to compare two fractions,
and the stream operators let us input and output data from our fraction. These functions are classified as friends as they are not member functions!
They are independent functions, but as a friend the function will have access to a Fraction’s m_num and m_denom , which are normally private.
This function is responsible for returning a decimal version of a fraction, such as 0.5 for 1
2
. To do this, you need to divide the numerator and
denominator.
The result of two integers being divided will be an integer result, which gets rid of our decimal point.
Make sure to CAST one of the values to a float in order to get the correct result: float( m_num )
We're going to lazily get the common denominator by multiplying FractionA's numerator by FractionB's denominator, and multiply FractionA's
denominator by FractionB's denominator. (That's not a typo, remember that d/d = 1).
1. Check to see if m_denom is equivalent to other.m_denom – if this is the case, then just return *this instead.
2. Otherwise:
1. Create a new Fraction to store the result.
2. Assign the Fraction to the result of *this fraction x other.denom/other.denom .
3. Return the result Fraction.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Fraction& Fraction::operator=( const Fraction& other )
1. Error check: If THIS item's address is the same as the rhs address then just return *this (don't try to change the data): = if ( this =
&other ) { return *this; }
2. Otherwise, set the numerator to the =other=’s numerator.
3. Set the denominator to the =other=’s denominator.
nL is "left numerator"
dL is "left denominator"
nR is "right numerator"
nL is "left numerator"
nL nR nL ⋅ dR
÷ =
dL dR dL ⋅ nR
nL is "left numerator"
dL is "left denominator"
nR is "right numerator"
nL is "left numerator"
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
When adding two fractions together we need to get a common denominator. After we have a common denominator, the solution will share this
same denominator, and the numerator will be the left numerator plus the right numerator.
Steps:
A. Original fractions:
nL nR
+
dL dR
B. Create a new version of the left fraction with the common denominator.
n1 nL ⋅ dR
=
d1 dL ⋅ dR
C. Create a new version of the right fraction with the common denominator.
n2 nR ⋅ dL
=
d2 dR ⋅ dL
n1 + n2
dL ⋅ dR
dL ⋅ dR
2
and 2
4
are the same), false otherwise.
Steps:
nR
A. We have two fractions, left and right: ??
nL
=
dL dR
B. Create a new version of the left fraction with the common denominator.
n1 nL ⋅ dR
=
d1 dL ⋅ dR
C. Create a new version of the right fraction with the common denominator.
n2 nR ⋅ dL
=
d2 dR ⋅ dL
D. If the numerators are the same and the denominators are the same, then return true , or false otherwise.
Returned output: true if the two fractions are NOT the same ( 1
2
and 2
4
are the same), false otherwise.
Steps:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
You can just return the result of !( a == b).
Returned output: true if the left fraction is less than the right fraction (1/2 is less than 3/4) or equal to (1/2 is equal to 2/4), false
otherwise.
Create two common denominatorized Fractions again (like with == ) and then compare the numerators: Return the result of commonLeft.mnum
<= commonRight.mnum.
Returned output: true if the left fraction is greater than the right fraction (3/4 is greater than 1/2) or equal to (1/2 is equal to 2/4), false
otherwise.
Create two common denominatorized Fractions again (like with == ) and then compare the numerators: Return the result of commonLeft.mnum
<= commonRight.mnum.
Returned output: true if the left fraction is less than the right fraction (1/2 is less than 3/4), false otherwise.
Returned output: true if the left fraction is greater than the right fraction (3/4 is greater than 1/2), false otherwise.
Output the numerator and the denominator to the out stream, formatted in a way that is clearly a fraction, like "1/2". (Then return the out stream
back out.)
Input the numerator and then the denominator via the in input stream. (Then return the in stream back out.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
in >> fraction.m_num >> fraction.m_denom;
return in;
}
Once all the unit tests run and pass, you can reasonably assume that your Fraction logic is correct. (I like to think that I’m not a terrible test
writer…)
📖️
Reading - Third party libraries (U19.READ)
Setting up third party libraries
Quick checklists
Setting up a library in Visual Studio
1. Download library from website.
2. Extract library to your hard-drive.
3. Create a new Empty project in Visual Studio.
4. Create a new source file (main.cpp) in Visual Studio.
5. Right-click on your project and go to Properties.
6. Make sure your Configuration is set to Release and your Platform is set to x64.
7. Under C/C++ > General, add SFML's include path to the Additional Include Directories property.
8. Under Linker > General, add SFML's lib path to the Additional Library Directories property.
9. Under Linker > Input, click the "v" dropdown on Additional Dependencies and click <Edit…>. Add your related .lib files (e.g.,
sfml-graphics.lib, sfml-window.lib, sfml-system.lib).
10. Click OK.
11. Move the .dll files (sfml-graphics-2.dll, sfml-window-2.dll, sfml-system-2.dll) from the SFML/bin folder to your project directory.
12. Done with configuration.
Setting up a library in Code::Blocks (Windows)
1. Download library from website.
2. Extract library to your hard-drive.
3. Create a new Empty project in Code::Blocks.
4. Create a new empty file (main.cpp) in Code::Blocks.
5. Right-click on your project and go to Build options…
6. Make sure you've selected Release instead of Debug on the left-hand side.
7. Under Search directories > Compiler, add SFML's include path.
8. Under Search directories > Linker, add SFML's lib path.
9. Under Linker settings and Link libraries:, add the libraries: sfml-system, sfml-graphics, sfml-window.
10. Click OK.
11. Move the .dll files (sfml-graphics-2.dll, sfml-window-2.dll, sfml-system-2.dll) from the SFML/bin folder to your project directory.
12. Done with configuration.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Setting up third-party libraries in your IDE
Downloading and extracting the library
For these instructions we will be working with the SFML (Simple Fast Media Library) library, but setting up most libraries will work
about the same.
Downloading: Go to the library webpage (https://www.sfml-dev.org/download.php) and select "SFML", latest stable version (as of
writing this is 2.6.1).
From the downloads page, there are various options for a Windows download.
third_party_libraries_sfmlpage.png
Figure 6: An image of the SFML downloads page, showing different versions that can be downloaded for Windows.
If you're working with Visual Studio, then download the latest version, even if the year doesn't match. You'll probably want the 64-
bit verison, since most computers these days are 64-bit.
If you're working with Code::Blocks, you will probably want the 64-bit SEH option ("GCC 13.1.0 MinGW (SEH) - 64-bit"), but
you can double-check which version you need by going to your CodeBlocks install directory (such as C:\Program
Files\CodeBlocks\MinGW\bin\) and looking for a file called "libgcc"… based on this version it will tell you which version of
SFML you need to download:
In Windows I like to have a "LIBRARIES" folder on my root directory, such as "C:\LIBRARIES\". So, all extracted, my default
path for SFML would be:
C:\LIBRARIES\SFML-2.6.1
You can download many libraries from your distro's package manager, such as synaptic for Debian-based systems. Do a search for
"libsfml" and download the libsfml-dev package. (Most libraries are "libXYZ-dev" as well.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The library will be automatically installed on your machine, with the relevant paths for configuration being.
Keeping track of important paths
You'll need to know where your library files are being kept while we're configuring the project, so make sure to take note of the
paths. Note that if you're in Windows, you might have unzipped your library to a different directory than me, and will need to
replace "C:\LIBRARIES\" with wherever you put your SFML folder.
You can also refer to the SFML Tutorials page on how to set up Visual Studio, Code::Blocks, and other platforms.
The following write-ups are step-by-step guides with screenshots to show you how to configure Visual Studio and Code::Blocks for SFML…
Visual Studio
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Set your Project name and Location, then click Create.
3. Create a source file: Create a new .cpp file for your project by going to your Solution Explorer, right-clicking on the project, going to
Add, then selecting New Item….
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In your main.cpp, it can be useful to add some starter code to make sure your project will build properly with the library linked within.
Here is a very stripped-down SFML program:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Window");
return 0;
}
At first this will generate build errors, but once we have the library set up properly, it should compile.
5. Go to the properties: Right-click on your project in the Solution Explorer and select Properties.
Make sure at the top of this screen, to set the Configuration to Release and Platform to x64.
6. Set up the include directory: On the left-hand side, open the C/C++ category and the General sub-category. In the Additional
Include Directories property, paste the path to your SFML directory's include folder, such as:
C:\LIBRARIES\SFML-2.6.1\include
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
7. Set up the lib directory: Now under the Linker category and the General sub-category, add the path for the SFML directory's lib
folder to the Additional Library Directories property, such as:
C:\LIBRARIES\SFML-2.6.1\lib
8. Set up dependencies: Under the Linker category and the Input sub-category, click the "v" button next to Additional Dependencies.
Click the <Edit…> button.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In the pop-up box, add the following in the top text box:
sfml-graphics.lib
sfml-window.lib
sfml-system.lib
9. Build the program: In the dropdown near the play button, select Release as our build type, and make sure x64 is selected as our
platform.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
10. Adding the .dll files to the project:
If we try to run the program right now, it will complain about missing dll files:
We need to copy the dll files from the SFML library to our project now.
In the SFML directory's bin folder (e.g., C:\LIBRARIES\SFML-2.6.1\bin\ ), copy the relevant library files (sfml-graphics-2.dll,
sfml-system-2.dll, sfml-window-2.dll).
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Paste these files into your project directory:
Your program should now start, open, and close without any error messages. Currently the program doesn't really do anything because
there's no game loop within. Reference the SFML setup page (https://www.sfml-dev.org/tutorials/2.6/start-vc.php) for some test code you
can use to verify that everything works properly.
Code::Blocks (Windows/Linux)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Set the Project title and Folder to create project in, then click Next >. Use the default options, then click Finish to create the project.
3. Create a source file: Go to File > New > Empty file and create a new file named "main.cpp".
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In your main.cpp, it can be useful to add some starter code to make sure your project will build properly with the library linked within.
Here is a very stripped-down SFML program:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Window");
return 0;
}
4. Go to the project options: Right-click on your project in the Projects view and select Build options….
On the left-hand side, make sure to select the Release configuration, not the Debug.
5. Link to the include directory: Under the Search directories tab, select the Compiler sub-tab. From here, click the Add button and
paste in the path to your SFML directory's include folder, such as:
C:\LIBRARIES\SFML-2.6.1\include
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
6. Link to the lib directory: Under the Search directories tab, select the Linker sub-tab. From here, click the Add button and paste in
the path to your SFML directory's lib folder, such as:
C:\LIBRARIES\SFML-2.6.1\lib
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
7. Set up linked libraries: Under the Linker settings tab…
For WINDOWS, under the Link libraries: section, click the For LINUX, under the Other linker options: section add
Add button. You'll do this three times, adding the three these flags: -lsfml-graphics, -lsfml-window, -lsfml-system):
libraries: sfml-graphics, sfml-window, and sfml-system.
8. Build the program: In the dropdown near the build buttons, make sure to change it from building the "Debug" version to building the
"Release" version.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Now when you build there shouldn't be any errors:
If we try to run the program right now, it will complain about missing dll files:
We need to copy the dll files from the SFML library to our project now.
In your file explorer, navigate one window to your SFML directory and one to your project directory.
In SFML's bin directory, highlight the dll files and copy them: sfml-graphics-2.dll, sfml-system-2.dll, and sfml-window-2.dll.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Paste these files into your project directory:
Your program should now start, open, and close without any error messages. Currently the program doesn't really do anything because
there's no game loop within. Reference the SFML setup page (https://www.sfml-dev.org/tutorials/2.6/start-cb.php) for some test code you
can use to verify that everything works properly.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
If you use the example code from the SFML webpage guide, after you build and run you should see a green circle rendered to our
window:
Goals:
Turn-in:
1. You'll commit your code to your repository, create a merge request, and submit the merge request URL in Canvas.
(Instructions in document.)
I can't always help out with every person's different computer configurations, so while I can often help with setup in
Code::Blocks and Visual Studio, sometimes I can't get it working on different machines. Because of this, this assignment is
optional. Try what you can and turn in what you get, you'll get credit either way.
Start this assignment by checking out main , pulling latest to get the files, and creating a new branch…
You'll be creating a new project in your IDE of choice and following the setup guide to create a project.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Setting up the library
Windows users:
First, go to the SFML downloads page here: https://www.sfml-dev.org/download.php. Then click on the "SFML", whatever the latest version is. You
will need to download a version based on whether you're using Visual Studio or Code::Blocks.
Download the latest version even if the year doesn't match. At time 1. Navigate to where you have Codeblocks installed on your
of writing, "Visual C++ 15 (2017) - xx-bit" is the version you computer, such as "C:\Program Files\CodeBlocks\".
should download. You can download the 32-bit or 64-bit version.
2. Then, go to the "MinGW" folder, then the "bin" folder.
3. Look for a "libgcc" dll file. We will know which SFML
version to download based on this file.
Once the library is downloaded, extract to an easy directory to find on your computer. For example, I usually have a "C:\Libraries\" folder on my
computer, and so I'd extract SFML here - "C:\Libraries\SFML-2.5.1\".
Linux users:
Go to your package manager and search for "libsfml". Install the libsfml-dev package.
The files will be installed to " /usr/include/SFML/ " and " /usr/lib/x86_64-linux-gnu/ " directories (at least that's where they're at on
my computer.)
Mac users:
You will have to try to follow the Xcode guide on the SFML page (https://www.sfml-dev.org/tutorials/2.6/); I do not have a Mac to try to be able to
setup SFML and write documentation with.
All users:
Within the SFML folder there are two important directories we care about: The lib folder and the include folder. You might keep these folders open or
keep a notepad document open and paste your paths into that file for reference while we're setting up our project.
Create a new project in Visual Studio or Code::Blocks. Right now we just need one file - main.cpp. The following code is the test program from the
SFML setup documentation, you can copy-paste it into the main.cpp file:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(evet))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
It won't build at the moment, we still need to configure the project to use SFML.
For instructions on how to configure SFML with your IDE, look at the reference page: "Setting up and using third party
libraries"
Download the assets in that directory, bunny.png, diamond.png, grass.png, and PressStart2P.ttf. Copy these files into your SFML project's directory
(where your .vcxproj is for Visual Studio, or your .cbp is for Code::Blocks).
We're going to keep everything in main.cpp for now so we can just focus on some basic SFML.
Additional #includes
At the top of the program, make sure you're including the following:
cmath
map
string
Handy functions
Add the following function to your program. You can copy/paste this above the int main() part in main.cpp. As long as they show up above
main() you'll be able to use these functions within main().
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
pos.y = rand() % screenHeight - 64;
return pos;
}
float GetDistance( sf::Vector2f obj1, sf::Vector2f obj2 )
{
return sqrt( pow( obj1.x - obj2.x, 2 ) + pow( obj1.y - obj2.y, 2 ) );
}
1. Create named constants for the window resolution: First, we’re going to define the screen width and height as named constants so we can
refer to them in the program without having the numbers hard-coded all over the place (this is handy if you want to change the resolution later.)
2. Set up the game window: Then we need to create a RenderWindow and set it up. We will set the resolution via the VideoMode class and
give the title bar the text “Example game”, as well as set our framerate.
3. Load in images: We will create a map of textures so we can grab them by a string key, instead of having to deal with index numbers. We’re
going to load each of the images.
map<string,sf::Texture> textures;
textures["bunny"].loadFromFile("bunny.png");
textures["diamond"].loadFromFile("diamond.png");
textures["grass"].loadFromFile("grass.png");
4. Load in a font: We’ll also create a Font variable and load in the font.
sf::Font font;
font.loadFromFile("PressStart2P.ttf");
5. Create a player sprite: Let’s create one Sprite for the player, set its texture and position, and create a couple other helper variables. (In a
larger program, these should be in a class.)
sf::Sprite player;
player.setTexture( textures["bunny"] );
player.setPosition( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 );
float playerSpeed = 5;
int playerScore = 0;
6. Create a diamond sprite: Let’s also create a Sprite for the diamond, the collectable item.
sf::Sprite item;
item.setTexture( textures["diamond"] );
item.setPosition( GetRandomPosition( SCREEN_WIDTH, SCREEN_HEIGHT ) );
7. Add score text: And a Text object to be able to render the player’s score to the screen.
sf::Text scoreText;
scoreText.setFont( font );
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
scoreText.setCharacterSize( 30 );
scoreText.setFillColor( sf::Color::White );
scoreText.setString( "Score: " + to_string( playerScore ) );
8. Add background tiles: Add a vector of sf::Sprites named groundTiles to make the background:
vector<sf::Sprite> groundTiles;
sf::Sprite ground;
ground.setTexture( textures["grass"] );
for ( int y = 0; y < SCREEN_HEIGHT; y += 32 )
{
for ( int x = 0; x < SCREEN_WIDTH; x += 32 )
{
ground.setPosition( x, y );
groundTiles.push_back( ground );
}
}
These are all the setup parts, and we will add in the grass background later. Next, we need to create the game loop – the game will continue
running until it gets a “close window” event.
Create the game loop. This will go after all the setup code.
while ( window.isOpen() )
{
}
9. Listen for window close event: This code checks for any events happening, and if the event code is a “Closed” event, then close the window.
This will cause the game to exit.
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
10. Listen for keyboard input: Next we’re going to listen for any keyboard presses. If an arrow key is pressed we are going to move the bunny
by changing its x, y coordinates.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
( sf::Keyboard::isKeyPressed( sf::Keyboard::Down ) )
{
playerPos.y += playerSpeed;
}
player.setPosition( playerPos );
11. Check for collision between player and diamond: Now that we’ve handled events and inputs, the only game logic we need at the moment
is to check if the Diamond and the Player are close to each other. We can use the GetDistance function here. You can adjust the value of 32, it is
the amount of pixels of “distance”, and if the two objects are within the threshold, we will count it as a collision
12. Draw items to the screen: Finally within the game loop we are going to clear the screen and draw all our items.
window.clear();
// Draw all the backgrounds
for ( auto& tile : groundTiles )
{
window.draw( tile );
}
// Draw item
window.draw( item );
// Draw player
window.draw( player );
// Draw text
window.draw( scoreText );
window.display();
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
When we run the program, the core bunny game should work. You can move the bunny around with the arrow keys and each time you collect a
diamond the score should go up.
There are lots of ways you could customize or add onto this game, and feel free to experiment, but this is just an example of what you could do
with additional libraries linked up in your IDE.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
About
For the semester project I've built out a codebase based on Amazon. There are objects created for different parts of the underlying shopping platform
system. You will be selecting one area to work in.
We will also be making use of more of the tools available on the GitLab webpage, such as Issues (tickets) for pulling tasks, merge request reviews, and
an automated build system.
We will also have documentation for the codebase as a whole, and you will be familiarizing yourself with this codebase as you work with it.
This is meant to imitate a real-world development scenario and teach you more about software development.
Overview
You will CLONE the shared group repository to your computer to work on the item.
Use git clone and then the HTTPS link from the GitLab repository page.
Clone this new repository somewhere on your hard drive - NOT IN YOUR OTHER CS235 REPOSITORY FOLDER!
You will select an Issue to work on. (GitLab page → Issues page → Select an issue and assign it to yourself).
The issue will include the acceptance criteria that you will use to help implement the required tickets.
v1, v2, and v3 of the project will have different sets of tickets to work on.
You will submit a merge request once you've implemented the feature.
You will review someone else's merge request changes and give productive feedback.
After each "version" (v1, v2, v3), the instructor will review your changes, give feedback, and if the changes are satisfactory, they will merge your
work into the main branch and mark the ticket as complete.
Information about using GitLab is located on the Repository front page README (Follow Repository link and scroll down).
The README here covers how to pull an issue, create a merge request, and review someone else's code.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Information about project requirements is located in the Issue ticket description (view on GitLab).
The ticket description explains what is required for the feature you're implementing.
Information about the codebase is located on the documentation webpage.
The documentation has information on all of the structures in the program and their relationships.
The documentation also covers details about how the program itself works.
You will turn in the URL to your merge request. Also include the URL to the request that YOU REIVEWED in the comment field of the
submission.
You don't have to have YOUR merge request reviewed to submit, but you should have reivewed someone else's work.
Feedback will be given and a follow up ticket for v2 will be given after grading.
I WILL STILL BE IN CLASS AND YOU CAN STILL COME TO CLASS TO ASK QUESTIONS AND WORK ON THINGS.
If you used one merge request for your main feature and the cleanup/UI/bug tickets, make sure to reference the ticket #s in your merge request title or
description!
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
WEEK 14 - APR 15 - R.W. COURSE BREAK
(This class only) - A break week where I can grade the turned in projects so far.
I WILL STILL BE IN CLASS AND YOU CAN STILL COME TO CLASS TO ASK QUESTIONS AND WORK ON THINGS.
If you haven't done v1 or v2 of the project, please start with those first. You can work on both and submit them in one branch/merge request as well.
About
For this part of the project you will test somebody else's work and create a ticket for any fixes and cleanup that need to be done, especially from the user
interface side of things. Follow along with the "expected behavior" part of this document for an idea of how things should be designed.
Who to test?
There will be tickets set up for "test XYZ feature". Assign one to yourself. Do not test something that you worked on, make sure you're testing
someone else's features.
Your assignment
Finding a testing ticket
More than one person can review the same menu set. Locate one of the tickets labeled "Quality Assurance" in the repository:
Don't assign it to yourself, you'll create a separate ticket. Just make sure to refer back to this ticket number when creating your own ticket. The QA
ticket contains some basic information including the original feature ticket that you can reference as well.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Creating a ticket
From the Issues page on GitLab, there will be a New issue button on the upper-right. Click on it to get started.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Title: "Cleanup for MODEL menus", plus the original ticket number.
1. You can find old tickets by going to the Issues page and doing a Search through CLOSED tickets. The ticket you're looking for will be
"MODELNAME – Add, Update, Remove functionality".
Desciption: Leave as "WIP" at first, you can come back and edit the text as you review.
Assignee: Assign this ticket to whomever was on the original ticket for "MODELNAME – Add, Update, Remove functionality".
Milestone: Project v3
Labels: Cleanup
Due date: 2024-04-28
After creating ticket, you can click on the white Edit button next to the ticket name. Add on to the description as you test out the model's menus.
You can also add screenshots as needed.
The review here is more about the actual user interface of the program. You don't necessarily need to go over the code itself. We're looking at
functionality and style and whether navigating the menu(s) are confusing in any way.
Make sure to reference the original "review XYZ model" ticket witin the description or title so I can get back to the original ticket easily.
Do I fix my ticket?
If you get assigned a cleanup ticket you don't have to fix it up. This is mostly a practice in testing and documentation.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Turn in?
Turn in the URL of the ticket you created as the assignment on Canvas.
Testing checklist
This is written to be generic, but you can follow these steps for any of the models.
Style guide
Submenu header should be rendered with the void TextHeader( std::string text ); function, giving this appearance:
Integer input within a range should be handled with the int Program::GetValidChoice( int min, int max ) function.
Prompts before input should clearly describe what input is expected from the user.
Submenu numbered menus should be handled with the void DisplaySubmenu( std::vector<std::string> options,
bool zeroIsGoBack ) function for a consistent appearance.
This code:
1. wallet_id
2. title
3. cc_last4
--------------------
0. Back to main menu
Option 0 should always be "go back" or "quit". (Except when displaying a table of models and selecting one of those model IDs.)
Update menu should stay editing a specific model until the user decides to cancel/go back.
Program dialog should not be misleading; it shouldn't say "model updated successfully" if nothing was updated OR if the update wasn't
successful.
Table information should adhere to column sizes; use string Helper::Truncate( string original, int length ) as
needed.
Add MODEL
During add the program should step the user through the process of setting up information related to the Model.
If there are any linking IDs (e.g., Store -> Account owner id):
Make sure that the table of data is displayed showing the linked item's entries (e.g., Account in this example).
Make sure that the given linking ID points to a valid entry. (e.g., account_manager.IsValidId( entered_id ) )
At end of Add functionality, a confirmation message should be displayed that the item was added successfully.
If there were any errors that meant the model wasn't added, display an error message, NOT a successful message.
id email
--------------------------------------------------------------------------
100 [email protected]
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
101 [email protected]
102 [email protected]
Wishlist added.
Notes
User should not be entering the unique ID for the Model itself; this should be assigned in the program.
Update MODEL
List of all models of this type should be displayed, then the user asked for an ID to edit.
There should be an error check to make sure the ID provided is valid.
All fields (except the Model's Unique ID) should be editable from this menu.
User should not be able to edit a model's unique ID for itself.
Submenu for editing the chosen model should continue looping until the user decides to back out back to the main menu.
Editable fields:
1. product_id
2. account_id
3. review_text
4. star_rating
--------------
0. Back to main menu
Your selection?
>> 2
Available accounts:
id email
--------------------------------------------------------------------------
100 [email protected]
101 [email protected]
102 [email protected]
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Updated account_id.
Editable fields:
1. product_id
2. account_id
3. review_text
4. star_rating
--------------
0. Back to main menu
Your selection?
>> 0
Remove MODEL
Stay on remove menu until user decides to return to main menu.
Give confirmation when a model is successfully removed.
Removed product.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
WEEK 16 - APR 29 - LAST WEEK OF CLASS / R.W.
COURSE BREAK
Catch-up week, last chance to get your assignments in.
I WILL STILL BE IN CLASS AND YOU CAN STILL COME TO CLASS TO ASK QUESTIONS AND WORK ON THINGS.
I USE FINALS WEEK TO GRADE ALL REMAINING WORK AND I DO NOT ACCEPT LATE WORK DURING FINALS WEEK.
Additional
About
About this book
This "course book" contains the concept notes, assignment documentation, reference material, and other resources, all of which make up the author's
Core C++ course. The goal is to be a one-stop location for all the resources you need for this course, and to give you something to keep for reference
later on - in other classes, for review before a job interview, or just as a reference manual. I encourage you to write in this book, keep your notes in it,
highlight it, and use it as your guide as you work through the course content.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
My course design ideals
I am interested in training you how to be a good software developer, which includes how the language works, designing software and good
interfaces, diagnosing and fixing issues and bugs, and so on. I am not interested in making sure you're a cookie-cutter "best-student", which
usually just translates to "a traditional student with the opportunity to give school 150% of their attention". I've been a non-traditional student,
I've had to work full time my entire adult life, I understand that many of my students are also adults with jobs, families, and other
responsibilities, and I am not interested in penalizing "non-traditional" students for not being able to make perfect attendance or get everything
in by the due date 100% of the time.
I try to build my courses in a way like a video game - start by tutorializing and easy challenges, and as you get more experience you are faced
with harder challenges, but everything's designed to help you build the skills you need to tackle everything.
I think that education should be free and available to everybody. (But also I need to pay bills so I am fortunate that I get to work as a teacher,
which I enjoy doing.)
All the (good) course content I create is available online for free for anyone to access. (GitLab, my webpage, YouTube). Anything that I think
you need to know to be successful will be available in some form online and outside of class; I'm not going to penalize you for not making it to
class.
I want to help you build up your problem solving skills so I may not always answer your assignment questions directly (more in a guided,
"here's a hint" way), but I am always here to answer questions and help guide you to where you need to go.
I miss teaching from home where I could wear sweat pants all day. We should all be able to do what we do while being comfy in sweat pants or
whatever.
I've been in the KC Metro area since I was around 11 years old. I started programming because I was in love with video games, and I spent my free
time in my teen years (badly) programming video games. :)
Education: Homeschooled, GED, Associates in Computer Science from MCCKC, Bachelors in Computer Science from UMKC, dropped out of
gradschool multiple times (UMKC, MS&T, KU) cuz money/time.
Development Work: Mostly C# (web development) and C++ (software development) professionally, also with PHP, HTML, CSS, JavaScript.
Independent mobile app development for Android, independent game development with Lua or C++.
Teaching Work: Tutoring math @ MCCKC (2004), creating programming tutorials on YouTube (since 2008), adjunct teacher @ UMKC (2013,
various other years), adjunct teacher @ JCCC (2016-2018), full time teacher @ JCCC (2020 - current).
Free time things: Playing video games, making video games, studying human languages, gardening, arts and crafts, journaling and organization,
animating, video editing, playing piano, writing music, TTRPGs, drinking coffee, making zines, volunteering.
Other names: In the work system I'm R.W., but my full name is Rachel Wil Sha Singh. Around many friends I go by "Moose". I am nonbinary and go
by various names in various contexts. I relate more to computers than I do to genders.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
My games and projects: http://www.moosadee.com/
Reference
Basic Computer Skills
Basic computer skills
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
You should be aware of the extensions of our files. You will need to be able to identify source code files, such as .cpp and .h files for C++, or
.py files for Python. Additionally, most executable (runnable) files end with the .exe extension in Windows.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
By default, Windows hides file extensions from you. However, it is important to know what kind of files you're working with in a programming class.
To view file extensions, search for "File Explorer Options". Select the "View" tab, and UNCHECK the option "Hide extensions for known file
types". Hit OK when done.
It is important to keep in mind that the default working directory of our programs is the location where the project file is. For Visual Studio, that's a
.vcxproj file. For Code::Blocks, that's a .cbp file.
Navigating quickly
Go to declaration
Go to definition
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Refactor - Rename
Your merge request should only contain files related to the current feature or project you're working on
It shouldn't contain code from multiple assignments.
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: Yes:
If you use an input statement it doesn't show anything on the Use an output statement to display a message before getting the
screen, so it looks like your program has crashed. user's input.
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:
Member variables
m_lowerCamelCase - Variables that belong to a class should be prefixed 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 underscore
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 .
Don't put an entire program in main() - Split out the program into separate menu functions; ideally use a Program class that
contains functions within it.
Naming conventions
Variable, function, and class names should be descriptive.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Arrays
Do not use a variable for an array's size; some compilers might support 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 function should have a specific 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
sophisticated 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.
void ClearScreen()
{
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__
system( "cls" );
#else
system( "clear" );
#endif
}
File guards
Always use ifndef instead of pragma once for your file guards.
Yes:
#ifndef _MYFILE_H
#define _MYFILE_H
// My code
#endif
No:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
#pragma once
// My code
File organization
Function/class declarations
Function and class declarations should go in a header (.h) file.
Function definitions
Function definitions should go in a source (.cpp) file, EXCEPT TEMPLATED FUNCTIONS (those all go in .h).
Each class/struct should have its own set of .h and .cpp (as needed) files
Don't put multiple class declarations in one file.
Clean code
Whitespace
Adequate whitespace should be used to differentiate logical sections of code. At the same time, don't use too much whitespace. The goal is to
have readable code.
No: Yes:
if ( a == b ) return ( a == b );
return true;
else
return false;
Curly braces
Preferred style:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
if ( a == b )
{
DoThing();
}
GNU styling:
if ( a == b )
{
DoThing();
}
if ( a == b ) {
DoThing();
}
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: Yes:
if ( CONDITION ) if ( CONDITION )
DoThingA(); {
else if ( CONDITION2 ) DoThingA();
DoThingB(); }
else else if ( CONDITION2 )
DoThingC(); {
DoThingB();
}
else
{
DoThingC();
}
Or:
if ( CONDITION ) { DoThi
else if ( CONDITION2 ) { DoThi
else { DoThi
Without arguments:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
int main()
{
return 0;
}
With arguments:
Declare a variable
DATATYPE VARIABLENAME;
int myNumber;
string myString;
float myFloat;
VARIABLENAME = VALUE;
myNumber = 100;
myString = "Goodbye";
UPDATEDVAR = COPYME;
vipStudent = student3;
You can mix variables and string literals, as long as the stream operator << is between each item.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
cout << "Text";
cout << myVariable;
cout << "Label: " << myVariable << endl;
Get a full line of text (with spaces) and store in a variable (string only)
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:
Branching
If statement
If the condition evaluates to true, then execute the code within the if statement. Otherwise, skip that code completely.
if ( a == 1 )
{
}
If/else statement
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 ( a == 1 )
{
}
else
{
}
If/else if statement
Checks each condition in order. If one is true, then subsequent else if statements are ignored.
if ( a == 1 )
{
}
else if ( a == 2 )
{
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Similar to above, but if all if and else if statements are false, then else is executed.
if ( a == 1 )
{
}
else if ( a == 2 )
{
}
else
{
}
Switch
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;
}
Loops
while ( CONDITION ) { }
while ( a < b )
{
cout << a << endl;
a++;
}
Runs at least once and then continues looping if the condition is true.
do { } while ( CONDITION );
do {
cout << "Enter a number: ";
cin >> input;
} while ( input < 0 || input > max );
Iterate some amount of times through the loop based on your counter variable and range.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
for ( int i = 0; i < 10; i++ )
{
cout << i << endl;
}
Iterates over all elements in a collection. Only moves forward, doesn't give access to index
vector<int> myVec = { 1, 2, 3, 4 };
for ( int element : myVec )
{
cout << element << endl;
}
When declaring a vanilla array, you need to set its size. You can either hard-code the size with a number:
string arr[10];
Declare an STL array object Remember that you will need #include <array> at the top of your file to use the array object.
Declare an array object, passing in what the data type of it values are, and the size of the array:
vector<string> studentList;
// C-style array:
for ( int i = 0; i < TOTAL_STUDENTS; i++ )
{
cout << "index: " << i << ", value: " << students[i] << endl;
}
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
// 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 I/O
Make sure to have #include <fstream> in any files using ifstream or ofstream !
ofstream output;
output.open( "file.txt" );
ifstream input;
input.open( "file.txt" );
if ( input.fail() )
{
cout << "ERROR: could not load file.txt!" << endl;
}
string buffer;
// read a word
input >> buffer;
// read a line
getline( input, buffer );
Functions
When creating .h/.hpp files, it is important to include these lines to prevent file duplication, which happens if you #include this file in more than one
place.
#endif
Function declaration
A function declaration contains the function header and no body. It declares that the function exists and will be defined elseware.
void DisplayMenu();
int Sum(int a, int b);
Function definition
A function definition defines how the function operates. It includes the function header and a function body, which has commands in it.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
void DisplayMenu()
{
cout << "1. Deposit" << endl;
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 num1 = 2;
int num2 = 5;
int result = Sum( num1, num2 ); // Passing in variable values
Classes
Declaring a class
Remember that classes must end with ; on their closing curly brace!
class CLASSNAME
{
public:
// Public members
protected:
// Protected members
private:
// Private members
};
class Student
{
public:
// Constructor functions
Student();
Student( string name, float gpa );
// Member functions
void Setup( string name, float gpa );
void Display();
private:
// Member variables
string m_name;
float m_gpa;
};
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Defining a class member function (method)
A class' member functions must be declared within the class declaration. Then, you define the member function within a .cpp file.
// Function definition
void Student::Setup( string name, float gpa )
{
m_name = name;
m_gpa = gpa;
}
It is best practice to make member variables private to protect the integrity of the data. Private members cannot be accessed outside of the function, so
instead you'll have to create interfacing functions to access (get) and mutate (set) data.
Pointers
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Declare a pointer
PTRNAME = &VARIABLE;
Pointer variables store addresses as their value. To get the address of a variable, prefix the variable name with the address-of operator & .
int myInteger = 5;
int * ptrInt = &myInteger;
Student studentA;
Student * ptrStudent = nullptr;
ptrStudent = &studentA;
Dereference a pointer
PTR->MEMBER
if ( ptrName != nullptr )
{
// Pointer is safe to use...
}
Memory management
DELETE PTRNAME;
delete num;
delete newNode;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Allocate memory for an array
DELETE [] PTRNAME;
delete [] numList;
delete [] nodeList;
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Common runtime errors
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Explanation: This is a result of creating a new file in XCode, but choosing the wrong file type. When adding .cpp files, make sure you
select a C++ file object.
Git issues
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Git: fatal: not a git repository (or any of the parent directories): .git
Error message: 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.
Git guide
Open Git Bash in Windows:
Use the Windows Explorer to navigate to a folder where you would like to open Git Bash in. Right-click in the empty space, and select "Git Bash
Here":
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Clone a repository to your hard drive:
Make sure to pull latest changes from main first before creating a new branch so that you have the most up-to-date code to start from:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
git checkout main
git pull
git status
git add .
git commit -m "CHANGE DESCRIPTION"
git push -u origin BRANCHNAME
Add:
Commit:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Push:
Afterwards, your changes will show up on the server. Make sure to use the dropdown to select the branch you're on:
Pull latest changes from server: You'll probably want to pull latest from the main branch. Note that if you're on a different branch, itw ill pull any
changes to your branch and attempt a merge.
Common errors/issues:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
There is no tracking information for the current branch. Please specify whic
Try to run: git pull origin main to point to the proper remote and branch.
! [rejected]
error: failed to push some refs
hint: Updates were rejected because the tip fo 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.
The hint gives you the solution: Run git pull and then repeat your git push .
fatal: not a git repository (or any of the parent directories): .git
You are not running your git commands from within a repository folder. Make sure you open Git Bash within a folder, or use cd commands to
navigate to your repository path.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
A default branch (e.g. main) does not yet exist for REPOSITORY
Ask a project Owner or Maintainer to create a default branch:
URL
![ remote rejected] BRANCH -> BRANCH (pre-receive hook declined)
Make sure you're on your own branch and not the main branch when trying to do your push command.
Alternatively, the instructor may need to make a commit to the main branch to get things up and ready to go.
warning: in the working copy of 'FILE', LF will be replaced by CRLF the next
This isn't a problem, this is just because the "enter" key is stored as "LF" or "CRLF" on Windows/Linux depending on the systems, Git automatically
converts it for us.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Navigate to the Project_Makefile folder on your computer and open this path in the Terminal, Command Prompt, or PowerShell.
Type in the make command to build the program. It will start showing the build output:
Once the build process is over, use ls to look at the files in the directory:
The file labeled " _out " is our executable file. To run the program, use the ./ command followed by the name of the program:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Any time you make changes to a code file in the project, you will need to run make again to rebuild the code.
Start by going to the File menu and selecting Open Folder…. Select the base path of the project you want to work with.
Building in VS Code:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
To build in VS Code, open up the Terminal. You can find it under the View menu.
After the build is done, use ls to view the files in the directory. A file with " _out " will be generated - this is the executable file.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Any time you make updates to the code you will need to run the make command to generate the latest version of the program to run.
Quick checklists
Setting up a library in Visual Studio
1. Download library from website.
2. Extract library to your hard-drive.
3. Create a new Empty project in Visual Studio.
4. Create a new source file (main.cpp) in Visual Studio.
5. Right-click on your project and go to Properties.
6. Make sure your Configuration is set to Release and your Platform is set to x64.
7. Under C/C++ > General, add SFML's include path to the Additional Include Directories property.
8. Under Linker > General, add SFML's lib path to the Additional Library Directories property.
9. Under Linker > Input, click the "v" dropdown on Additional Dependencies and click <Edit…>. Add your related .lib files (e.g., sfml-
graphics.lib, sfml-window.lib, sfml-system.lib).
10. Click OK.
11. Move the .dll files (sfml-graphics-2.dll, sfml-window-2.dll, sfml-system-2.dll) from the SFML/bin folder to your project directory.
12. Done with configuration.
Setting up a library in Code::Blocks (Windows)
1. Download library from website.
2. Extract library to your hard-drive.
3. Create a new Empty project in Code::Blocks.
4. Create a new empty file (main.cpp) in Code::Blocks.
5. Right-click on your project and go to Build options…
6. Make sure you've selected Release instead of Debug on the left-hand side.
7. Under Search directories > Compiler, add SFML's include path.
8. Under Search directories > Linker, add SFML's lib path.
9. Under Linker settings and Link libraries:, add the libraries: sfml-system, sfml-graphics, sfml-window.
10. Click OK.
11. Move the .dll files (sfml-graphics-2.dll, sfml-window-2.dll, sfml-system-2.dll) from the SFML/bin folder to your project directory.
12. Done with configuration.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Downloading and extracting the library
For these instructions we will be working with the SFML (Simple Fast Media Library) library, but setting up most libraries will work about the
same.
Downloading: Go to the library webpage (https://www.sfml-dev.org/download.php) and select "SFML", latest stable version (as of
writing this is 2.6.1).
From the downloads page, there are various options for a Windows download.
Figure 7: An image of the SFML downloads page, showing different versions that can be downloaded for Windows.
If you're working with Visual Studio, then download the latest version, even if the year doesn't match. You'll probably want the 64-bit
verison, since most computers these days are 64-bit.
If you're working with Code::Blocks, you will probably want the 64-bit SEH option ("GCC 13.1.0 MinGW (SEH) - 64-bit"), but you can
double-check which version you need by going to your CodeBlocks install directory (such as C:\Program Files\CodeBlocks\MinGW\bin\)
and looking for a file called "libgcc"… based on this version it will tell you which version of SFML you need to download:
In Windows I like to have a "LIBRARIES" folder on my root directory, such as "C:\LIBRARIES\". So, all extracted, my default path for
SFML would be:
C:\LIBRARIES\SFML-2.6.1
You can download many libraries from your distro's package manager, such as synaptic for Debian-based systems. Do a search for
"libsfml" and download the libsfml-dev package. (Most libraries are "libXYZ-dev" as well.)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
The library will be automatically installed on your machine, with the relevant paths for configuration being.
Keeping track of important paths
You'll need to know where your library files are being kept while we're configuring the project, so make sure to take note of the paths.
Note that if you're in Windows, you might have unzipped your library to a different directory than me, and will need to replace
"C:\LIBRARIES\" with wherever you put your SFML folder.
You can also refer to the SFML Tutorials page on how to set up Visual Studio, Code::Blocks, and other platforms.
The following write-ups are step-by-step guides with screenshots to show you how to configure Visual Studio and Code::Blocks for SFML…
Visual Studio
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Set your Project name and Location, then click Create.
3. Create a source file: Create a new .cpp file for your project by going to your Solution Explorer, right-clicking on the project, going to
Add, then selecting New Item….
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In your main.cpp, it can be useful to add some starter code to make sure your project will build properly with the library linked within.
Here is a very stripped-down SFML program:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Window");
return 0;
}
At first this will generate build errors, but once we have the library set up properly, it should compile.
5. Go to the properties: Right-click on your project in the Solution Explorer and select Properties.
Make sure at the top of this screen, to set the Configuration to Release and Platform to x64.
6. Set up the include directory: On the left-hand side, open the C/C++ category and the General sub-category. In the Additional
Include Directories property, paste the path to your SFML directory's include folder, such as:
C:\LIBRARIES\SFML-2.6.1\include
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
7. Set up the lib directory: Now under the Linker category and the General sub-category, add the path for the SFML directory's lib
folder to the Additional Library Directories property, such as:
C:\LIBRARIES\SFML-2.6.1\lib
8. Set up dependencies: Under the Linker category and the Input sub-category, click the "v" button next to Additional Dependencies.
Click the <Edit…> button.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In the pop-up box, add the following in the top text box:
sfml-graphics.lib
sfml-window.lib
sfml-system.lib
9. Build the program: In the dropdown near the play button, select Release as our build type, and make sure x64 is selected as our
platform.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
10. Adding the .dll files to the project:
If we try to run the program right now, it will complain about missing dll files:
We need to copy the dll files from the SFML library to our project now.
In the SFML directory's bin folder (e.g., C:\LIBRARIES\SFML-2.6.1\bin\ ), copy the relevant library files (sfml-graphics-2.dll,
sfml-system-2.dll, sfml-window-2.dll).
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Paste these files into your project directory:
Your program should now start, open, and close without any error messages. Currently the program doesn't really do anything because
there's no game loop within. Reference the SFML setup page (https://www.sfml-dev.org/tutorials/2.6/start-vc.php) for some test code you
can use to verify that everything works properly.
Code::Blocks (Windows/Linux)
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
2. Set the Project title and Folder to create project in, then click Next >. Use the default options, then click Finish to create the project.
3. Create a source file: Go to File > New > Empty file and create a new file named "main.cpp".
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
In your main.cpp, it can be useful to add some starter code to make sure your project will build properly with the library linked within.
Here is a very stripped-down SFML program:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "Window");
return 0;
}
4. Go to the project options: Right-click on your project in the Projects view and select Build options….
On the left-hand side, make sure to select the Release configuration, not the Debug.
5. Link to the include directory: Under the Search directories tab, select the Compiler sub-tab. From here, click the Add button and
paste in the path to your SFML directory's include folder, such as:
C:\LIBRARIES\SFML-2.6.1\include
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
6. Link to the lib directory: Under the Search directories tab, select the Linker sub-tab. From here, click the Add button and paste in
the path to your SFML directory's lib folder, such as:
C:\LIBRARIES\SFML-2.6.1\lib
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
7. Set up linked libraries: Under the Linker settings tab…
For WINDOWS, under the Link libraries: section, click the For LINUX, under the Other linker options: section add
Add button. You'll do this three times, adding the three these flags: -lsfml-graphics, -lsfml-window, -lsfml-system):
libraries: sfml-graphics, sfml-window, and sfml-system.
8. Build the program: In the dropdown near the build buttons, make sure to change it from building the "Debug" version to building the
"Release" version.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Now when you build there shouldn't be any errors:
If we try to run the program right now, it will complain about missing dll files:
We need to copy the dll files from the SFML library to our project now.
In your file explorer, navigate one window to your SFML directory and one to your project directory.
In SFML's bin directory, highlight the dll files and copy them: sfml-graphics-2.dll, sfml-system-2.dll, and sfml-window-2.dll.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Paste these files into your project directory:
Your program should now start, open, and close without any error messages. Currently the program doesn't really do anything because
there's no game loop within. Reference the SFML setup page (https://www.sfml-dev.org/tutorials/2.6/start-cb.php) for some test code you
can use to verify that everything works properly.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
If you use the example code from the SFML webpage guide, after you build and run you should see a green circle rendered to our
window:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Functions
Old lecture video: http://lectures.moosader.com/cs200/05-Functions.mp4
Class archive:
http://lectures.moosader.com/cs200/2021-06_Summer/2021-07-01_cs200_lecture_functions.mp4
http://lectures.moosader.com/cs200/2021-01_Spring/2021-03-16_cs200_lecture_functions.mp4
http://lectures.moosader.com/cs200/2021-01_Spring/2021-03-18_cs200_lecture_functions_arrays_and_const.mp4
Const
Old lecture video:
http://lectures.moosader.com/cs200/09-Const.mp4
http://lectures.moosader.com/cs200/21-Const-2.mp4
Structs
Old lecture video:
https://youtu.be/kcfwQ2duNIE
http://lectures.moosader.com/cs200/10-Struct.mp4
Classes
Old lecture video:
http://lectures.moosader.com/cs200/11-Class-1.mp4
http://lectures.moosader.com/cs200/12-Class-2.mp4
http://lectures.moosader.com/cs200/13-Class-Design.mp4
Class archive: http://lectures.moosader.com/cs200/2021-06_Summer/2021-07-06_cs200_lecture_classes.mp4
Inheritance
Old lecture video: http://lectures.moosader.com/cs200/15-Inheritance.mp4
Class archive: http://lectures.moosader.com/cs200/2021-06_Summer/2021-07-08_cs200_lecture_inheritance.mp4
Pointers and memory
60 Second Review: https://www.tiktok.com/@rwsskc/video/7146577130120318250
Old lecture video:
http://lectures.moosader.com/cs200/16-Pointer.mp4
http://lectures.moosader.com/cs200/17-Memory-Management.mp4
http://lectures.moosader.com/cs200/18-Dynamic-Arrays.mp4
Recursion
Class archive: http://lectures.moosader.com/cs250/2021-01_Spring/2021-03-24_cs250_lecture_recursion.mp4
Searching and sorting
60 Second Review:
Old lecture video:
Class archive:
CS 235 Topics
Testing and Debugging
Class archive: http://lectures.moosader.com/cs250/2021-01_Spring/2021-01-26_cs250_lecture.mp4
Function overloading
60 Second Review:
Old lecture video:
Class archive:
Operator overloading
Old lecture video: http://lectures.moosader.com/cs200/20-Operator-Overloading.mp4
Smart Pointers
60 Second Review:
Old lecture video:
Class archive:
Polymorphism
60 Second Review:
Old lecture video: http://lectures.moosader.com/cs200/22-Polymorphism.mp4
Class archive:
Exceptions
Old lecture video: http://lectures.moosader.com/cs200/06-Exceptions.mp4
Class archive:
https://www.youtube.com/watch?v=N269qOGckQE
http://lectures.moosader.com/cs250/2021-01_Spring/2021-02-02_cs250_templates_and_exceptions.mp4
https://www.youtube.com/watch?v=hQVOOxCKl2s
Templates
Old lecture video: https://www.youtube.com/watch?v=1sLim0ln5UQ
Class archive:
https://www.youtube.com/watch?v=bUAqsECFc54
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
http://lectures.moosader.com/cs250/2021-01_Spring/2021-02-02_cs250_templates_and_exceptions.mp4
https://www.youtube.com/watch?v=hQVOOxCKl2s
Anonymous Functions
Static
Friends
The Standard Template Library
Old lecture video: http://lectures.moosader.com/cs200/27-STL.mp4
Class archive:
https://youtu.be/iKyLwc8G4l0
https://www.youtube.com/watch?v=hQVOOxCKl2s
CS 250 Topics
Intro to Data Structures
Old lecture video: https://www.youtube.com/watch?v=INGLTz6jBuk
Algorithm Efficiency
Class archive: http://lectures.moosader.com/cs250/2021-01_Spring/2021-03-16_cs250_lecture_algorithm_efficiency.mp4
Smart Arrays
Class archive:
https://www.youtube.com/watch?v=74CZ3LmMgyU
http://lectures.moosader.com/cs250/2021-01_Spring/2021-02-16_cs250_lecture.mp4
http://lectures.moosader.com/cs250/2021-01_Spring/2021-02-16_cs250_lecture.mp4
Linked Lists
Old lecture video:
https://www.youtube.com/watch?v=Qm6ooxonq3w
https://www.youtube.com/watch?v=kKM9dpST-Z0
Class archive:
http://lectures.moosader.com/cs250/2021-01_Spring/2021-02-23_cs250_lectureB_linked_lists.mp4
Stacks and Queues
Old lecture video: https://www.youtube.com/watch?v=hNfgrGFIAVs
Intro to Trees
Class archive: https://www.youtube.com/watch?v=7ZcZuYvBAVw
Binary Search Trees
Hash Tables
Syllabus
Course information
Course description
This course emphasizes programming methodology and problem solving using the object-oriented paradigm. Students will develop software
applications using the object-oriented concepts of data abstraction, encapsulation, inheritance, and polymorphism. Students will apply the C++
techniques of dynamic memory, pointers, built-in classes, function and operator overloading, exception handling, recursion and templates. 3 hrs.
lecture, 2 hrs. lab by arrangement/wk. Catalog link: https://catalog.jccc.edu/coursedescriptions/cs/#CS_235
Prerequisites
CS 200 or CS 201 or CS 205.
Drop deadlines
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
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 financially responsible for the tuition charges; for details, search on Student
Financial Responsibility on the JCCC web page. Changing your schedule may reduce eligibility for financial aid and other third party funding.
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 first 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.
Instructor information
Course delivery
To see more about JCCC course delivery options, please visit: https://www.jccc.edu/student-resources/course-delivery-methods.html
Office hours Office hours are weekly times that the instructor is available, either on-campus and/or via Zoom. If the pre-determined office hours don't
work with your schedule, you can also schedule a one-on-one time to meet with the instructor.
Office hours are drop-in, and you can attend during any pre-scheduled times; you do not need to ask to join in. You may be placed in a waiting room if
I am working with another student on something.
Class communication
Please use Canvas email, not the @jccc email, to contact the instructor! 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,
department 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!
Course supplies
1. Textbook: Rachel's CS 250 course notes (https://moosadee.gitlab.io/courses/202401_Spring/book_datastructurescpp.html)
2. Zoom: Needed for remote attendance / office hours
3. Tools: See the UNIT 00 SETUP assignments for steps on installation.
An Integrated Development Environment, such as:
Visual Studio Community Edition (Windows only for C++) (https://visualstudio.microsoft.com/vs/community/)
Code::Blocks (multiplatform and lightweight, Windows users download the "mingw-setup.exe" version)
(https://www.codeblocks.org/downloads/binaries/)
XCode (Mac) (https://developer.apple.com/xcode/)
You can use whatever you prefer, or even compile from the command line.
The instructor builds all assignments with g++ from a Linux platform.
Git Bash (https://git-scm.com/) for source code management.
You may need a document editor, such as LibreOffice Writer, MS Word, or Google Documents.
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/)
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 computer, including:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Navigating your Operating System, including:
Installing software
Running software
Locating saved files on your computer
Writing text documents, exporting to PDF
Taking screenshots
Editing .txt and other plaintext files
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 tackling 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.
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 specific assignment name, so I can find it.
2. Include a SCREENSHOT of what's going wrong.
3. What have you tried so far?
Course policies
Grading breakdown
Assessment types are given a certain weight in the overall class. Breakdown percentages are based off the course catalog requirements
(https://catalog.jccc.edu/coursedescriptions/cs/#CS_235)
Final letter grade: JCCC uses whole letter grades for final 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:
Tentative schedule
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Week # Monday Topic A Topic B Topic C
1 Jan 15 Unit 00: Setup Unit 01: Exploring design Unit 02: Review - Basics
2 Jan 22 Unit 03: Review - Functions/classes Unit 04: Debugging/testing Unit 05: Algorithm efficiency
3 Jan 29 Unit 06: Review - Pointers Unit 07: Standard Template Library
4 Feb 5 Unit 08: Recursion Unit 09: Searching & sorting
5 Feb 12 Unit 10: Templates Unit 11: Exceptions
6 Feb 19 Unit 12: Overloading functions & ctors
7 Feb 26 Unit 14: Static members Unit 15: Friends
8 Mar 4 Unit 16: Anonymous functions Unit 17: Polymorphism
9 Mar 11 SPRING BREAK
10 Mar 18 Unit 18: Operator overloading Unit 19: Third party libraries
11 Mar 25 Semester project v1
12 Apr 1 Semester project v1
13 Apr 8 Semester project v2
14 Apr 15 Semester project v2
15 Apr 22 (Catch up week)
JCCC requires us to take attendance during the first week of the semester. Students are required to attend class (if there is a scheduled class session)
this first week. If there are scheduling conflicts during the first week of class, please reach out to the instructor to let them know. JCCC auto-drops
students marked as not in attendance during the first week of class, but students can be reinstated. See
https://www.jccc.edu/admissions/enrollment/reinstatement.html for more details.
HyFlex classes: The following three scenarios count as student attendance for my classes:
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.
OK things:
Asking the instructor for help, hints, or clarification, on any assignment.
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 statements", error messages).
Working with a tutor through the assignments, as long as they're not doing the work for you.
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 files with other students, or asking other students for their code files.
Asking a tutor, peer, family member, friend, AI, etc. to do your assignments for you.
Searching for specific solutions to assignments online/elseware.
Basically, any work/research you aren't doing on your own, that means you're not learning the topics.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Don't give your code files to other students, even if it is "to verify my work!"
Don't copy solutions off other parts of the internet; assignments get modified a little bit each semester.
Each instructor is different, so make sure you don't assume that what is OK with one instructor is OK with another.
Student success tips
I need to achieve a certain grade for my financial 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 financial 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 office hours to
ask questions.
What are some suggestions for approaching studying and assignments for this course?
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.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
Additional information
ADA compliance / disabilities
JCCC provides a range of services to allow persons with disabilities to participate 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 responsibility 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 floor of the Student Center (SC202)
Educational research demonstrates that students who regularly attend and participate 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 adhering 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.
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
distribution 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 fictitious 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.
A faculty member may further define academic dishonesty, cheating or plagiarism in the course syllabus.
https://www.jccc.edu/student-resources/police-safety/police-department/college-emergency-response-plan/
http://www.jccc.edu/about/leadership-governance/policies/students/student-code-of-conduct/student-code-conduct.html
Student handbook
http://www.jccc.edu/student-resources/student-handbook.html
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
following:
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
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 (https://www.jccc.edu/student-resources/police-safety/college-
emergency-response-plan/)
During an emergency: Notifications/Alerts (emergencies and inclement weather) are sent to all employees and students using email and text
messaging
students are automatically enrolled, see JCCC Alert - Emergency Notification (https://www.jccc.edu/student-resources/police-safety/jccc-
alert.html)
Weapons policy: Effective 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.
I. Software Development
C. Develop a solution.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF
4. Define objects containing pointers.
IV. Inheritance
V. Polymorphism
C. Create documentation.
Explore our developer-friendly HTML to PDF API Printed using PDFCrowd HTML to PDF