CSSE 120 — Intro. to Software Development
Final C Project — Transcript
Overview
For your final project in CSSE 120, you’ll write a program for Rose transcripts. The program will let the user enter courses and letter grades and will calculate term and cumulative GPAs, along with cumulative credit hours earned. It will display the a transcript with the calculated GPAs and credit hours earned.
- Important note: You should assume that none of the input contains spaces. So for a course whose name is Intro to Yodeling, the user is expected to enter Intro_to_Yodeling (or use dashes instead of underscores, or both, your choice). This restriction avoids some nasty issues that would crop up otherwise.
Accomplishing the above earns a score of 80%. For each of the following, allowing the user to accomplish the action earns an additional 10% (but with the maximum score capped at 110%).
- Save the transcript to a file. (You decide the format in which to save the data.)
- Load a saved transcript.
- Delete an individual course. (This is useful in case the user makes a mistake while entering a course.)
- Edit the data of an existing individual course. (Again, to help correct mistakes in data entry.)
- Allow course names (and course identifiers if you wish) to contain spaces.
This is an individual project, but you may work in pairs if you indicated your pair preferences to your instructor. We want everyone to keep practicing their C programming so you do well on the final exam!
- Reminder: As always with individual work, it is fine to get help with general issues, or to get help learning how to (say) use structures, or to understand a mysterious compile-time error, but sharing code is never allowed for individual projects.
Your work for this project should be done in the Transcript project that you can check out from your individual or pair SVN repository.
Sample Input and Output
The main menu should look something like:
1: Select term
2: Add a course and letter grade
3: Display current transcript
4: Save current transcript to a file
5: Load a transcript file
9: Exit
Enter selection:
Notes:
- If you use the form shown above, the user should enter one of the numbers shown (1, 2, 3, 4, 5, 9) and the program should then do the associated action.
- Throughout this project, you are NOT required to do input validation. For example, it is OK if your program does the wrong thing or crashes if the user:
- enters something like this:
Enter selection: Add
in response to the above menu, or
- enters spaces in any of the inputs (the examples below will use underscores, that's OK!), or
- enters spaces before or after any of the inputs.
Pressing 1 on the main menu might display:
Current term is Fall 2010-2011, change selected term to:
1: Fall 2009-2010
2: Winter 2009-2010
3: Spring 2009-2010
4: Fall 2010-2011
5: Winter 2010-2011
6: Spring 2010-2011
7: Fall 2011-2012
8: Winter 2011-2012
9: Spring 2011-2012
10: Fall 2012-2013
11: Winter 2012-2013
12: Spring 2012-2013
13: Back
Enter selection:
Notes:
- You do not have to implement Back unless you want to.
- You can use Banner-like term names (e.g., 201110 for Fall 2010-2011) if you prefer (but the names above are prettier).
Pressing 2 on the main menu might display:
Enter course identifier (example: CSSE120):
Enter course name (example: Intro_to Software_Development):
Enter course grade (example: B+):
Enter course credit hours (example: 4):
Notes:
- Three of the above inputs are strings. You can (and should) make reasonable assumptions about the maximum length that the user will enter for those strings. For example, you might assume that all input strings in the program are at most 30 characters. Or, you might have different sizes for different kinds of information — your choice.
- It is fine to use underscores or dashes for strings which would otherwise have spaces in them. (But if you do allow spaces, that's an extra 10% above the baseline 80%.)
- Again, input validation is NOT required (but permitted, of course).
Pressing 3 on the main menu might display (after entering some courses/grades):
Fall 2009-2010 Grade CrHrs
CLSK100 College and Life Skills A 1
CSSE120 Intro to Software Development B+ 4
MA111 Calculus I C 5
PH111 Physics I D+ 4
PH111L Physics I Lab NG 0
RH131 Rhetoric and Composition A 4
TERM GPA: 2.78
CUM GPA: 2.78
CR HRS Total: 18
Winter 2009-2010 Grade CrHrs
CSSE220 Object-Oriented Software Dvlpm A 4
MA112 Calculus II B+ 5
ECE130 Introduction to Logic Design A 4
PH112 Physics II F 4
PH111L Physics II Lab NG 0
TERM GPA: 2.91
CUM GPA: 2.84
CR HRS Total: 31
Spring 2009-2010 Grade CrHrs
(No classes entered)
TERM GPA: 0.00
CUM GPA: 2.84
CR HRS Total: 31
...
Spring 2012-2013 Grade CrHrs
CSSE479 Cryptography A 4
CSSE499 Senior Project III A 4
SV245 Mus Hist:Classicl,Romntc,Modrn A 4
TERM GPA: 4.00
CUM GPA: 3.14
CR HRS Total: 43
Notes:
- As the above example suggests, you should allow for grades of A, B+, B, C+, C, D+, D, F and (if you can) NG (no grade).
- The number of credit hours displayed is the number earned (i.e., a passing grade in these courses); the
cumulative and term GPAs are based on the number of hours attempted.
- You do not need to deal with grade replacement or grades other than those just listed.
- Partial credit is available if you don't get all aspects of the above transcript sample.
Other Requirements
It is not enough to just get the program to work!
A correct solution will demonstrate good decomposition into functions and good use of structures. This will vary depending on how you approach the problem, but a reasonable decomposition would include at least two structures and on the order of 10-35 functions. (Two 110% solutions by two professors had 32 and 19 functions, respectively.)
Your structures should be defined in one or more appropriate .h files.
Grading — 200 Points Total
Basic features (you should get these working first) — 160 points of 200 possible:
- (15) The term to be used as the current term can be selected.
- Note: For this and all these features, you can demonstrate success by printing a correct transcript after entering appropriate data. However, if you cannot print a transcript correctly, instead simply print the featured data (here, the current term) to earn the points for that feature.
- (15) The current term is applied appropriately to subsequent course/grade entries.
- (15) The course and letter grade information can be entered successfully.
- (90) When the transcript is displayed, it:
- (15) Has the correct courses grouped by term correctly.
- (15) Has the terms ordered chronologically.
- (15) Shows correctly calculated term GPA on data like that shown in the example above.
- (15) Shows correctly calculated cumulative GPA.
- (15) Shows correctly calculated cumulative credit hours earned.
- (15) Is formatted neatly as suggested by the above example (the formatting need not be identical to the example, but for full credit it must include all information shown in the example and be neatly formatted).
- (10) The code has appropriate documentation (comments).
- (15) The code uses appropriate style regarding: variable names, breakdown into functions and structures, indenting, use of white space, and so forth.
Additional features (you choose from these) — 20 additional points for each feature below, but capped at 220 total points (110%):
The user can:
- (20) Save the transcript to a file. (You decide the format in which to save the data.)
- (20) Load a saved transcript.
- (20) Delete an individual course. (This is useful in case the user makes a mistake while entering a course.)
- (20) Edit the data of an existing individual course. (Again, to help correct mistakes in data entry.)
- (20) Allow course names (and course identifiers if you wish) to contain spaces.
Suggestions — Read and Obey These! You'll be sorry if you don't!
Structures
Your FIRST step for solving this problem should be thinking about what structures you want. A couple of useful structures might be:
typedef struct {
// elided
} GPA;
typedef struct {
// elided
} Course;
FYI, two 110% solutions by two professors had 3 and 4 structures, respectively. You choose your own structures (but include at least two structures).
Also at this point think about what arrays you will want.
Procedural decomposition
Your SECOND step for solving this problem should be writing down the calls that main will make to functions that you will (LATER) define.
- Writing all your code in main (with no calls to functions that you define) would be terribly hard to debug!
- Your main might have about 5 to 10 calls to functions that you will (later) define. (Two 110% solutions by two professors had 6 and 9 calls from main to functions that they defined, respectively.)
Stubs
Your third step for solving this problem should probably be writing stubs for the functions that main calls.
- A stub is a function definition whose body is empty or trivial.
- Once you have the stubs in place, your program should compile successfully (although you will undoubtedly first have to correct some typo's, etc.)
- You can run the program now, but it won't do anything interesting since all your functions are just stubs at this point.
Iterative enhancement
This is critical: For the rest of your coding, identify one TEENY additional functionality that seems right to do next. Implement and test. Don't proceed until you get that teeny functionality working.
- This way, you ALWAYS have an operative program.
- We cannot grade an inoperative program, so this is really important.
- Additionally, using this iterative enhancement ensures that you don't lose control of your program — in C, you risk losing control each time you add more than 50 lines of code or so. So work and test in much smaller increments.
The key is testing as you go. Work through the problem in an order than helps you accomplish that.
Gotcha's
As you have seen, the hard part of C is avoiding mistakes. Once you make a mistake, it is often time-consuming to track down the error.
So try to avoid these common mistakes:
- Abusing scanf.
- Have exactly as many variables to be set as there are % signs in the format string.
- Make sure your variable types match up to your % formatting character:
-
%d for int variables
-
%f for float variables
-
%lf for double variables (memory aid: lf means “long float”)
-
%s for strings (and remember that %s stops when it sees whitespace — that's why we made the restriction of no spaces in course names)
- Remember to send pointers as the arguments after the format string.
- Abusing printf. Likewise, make sure that printf has exactly as many variables to be set as there are % signs in the format string, and that the types match.
- Mixing scanf with other input functions. Don't, unless you know what you are doing. Instead, stick to scanf (and fscanf for reading from a file).
- Launching with errors. Never run the program if you see compiler error-messages. If you see:
Errors exist in a required project. Continue launch?
always respond No.
- If you do the run, you are running an old version of the program that contains who-knows-what.
- So fix the compiler error messages FIRST, then run.
- Even warning messages are usually worth fixing. Your compiler does an excellent job with warnings, far better than compilers from a decade ago.
If you see a little asterisk by the name of the file on the tab in the Editor, that means that file has not been saved. Never run unless it has been saved (for most of you, running asks if you want to save it).
- Mysterious compile-time error messages. If you experience this, here are several things to try:
- First, make sure you are looking at the right line of code. Click on the relevant blue link in the Console.
- Change the file in some innocuous way (add a space somewhere). Save the file manually. Then do Project ~ Clean. This forces a recompile and often “wakes up” the compiler when it falls behind.
- Do Edit ~ Format (or its shortcut Control-Shift-F). If your code is now indented in an unexpected way, you probably have a missing curly-brace somewhere (or possibly an extra one). Find the first place where the indentation is not what you expect. You are probably missing a curly-brace right above that point.
- Get another set of eyes — ask someone else to look at the line with the error and offer their advice.
- Compiling while running. If you get an error message that is something like:
mingw32\bin\ld.exe: cannot open output file [SOMETHING HERE].exe: Permission denied
that almost certainly means that you are still running the program in this or another console. To fix this, you often have to use the pull-down menu on the right-hand-side of Console et al windows that says Display Selected Console. Select it, find the running programs and stop them with the usual red boxes. There are often MANY running programs in this situation; you must stop them all.
- Missing functions. Suppose you get a compile-time error message like:
implicit declaration of function 'foo'
or perhaps:
conflicting types for 'foo'
Any of the following could be the problem:
- You misspelled the name of the function, either in the call or the definition of the function.
- You called or defined the function with the wrong number or wrong type(s) of arguments.
- The function belongs to a library that you failed to #include.
- You defined the function BELOW the place in the file where you called it.
- The C compiler barfs at this because it processes a source file from top to bottom,
so when it hits the function call it does not yet know what it needs to know about the function.
- One way to solve this problem is to move the function definition ABOVE its call(s).
- Another, perhaps better, way is to put prototypes
near the top of the file (before any function definitions), like this:
double foo(double y[], int size); // Prototype, near the top of the file.
...
double foo(double y[], int size) {
... // Code for the function here
}
The prototype is shown in red. It's easy to obtain — just copy the first line of the function definition
and replace the curly-brace (and its preceding space, if any) by a semicolon. Its a good habit to make a prototype
every time you define a function, because it avoids this problem and provides a handy list of your functions
at the top of the file.
- Messy code is almost impossible to get correct. Keep things simple and clean. Refactor often to maintain that simplicity and cleanliness.
- Waiting to the last minute guarantees failure.
- Start early.
- Work steadily.
- The CSSE lab from 7 to 9 p.m. is the PERFECT place to work because you get instant help when needed.
- Email
csse120-staff@rose-hulman.edu if you can't get help in person.
Turn In
Submit your work by committing it to your individual SVN repository. Commit often since that backs up your work.