CSCI 222: Programming Concepts & Problem Solving II
Fall 2018

Course Assignments




zyBooks Assignments

CH2: Due 9/5 CH3,4: Due 9/12
CH5: Due 9/19 CH6: Due 9/26
CH7: Due 10/3 CH8: Due 10/17
CH9: Due 10/31 CH10: Due 11/7
CH11: Due 11/14 CH12: Due 11/28
NOTE: this is a proposed schedule, check back for updates!
ALSO: look for 1 lab outside of ZyBooks (Chapter: TBA)
HERE: CH9 External Lab: instructions here: Parallel Lab

Programming Assignments

Programming Assignment 1: DNA analysis

Assigned: 8/27
Checkin (1): 8/29 - show a working length() function
Checkin (2): 9/5 - show a working count_nucleotides() function
Due: 9/10 by email before the start of class

Purpose: The purpose of this assignment is to get back into programming after (possibly) a summer of not coding. You will be working on a Bioinformatics task. Bioinformatics is an important cross-disciplinary area of study that incorporates methods and tools from computer science, statistics, and biology to analyze biological data.

Skills/Knowledge: This assignment should help get us back into coding and serve as a refresher for several topics, including:

  • Functions
  • Arrays
  • C-style Strings
  • Basic I/O

Task: Your assignment is to write a program that will take two strings of DNA as input and collect and print some basic statistics for both strings. A DNA string is a string consisting of the alphabet A, C, G, and T (adenine, cytosine, guanine, and thymine). The statistics that you shall calculate are:

  • The length of both DNA strings
  • The number of occurrences of 'A', 'C', 'G', and 'T' in each string
  • The Hamming distance between the two strings

The Hamming distance between two strings of equal length is one of the simplest metrics in information theory. The Hamming distance between two strings is the total number of places where the strings differ. In terms of DNA, it can be used to calculate the total number of errors (mutations) that were introduced by copying a DNA string. For instance, te strings:

"GCCATCCATCAC"
"GTCAGCCAACAC"
differ in 3 places (hilighted in red), making the Hamming distance of the above 3.

For your first program, you are given the structure of a C++ program that generates simple reports about DNA strings. The general program structure is given, including stubs for each function you will need. You may write additional helper functions to solve the problem, but additional functions are not strictly necessary.

You can download the program outline: here

A sample run of your program should match the following:

Please enter the first DNA sequence: GCCATCCATCACCTACA
Please enter the second DNA sequence: GTCAGCCAACACGACTA
Generating DNA report.
DNA string 1: GCCATCCATCACCTACA
String length: 17
Nucleotides:
5 occurrences of adenine (A)
8 occurrences of cytosine (C)
1 occurrences of guanine (G)
3 occurrences of thymine (T)
DNA string 2: GTCAGCCAACACGACTA
String length: 17
Nucleotides:
6 occurrences of adenine (A)
6 occurrences of cytosine (C)
3 occurrences of guanine (G)
2 occurrences of thymine (T)
The Hamming distance between DNA strings 1 and 2 is: 7
      

Notes and Gotchas:

  • You are limited to the following libraries (extra libraries will result in the loss of points):
    • iostream
  • You should declare all array sizes using a symbolic constant.
  • Whenever you are accessing the array you should make sure that you use the null character '\0' to control your loops as well as the maximum array size defined by your constant. In other words: Make sure not to overrun your array bounds.
  • Don't forget your checkins! This is worth 10% of your assignment grade!
  • Make sure to note any extra credit you have attempted in your header comments

What to Turn in:

  • dna_report.cpp - a valid C++ file containing all of your code

BONUS:
(1pt) Make your code case agnostic - it should treat 'A' and 'a' as the same character
(1pt) Occasionally a DNA sequence read fails. In this case, garbage characters (something other than 'A', 'C', 'G', or 'T') are introduced. In addition to tracking 'A', 'C', 'G', and 'T', also track how many garbage characters occur.




Programming Assignment 2: Code Making and Code Breaking

Assigned: 9/10
Checkin: 9/12 -- Start a new project, get length() working and be able to call (a possibly buggy) encryptChar function.

Due: 9/17 by email before the start of class.

Libraries you may use:

  • iostream

Purpose: The purpose of this assignment is to continue our C++ warmup, working with C-style strings and arrays. Cryptography is the practice and study of techniques for secure communication. For this assignment, we will be working on implementing a variation of the Caesar cipher. This is a simple substitution cipher where letters are rotated a fixed number of places through the alphabet (image below courtesy of learncryptography.com):

NOTE: This will require the use of a modulus in order to properly 'wrap around'.

We will be creating a slightly more robust version by leveraging our (possibly) newfound knowledge of ascii values. When looking at the ascii table, we can see that all of the printable characters are located from ascii value 32 (a space: ' ') up through ascii value 126 (a tilda: '~'). Using this knowledge, we can implement a caesar cipher across these 95 characters, instead of the simpler 26 character cipher.

Skills/Knowledge: This assignment covers several topics, including:

  • Functions
  • Arrays
  • C-style Strings
  • Basic I/O
  • ASCII values

Task: For this assignment, we will be working with C style strings, giving us more practice with C strings and arrays. Your main will first need to prompt the user for a string to encrypt, followed by the rotation amount. It should then perform encryption, and print out the result to the user.

A sample run of your program should look like this:

Please enter string for encryption: Hello world!
Please enter the amount of rotation needed for your cipher: 19

Your encrypted string: [x #3+#& w4

Notice how both the space and the exclamation point have been encrypted! One interesting aspect of Caesar ciphers is that they are symmetrical. If we continue to rotate the resulting string by 19 enough times (5), we will find our way back to our original input string!

Please enter string for encryption: 5RYY\ld\_YQm
Please enter the amount of rotation needed for your cipher: 19

Your encrypted string: Hello world!

Now that we are on our second program, I will no longer provide stubs. Feel free, however, to use the first assignment stub as a starting point!

At a minimum, you will need to implement the following functions:

  • int length(const char input[]); - This function should return the length of the c string input
  • char encryptCharacter(const char c, int rotation); - This function should return an encrypted character, based on the input character and the rotation amount.
  • void encryptString(const char original[], char encrypted[], int rotation); - This function will encrypt the character array original and store the new, encrypted value into the character array encrypted. This function should rely on both the length and encryptCharacter functions. Don't forget, your encrypted array will need a null character ('\0') at the end!

Notes and Gotchas:

  • Make sure you do not use any extra libraries (extra libraries will result in the loss of points)
  • You should declare all array sizes using a symbolic constant.
  • The length() function is meant to be a helper function Use it to help your other functions!
  • Make sure your function signatures match the assignment description.
  • Don't forget your checkin, this is worth 10% of your assignment grade!
  • Don't forget commenting/style:
    • Don't forget your comments: header, and for every funtion (except main)
    • Make sure you have a space on both sides of your binary operators (only 1 side for your unary operators: int k = i++; is perfect)
  • Make sure to note any extra credit you have attempted in your header comments

What to Turn in:

  • cipher.cpp - a valid C++ file containing all of your code

BONUS:
(2pts) Only encrypting one thing at a time is boring. Put your logic into a loop, so users can encrypt more than one string in a single run of your program. Make sure to ask the user for a new rotation amount and new string on every loop!




Programming Assignment 3: File I/O with iomanip!

Assigned: 9/17
Checkin: 9/19 -- Start a new project, implement and demonstrate a working loadData()function.

Due: 9/24 by email before the start of class.

Libraries you may use:

  • iostream
  • iomanip
  • fstream
  • string

Purpose: The purpose of this assignment is to put into practice file I/O and iomanip skills that we have been building in class. This assignment also continues to add more array practice, as well as make sure we all understand weighted grade calculation. You will read in data from a file, store it into arrays, and generate a typeset grade report showing off each trade as well as a calculated final grade.

Task: First, you will need to create 6 arrays to hold all data you will read from the file: One array of strings to hold student names and 5 arrays of doubles to hold each grade. Your main should then prompt the user for the name of an input file to process. You will then need to load the data from the file into your 6 arrays. As you are reading data from the file, make sure that all information remains lined up: the name in position i of the name array should correspond to the programming assignment grade at position i of the programming assignment grade array, etc. Data should be loaded into arrays via the loadData() function.

A sample input file can be found here: input.txt. Each student will first have their name listed, followed by 5 grades: Programming Assignments, Labs, Book Assignments, Exams, and Attendance/Participation. It is safe to assume you will never have more than 200 students in a grade report.

After loading data, printReport() should be called to generate a final grade report. You will need to call calculateGrade() inside printReport() to calculate the final weighted grade based on each input grade. Your weighted grade should be calculated the same way the final grade is calculated for this class:
Programming Assignments 45%
Labs 10%
Book Assignments 5%
Exams 30%
Attendance/Participation 10%

A sample run of your program on the provided input file should look like this:

Enter the name of the file to process: input.txt
-----------------------------------------------------------------------
|Name                      PA     Lab    Book   Exams       A|   Final|
-----------------------------------------------------------------------
|Sparky Button          80.73   90.00   75.00   90.40   40.00|   80.20|
|John Doe               73.00   29.90  100.00   20.80   87.00|   55.78|
|Someone Else          102.00   12.01   23.00   98.00   99.00|   87.55|
-----------------------------------------------------------------------
      


At a minimum, you will need to implement the following functions:
  • double calculateGrade(double programming, double lab, double book, double exams, double participation); - this function applies the weights to produce the final weighted grade. Note: it takes all grades for a single student.
  • void printReport(const string names[], const double programming[], const double lab[], const double book[], const double exams[], const double participation[], int num); - this function is responsible for actually generating the pretty report. It will need all of your arrays (after filling them with data from file), as well as the number of students found in the file.
  • int loadData(ifstream &inFile, string names[], double programming[], double lab[], double book[], double exams[], double participation[]); - This function actually reads in the student data from the file and fills in your arrays. It will then return the number of complete student files it read in. Note: you are explicitly passing in a reference to an ifstream which has already been created and opened in main. You do not need to do anything special when you call this function to pass it by reference.

Notes and Gotchas:

  • Make sure you do not use any extra libraries (extra libraries will result in the loss of points)
  • You should declare all array sizes using a symbolic constant. It is safe to assume that there will never be more than 200 students in a grade report.
  • loadData() has ifstream &inFile as an argument. This tells the compiler to pass an ifstream by reference instead of by value. You don't need to do anything special when you call this function, just pass the variable name as normal
  • When working with files, don't forget to close() them when you are done. As a general rule of thumb - call close() as soon as you are done, and in the same scope that you called open().
  • Make sure your function signatures match the assignment description. (Unless you are attempting the first extra credit)
  • Don't forget your checkin, this is worth 10% of your assignment grade!
  • Don't forget commenting/style:
    • Don't forget your comments: header, and for every funtion (except main)
    • Make sure you have a space on both sides of your binary operators (only 1 side for your unary operators: int k = i++; is perfect)
  • Make sure to note any extra credit you have attempted in your header comments

What to turn in:

  • gradeDisplay.cpp - a C++ file containing all of your source code.

BONUS

  • (2pts) Passing around all these arrays can be annoying - instead of using 5 1D arrays to hold grades, instead use a single 2D array. NOTE: this will change the signatures for loadData() and printReport()
  • (1pts) Create a void saveReport(ofstream &outFile, const string names[], const double programming[], const double lab[], const double book[], const double exams[], const double participation[], int num) function that will save the report to a file. The user should be asked in main if they would like to save to file, and prompted for a file name if they indicate yes. You should then call this function to save the report to file - it should look the same as what was printed to the console in printReport(). NOTE: If you attempt the above extra credit as well, the signature of this function should change too!



Programming Assignment 4: Painting with text

Assigned: 9/24
Checkin: 9/26 - Start a new project, have initialize_canvas() and print_canvas() functions fully implemented. Demo by initializing your image, changing a pixel, and then printing it out.

Due: 10/1 by email before the start of class.

Libraries you may use:

  • iostream
  • fstream (only if attempting bonus credit)
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to practice creating interactive programs, as well as work on using 2D arrays. It will also be a chance for us to practice some of the more creative skills we don't always get to see in our introductory programming classes. The goal is to create a program that allows users to "paint" a picture using characters.

Task: First, you will need to create a 2D array of characters to hold the user's painting. You will additionally need to initialize this array to hold spaces (' '). This will give the user a blank canvas to start with, instead of a canvas full of garbage. Your main should then start by calling the paint() function, which should continue to prompt the user for their next action until the user specifies that they want to quit.

A sample output of such a program may be found here. Again, note that your program will loop until the user specifies that they want to quit. On quitting, your program should print out the picture one final time and exit. If the user chooses to paint an individual pixel, be sure to verify that the input dimensions are valid! My program is very simplistic, feel free to improve it as much as you want. For those of you wishing to work with switch statements, this would be a great opportunity to do so!

At a minimum you should implement the following:

  • Your main should have a 2D array: char canvas[MAX_ARRAY][MAX_ARRAY];
  • void initialize_canvas(char canvas[][MAX_ARRAY]); - use a nested for loop to initialize the picture to all spaces.
  • void print_canvas(const char canvas[][MAX_ARRAY]); - use a nested for loop to print the picture to the screen.
  • void paint(char canvas[][MAX_ARRAY]); - Allows the user to paint. Will loop until the user says that they want to exit. This is your interactive looping function that main should call!
  • void paint_pixel(char canvas[][MAX_ARRAY], int row, int col, char pixel); - Changes the value of the picture at row, col to pixel (only one character). All error checking should occur in here. If any input value is incorrect, you should print an error and leave the canvas unchanged.
  • void swap_all(char canvas[][MAX_ARRAY], char source, char target); - Loops over the entire canvas, replacing all instances of source with target.

Notes and Gotchas:

  • MAX_ARRAY should be a symbolic constant. It should be set to 26.
  • Make sure you do not use any extra libraries (extra libraries will result in the loss of points)
  • The prototypes I have provided are in the most correct form for passing 2D arrays as arguments - don't modify them
  • Don't forget your newlines when printing to the screen!
  • Don't forget your checkin, this is worth 10% of your assignment grade!
  • Don't forget commenting/style:
    • Don't forget your comments: header, and for every funtion (except main)
    • Make sure you have a space on both sides of your binary operators (only 1 side for your unary operators: int k = i++; is perfect)
  • Make sure to note any extra credit you have attempted in your header comments

What to turn in:

  • picasso.cpp - a C++ file containing all of your source code.
  • A picture that you have made with your assignment.

BONUS

  • (1 pt) Create an additional function: save_to_file(char str[], char canvas[][MAX_SIZE]);. When the user exits, ask if they would like to save the picture to file. On a 'Y' or 'y', prompt for a file name, and save their work (as it would otherwise appear on the screen)
  • (1 pt) Create an additional function/option for the user: paint_horizontal(char canvas[][MAX_ARRAY], int row, char c);. This should paint a horizontal line in row of your canvas, using character c. Make sure to perform error checking and print an error message if row is not valid.
  • (1 pt) Create an additional function/option for the user: paint_vertical(char canvas[][MAX_ARRAY], int col, char c);. This should paint a vertical line in col of your canvas, using character c. Make sure to perform error checking and print an error message if col is not valid.



Programming Assignment 5: Structured Grades

Assigned: 10/1
Checkin: 10/3 - Start a new project, implement loadData, and be able to demonstrate it working.

Due: 10/8 by email before the start of class.

Libraries you may use:

  • iostream
  • iomanip
  • fstream
  • string
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to practice creating and working with structs. To make working with structs a bit easier, you will be approaching this task within the familiar ground of our previous grade calculation assignment. This is a chance to again practice your file i/o and iomanip skills.

Task: For this assignment, we will be revisiting the gradeDisplay program, and upgrading it to use structs! Now, instead of many arrays, we will have a single array of our struct: student. This is the same modification we spoke about in class, where instead of neading multiple arrays to handle the data, we have a single 1D array of student structs.

Your student struct will have the folowing attributes:

  • string name -- the student's name
  • double programming -- the student's programming grade
  • double lab -- the student's lab grade
  • double book -- the student's book assignment grade
  • double exam -- the student's exam grade
  • double attend -- the student's attendance/participation grade
  • double finalGrade -- the student's calculated final grade

Our sample input file from before can still be used input.txt. Remember, you need to be able to support 200 students in a grade report.

Your main will need to create your array of your student structs, then prompt the user for the name of an input file to process. After opening this file, you should call your new loadData function, and finally a new printReport function to generate a final grade report. This time, you should call calculateGrade inside your loadData - this will allow you to fill in the final grade inside your student struct as you build it. The weighted final grade should be calculated the same as it was in Assignment 3. Your grade report output should match the style presented in Assignment 3 as well. For this assignment you will then need to write the grade report to disk after prompting the user for an output file name.

At a minimum, you will need to implement the following functions:
  • void calculateGrade(student& s); - this function applies the weights to produce the final weighted grade. Note: modify the student in place
  • void printReport(const student myClass[], int studentCount); - this function is responsible for actually generating the formatted report that will be displayed in the console.
  • int loadData(ifstream &inFile, student myClass[]); - This function actually reads in the student data from the file and fills in your array of student structs. Don't forget to use proper sentinel logic!
  • int storeData(ofstream &outFile, const student myClass[], int studentCount); - this function is responsible for writing your generated grade report to file. The output file should have the same formatting as the output you print to console in printReport. Make sure you prompt the user for an output file name inside main, and open the file before calling this function.

What to turn in:

  • gradeDisplayStructs.cpp - a C++ file containing all of your source code.

BONUS

  • (2pts) Update printReport and storeData to display an additional 3 lines with labels: Maximum, Minimum, and Average. For each grade (programming, lab, book, exam, attend, final), find the maximum, minimum, and average values, and add them to your grade report table.



Programming Assignment 6: Inheriting Animals

Assigned: 10/8
Checkin 1: 10/10 - Start a new project, implement your base Animal class, and be able to demonstrate it working.

Checkin 2: 10/17 - Implement at least one derived class, and be able to demonstrate it working using one of the helper functions in main().

Due: 10/22 by email before the start of class.

Libraries you may use:

  • string
  • iostream
  • iomanip
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to practice working with classes, protection levels, and inheritance. You will need to create a base or parent class, and 3 derived or child classes. Make sure to pay careful attention to access levels as you are developing your classes, as this can effect how your classes work together!

Task: You will be creating a base or parent class: Animal, as well as derived or children classes Horse, Duck, and one one other class you design. This is a chance for some creativity! You main function will need to walk through all functions for all of your classes, with the help of several required test functions.

Your Animal class will require the following attributes:

  • string species - this should be private. It will designate the type of animal it is. For example: "Horse"
  • string name - this should be protected. It will be the name of the animal. For example: "Sally"
  • string favoriteFood - this should be private. What is this animal's favorite food?
  • int age - this should be private. How old is this animal?
  • string noise - this should be private. What noise does this animal make?
  • virtual void print() - this should be accessible by anyone. It will print out all private and protected data that is held inside your animal class.
  • virtual void feedAnimal() - this should be accessible by anyone. It should print out a string: "*name* eats *favoriteFood*, *noise*!". For example: "Sally eats hay, Neigh!"
  • virtual void speak() - this should be accessible by only this class and its children. It should print out: "*name* says *noise*!". For example: "Sally says Neigh!"
  • void happyBirthday() - this should be accessible by anyone. It will increase age by 1!
  • void changeFood(string newFood) - this should be accessible by anyone. This is a modifier. It will allow you to change the favoriteFood to newFood.
  • Animal() - a default constructor. Make sure you initialize all private and protected variables.
  • Animal(string name, string species, string favoriteFood, int age, string noise) - a parameterized constructor. Make sure you initialize all private and protected variables!

Your Horse class will require the following attributes:

  • double height - this should be a private variable, stating the height of this horse
  • double topSpeed - this should be a private variable, stating how fast this horse can run
  • void print() - this should be accessible by anyone. It is overriding the base print(). When implementing, make sure to first call the base print(), then add on Horse specific information (height and topSpeed).
  • void feedAnimal() - this should be accessible by anyone. It is overriding the base feedAnimal(). When implementing, make sure to first call the base feedAnimal(), and make sure to update height by a small factor (up to you, but try to keep the horses smaller than EPS).
  • void speak() - this should be accessible by anyone. It is overriding the base speak(). It should print out: "*name* hits top speed: *topSpeed*", you should then call the base speak().
  • Horse() - a default constructor. Make sure you initialize all private and protected variables (all the way down to the base class). Don't forget about the Horse-specific variables!
  • Horse(string name, string favoriteFood, int age, string noise, double height, double topSpeed) - a parameterized constructor. Make sure you initialize all private and protected variables (all the way down to the base class).

Your Duck class will require the following attributes:

  • double wingSpan - this should be a private variable, stating the wingspan of this duck
  • double flightTime - this should be a private variable, stating the hours this duck has spent in the air
  • void print() - this should be accessible by anyone. It is overriding the base print(). When implementing, make sure to first call the base print(), then add on Duck specific information (wingSpan and flightTime).
  • void feedAnimal() - this should be accessible by anyone. It is overriding the base feedAnimal(). When implementing, make sure to first call the base feedAnimal(), and make sure to update wingSpan by a small factor (up to you, but try to keep the ducks smaller than a Cessna.).
  • void speak() - this should be accessible by anyone. It is overriding the base speak(). It should print out: "*name* takes off, flying *flightTime*", you should then call the base speak().
  • Duck() - a default constructor. Make sure you initialize all private and protected variables (all the way down to the base class). Don't forget about the Duck-specific variables!
  • Duck(string name, string favoriteFood, int age, string noise, double wingSpan, double flightTime) - a parameterized constructor. Make sure you initialize all private and protected variables (all the way down to the base class).

You will need to additionally make 1 more derived/child class of your choice. Make sure your new class has at least 1 private attribute, and overrides all virtual functions from the base class.

Your main.cpp will be responsible for creating 1 object using each constructor (one with the default, one with the parameterized for each class - you should minimally have 8). You will need to check every public function available for each class. To help, implement the following functions:

  • void printAnimal(Animal & a) - this will call print() on Animal a.
  • void feed(Animal & a) - this will call feedAnimal() on Animal a
  • void speek(Animal & a) - this will call speak() on Animal a.
  • void birthday(Animal & a) - this will call happyBirthday() on Animal a.
  • void updateFood(Animal & a, string food) - this will call changeFood(food) on Animal a.
NOTE: make sure your output is human readable! Make sure to print out what your are testing before running each test. Make sure to call printAnimal() before and after modifications!

What to turn in:

A zip file containing:
  • Animal.h/cpp - the header and implementation for your base animal class
  • Horse.h/cpp - the header and implementation for your derived Horse class
  • Duck.h/cpp - the header and implementation for your derived Duck class
  • *.h/.cpp - the header and implementation for your custom derived class (name up to you!)
  • main.cpp - a main driver you have developed to test all functionality
  • CMakeLists.txt - the CMake file generated by JetBrains to build your project
  • README - your README file: make sure to include all design decisions
NOTE: it may be easiest to just zip up your project folder after deleting the cmake-build-debug folder

Notes and Gotchas:

  • READMEs are small text files, explaing how to run your program, any design decisions you make, and should include the same header comments as any code files.
  • Don't forget your header comments in every file (headers, implementations, main, etc).
  • Remember you need function comments with prototypes - this means in your header files!
  • Don't forget your checkins, this is worth 10% of your assignment grade!
  • The roughly 2 weeks to work on this is a trap! Start early so you don't hit a last minute panic!
  • Make sure to note any extra credit you have attempted in your header comments

BONUS

(2 pts) Implement another derived animal class - make sure your derived class has at least 1 additional attribute and overrides all virtual functions!




Programming assignment 7: Dynamic Payroll System

Assigned: 10/22
Checkin: 10/24 - Start a new project, define your payroll class. Create a simple main that will create your payroll class, then call a fully implemented read_employee_data(). Prove that it works by calling print_employee_info().
Due: 10/29 by email before the start of class

Libraries you may use:

  • string
  • iostream
  • fstream
  • iomanip
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to practice working with dynamic arrays. Specifically, how to properly use them in a class. It will also be a chance to improve our file I/O and iomanip skills, and a chance for some creativity! You will be creating a payroll application for a ficticious company (feel free to have some fun here!). The payroll file will read an employee database on file, and use the information stored in it to generate pay stubs. Your program will then update the database so you are ready for the next payroll operation.

Task: First, you will need to define a payroll class with the following private data:

  • string *names - a (dynamic) array of employee names
  • float *hourly_wages - a dynamic array of each employee's hourly wage
  • int *employee_ids, *hours_worked - arrays containing each employee's unique ID and the number of hours they have worked this pay period
  • int total_employees, check_number - (read from file) the total number of employees you will store data about and the (next) check number to be issued
  • string payroll_file - the name of the payroll file read by read_employee_data() so that it can be written again by store_employee_data()

Your class will additionally need the following publicly accessible functions:

  • payroll() - initializes each array pointer to NULL
  • ~payroll() - calls delete[] for each array when the object goes out of scope
  • void read_employee_data(string file_name) - opens the file file_name and reads in the data (total_employees, check_number), declares room for the appropriate number of entries in each dynamic array, and loads the employee data from the file. You should store the file name in payroll_file so you can write data back to the file in the next method
  • void store_employee_data() - opens the file file_name and prints all employee data back to the file it was read from (stored in payroll_file) including the updated check number. Remember, your data should be readable by your program later.
  • void print_employee_info(int employee_id) - prints the data of a single employee
  • void print_paycheck(int employee_id) - prints the paycheck of an employee
  • void print_paychecks() - prints the paychecks of all employees
  • int employee_index(int employee_id) - searches the array employee_ids[] and returns the numerical index of the employee with the provided id (makes the implementation of the preceding three functions easier)

You will then need to develop a main driver in main() that provides the user with a menu that allows them to select between program features. Your program should read from a simple database file that stores the employee information. You can find such a file here. The file is formatted in the following manner:

  1. A single integer denoting the number of users in the payroll system
  2. The next check in the sequence
  3. Data for each user including (in this order):
    • The employee's name
    • The employee's id
    • The employee's hourly wage
    • The number of hours the employee worked this week.

You can find sample runs of the program here.

Don't forget documentation!

Our programs are getting more complicated, particularly from here on out. Remember to keep good documentation. This includes documenting:

  • Each class (at the start of the class definition).
  • Each method (at the prototype in the class definition).
  • Each file at the top of the file.
  • Your code in your methods and main when necessary.

What you should turn in:

You should turn in a zip file of your work, with the following items included:

  • main.cpp - A driver that organizes your code and interfaces with the user.
  • payroll.cpp - The implementation file for your class.
  • payroll.h - A header file containing your class definition
  • CMakeLists.txt - the CMake file generated by JetBrains to build your project
  • README - your README file: make sure to include all design decisions
NOTE: it may be easiest to just zip up your project folder after deleting the cmake-build-debug folder

Notes and Gotchas:

  • Remember: READMEs are small text files, explaing how to run your program, any design decisions you make, and should include the same header comments as any code files.
  • Don't forget the rest of your documentation! (see above).
  • Don't forget your checkins, this is worth 10% of your assignment grade!
  • Constructors need to make sure to initialize every private/protected variable in a class
  • To avoid memory leaks, every object created with the new keyword must be released with the delete keyword. When you have dynamic objects in classes, this is what your destructor is for.
  • Make sure to note any extra credit you have attempted in your README

BONUS

  • (2 points) Allowing your program to perform only one option at a time can make it awkward. Put your menu in a loop, allowing a user to perform multiple actions before saving to disk.



Programming assignment 8: Classy Painting with text

Assigned: 10/29
Checkin: 10/31 - Start a new project, define your canvas class. Make sure you can demo at least 4 functions of your canvas class, not counting the constructor(s).
Due: 11/5 by email before the start of class

Libraries you may use:

  • iostream
  • fstream
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to continue to build our familiarity with classes and the object oriented paradigm as well as to proctice working with recursion, specifically flood fill!. We are revisiting our painting program from before, but with several variations: the actual painting will be done inside a class called canvas, the program should be able to load images from file, and there will be an additional flood functionality. Again, this is a chance for you to show off some creativity!

Task: First, you will need to define a canvas class with the following member attributes and functionality:

  • char arr[MAX_ARRAY][MAX_ARRAY] - this is your new 2D array for all painting. It should be private.
  • int rows - this should be private, it denotes how many rows make up your drawing. It should be less than MAX_ARRAY.
  • int cols - this should be private, it denotes how many columns make up your drawing. It should be less than MAX_ARRAY.
  • void print() - this function needs to be accessible by everyone. It will need to loop over your arr and print all data to the console.
  • void paint_pixel(int row, int col, char pixel) - this function needs to be accessible by everyone. It will accept a location, as well as a character denoting what value to place in that location of the array. If an invalid location is provided, your function should inform the user and return, making no changes
  • void swap_all(char orig, char target) - this function needs to be accessible by everyone. It should loop over your array and replace every instance of orig with target.
  • void save_to_file(char str[]) - save your canvas out to the indicated file. It should first print out the number of rows and then the number of columns used, then it should simply the contents of your 2D array arr. (This way it can be read in and modified later).
  • void flood(int row, int col, char fill, char block) - this is your flood fill function. For the base assignment, you need to make sure you flood up, down, left, and right. You will flood until you hit the edge of your canvas, or you see the character block.
  • canvas() - a default constructor. Make sure all member variables are initialized properly (don't forget to initizlize arr!).
  • void load_data(char str[]) - allow the user to load a saved image to work from if they desire.
In your main, you will need to create a canvas object, and then pass it to one other function you will need to implement in main.cpp:
  • paint(canvas& c) - this should launch the main driver of your program, where you will ask the user what they want to do, and continue until they indicate they would like to quit the program
Make sure that your program can (minimally) handle a 30x30 canvas.

Remember to document

Our programs are getting more complicated, particularly from here on out. Remember to keep good documentation. This includes documenting:

  • Each class (at the start of the class definition).
  • Each method (at the prototype in the class definition).
  • Each file at the top of the file.
  • Your code in your methods and main when necessary.

What to turn in:

A zip file containing:
  • canvas.h/cpp - the definition and implementation of your canvas class
  • main.cpp - the main driver of your program
  • CMakeLists.txt - the CMake file generated by JetBrains to build your project
  • README - your README file: make sure to include all design decisions
  • A picture created with your program, saved to file with the save_to_file() function
NOTE: it may be easiest to just zip up your project folder after deleting the cmake-build-debug folder

Notes and Gotchas:

  • Remember: READMEs are small text files, explaing how to run your program, any design decisions you make, and should include the same header comments as any code files.
  • Don't forget the rest of your documentation! (see above).
  • Don't forget your checkins, this is worth 10% of your assignment grade!
  • Constructors need to make sure to initialize every private/protected variable in a class
  • Make sure to note any extra credit you have attempted in your README

BONUS

  • (1pts) the base assignment only requires a 4-directional flood, modify your flood to spread in 8 directions!
  • (2pts) Fixed array sizes are boring! Implement arr as a 2D dynamic array!
  • Notes:
    • Dynamic 2D arrays

      These guys are a bit tricksy (this is a good chance to practice!), and need some special care when being created and destroyed (HINT: you will need a special destructor). As an example, lets walk through creating and destroying a dynamic 2d array of ints that has 5 rows and 3 columns Example Code:

                int** myArr; //note the double derefrence pointer (needed for 2D arrays)
                myArr = new int*[5]; //create an array of 5 pointers to ints (your 5 rows)
                for (int i = 0; i < 5; i++) { //you will need a for loop to put your columns into each row
                  myArr[i] = new int[3]; //make 3 columns in each row
                }
      
                //deleting - undo things, backwards
                for (int i = 0; i < 5; i++) { //walk through ROWs
                  delete[] myArr[i];
                }
                //then delete the pointer to the array of pointers
                delete[] myArr;
      
      
              




Programming assignment 9: Custom Rationals

Assigned: 11/5
Checkin: 11/7 - Start a new project, import the provided rational header. Have at minimum 3 functions implemented (not constructors), as well as the insertion operator. Create a simple main that will create at minimum 2 rationals (using the 2 separate constructors), and call all implemented functions.
Due: 11/12 by email before the start of class

Libraries you may use:

  • iostream
The use of any other libraries will result in the loss of points.

Purpose: The goal of this assignment is to practice operator overloading. To do so, you will implement a custom rational number class that looks and feels like a base class!

Task: Use the the header file here as a starting point.

You need to make sure you overload all the operators listed in the header:

  • Assignment
  • Standard arithmetic operators
  • Comparison Operators
  • Stream insertion
  • Typecasts (new!)

Additionally, you will need to develop a reduce() method to simplify fractions. You should find the greatest common factor of both numerator and denominator, and divide both by them. This will turn 3/6 into 1/2. reduce() should be called at the end of each arithmetic operation to make sure the internal representation is simplified. As a starting point to find greatest common denominator (gcd), try the Euclidean algorithm (from Wiki):

        Function gcd(a,b)
          while b != 0
            t := b
            b := a mod b
            a := t
          return a
      

If you feel the need to brush up on the basics of fractional arithmetic, mathisfun.com is a nice, shiny resource.

Your main function is up to you, but you need to make sure to use it to fully stress test all your class functionality. NOTE: Not fully testing all functions you've developed will lead to lost points!

Remember to document

Our programs are getting more complicated, particularly from here on out. Remember to keep good documentation. This includes documenting:

  • Each class (at the start of the class definition).
  • Each method (at the prototype in the class definition/the top of main).
  • Each file at the top of the file.
  • Your code in your methods and main when necessary.

What you should turn in:

You should turn in a zip file of your work, including all classes needed, your CMakeLists.txt, and a README file

Notes and Gotchas:

  • Remember: READMEs are small text files, explaing how to run your program, any design decisions you make, and should include the same header comments as any code files.
  • Don't forget the rest of your documentation! The header file I gave you does not contain sufficient documentation
  • Don't forget your checkin, this is worth 10% of your assignment grade!
  • Constructors need to make sure to initialize every private/protected variable in a class
  • Your parameterized constructor should ensure that the denominator is valid
  • Make sure to note any extra credit you have attempted in your README
  • Don't forget to reach out for help if you are feeling stuck!

BONUS

  • (up to 4 points) Add more basic operator overloads! Make sure to document all additional operator overloads in your README. NOTE: to get extra credit here your base assignment must be fully functional!
  • (2 pts) Implement a recursive reduce function. Remember, always code up how to escape the function first!






Programming assignment 10: Maze Solvability

Assigned: 11/12
Checkin: 11/14 (by email by 5pm) - Start a new project, define your maze class. Make sure you can load and display an ASCII map given a provided file
Due: 11/19 by email before the start of class

Libraries you may use:

  • iostream
  • fstream
  • string
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to give us all a bit more practice working with recursion, specifically flood fill! In addition to performing traditional flood applications, a flood fill can be used to determine if it is possible to solve a maze: Start the flood at the 'Start' location, and see if your flood makes it to the 'end' location!

Task: First, you will need to define a maze class with the following member attributes and functionality:

Your maze class will minimally require the following private attributes:

  • struct point - you will need to define a point struct, containing a row and a column. This will be used by your program to determine start and end locations.
  • char** plan - a dynamic 2D array that holding an ASCII representation of your maze
  • int rows - number of rows in your dynamic array
  • int cols - number of columns in your dynamic array
  • string outputFile - a string of the output file you will be generating. This will be derived from the input file (see constructor below). Simply add a ".flooded" to the end of the input file name.
  • point start - a row and column position of the starting point
  • point end - a row and a column position of the end point

Your maze class should also minimally contain the following public member functions:

  • maze(string infile) - parameterized constructor. Note, there should be no default constructor. Open the file specified by infile, and read in the data. The first 2 values in the file will be rows then cols. The next 4 values will be row and colum pairs defining the start and end points of this maze. You will then need to create your dynamic 2D array and load data from the input file. It is safe to assume that a space means the area is clear, and pipes '|', hyphens '-', and plus signs '+' define maze walls/edges.
  • ~maze() - a destructor to cleanly destroy your 2D arrays
  • void flood(char c) - Your flood should start at point start, and should flood the maze with the character c.
  • void storeResult() - this function outputs your maze data to file. It should be in the same format you read it in, but show the results of the flood.
  • bool isSolveable(char c) - this function should check to see if the flood reached the end position. You will need to pass it the same character you used for the flood. It is a helper function so main() can check to see if the maze is solveable.

Your main file will be very sparse for this assignment: Start by asking the name of the file to load. You will use this information to create a maze object. Your main will then need to prompt the user for a flood character, flood it via the flood function, print out whether or not the maze is solveable, and then finally save it via the storeResult function. As such, you will not need to implement any further function in your main (unless you feel it would be helpful).

Sample input files can be found here: maze1.txt, maze2.txt

Notes:

  • Dynamic 2D arrays

    In case you didn't try it with the last assignment: These guys are a bit tricksy (why we are practicing now!), and need some special care when being created and destroyed (HINT: you will need a special destructor). As an example, lets walk through creating and destroying a dynamic 2d array of ints that has 5 rows and 3 columns Example Code:

              int** myArr; //note the double derefrence pointer (needed for 2D arrays)
              myArr = new int*[5]; //create an array of 5 pointers to ints (your 5 rows)
              for (int i = 0; i < 5; i++) { //you will need a for loop to put your columns into each row
                myArr[i] = new int[3]; //make 3 columns in each row
              }
    
              //deleting - undo things, backwards
              for (int i = 0; i < 5; i++) { //walk through ROWs
                delete[] myArr[i];
              }
              //then delete the pointer to the array of pointers
              delete[] myArr;
    
    
            

  • Generating a PPM (Extra Credit Note:)

    PPMs are very simple graphics files. To create a file in PPM format, you will need to first write out the following data:

            P3
            # filename here
            COLUMNS ROWS
          255
            
    After this, you will need to print out your plan array. PPMs expect triplets (sets of 3) in the form of R(ed) G(reen) B(lue) values. HINT - a triplet of 0s will result in a black line (perfect for walls), and a triplet of 225s will result in white (perfect for unflooded spaces). Your flood can be any color you want, but you should also try to make the start and end points a different color!
  • FLOODING NOTES:

    Remember, check your edge cases first:

    • Is this position in bounds?
    • Have I already visited this position?
    • Can I flood this position? (is it a wall?)
    Before your recursive calls, make sure you mark your current location as visited! (or infinite loops await).

What to turn in:

A zip file containing all files needed to run, including a README and your CMakeLists.txt file!

BONUS

(2 pt) Create an additional function to generate a PPM! (this is a simple graphical file) See notes above for the PPM format! To view PPMs on Windows, download Irfanview. You should call this function after saving the results to file, and append "*.ppm" to the end of the input file name.
(2 pt) Modify your class to maintain an array of "blocking" characters, as well as an integer marking how many wall characters you have seen. Determine what characters should count as "walls" to your maze as you load in the file (this allows you to handle different mazes, such as one that uses '\', '/', and '_' for walls!).





Programming assignment 11: Better Arrays

Assigned: 11/19
Checkin: 11/28 - Start a new project, and implement 4 properties of your array class, not counting constructors. Make sure you can demonstrate each of them in main()
Due 12/3, by email before the start of class

Libraries you may use:

  • iostream
  • typeinfo
  • string
The use of any other libraries will result in the loss of points.

Purpose: The purpose of this assignment is to put into use all of the skills that we've been developing this semester. In class we worked on creating our own array class, with a lot of helper functions to improve the experience. In this assignment you will be creating your own improved array class.

Task: You will need to create a custom array class with the following properties:

  • Your class should be a template so the user can use your array for any arbitrary type
  • You should have a default constructor that initializes a dynamic array to 100 elements
  • You should have a parameterized constructor that takes the number of elements in the array as a parameter and initializes the dynamic array to that size
  • You will need a destructor to clean up your arrays
  • You should have a set method that takes a value (type T) and an array index and stores the value at the correct location in the array
  • You should have a get method that takes an array index and returns the element at that location
  • Your get and set methods should allow for negative array indices. A negative index should iterate backwards over the array (-1 is the last location, -2 is the second to last, etc)
  • Yourget and set methods should perform error checking. If the array index you povide is too large (or too small), they should not act upon the array. Instead, report an error message to the stderr stream (cerr), and throw an exception (in the case of the get).
  • You should also make sure to overload the bracket operators, so the user experience is consistent with normal arrays. The bracket operators should accept negative indices just as the get and set methods do. If the provided index is too big (or too small), make sure to report an error message to the stderr stream and throw an exception.
  • You should make sure to implement a deep copy function

A sample header to get you started:

            template <typename Type>
            class array {
              private:
                Type *elements;
                int size;

              public:
                array();
                array(int num_elements);
                ~array();
                void set(int index, Type value);
                Type get(int index);
                Type &operator[](int index);
                array<Type> &operator=(const array<Type>& toCopy);
            };
          

Again, I'm leaving testing up to you, but I expect that you will be testing your array thoroughly in your main.cpp. Use for loops to test positive and negative indices, and show that all base functionality and error checking is working. Be sure to document all methods thoroughly.

What to turn in:

A zip file containing:
  • Your array header file (name left up to you).
  • main.cpp - your driver cpp
  • CMakeLists.txt
  • README - a file describing your design decisions/any special information I need to run your program/outlining any bonus credit attempted

BONUS

(2 pts) If you get all of the above working, write a resize() method. When the user calls resize, it should double the size of the array in a manner that is transparent to the user:

  1. Declare a new dynamic array that is double the old array's size.
  2. Using a for loop, copy all of the data from the old array to the new array.
  3. Delete the old array.
  4. Store the address of the new array in the appropriate variable of your class, and store the new (doubled) size.

(1 point) Create a (deep) copy constructor that takes an existing array as an argument. Make sure all data is copied over from the original array!






Programming assignment 12: ASSIGNMENT MAKEUP

Assigned: 12/3
Due: 12/8 by email by 5pm

Libraries you may use:

  • See original assignment specifications
The use of any other libraries will result in the loss of points.

What you need for Wednesday Checkin (12/5):
Whatever was specified for the original assignment's checkin.

This is the fabled makeup assignment! Go back to any previous assignment and redo it for a chance to earn full credit on the assignment (will require a checkin/full submission at the date above to get checkin points).

You are allowed to tackle any single previous assignment.

RULES
  • Use only the skills available when the assignment was assigned (no dynamic memory for assignments prior to Assignment 7)
  • Only one assignment can be made up