You are expected to complete this assignment individually. If you need help, you are invited to come to office hours and/or ask questions on piazza. Clarification questions about the assignments may be asked publicly. Once you have specific bugs related to your code, make the posts private.
Another note about Piazza. Piazza is your community resource - please use those as discussions amongst yourselves. We are not monitoring it all day, rather we each have check-in times once a day. Therefore, you need to start early enough to wait for feedback and/or build a vibrant, supportive community that helps each other while we are completing other necessary tasks (research, developing assignments, preparing for lecture, performing advising tasks, etc.).
Make sure you filled out the Student Information Form
This homework has several exercises. We are also providing you with some resources on printf and error handling for this assignment.Homework 1, which includes warmup 1, will be collected from your subversion repository at 11:59pm prior to your next lab session.
You should submit two files for this assignment (hw1.c and Makefile), in addition to ones from your warm-up, in your subversion repository as directed below. Your subversion repository is named CNET-cs152-win-19, and you can check it out with the following command:
$ svn checkout https://phoenixforge.cs.uchicago.edu/svn/CNET-cs152-win-19(where CNET is your cnetid). Do not commit any executable, a.out or any other, to your repository; we will (in fact, must) recompile your code on our own machines on our end.
The printf() function takes a string as its first argument. The contents of this string are printed to the screen as-is, but with the same kinds of escape conventions as we saw in Racket (e.g., \n is the newline character). The function can be used with a string and no other parameters:
printf("Hello, world!\n");
If you want to include a representation of the value of one or more expression in the string printed by printf, you need to include one or more format codes in printf's string argument, and you need to pass correspondingly many expressions as additional arguments to printf, separated by commas. Some examples follow.
Format codes begin with the character % and the next character(s) specify the type of the value to be printed. For now, it suffices to know that d specifies an int, and lf specifies a double. To be clear, put together, we write %d as a placeholder when we want to write an int, %ld for a long int, and %lf for a double.
For example,
printf("The number is %d.\n", 42);prints this:
The number is 42.
If we want more than one expression included in the same string, we use multiple format codes and pass arguments in lockstep with those codes:
int ndigits = 6; double approx_pi = 3.14159; printf("Pi to %d digits is %lf, and pi squared is %lf\n", ndigits, approx_pi, approx_pi * approx_pi);For this assignment, you'll also need to control the spacing of your printing. Here is a website that provides a reference in how to format with printf.
Error handling capabilities vary by language, and what you want to do in an error varies by the situation. When an error occurs in a function, the question becomes, what should you do, and how do you notify the caller that an error occurred?
In C, there is no good way to distinguish error conditions from normal execution. This is unfortunate because if you write a function, and it's used in a variety of different circumstances, it is bad programming practice to determine within the function what will be done. For example, one program might want to exit, whereas another might want to notify the user that there was bad input and to try again.
In this course, we will print the error message in a special way (see below). If there is an opportunity, we will designate a specific return value for an error condition. If there is no available return value, then we will exit from within the function.
When we print error messages, it is helpful and appropriate for them to be routed through a special error mechanism. This gives them priority, increases their likelihood of being printed in the case of a program crash, and allows them to be separated from other output. To accomplish this, we use a variant of printf called fprintf. This function works the same as printf, but takes in an extra argument at the beginning: the "file" to which to write the message. Passing in stderr as that argument will send the output to the screen, but using the special error mechanism:
fprintf(stderr, "error: too many widgets for the number of grommets\n"); fprintf(stderr, "error: need ten boondoggles, but only have %d\n", num_bds);
Sometimes, these lines will be followed by exit(1); This immediately exits the program and returns a code. If you were writing a large program, you might assign a different code to each type of error that would result in an exit.
hw1: hw1.c clang -Wall -o hw1 hw1.cTo compile, type:
$ make hw1
$ ./hw1
double surface_area_cylinder(double height, double radius) { fprintf(stderr,"surface_area_cylinder not yet implemented\n"); return 0.0; }
int main() { double dval; dval = surface_area_cylinder(2,1.5); }
First get this compiling and running. It won't print out anything, but this will mean that your code will compile and execute with our infrastructure. This must work in order to get any points in this course. Do this first, not last.
This exercise pertains to geometric shapes. You are going to write two functions, in increasing difficulty (from a programming perspective).
double surface_area_cube(double edge_length);
Write a function that calculates the surface area of a cube. Each side has length edge_length. Return the result - do not print it out.
Once you have written the calculation in code, make sure you also identify what values of edge_length would not be valid. For any invalid input, print an appropriate error message and return -1.
double sides_to_area(unsigned int num_sides, double side_length);
Write a function that calculates the area (not surface area, but internal area) of a 2-d polygon with all equal-length sides. Support a triangle, square, pentagon, hexagon, octagon, and nonagon.
Consider any input outside of those to be invalid input. For invalid input, print an appropriate error message and return -1.
For both functions, if the user enters an invalid input, print out an error with the format "error (function_name): [description of error]". Remember, as described above, to use fprintf rather than printf and send the output to stderr. Return -1.0 to indicate that an invalid input was received. Do not exit.
Don't forget to complete this portion, test it, and commit it before moving on! This means you need to write a test function and develop a suite of test cases!This exercise pertains to printing. You are going to print out a number grid, starting with the 10's of the input number and going on for 100 numbers. It will be formatted such that every column lines up, and the numbers within the column are right justified. Click on this example for clarification.
Some details:void print_number_grid(int start_num);
If a number larger than 999999 or smaller than -999999 would need to be printed out for a particular input value, then it is an invalid input. Print out an appropriate error message and return early (by doing return with no input arguments).
This exercise pertains to operators and functions. You are going to implement a key function in the game of Mastermind. In mastermind, the goal is to match the pattern of pegs that the master has set. There are 6 different colors of guessing pegs (which Wikipedia calls code pegs). Each guess, the master provides limited feedback using feedback pegs (which Wikipedia calls key pegs). There are up to 12 rounds of guessing / feedback to try to guess the pattern.
There are two feedback colors - black and white. You receive a black feedback peg for each guessing peg that is the right color and location. You receive a white feedback peg for each guessing peg that is the right color and incorrect location. You receive no feedback pegs for any other guessin pegs. The feedback pegs are given to you in random order - you do not know which feedback peg goes with which guessing peg within a single round - you need to look at past guessing / feedback rounds to deduce more information.
You will write the function that, given a guess and a solution, provides the feedback. The guessing pegs and solution pegs are encoded as 4-digit integers, each digit holding a color between 1 and 6. The feedback is a little different - it will be two digits. The 10's place will be the number of black pegs (exact matches). The 1's place will be the number of white pegs (matches that are the right color but not the right position).
For this exercise, we will write a series of helper functions to break down the problem.
What value is in specified digit of pattern? Digit 0 is the right-most digit, digit 1 is to the left of it, etc. You only need to support extraction of digits for this project, which is a 4-digit number.unsigned int extract_digit(unsigned int pattern, unsigned int digit);
How many instances of color are there in pattern? The pattern is a 4-digit, base-10 number. Color is also a number.unsigned int num_of_color(unsigned int pattern, unsigned int color);
Count how many digits in guess match both in color and position as compared to the solution. There are four digits in each of guess and solution.unsigned int count_exact_matches(unsigned int guess, unsigned int solution);
Count how many digits in guess match in color, regardless of position, as compared to the solution. There are four digits in the guess and solution.unsigned int count_color_matches(unsigned int guess, unsigned int solution);
unsigned int get_guess_feedback(unsigned int guess, unsigned int solution);
$ svn add hw1.c
$ svn commit -m "hw1 complete"