Homework 1
Caution
  • You are expected to work individually.
  • Due: Friday, February 7th at 11pm EST (Baltimore time).
  • This assignment is worth 60 points.

Learning Objectives

Objectives
  • arithmetic operators
  • arrays
  • control structures
  • input collection and validation
  • version control using git

Overview

This assignment is inspired by the “Rocks, Stones, Sand in a Jar” story that you may have heard with respect to prioritizing important things in your life. You can read about it in many forms, such as this one. In this homework, you will write a program to help the user keep track of tasks of different time durations, as long as they fit into a “jar” of a specified size.

Program Requirements

We will use 10 as the maximum number of different task types/durations that the program must handle and 600 (10 hours) as the maximum number of minutes that any user can specify as their jar size. When the program starts, it prompts the user to enter the number of minutes they have available, ie, the size of their current jar. It must do error handling to make sure that the input is an integer and that it is a valid value (not negative and no more than the program maximum of 600). (See below for prompts and error handling details.)

Next the program will prompt the user to enter pairs of task identifiers and time durations. The identifiers must be single characters (such as ‘i’ for interview or ‘m’ for meeting) and the durations must be integers. You do not need to do any error checking on these values. The user must enter 0 0 as the input to end this process. Your program must enforce the program limit of at most 10 different type/duration pairs. Any extra user input should be treated as input to later parts of the program, not reported as an error (because it should not be read during set-up at all).

Once all of the task identifiers and durations are recorded (set-up is complete), the program enters a command loop. Each time the program prompts the user to enter a command the user enters the one-letter name of the command, and any additional values needed for the command. The program then carries out the command if legal as described below, and if the command was not “q” (quit), continues the command loop.

There are four commands:

Note that the user could also terminate the command loop by typing ctrl-d when prompted for a command.

Tip

In some situations, the user will need to press ctrl-d twice in a row in order to generate an end-of-file condition for the program's standard input.

When the command loop terminates, the program prints a line with the text Bye! and then exits with the exit code 0.

Error Handling

The program should handle errors as follows.

If one of

then the program should print the line “Invalid input” to stderr and exit with the exit code 1.

If the user enters a task identifier as part of an a or r command that is not one of the identifiers entered by the user during set-up, the program should print the line “Unknown task type identifier” to stderr and exit with the exit code 2. Note that the “Unknown task identifier” should only be printed if the task identifier and count were both read successfully. Also note that identifier matching is case-sensitive.

If one of

then the program should print the line “Invalid command” to stderr and continue with the next command loop.

If no errors occur and the program completes normally, it should exit with the exit code 0.

Note that all of your code can be in a single main function, so any return statement will exit the program. E.g., the statement

return 1;

will exit the program with the exit code 1. (In future assignments, we will expect you to write functions to modularize your program, but you don’t need to use functions for this assignment.)

You do not need to handle the following kinds of errors:

Hints and Specifications

You should use arrays to keep track of the identifiers for each type of task and their durations. (Remember there can be at most 10 of each.) For example,

char identifiers[MAX_TYPES];
int durations[MAX_TYPES];

assuming MAX_TYPES has been defined appropriately. You’ll also need a variable to count how many different types of tasks are entered during set-up, so that you know which elements of these arrays are used.

It will also make sense to have an array keeping track of how many tasks of each type are in the user’s jar.

Make sure that your program consistently checks the return value of scanf so that it knows whether or not input was read successfully.

Keep in mind that error messages should be printed to stderr and not stdout.

Development Requirements

In the homework folder of your private repository (2025-spring-student-JHED), you should create a new subfolder named homework/hw1. In that homework/hw1 subfolder, you will create your program in a new C source file named tasks.c. At the top of the file, add a comment with your six character alphanumeric Hopkins ID. (Please do not include your name or JHED so as to allow for blind grading.)

Throughout your work on this assignment, be sure to frequently add, commit (supplying meaningful messages) and push your changes to your personal git repository. After you complete your work on the assignment, you will be asked to submit a gitlog.txt file, just as in Homework 0. However, we expect your log for this homework to show more activity.

Your code is always expected to compile without errors or warnings on the ugrad servers. Submissions which do not compile properly may earn zero points, so be sure to submit to Gradescope early and often! And once you get a good start on the assignment, always have some earlier compiling version of your work pushed to Github.

Sample Runs

Caution

When you test your program in a terminal using the example inputs shown below, the result should be exactly what is shown below, including spacing. Note that

  • Each prompt should end with a space, but should not have a newline at the end, with the exemption of the prompt to enter type identifiers and durations.
  • Each output line in response to the "`s`" and "`q`" commands should end with a newline.

Here are several samples runs of the program on ugrad, where ‘$’ denotes the command prompt, and user input is shown in bold. Note that the first line shown below is the command you are expected to use as you compile your program (and the one that will be used by the graders). The compilation line should report zero errors and warnings, as demonstrated in these examples.

Example 1 (no input errors)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? 280
Enter task type identifiers and durations in minutes,
one per line; enter '0 0' to stop
c 75
p 50
i 10
0 0
Enter a command [a, r, s, q]: a c 2
Enter a command [a, r, s, q]: a i 3
Enter a command [a, r, s, q]: s
Identifier,Duration,Count,Total Time
c,75,2,150
p,50,0,0
i,10,3,30
Total time in jar: 3:00 out of: 4:40 possible
Enter a command [a, r, s, q]: r c 1
Enter a command [a, r, s, q]: a p 2
Enter a command [a, r, s, q]: s
Identifier,Duration,Count,Total Time
c,75,1,75
p,50,2,100
i,10,3,30
Total time in jar: 3:25 out of: 4:40 possible
Enter a command [a, r, s, q]: q
Bye!
$

Example 2 (case-sensitive task identifiers)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? 300
Enter task type identifiers and durations in minutes,
one per line; enter '0 0' to stop
c 50
C 75
0 0
Enter a command [a, r, s, q]: a c 2
Enter a command [a, r, s, q]: a C 1
Enter a command [a, r, s, q]: s
Identifier,Duration,Count,Total Time
c,50,2,100
C,75,1,75
Total time in jar: 2:55 out of: 5:00 possible
Enter a command [a, r, s, q]: q
Bye!
$

Example 3 (invalid remove quantity and quitting using Control-D)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? 480
Enter task type identifiers and durations in minutes,
one per line; enter '0 0' to stop
i 15
m 60
M 90
0 0
Enter a command [a, r, s, q]: a m 2
Enter a command [a, r, s, q]: s
Identifier,Duration,Count,Total Time
i,15,0,0
m,60,2,120
M,90,0,0
Total time in jar: 2:00 out of: 8:00 possible
Enter a command [a, r, s, q]: r m 3
Invalid command
Enter a command [a, r, s, q]: [...user types Control-D...]Bye!
$

Example 4 (invalid jar size)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? -300
Invalid input
$

Example 5 (invalid identifier/duration input)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? 300
Enter task type identifiers and durations in minutes,
one per line; enter '0 0' to stop
p 50
c 75
i ten
Invalid input
$

Example 6 (task identifier not found)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? 300
Enter task type identifiers and durations in minutes,
one per line; enter '0 0' to stop
p 60
c 75
m 30
0 0
Enter a command [a, r, s, q]: a t 1
Unknown task type identifier
$

Example 7 (invalid commands - treats each input character as a command as the loop continues)

$ gcc -std=c99 -pedantic -Wall -Wextra tasks.c
$ ./a.out
How many minutes to spend? 60
Enter task type identifiers and durations in minutes,
one per line; enter '0 0' to stop
c 75
p 50
i 10
0 0
Enter a command [a, r, s, q]: i p 1
Invalid command
Invalid command
Invalid command
Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: q
Bye!
$
Tip

There may be other ways for the input to be malformed, besides the ways shown above. You must be careful to check for all the various ways it might be malformed.

Testing

It is your responsibility to test a variety of valid input situations as well as invalid inputs. Make sure to test that every possible error condition detailed above is handled as specified. Make sure that you check for correct summary results even in cases where no add or no remove commands have been executed. What if the user doesn’t enter any task identifiers and durations? Think critically as an adversary for other problems or edge cases that your program might encounter, and test that they are handled appropriately.

If you identify any input scenarios or possible error situations that are not already covered by our notes in the Error Handling section, please post on Piazza regarding how to handle them.

For this first real assignment we are providing a sample input file and matching output file that you can use to check whether your prompts and outputs are programmed exactly as expected. This is the type of testing (not the exact tests) that our autograder will usually perform in hidden tests. In order to access the samples you will need to download them from our public course repo using commands similar to those in exercise 3b, assuming you have successfully cloned that repository. If not, complete exercises 3a and 3b and ask for help in office hours or class if needed.

First, log into the ugrad system and navigate into your clone of the cs220-sp25-public repo. Do a git pull to get the latest files we have provided.

Second, using the unix command cp (copy) along with customized file paths based on your file directory set-up, you’ll want to copy from cs220-sp25-public/homework/hw1/sampleIn.txt to the directory where you are coding your solution to this assignment. Similarly, copy from cs220-sp25-public/homework/hw1/sampleOut.txt to the same place.

Next, assuming your solution has been compiled to file a.out, run it on the input file using input redirection, and saving the [stdout] output to file myOut.txt as follows. You will see that the error messages that should be printed to stderr are still displayed on the screen, not in the myOut.txt output file and the stdout output is redirected to the text file instead of being displayed on the screen.

prompt> ./a.out <sampleIn.txt >myOut.txt
Invalid command
Invalid command
Invalid command

Now use the unix diff command to compare our output file to yours. This does an exact character comparison. The output should be nothing if the files match exactly as shown below.

prompt> diff sampleOut.txt myOut.txt
prompt>

If the output files don’t match, then it will show you which lines differ, and sometimes the difference may only be a space that is invisible to us, but that could cause an autograder test to fail. Here is an example where there is an extra space at the end of the first line and also with some “Invalid Command” error messages going to stdout (the file) instead of the screen.

prompt> diff sampleOut.txt myOut.txt
1c1
< How many minutes to spend? Enter task type identifiers and durations in minutes,
---
> How many minutes to spend? Enter task type identifiers and durations in minutes,
15c15,18
< Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Identifier,Duration,Count,Total Time
---
> Enter a command [a, r, s, q]: Invalid command
> Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Invalid
> command
> Enter a command [a, r, s, q]: Identifier,Duration,Count,Total Time
21c24,25
< Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Identifier,Duration,Count,Total Time
---
> Enter a command [a, r, s, q]: Enter a command [a, r, s, q]: Invalid command
> Enter a command [a, r, s, q]: Identifier,Duration,Count,Total Time
prompt>

What you see is the output in the first file (sampleOut.txt) indicated by lines that start with < and the output in the second file (myOut.txt) indicated by >. Each pair of lines that differ start with the line number(s) in the first file (21 in the last pair) and the line number(s) of the mismatches in the second file (24-25 for the last pair). It is generally recommend that you use the reference file as the first argument to diff for consistent interpretation of these results.

You can use this style of testing to make your assignment process smoother throughout the semester. We recommend writing multiple small input files so you can easily re-run them on your evolving solution with input redirection to see if you get the right output. However, we won’t usually provide either the input or the reference output for you. You’ll need to figure out what that should be.

Style

You should also make sure that your code has good style. You can look at the coding style guidelines here from a course you may take later that also applies to this course. In brief, you should make sure that your submission is well formed, readable, consistently styled, and documented as follows:

Submission

Create a .zip file named hw1.zip which contains only tasks.c and gitlog.txt. (Do not zip your entire hw1 folder - only these two files.) Copy the hw1.zip file to your local machine and submit it as Homework 1 on Gradescope.

Recall you can create your gitlog.txt file by running git log > gitlog.txt.

When you submit, Gradescope conducts a series of automatic tests. These tests do basic checks like making sure that you submitted the right files and that your .c file compiles properly. If you see error messages here (look for red), address them and resubmit until you pass them. Some of the error messages will show results similar to the diff in Testing example above.

Tip

You may re-submit any number of times prior to the deadline; only your latest submission will be graded.

Info

Review the course syllabus for late submission policies. You will want to save your late days for future assignments as they will be more involved. Remember that you can use at most 2 for any one assignment and any portion of a day counts as 1 whole day.

Grading

Two notes regarding automatic checks for programming assignments:

No-compile Policy

Remember that if your final code submission does not compile, you will receive a zero score for the assignment.

The 60 points for this assignment will be distributed roughly as follows when we grade:

Please plan accordingly, and practice incremental coding and testing for best results!