CSCI 222: Programming Concepts & Problem Solving II
Spring 2018

Course Assignments




zyBooks Assignments

CH2: Due 1/24 CH2,CH3,4: Due 1/31
CH5: Due 2/7 CH6: Due 2/14
CH7: Due 2/21 CH8: Due 3/14
CH9: Due 3/21 CH10: Due 3/28
CH11: Due 4/4 CH12: Due 4/11
NOTE: this is a proposed schedule, check back for updates!

Programming Assignments

Programming Assignment 1: Hamming Distances

Assigned: 1/12
Due: 1/29 by email before the start of class

Libraries you may use:

  • iostream

What you need for Wednesday part 1 checkin (1/17):
Start a new project with the provided code stub, get one function working. I would suggest the length() function. Make sure you can demonstrate your function during the lab period.
What you need for Wednesday part 2 checkin (1/24):
Make sure you have one more function (for a total of 2) working. Be able to demonstrate your functions during the lab period.



The Hamming Distance between two strings is the number of positions in the strings where the corresponding character is different. In this first assignment you will be prompting the user for two strings, computing the Hamming Distance between them, and then reporting the result to the user.

Traditionally, Hamming Distances are only computed between strings of the same length. Our program is going to be a bit more flexible, and count differences in string length towards Hamming Distance. For example: The difference between "per" and "person" will be 3.

For your first assignment, I have provided a general program structure, including stubs for each function you will need. If you wish, you may write additional helper functions to solve the problem, though you are not required to do so.

You can download the program outline here: distance.cpp. NOTE: does not always open correctly in Microsoft Edge/IE, instead use Chrome.

A sample run of your program should match the following:

Please enter string 1: per
Please enter string 2: person
per and person are 3 characters apart

A second sample run:
Please enter string 1: apple
Please enter string 2: pineapple
apple and pineapple are 9 characters apart

NOTE: for this last example we are not matching the first string to the "apple" part of "pineapple", and instead just looking from the beginning of both strings. This is a more difficult problem and beyond the scope of this class.

What to turn in:

  • distance.cpp: A valid C++ file containing all of your code.

BONUS

  • (2 points) Implement a loop which allows the user to check multiple strings in a single run.





Programming Assignment 2: Code Making and Code Breaking

Assigned: 1/29
Due: 2/5 by email before the start of class.

Libraries you may use:

  • iostream

What you need for Wednesday checkin (1/31>:
Start a new project, get length() working, and make some progess with encrypt().

Cryptography is the practice and study of techniques for secure communication. For this assignment, we will be working on creating a simple method for encryption/decryption. We will be working with C style strings for this assignment again, giving us more practice with C strings and arrays.

To keep things simple, we will follow a simple algorithm for encryption. A C string will be scrambled by alternating characters from the end and then the beginning of an array. Consider the example below:

Index 4 (the last letter of the string in this example) is first moved to index 0 of the encrypted string. Next, index 0 of the original string is moved to index 1 of the encrypted string. Index 3 of the original string is moved to index 2 of the encrypted string. This continues until the entire string has been encrypted.

NOTE: You will need to be moving from both ends of the original string, but make sure you don't cross over!

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
  • void encrypt(const char original[], char encrypted[]); - This function will encrypt original following the algorithm outlined above, placing the encrypted c string into encrypted.

A sample run of your program should look like this:

Enter string for encryption: Hello CSCI 222!
Your encrypted string: !H2e2l2l oI CCS

What to turn in:

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

BONUS

(2pts) Create an additional decrypt(const char input[], char decrypted[]); Because we used a well-defined pattern to create our encrypted messages, it should be possible to reverse the process to decrypt the encrypted messages.

(2pts) Our encryption alone is very simple. To add complexity, perform a ROT-13 (Wiki Page) after running your encryption function.




Programming Assignment 3: File I/O, array management, and iomanip

Assigned: 02/5
Due: 02/12 by email before the start of class.

Libraries you may use:

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

What you need for Wednesday checkin (2/7):
Start a new project, prompt the user for input file, and call a fully implemented loadResults(). Demo by printing out elements of the teamNames array.

For this assignment we are going to be showing off our new File I/O and iomanip skills to calculate scores for a programming competition. In a programming competition, the team that solves the most problems wins. In the case of a tie, the team that took the shortest combined time to solve all problems wins. Each team will attempt to complete 5 problems. If a team successfully solves a problem, they will have a positive number associated with the problem. This is the amount of seconds it took to solve the problem. A negative time indicates that the problem was not solved.

You will first prompt the user for the name of an input file, then read in the file which consists of alternating lines of team names, and their times for the 5 problems, separated by spaces. With this data you will create 6 arrays: one will be an array of strings which is every team name, the others will be arrays of ints, consisting of the time to complete each problem. Make sure that these arrays are built in order, so that problem1[0] through problem5[0] are all times corresponding to the team listed in teamNames[0]. You will then use this information to calculate statistics for each question: the average solve time, and solvability (how many teams solved each question).

A sample input file can be found here, while the output of the sample file can be found here. It is safe to assume that there will never be more than 30 teams in a file (though there may be less!).

What you must implement

You must implement the following methods. Please use the coding/documentation standards outlined in the first assignment as an example of what I expect.

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

  • int loadResults(ifstream & file, string teamNames[], int problem1[], int problem2[], int problem3[], int problem4[], int problem5[]); - This function reads the data in file, storing team names into teamNames, and the associated scores into problem1-5, respectively. It should return the number of teams whose scores are reported.
  • double calculateAverage(int teamCount, const int problemTimes[]); - For the provided array of solving times, find the average time it took to solve a problem (do not include teams that did not solve the problem). It will return the average time.
  • int solved(int teamCount, const int problemTimes[]); - For the provided array of solving times, find out how many teams actually solved the problem, and return that number.
  • void printResults(int teamCount, string teamNames[], int problem1[], int problem2[], int problem3[], int problem4[], int problem5[]); - This function is responsible for printing out the scores and all computed information nice and pretty.

Notes:

  • You should declare all array sizes using a symbolic constant. It is safe to assume that there will never be more than 30 teams at a time.
  • Make sure that you do not include times of teams who do not complete a problem in your average calculations.
  • Your sample file has -1 for all negative values, but it is not safe to assume that your negative value will always be 1

What to turn in:

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

BONUS

(1 pts) On your report, mark the team in first place with a happy face (":-)") before their team name.

(1 pts) On your report, mark the team in last place with a sad face (":'(") before their team name.

(2 pts) Passing around 6 arrays is annoying. Rewrite your code to use a 2D array of ints to store problem times.




Programming Assignment 4: Mountain Pictures

Assigned: 02/12
Due: 02/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.

What you need for Wednesday checkin (2/14):
Start a new project, prompt the user for input file, call a fully implemented loadData(), findMax() and findMin(). Demo by printing out elements of the results of findMin() and findMax().

For this assignment we are going to be generating topographical images of mountain ranges from GIS data. The data we are working with consists of a series of digits representing elevation. A larger number means a higher elevation, while lower numbers signal lower elevations. We will be taking this raw data, loading it into memory, scaling it, and then generating a PGM image. This is a simple format for gray-scale images

You will first need to create a struct named image to hold your image. You struct should have the following attributes:

  • int rows - this will hold the number of rows found in the input file
  • int cols - this will hold the number of columns found in the input file
  • int data[MAX_ROWS][MAX_COLS] - this will hold your elevation data!
It is safe to assume that your input files will never have more than 1000 columns, and 500 rows.

In your main, you will first prompt the user for the name of an input file, then read in the file to load your data. The first line of input should be 2 numbers: the first being the numbers of rows of data which will follow, the second being the number of columns. You will then store this information into your image struct, and then use a loop to read in the rest of the file into your data array. Before writing out to file, you will first need to scale your input elevation data into the range from 0 through 255 (for our gray scale). After successfully scaling your data, your main should prompt the user for the name of an output file, and then write it out in PPM format.

A sample input file can be found here: good.asc, which should generate the image found here: good.pgm. A larger example: etopo1.asc, which results in this image: out.pgm. To view PGM images on Windows, use IrfanView (this will reqire a quick download on the lab machines).

What you must implement

You must implement the following methods. Please use the coding/documentation standards outlined in the first assignment as an example of what I expect.

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

  • void loadData(image& im, string file); - This function opens the file named file, and loads all information into the struct im
  • int findMax(int data[][MAX_COLS], int rows, int cols); - This is a helper function you will need in scaleData(). It will find the maximum value in the array.
  • int findMin(int data[][MAX_COLS], int rows, int cols); - This is a helper function you will need in scaleData(). It will find the minimum value in the array.
  • void scaleData(image& im); - This function is responsible for scaling your data from 0=255 so it can be displayed in your PPM image. The algorithm for this is: new_value = (old_value - minimum) * 255 / (maximum - minimum).
  • void generatePPM(image& im, string ofile); - This function opens the file named ofile, and generates the PPM image. See PPM notes below for more information on generating PPMs

Notes:

Generating Gray-Scale PPMs

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

        P2
        #  this is a comment field: it should have your file name on it
        COLUMNS ROWS
        255
        
After this, you will need to print out your data array. For Gray-Scale PPMs, you just need to print out each element of the array once, but make sure the array elements are separated by whitespace!

What to turn in:

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

BONUS

  • (1 pt) Put in a loop, allowing the user to generate multiple images from multiple files in a single run.




Programming Assignment 5: Classy Competitions

Assigned: 02/19
Due: 02/26 by email before the start of class.

Libraries you may use:

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

What you need for Wednesday Checkin (2/21):
Start a new project, prompt the user for input file, and call a fully implemented loadTeams(), that will read the input file and load all information into an array of Teams. This implies that your parameterized Team constructor exists.

For this assignment we are going to revisit the programming competition problem. This time, you are responsible for creating a new class Team. Your Team class will have the following attributes:

  • string name - the team name
  • int times[] - an array containing the time it took for the team to solve each problem. There will always be exactly 5 problems reported. The 0th element of the array corresponds to the time it took to solve the first problem, the 1th element the 2nd problem, etc.

Your array class should also contain the following member functions:

  • Team() - the default constructor. Make sure you initialize all member attributes!
  • Team(string n, int t1, int t2, int t3, int t4, int t5) - parameterized constructor. All the information needed to create a team: the name, and the time it took the team to solve each problem
  • double averageTime() - this will calculate the average amount of time the team spends on any given problem. Remember, do not take into account negative times, as this is a sign that the team did not solve the problem.
  • int problemsSolved() - this will count how many problems the team actually solved. Don't forget, a negative time indicates that the problem was not solved.
  • int totalTime() - this will calculate the total time for all solved problems for the team.
  • int getTime(int problem) - this is a helper function, an accessor. It will return the time it took the team to solve problem problem.
  • void print() - will print out all information about the team, as well as derived information (number of problems solved, the total time spent on all solved problems, and the average time spent per solved problem). See sample output for what this should look like.
Don't forget, you will want to use a symbolic constant for your problem array size/looping over the array. You will want to declare this in your header file.

Your main.cpp file will be the primary driver for everything that happens in your code. You will need another symbolic constant for the maximum number of possible teams (30), and will need to declare an array of your new class, Team. First, you will prompt the user for a file to open. After opening the file, you will pass it to a loadTeams() function, which will read in the input file and use the data to create Teams to fill up your array. You will then need to find out how many teams solved each problem and the amount of time it took on average to solve each problem. This data will be derived using the solveRates and questionAverage functions defined below. Last, you will call a prettyPrint function to create a nice table for output.

A sample input file can be found here, while the output of the sample file can be found here. It is safe to assume that there will never be more than 30 teams in a file (though there may be less!).

What you must implement

You must implement the following methods. Please use the coding/documentation standards outlined in the first assignment as an example of what I expect.

At a minimum, you will need to implement the following functions (in main):

  • int loadTeams(ifstream & file, Team teamList[]); - This function reads the data in file, creates a new Team using the parameterized constructor, and places that new Team into the appropriate position of teamList. It will return the number of teams read in.
  • void questionAverage(int teamCount, Team teamList[], double avgs[]); - Loop over all Teams in teamList. Figure out how many teams it took to solve each problem, as well as how long. Use this information to calculate an average time to solve each problem. This information should be placed into the array avgs.
  • void solveRates(int teamCount, Team teamList[], int solveCount[]); - Loop over all Teams in teamList. Count how many teams solved each problem, and place into solveCount.
  • void prettyPrint(int teamCount, Team teamList[], double avgs[], int solveCount[]); - This function is responsible for printing out the scores and all derived information nice and pretty. Nothing after prompting the user for an input file should be printed out in main.

Notes:

  • You should declare all array sizes using a symbolic constant. It is safe to assume that there will never be more than 30 teams at a time, and there will always be exactly 5 problems.
  • Make sure that you do not include times of teams who do not complete a problem in your average calculations. Any negative number indicates that a team did not solve the problem.

What to turn in:

A zip file containing:
  • main.cpp - Your main driver for this program.
  • Team.h - The header file for our new Team object.
  • Team.cpp - The implementation of our new Team object.

BONUS

(2 pts) Print out team ranking next to each team name. For example, first place should have "1: " next to their name, second "2: ", etc.



Programming Assignment 6: Mountain paths

Assigned: 2/26
Due: 3/12 by email before the start of class

Libraries you may use:

  • iostream
  • fstream
  • string
  • cstdlib
  • ctime
NOTE: You do not need all of these in every file.
The use of any other libraries will result in the loss of points.

What you need for Wednesday Checkin (2/28):
Start a new project, your main should prompt the user for your topographical input file. You should use that information to create a GISMap object, then save your map converted to grayscale to disk. Demo this by reading in a sample image file (etopo1.asc, good.asc). Show that it works by viewing the image you have generated in IrfanView (will reqire a quick download on the lab machines if you do not still have it from last time).

For this assignment, we will be revisiting out mountain assignment from before, this time with classes. In addition, we will also be plotting a path through the mountains, and tracing it across our generated image. For this assignment we will be creating a GISMap class. It will store the data in a pixel struct, which you will use to find a path across the montain. We will be displaying this data in a PPM image. Unlike the PGM format we used before, this format requires tuples of data: red, green, and blue values. These values will need to be scaled beetween 0 and 255. If all 3 values are the same, you will get a gray-scale image. We will start by creating that, and then overlaying red lines on our mountain. You can turn a pixel red by maxing out the red value of the pixel.

Your pixel structure consists of 3 integers:

  • int red - this will eventually hold the red value which will be attributed to your image
  • int green - this will eventually hold the green value which will be attributed to your image
  • int blue - this will eventually hold the blue value which will be attributed to your image
NOTE: they will eventually hold values from 0-255, but you will likely want to designate at least one of these to start off holding your raw data from disk (before you scale it down).

Your GISMap class will minimally require the following attributes:

  • pixel data[MAX_ROWS][MAX_COLS] - the 2D array that holds your topographical data
  • int rows - the actual number of rows used in this map.
  • int cols - the actual number of columns used in this map.

Your GISMap class should also minimally contain the following member functions:

  • GISMap(string infile) - parameterized constructor. Note, there should be no default constructor. Open the file specified by infile, and read in the data. Remember, the first 2 integers in the file are the rows and columns of the data.
  • void scaleData() - this will walk through your data, and perform an in-place modification to convert all inputs to values from 0 through 255. This is effectively creating a gray-scale image.
  • void plotPath() - this function will find walkable paths over the mountain range you have loaded. You will likely want to call this before scaling your data (could make it easier). Pseudocode for this algorithm is below.
  • void saveToDisk(string outfile) - this function generates a full ppm file from your array of pixels. See ppm notes below
Don't forget, you will want to use symbolic constants for your data dimensions. You can assume that no image will have more than 500 rows and 1000 columns. You will want to declare this information in your header file. Feel free to add additional helper functions if you find it necessary.

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 GISMap object. Your main will then need to plot paths over the mountains via the plotPath function, convert it via the scaleData function, and then finally save it via the saveToDisk function after prompting the user for an output file path. As such, you will not need to implement any further function in your main (unless you feel it would be helpful).

Sample outputs for these files can be found here: etopo1.ppm, good.ppm. Remember, there is an element of randomness to this, so yours may not look exactly the same.

Notes:

  • Mountain climbing:

    We will be using a simple approach for this part of the assignment. Your algorithm should start from every pixel on the left hand side, and find a path across the map to the right hand side. For each pixel, look at the 3 pixels adjacent in the next column. Choose to move to the pixel that results in the lowest elevation change.

    If there is a tie, flip a coin to choose which direction to move. As this walk will need to be done in place, it is suggested that you mark any position as being visited by making it negative (multiply by -1). Pseudocode:

              for every row:
                currentCol := 0
                while currentCol is less than max_cols:
                  #note, a negative value means the position has already been visited
                  # if the current position has been visited, you are done
                  val := currentPosition
                  up := checkUp()
                  down := checkDown()
                  across := checkAcross()
                  markAsVisited(currentPosition) #mark the current position as being visited
                  if across is minimum:
                    move across #update currentCol accordingly
                  else if up equals down:
                    flip a coin to choose #update currentCol and currentRow correctly
                  else:
                    choose the minimum #update currentCol and currentRow correctly
              start from the next row down
    
            
    NOTE: I have chosen to make things look like functions here. You are not required to create additional functions. If you do, make sure to fully document your new functions.

  • Generating a PPM -

    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 data array. PPMs expect triplets (sets of 3) in the form of R(ed) G(reen) B(lue) values. For a sample file of
    0125255
    1310098
    your generated PPM will look like this:
            P3
            # sample.ppm
            3 2
            255
            0 0 0    125 125 125    255 255 255
            13 13 13    100 100 100    98 98 98
            
    To mark a visited pixel red (remember, after visiting it, it should be marked negative), simply set the R value (the first number) to the maximum value (255)

What to turn in:

A zip file containing:
  • GISMap.h - your topographical map header file.
  • GISMap.cpp - your implementation of your topographical map
  • main.cpp - your driver cpp
  • mountains.cbp - the code blocks project for this assignment
  • README - this is a simple text file. It should minimally contain: your name, the date, the name of the project, and a brief description of the project. Additionally, this is where you add implementation notes: did you have any modifications to the assignment? What default values did you assign in the constructor(s)? Why did you decide on the default values? Did you run into any problems? Did you attempt any extra credit? READMEs are a chance for you to pass on extra information about your work to whoever looks at it next (possibly future you!)

BONUS

(3 pts) Find the path out of the mountains with the smallest overall elevation change. Mark this path in green.





Programming Assignment 7: Inheriting Products

Assigned: 3/12
Due: 3/19 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.

What you need for Wednesday Checkin (3/14):
Start a new project, make sure you have the base class implemented. Create a simple main that will loop through all of the functions available to the base class, and demo by showing it running with full output.

For this assignment, we will be practicing what we have been working on in lecture: inheritance. You will create a base Product class, as well as a derived EBook and a derived Book class. You will need to develop a main function to test all of your code, with the help of several required test functions.

Your Product class will require the following attributes:

  • string type - this should be private. It will designate the type of product it is.
  • string name - this should be protected. It will be the name of the product.
  • double taxPercentage - this should be private. It will be a generic tax percentage to apply to the product.
  • int quantity - this should be protected. It will be the amount of product currently in stock.
  • double price - this should be private. It will be the base cost of the product (without tax).
  • virtual void print() - this should be accessible by anyone. It will print out all private and protected data that is held inside the Product class.
  • virtual void sellItem() - this should be accessible by anyone. It will first check that there are enough items in stock (more than 0). If there are not enough items, it will print out a warning and return. Otherwise, it will calculate the cost, print out a message stating which item has been sold, and what the price was. It will additionally decrement the quantity of the item. Make sure when printing the item that you use iomanip to ensure only 2 places after the decimal are reported.
  • double calculateCost() - this should be accessible by only this class and its children. It is responsible for calculating the cost of a product. This will be: price + price * taxPercentage.
  • void restock(int amount) - this should be accessible by anyone. It will increase quantity by amount. Before doing so, make sure that amount is a positive number.
  • void setTaxRate(double taxPercent) - this should be accessible by anyone. This is a modifier. It will allow you to change the taxPercentage to taxPercent. Before making any changes, ensure that taxPercent is valid (between 0 and 1).
  • Product() - a default constructor. Make sure you initialize all private and protected variables.
  • Product(string name, string type, double price, int quantity) - a parameterized constructor. Make sure you initialize all private and protected variables. NOTE: it is up to you to choose the starting taxPercentage!

Your EBook class will require the following attributes:

  • string genre - this should be a private variable, stating the genre of the e-book
  • 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 EBook specific information (the genre).
  • void sellItem() - this should be accessible by anyone. It is overriding the base sellItem(). When implementing, make sure to first perfom a quantity check, and then use the base calculateCost() as a starting point. You will then need to add on the DIGITAL_TAX to that amount. Otherwise, this should look the same as the original sellItem().
  • EBook() - a default constructor. Make sure you initialize all private and protected variables (all the way down to the base class). To modify the taxPercentage, make use of setTaxRate()
  • EBook(string name, string genre, double price, int quantity) - a parameterized constructor. Make sure you initialize all private and protected variables (all the way down to the base class). To modify the taxPercentage, make use of setTaxRate()
NOTE: you will also need to declare a constant double for the DIGITAL_TAX to be applied to your EBooks - the exact value is left to you (I chose $0.05).

Your Book class will require the following attributes:

  • string genre - this should be a private variable, stating the genre of the book
  • double weight - this should be a private variable. As this is a physical book, it has a weight, which is important for calculating shipping costs.
  • 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 Book specific information (the genre and weight).
  • void sellItem() - this should be accessible by anyone. It is overriding the base sellItem(). When implementing, make sure to first perfom a quantity check, and then use the base calculateCost() as a starting point. You will then need to add on the SHIPPING_COST * weight to that amount. Otherwise, this should look the same as the original sellItem().
  • Book() - a default constructor. Make sure you initialize all private and protected variables (all the way down to the base class). To modify the taxPercentage, make use of setTaxRate()
  • Book(string name, string genre, double price, int quantity, double weight) - a parameterized constructor. Make sure you initialize all private and protected variables (all the way down to the base class). To modify the taxPercentage, make use of setTaxRate()
NOTE: you will need to declare a constant double for the SHIPPING_COST to be applied to your Books - the exact value is left to you (I chose $0.15).

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

  • void printProduct(Product & p) - this will call print() on Product p.
  • void sellProduct(Product & p) - this will call sellItem() on Product p
  • void restockProduct(Product & p, int amount) - this will call restock(amount) on Product p.
  • void setProductTax(Product & p, double tax) - this will call setTaxRate(tax) on Product p.
NOTE: make sure your output is human readable! Make sure to print out what your are testing before running each test. Make sure to test both good and fail states. For example, try settting a bad tax rate as well as a good one. Make sure to try to restock with negative numbers, and try to sell a product that has a quantity of 0.

What to turn in:

A zip file containing:
  • Product.h - the header for your base product class
  • Product.cpp - your implementation of your base product class
  • EBook.h - the header for your derived e-book class
  • EBook.cpp - the implementation for your derived e-book class
  • Book.h - the header for your derived book class
  • Book.cpp - the implementation of your derived book class
  • main.cpp - a main driver you have developed to test all functionality
  • README - your README file: make sure to include all design decisions

BONUS

(2 pts) Implement another derived product class - make sure your derived class has additional attributes and "interesting" calculations involved for sellItem().





Programming assignment 8: Dynamic Shopping System

Assigned: 3/19
Due: 3/26 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.

What you need for Wednesday Checkin (3/21):
Start a new project, define your inventory class. Create a simple main that will create your inventory class, then call a fully implemented read_inventory_data(). Prove that it works by calling print_inventory_info().

For this assignment, we will be practicing working with dynamic arrays! You are to define an inventory class with the following private data:

  • string *items - a (dynamic) array of inventory items
  • float *prices - a dynamic array of each item's cost
  • int *amounts - a (dynamic) array containing the quantity of each item in stock
  • int total_items, sale_number - (read from file) the total number of items you will store data about and the (next) sale number to be issued
  • string inventory_file - the name of the inventory file read by read_inventory_data() so that it can be written again by store_inventory_data()

You are to define the following public methods:

  • inventory() - Make sure to initialize each array pointer to NULL
  • ~inventory() - calls delete[] for each array when the object goes out of scope
  • void read_inventory_data(string file_name) - opens the file file_name and reads in the data (total_items, sale_number), declares room for the appropriate number of entries in each dynamic array, and loads the inventory data from the file. You should store the file name in inventory_file so you can write data back to the file in the next method
  • void store_inventory_data() - opens the file inventory_file and prints all inventory data back to the file it was read from including the updated sale number. Remember, your data should be readable by your program later.
  • void print_inventory_info(int index) - prints the current quantity and price of a specific item
  • void print_inventory_info() - prints out information about all items in the inventory.
  • void sell_item(int index, int quantity) - assuming that there are enough of the item in inventory, will print a sales receipt for quantity of the item. Make sure to update the sale_number after this.
  • void order_item(int index, int quantity) - restocks inventory by quantity of the specific item
  • int find_index(string item_name) - searches the array items[] and returns the numerical index of the item with the given name(makes the implementation of the preceding three functions easier)

Your program should provide 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 items in the inventory system
  2. The next sales number in the sequence
  3. Data for each item including (in this order):
    • The item name
    • The item quantity in stock
    • The price per unit of the item

You can find sample runs of the program here. NOTE: your program should write an updated version of your inventory to disk after every run.

Remember to document

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

  • 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.
  • inventory.cpp - The implementation file for your class.
  • inventory.h - A header file containing your class definition
  • store.cbp - Including the project file makes grading easier.
  • README - a text file describing your work, and giving a high-level overview of your design decisions. Make sure to note any extra credit work that you have done here.

BONUS

  • (2 points) Allowing your program to do 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 9: Custom Rationals

Assigned: 3/26
Due: 4/2 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.

What you need for Wednesday Checkin (11/8):
Start a new project, import the provided rational header. Have at minimum 5 functions implemented, 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.

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.

Use 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 and a README file

BONUS

  • (variable) Add more basic operator overloads! Make sure to document all additional operator overloads in your README.
  • (2 pts) Implement a recursive reduce function. Remember, always code up how to escape the function first!






Programming Assignment 10: The Mountains are Lava

Assigned: 4/2
Due: 4/9 by email before the start of class

Libraries you may use:

  • iostream
  • fstream
  • string
  • cstdlib
  • ctime
NOTE: You do not need all of these in every file.
The use of any other libraries will result in the loss of points.

What you need for Wednesday Checkin (4/4):
Start a new project, your main should prompt the user for your topographical input file. You should use that information to create a FloodMap object, then save your map converted to grayscale to disk. Demo this by reading in a sample image file (etopo1.asc, good.asc). Show that it works by viewing the image you have generated in IrfanView (will reqire a quick download on the lab machines if you do not still have it from last time).

For this assignment, we will be practicing recursion by implementing a recursive flood algorithm. As I believe everyone is now sick of dealing with the mountains, instead of a traditional water-like flood, we will be covering our mountains in lava. We will not be assuming a large explosion, instead lava will emerge from a user-provided point on the mountain range. Furthermore, the lava will only flow downhill, or flood adjacent spaces of a similar elevation.

You will again need to create a pixel structure consisting of 3 integers:

  • int red - this will eventually hold the red value which will be attributed to your image
  • int green - this will eventually hold the green value which will be attributed to your image
  • int blue - this will eventually hold the blue value which will be attributed to your image
NOTE: they will eventually hold values from 0-255, but you will likely want to designate at least one of these to start off holding your raw data from disk (before you scale it down).

Your FloodMap class will minimally require the following attributes:

  • pixel **map - the dynamic 2D array that holds your topographical data
  • int rows - the actual number of rows used in this map.
  • int cols - the actual number of columns used in this map.

Your FloodMap class should also minimally contain the following member functions:

  • FloodMap(string infile) - parameterized constructor. Note, there should be no default constructor. Open the file specified by infile, and read in the data. Remember, the first 2 integers in the file are the rows and columns of the data.
  • ~FloodMap() - destructor, needed since we have dynamic memory.
  • void scaleData() - this will walk through your data, and perform an in-place modification to convert all inputs to values from 0 through 255. This is effectively creating a gray-scale image.
  • void flood(int r, int c, int height) - This is your height-sensetive recursive flood algorithm. You will look at position (r, c) in your internal map array. If that position is at the same level or downhill from the previous location's height, mark that location as flooded, and continue onwards. For the base assignment, implement a simple 4-directional flood.
  • void saveToDisk(string outfile) - this function generates a full ppm file from your array of pixels. See ppm notes below
Feel free to add additional helper functions if you find it necessary, but if you do make sure to fully comment them.

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 FloodMap object. Your main will then need to convert it via the scaleData function, flood it via the flood after prompting the user for a starting location, and then finally save it via the saveToDisk function after prompting the user for an output file path. As such, you will not need to implement any further function in your main (unless you feel it would be helpful).

Notes:

  • Dynamic 2D arrays

    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;
    
    
            

What to turn in:

A zip file containing:
  • FloodMap.h - your topographical map header file.
  • FloodMap.cpp - your implementation of your topographical map
  • main.cpp - your driver cpp
  • flood.cbp - the code blocks project for this assignment
  • README - this is a simple text file. It should minimally contain: your name, the date, the name of the project, and a brief description of the project. Additionally, this is where you add implementation notes: did you have any modifications to the assignment? What default values did you assign in the constructor(s)? Why did you decide on the default values? Did you run into any problems? Did you attempt any extra credit? READMEs are a chance for you to pass on extra information about your work to whoever looks at it next (possibly future you!)

BONUS

(1 pt) Modify your flood to check all 8 possible directions (diagonals too!). Does this change your floods? Discuss your findings in the README.
(2pt) Modify your flood to save a copy to disk after each visit (you will need to generate unique file names on the fly!). Each PPM image will show one step further into the flood function - this is a first step in creating an animated flood! Be sure to describe how you are choosing the file names in your README.
(variable) Define several ways to destroy the mountains, and give the user a menu of destruction options from main!





Programming assignment 11: Better Arrays

Assigned: 4/9
Due 4/23, by email before the start of class

Libraries you may use:

  • iostream
  • typeinfo
  • string

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.

What you need for Wednesday checkin 1 4/11):
Project has been started in Code::Blocks, you have implemented 2 of the properties listed below (not including constructors), and can demonstrate them.

What you need for Wednesday checkin 2 4/18):
You have implemented 2 more of the properties listed below (total of 4, again, not including constructors), and can demonstrate them.

Your class should have 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 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
  • Don't forget to include a destructor!

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);
                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
  • The code blocks project for this assignment (name left up to you)
  • README - a file describing your design decisions/any special information I need to run your program/outlining any bonus credit attempted

BONUS

(4 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) Implement a saner deep copy overload. The prototype should be: array<Type> &operator=(const array<Type>& toCopy); NOTE: you will need to remove the base assignment deep copy overload for this extra credit. If you take it, make sure you mention it in your README!






Programming assignment 12: ASSIGNMENT MAKEUP

Assigned: 4/20
Due: 4/28 by email by 1pm

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 (4/25):
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 8)
  • Only one assignment can be made up