Project 1 Rubric

The grading of this project follows a specifications grading approach. If you have not already done so, make sure to read our Grading section of the syllabus for more details.

This project has two submissions: Project 1A and Project 1B. You will receive two SNU scores for each submission:

  • Completeness score: This score will be determined solely by the result of running the automated tests, as these give a measure of how complete your implementation is (i.e., how much of the assignment you implemented).

  • Code Quality score: This score is determined by a review of your code done by the course staff, and is based on four aspects of your code:

    • Correctness: This encompasses issues with your code that, while not explicitly captured by the tests, could lead to incorrect or inefficient behaviour in your code. This can include small mistakes in your code, as well as larger issues that reveal a lack of mastery in the material.

    • Design: This encompasses “qualities, many of which are intangible, that don’t have to do with (and exist to some extent independently of) the correct operation of your code.” (thanks to Adam Shaw for this concise phrasing).

    • Style: This encompasses your adherence to our Style Guide.

    • Documentation: You will be required to submit certain documentation on your code (the exact documentation is described below)

This project also has a “Warm-up” submission. This submission does not directly contribute to your final grade but, if you complete it, you will be more likely to get an S in Project 1A. To complete the “Warm-up” submission, you must score at least 90/100 points on the autograder for that submission.

Submission Timeline

The exact timeline of submissions will be the following:

Submission

Requirements

Due Date

Project Warmup

Assignment 1 of chirc

Thursday, October 10, 8pm

Project 1A

(Note: Assignment 4 builds on Assignment 1)

Thursday, October 17, 8pm

Project 1B

(Note: Assignment 5 builds on Assignment 4)

Thursday, October 24, 8pm

Resubmission (Optional)

Address feedback received in Project 1

One week after Project 1B is graded

You will receive some early feedback from the Project 1 Warm-up before Project 1A is due.

Project 1A will likely not be graded until after Project 1B is due. Once Project 1B is graded, you will have an opportunity to make a resubmission for Project 1A and/or 1B (and, at that point, you will have feedback for both Project 1A and 1B). We will post more details about the resubmission process at a later time.

Completeness

The Completeness components will be determined by running the following commands:

  • Project 1 Warm-up:

    make assignment-1
    
  • Project 1A:

    make assignment-4
    
  • Project 1B:

    make assignment-4+5
    

(see Using the automated tests in the chirc documentation for more details on these commands)

Your SNU score will then be determined as follows:

Grade

Project 1A

Project 1B

Satisfactory

at least 90

at least 180

Needs Improvement

at least 60

at least 120

Unsatisfactory

less than 60

less than 120

Note that the completeness score for Project 1B is based on the tests for both Assignment 4 and Assignment 5 of chirc (and is scored out of 200 possible points)

Code Quality

When assessing your code quality, there are a number of things we will be paying close attention to, and which we describe in the sections below (including major issues, labelled “[Major Issue]” that you should be particularly mindful of).

In general, your SNU score will be determined as follows:

  • Satisfactory: Your submission has a few of the issues described below (but no major issues).

  • Needs Improvement: Your submission has several of the issues described below, or at least one major issue. In general, major revisions are typically required to get up to an S.

  • Unsatisfactory: Your submission does not constitute a good-faith effort to complete the work. This includes not submitting any work at all, as well as submitting only placeholder code (e.g., code that includes functions for all the required IRC commands, but where the functions are empty or filled with “TODO”s, etc.)

That said, while the issues listed below are the main things we care about in this project, it is not possible for us to give you an exhaustive list of every single thing that could affect your code quality score. If you get a comment pointing out an issue in your code that we did not list below, take it as an opportunity to improve your work (and remember that you’ll have a chance to revise your work!)

Correctness

When assessing the correctness of your code, we will be paying special attention to the following:

All Submissions (including Warm-up)

  • Not checking the return value of send(): send is not guaranteed to send the entire buffer you provide, which you can only tell by looking at the return value (Beej’s Guide for Socket Programming provides a ready-to-use solution to this, which you’re welcome to use). Of course, send could also fail, and you need to check its return value for this too.

  • [Major Issue] Not checking the return value of any socket function.

  • Not using getaddrinfo to create the server socket. Please note that some of the socket examples we provide (most notably the first server example, oneshot-single.c) manually create the sockaddr struct for the sake of highlighting what that struct looks like, but that is not the usual way to create a server socket. You can see an example of how to create a server socket with getaddrinfo in the server-pthreads.c example.

  • Not using safe string functions (strncpy vs strcpy): Most C string functions (strcpy, strcat, etc.) have an equivalent “safe” version (strncpy, strncat, etc.) where you can specify the maximum number of characters to copy/concatenate/etc. Use these instead to protect against accidental (or malicious) buffer overflows. Alternatively, consider using a string library like sds

  • Treating the return of recv() as a C-string: recv() returns the raw bytes received through the network. In a protocol like IRC, this happens to be human-readable commands, but recv() won’t return a C-string (i.e., an array of characters terminated by a NULL character). It is your responsibility to add that NULL terminator if you want to manipulate the bytes returned by recv() as a C-string.

  • Hardcoding reply values that happen to make some tests pass, but which would fail under reasonable use cases. Take into account that the chirc specification does allow you to hardcode certain replies as a stop-gap measure (e.g., hardcoding the LUSERS replies during connection registration, so you can make progress on those tests before you properly implement the LUSERS command). However, you must ultimately remove those hardcoded replies with a more general implementation. Finally, for avoidance of doubt, there are also a few spots where the specification allows you to unconditionally hardcode certain values; those can be left hardcoded.

  • Memory accesses that could lead to segfaults under reasonable use cases. The graders won’t be trying to make your code fail with bizarre corner cases but, for example, if there is a very evident buffer overrun in your code, that will need to be fixed.

  • Not implementing something that is clearly specified in the project, even if the tests don’t test for it (e.g., implementing a command almost completely, but not implementing one of the replies).

Project 1A and 1B

  • [Major issue] Not protecting access to shared data structures (channels hash table, users hash table, etc.) with a mutex

  • Using mutexes to protect access to data structures, but doing so inconsistently (e.g., locking the mutex only when writing to a data structure, and not when reading).

  • Using mutexes to protect access to data structures, but not to socket accesses. See Inadequate locking in the Project 1 tips for more details.

  • [Major issue] Using a Big Fat Lock (i.e., using a single mutex lock for the entire server).

Design

When assessing the design of your code, we will be paying special attention to the following:

All Submissions (including Warm-up)

  • How you reassemble incoming messages: You should have some sort of array for assembling the next message that will be processed, separate from the buffer you pass to the recv() function (which cannot be a 1-byte array; using a 1-byte array when calling recv() is considered a major issue).

Project 1A and 1B

  • How you parse IRC commands: You should use the provided message.c module, instead of rolling out your own parsing code.

  • How you process IRC commands: You should use the provided handlers.c module, instead of reinventing a message dispatching mechanism.

  • Implementing modules or structs that are already provided to you: Make sure you don’t reinvent the wheel: we provide a lot of scaffolding code, and you should make sure to use the data structures and functions provided to you.

  • Not implementing the chirc_connection_send_message function

  • Implementing the chirc_connection_send_message function, but using it inconsistently e.g., making direct calls to send() from elsewhere in your code. Your code should be written in such a way that chirc_connection_send_message is the only function in your entire code to call the send function (or some sort of sendall helper function)

  • [Major issue] Putting all your code inside the chirc_run function: This is fine for the Project 1 Warm-up, but not once you move on to Project 1A

Project 1B only

  • [Major issue] Using two separate thread functions to handle connections (one for users and another for servers), instead of having a general-purpose thread function that handles commands that arrive on a connection (regardless of whether it’s a user or server connection).

Style

We will be checking your general adherence to our Style Guide and, while we will not be checking that you follow every minute aspect of our style guide, we do expect you to follow a consistent style that asymptotically approaches the one specified in our style guide. That said, there are certain aspects we will be paying more attention to:

  • Documenting functions: Every function written by you must have a function comment with a brief description of what the function does, and a description of the parameters and the return value. Please note that not documenting your functions at all (as opposed to doing so inconsistently or not following the style guide) is considered a major issue.

    Note: The chirc code uses Doxygen-style function comments. These are different from the ones in the style guide, but we will also accept them if you want to follow that style instead.

  • Consistent indentation: Your code must follow one of the allowed indentation styles consistently.

  • Clarity: Your code must be easy to read and understand. This is a fairly subjective aspect, but remember that things like using variable names without descriptive names or using magic numbers will usually make your code harder to read.

  • [Major Issue] Using global variables, except when defining compile-time constants.

  • [Major Issue] Using goto statements, except in the very limited cases described in the style guide.

Documentation

Your submission must include a DOCUMENTATION.md file in the root of your repository with some specific documentation about the code you have written. If you do not include this file, Gradescope will reject your submission entirely. If you do include it, but the file does not provide the information we request below, this will be treated as a major issue in your submission.

The DOCUMENTATION.md file must follow the template below (the exact sections are explained further below):

Project 1
=========

Team members:
- TEAM MEMBER 1 (CNETID1)
- TEAM MEMBER 2 (CNETID2)

Test score: XXX / YYY

New files
---------
- file1.c
- file2.c
- file3.c

New/modified functions (in existing files)
---------------------------------
- function1() in message.c
- function2() in channel.c

Other code details / requests for feedback
------------------------------------------
<COMPLETE THIS SECTION>

Known omissions
---------------
<COMPLETE THIS SECTION>

Citations
---------
<COMPLETE THIS SECTION>

Below you can find more details on each of the sections. If you are not providing any information in a given section, please do not remove the section. Instead, just write N/A below it.

  • Team members: Include the names and CNetIDs of both team members.

  • Test score: Please include the test score you are seeing when running the tests on your computer. This will allow us to look into situations where the Gradescope autograder reports a different score (in these cases, we will run the tests manually to verify we can get the same score you are getting)

  • New files: If you added any new C files to the repository, please list them here.

  • New functions (in existing files): If you added new functions to any of the files we provided to you, or if you modified any existing function, please list them here. Note: this does not include the handler functions you will be adding in the handlers.c file. You do not need to list those functions.

  • Other code details / requests for feedback: Use this section to provide any other information that may be relevant to the graders as they read through your code. If you would like us to provide feedback on any specific aspect of your work, you can also let us know in this section.

  • Known omissions: If you intentionally skipped any part of the project, or intentionally did not address any rubric items, please list them here. If we can provide any feedback that would help you address these rubric items, please let us know here as well.

  • Citations: Citations for use of Generative AI or external resources should be included, when possible, as code comments above any code where you relied on external sources. However, if you consulted a source that had a more broad impact on your work (and not on specific pieces of code), you can include the citation here. Additionally, if you had any high-level discussions about the project with other students in the class, please list their names here.

    Note: If the Generative AI platform you’re using does not allow you to easily generate a shareable link, please include a copy of the conversation(s) at the bottom of the DOCUMENTATION.md file.

Other Code Quality Issues

There are a couple of other issues that we care about across all projects:

  • Reinventing wheels that don’t need to be reinvented: In this class, we expect you to know how to use data structures like linked lists, hash tables, etc. (and how to choose the right data structure for a given task). However, this is a Networks class, not a Data Structures class, and you should not be spending any time implementing such data structures. The projects largely use the following data structure implementations:

    • utlist: A linked list library

    • uthash: A hash table for C structures

    • SDS: Simple Dynamic Strings

    Implementing your own linked list, hash table, etc. from scratch is considered a major issue. While you may think that implementing your own data structure is a worthwhile exercise, it invariably results in more work for the TAs and graders (as you will likely run into all sorts of issues and segfaults that could have been avoided by using a well-known and well-tested data structures library). Plus, it will be a much more worthwhile experience for you to understand how to incorporate an existing library into your own code.

  • Submitting code that doesn’t build: If you submit code that does not build on Gradescope’s autograder, but the graders can get it to build with some minor fixes (missing semicolons, parenthesis, etc.), this will just be treated as a major issue. However, if your code requires substantial work to get it to build, you will receive a U score.

    So, make sure you verify that the version of the code you submitted builds correctly on a supported software environment (see the Projects - Getting Started page for more details on this) Additionally, it is your responsibility to check that the code you submitted to Gradescope builds correctly. If it doesn’t, but it builds correctly on your end, please let us know so we can look into it.

  • Using printf instead of chilog: All the projects in this class use a simple logging library called chilog that is documented in each of the project specifications. You must use the chilog functions exclusively for printing logging or debug messages. Do not use printf() directly in your code. Please note that the chilog functions provide essentially the same functionality as printf, so there is no situation where printf would be necessary instead of chilog (using chilog consistently also means you will not have to scrub printf’s from your code before submitting it).

    Furthermore, all the messages at the INFO, WARNING, ERROR, and CRITICAL levels must be used only for their intended purposes (e.g., only use ERROR to print out actual errors in the execution of your program). You must use the DEBUG level only to print informative debug messages that would be understood by any developer trying to debug your code. You may use the TRACE level to print any debug message (including those that would only be understood by you). However, if your code is riddled with TRACE logging statements (including commented out ones) to the point where it is hard to read the code itself, we may penalize you for this. So, once a TRACE logging statement has served its purpose, we suggest you remove it (not just comment it out).

    You should assume that graders will run your code with logging at the INFO level, and will only use the DEBUG level if they need to debug an issue with your code. We will never run your code with logging at the TRACE level.

    Please note that, in assignments where you are responsible for writing the main function, you may use fprintf to print to standard error if there is an error that prevents the program from starting (e.g., if a command-line parameter has not been provided, etc.)

  • Grossly incorrect memory management: You should make sure to free any memory you malloc, but we will usually not penalize you unless you’ve been grossly negligent in your malloc’ing/freeing. You should also make sure to not “save” pointers to stack-allocated memory that is going to be deallocated. This can happen if you store a pointer to a functions’ local variable in a struct that is heap-allocated.

Resubmission

When you receive your graded Project 1B, you can make a resubmission to address any feedback you received in Projects 1A and/or 1B. This may increase your scores in those projects.

While the project is divided into two parts (1A and 1B), remember that Project 1B builds on Project 1A, As such, you should think about your resubmission as a final cumulative submission that addresses any remaining issues in your Project 1B submission (i.e., you should not think in terms of making two separate resubmissions, one for 1A and another for 1B, with different code for each submission).

Note

If you scored two S’s in your initial submission for Project 1B, but not in your initial Project 1A submission, you do not need to make any further changes to your Project 1B code to bump your 1A scores up to two S’s. However, we do still need you to make an (abbreviated) resubmission. If you are in this situation, please skip to “Project 1B Submissions with two S’s” below.

Required Documentation

Making a resubmission involves not just addressing the feedback we gave you, but also preparing some documentation explaining the changes you made to your code. You should consider this documentation as important as the changes you are making to your code: resubmissions that do not include the information requested below WILL NOT BE GRADED.

If you decide to make a resubmission, you MUST add a RESUBMISSION.md file in the root of your repository using the following template: (the exact sections are explained below)

Project 1 Resubmission
======================

Team members:
- TEAM MEMBER 1 (CNETID1)
- TEAM MEMBER 2 (CNETID2)

Rubric items you have addressed
-------------------------------
<COMPLETE THIS SECTION>

Rubric items you have NOT addressed
-----------------------------------
<COMPLETE THIS SECTION>

Substantial new code added to your submission
---------------------------------------------
<COMPLETE THIS SECTION>

Changes made to pass additional tests
-------------------------------------
<COMPLETE THIS SECTION>

Other changes
-------------
<COMPLETE THIS SECTION>

Below you can find more details on each of the sections. If you are not providing any information in a given section, please do not remove the section. Instead, just write N/A below it.

  • Team members: Ordinarily, this would be the same two team members who made the original submission. However, if you worked individually on the resubmission (because your teammate was happy with the original submission, and didn’t want to work further on it), please make sure to note this here.

  • Rubric items you have addressed: Rubric items that appear selected on Gradescope (under “Manual Grading”) represent issues that had an impact on your Code Quality score. To facilitate the work of the graders, you must list each rubric item you have addressed, with the following information:

    • The rubric item description, exactly as it appears on Gradescope.

    • 1-2 sentences explaining how you addressed the rubric item.

    • If the work you did on the rubric item is limited to a few lines of code, specify the filename and line number(s), If your work on this rubric item involved deeper changes to your code, you do not need to list every single line of code you changed, but you should try to give the graders a general sense of where you made the changes, including a few examples if possible (e.g., “I combed through the code to make sure I was using descriptive variable names; for example, I changed c to channel in several functions”, “I reorganized functions foo(), bar(), and baz() as requested”, etc.)

    Bear in mind that the Project 1A rubric items are a subset of the Project 1B rubric items. This means that…

    • If your initial Project 1B submission already addressed a rubric item from Project 1A (and the rubric item was no longer selected in your graded Project 1B), it is enough to say “This rubric item was addressed in Project 1B”

    • If you scored an N in Code Quality in Project 1A, but then scored an S in Code Quality in Project 1B, you do not need to explain how you addressed each individual rubric item. Instead, please include the following text in this section: “We earned an S in Code Quality in Project 1B”

  • Rubric items you have NOT addressed: It is also important that you let us know what rubric items you decided not to address, as this will expedite the work of the graders. For these rubric items, it is enough to provide a list of the rubric item descriptions (exactly as they appear on Gradescope)

  • Substantial new code added to your submission: If you added substantial new code that was not present in your original submission (e.g., if your original submission did not implement several commands, and you have now included new code to implement those commands), you must specify the affected files, as well as the new functionality that is added by the new code. For example, you could include something like this:

    Modified files: ctx.h, handlers.c
    
    Locks: Added locks X, Y, and Z in chirc_ctx_t
    
    JOIN and PART: Implemented the handlers for these commands in handlers.c
    
    QUIT: Updated the QUIT handler to relay the QUIT to users on the same channel as the user.
    
  • Changes made to pass additional tests: If you made changes to your code with the goal of passing more tests, please specify your original test score, and the new test score. If your work only involved a few minor bug fixes, please let us know you did this (but you do not need to specify the exact changes you made). On the other hand, if you skipped parts of Project 1B in your original submission, and have written entirely new code, please make sure you have specified this as part of the “substantial new code”, and that you also specify that doing so allowed you to pass additional tests.

  • Other changes: If you made other changes to your code, such as refactoring large parts of your code, make sure to specify this too.

Once again, if you do not include a RESUBMISSION.md file with the above information, your resubmission will not be graded.

Project 1B Submissions with two S’s

If you scored two S’s in your initial submission for Project 1B, but not in your original Project 1A submission, you do not need to submit all the documentation requested above. However, we do still need you to make a resubmission so we know you want us to revise your Project 1A submission.

In this resubmission, you do not need to make any changes to your Project 1B code, and can simply resubmit the exact same code your submitted in our original Project 1B submission. All you need to do is add a RESUBMISSION.md file with the following contents:

Project 1 Resubmission
======================

Team members:
- TEAM MEMBER 1 (CNETID1)
- TEAM MEMBER 2 (CNETID2)

We earned two S's in Project 1B, but not Project 1A.

Note: If you already earned two S’s in both Project 1A and 1B, do not make a resubmission (it will be ignored). If you have questions about any of the feedback you received, please post a question on Ed.

Submitting

You will submit your code through the “Project 1 (Resubmission)” assignment on Gradescope. Other than that, you should follow the same submission instructions as in the original submissions.

Resubmission Grading

In general, if you are making a resubmission that only involved addressing rubric items, without adding substantial new code to your submission, there is a very high likelihood that addressing all the rubric items will bump your Code Quality score to an S. You may leave up to two non-major rubric items unaddressed.

On the other hand, if you are making a resubmission that involves adding substantial new code, please bear in mind that the graders could identify issues in that new code that will impact your Code Quality score. Please make sure to carefully review the Project 1 Rubric so you know what the graders will be looking at.