CSA Unit 1.9 — Assignment Statements and Input

Popcorn Hack #1

/**
 * Calculates the sum of all positive even numbers in the array.
 * 
 * Preconditions:
 * - nums is not null
 * 
 * Postconditions:
 * - Returns 0 if there are no positive even numbers
 *
 * @param nums the array of integers
 * @return the total of all positive even integers
 */
public int doSomething(int[] nums) {
    int result = 0;
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] > 0 && nums[i] % 2 == 0) {
            result += nums[i];
        }
    }
    return result;
}

Popcorn Hack #2

/**
 * Represents a grade book that stores assignments and calculates final grades.
 * 
 * This class allows users to add assignments, assign category weights,
 * calculate a weighted final grade, and generate a simple report.
 * 
 * Example:
 * GradeBook gb = new GradeBook();
 * gb.setCategoryWeight("Homework", 0.4);
 * gb.setCategoryWeight("Tests", 0.6);
 * gb.addAssignment("Homework", "HW1", 95.0);
 * gb.addAssignment("Tests", "Unit Test", 88.0);
 * double finalGrade = gb.calculateFinalGrade();
 * 
 * @author Your Name
 * @version 1.0
 * @since 2025-10-13
 */
public class GradeBook {
    private HashMap<String, Double> assignments;
    private HashMap<String, Double> categoryWeights;
    private double extraCredit;

    /**
     * Adds an assignment score to a specific category.
     *
     * @param category the category name (e.g., "Homework")
     * @param name the name of the assignment
     * @param score the score earned (0–100)
     */
    public void addAssignment(String category, String name, double score) { }

    /**
     * Sets the weight for a given category.
     *
     * @param category the category name
     * @param weight the category’s weight (e.g., 0.3 for 30%)
     */
    public void setCategoryWeight(String category, double weight) { }

    /**
     * Calculates the final weighted grade including extra credit.
     *
     * @return the final grade as a percentage
     */
    public double calculateFinalGrade() { return 0.0; }

    /**
     * Generates a simple grade report listing categories and scores.
     *
     * @return a string containing the formatted grade report
     */
    public String generateReport() { return ""; }
}

Part 1

/**
 * Demonstrates adding two integers using a helper method.
 * 
 * This program defines a method that adds two numbers and prints the result.
 * It serves as a simple example of documentation and method use.
 * 
 * @author Your Name
 * @version 1.0
 * @since 2025-10-13
 */
public class Stuff {

    /**
     * The main method that runs the program.
     * Initializes two integers, adds them, and prints the result.
     *
     * @param args command-line arguments (not used)
     */
    public static void main(String[] args) {
        int x = 5;
        int y = 10;
        int z = add(x, y);
        System.out.println("The sum is " + z);
    }

    /**
     * Adds two integers and returns their sum.
     *
     * Preconditions:
     * - a and b are valid integers
     * 
     * Postconditions:
     * - Returns the correct sum of a and b
     *
     * @param a the first integer
     * @param b the second integer
     * @return the sum of a and b
     */
    public static int add(int a, int b) {
        return a + b;
    }
}

Explanation of Improvements

  • Added clear Javadoc comments for the class and methods.
  • Included tags for author, version, and parameters.
  • Added simple preconditions and postconditions.
  • Fixed the class name to follow Java conventions (Stuff).
  • Made the print message and formatting clearer.

Part 2

/**
 * Enrolls a student in a course if all enrollment conditions are met.
 * 
 * This method checks that both the student and course exist, ensures
 * the course is not full, verifies prerequisites, checks for schedule
 * conflicts, and confirms the student will not exceed 18 credit hours.
 * If all conditions pass, the student is added to the course and the
 * enrollment is recorded.
 * 
 * Preconditions:
 * - studentId and courseCode are valid (not null or empty)
 * - semester is a valid semester number
 * 
 * Postconditions:
 * - Student is enrolled in the course if all checks pass
 * - Returns true if enrollment succeeds, false otherwise
 *
 * @param studentId the unique ID of the student
 * @param courseCode the code of the course to enroll in
 * @param semester the semester number for enrollment
 * @return true if the student was successfully enrolled, false otherwise
 */
public boolean enrollStudent(String studentId, String courseCode, int semester) {
    Student student = findStudentById(studentId);
    if (student == null) return false;

    Course course = findCourseByCode(courseCode);
    if (course == null) return false;

    if (course.isFull()) return false;
    if (student.hasScheduleConflict(course)) return false;
    if (!student.hasPrerequisites(course)) return false;
    if (student.getCreditHours() + course.getCreditHours() > 18) return false;

    student.addCourse(course);
    course.addStudent(student);
    recordEnrollmentTransaction(studentId, courseCode, semester);
    return true;
}

Reflection Questions

Reflection Questions

1. Why is documentation more important in team projects than solo projects?
Documentation is more important in team projects because multiple people need to understand and maintain the same code. Good comments and Javadoc help teammates quickly learn how methods work, what inputs they expect, and what results they produce. Without documentation, team members waste time guessing how parts of the code function.

2. Give an example of when a method SHOULD be documented and when it SHOULD NOT.
A method should be documented when it has complex logic, multiple conditions, or special cases — for example, a method that calculates student grades with weighted categories.
A method should not be documented when it’s simple or self-explanatory, such as a basic getter or setter like getName() or setAge().

Extra Credit

Challenge 1

/**
 * Calculates the factorial of a given non-negative integer using recursion.
 * 
 * The factorial of n (written as n!) is defined as:
 * - 0! = 1  (base case)
 * - n! = n * (n - 1)!  (recursive case)
 * 
 * This method demonstrates a classic recursive pattern with a simple base case
 * and a recursive call that reduces the problem size at each step.
 * 
 * Complexity Analysis:
 * - Time Complexity: O(n) — one recursive call per integer down to 1.
 * - Space Complexity: O(n) — due to recursive call stack.
 * 
 * Preconditions:
 * - n must be greater than or equal to 0.
 * 
 * Postconditions:
 * - Returns the factorial of n.
 *
 * @param n the non-negative integer to calculate the factorial of
 * @return the factorial of n
 */
public int factorial(int n) {
    if (n == 0) {  // Base case
        return 1;
    } else {       // Recursive case
        return n * factorial(n - 1);
    }
}

Challenge 2

When to Document

  • Document when:
    • A method has multiple parameters, complex logic, or special cases.
    • A class represents a main component or has several responsibilities.
    • The method interacts with external systems (files, APIs, databases).
    • Code decisions or algorithms are not immediately clear.
  • Do not document when:
    • The method is a simple getter/setter.
    • The method’s purpose is obvious from its name and one line of code.

Required Tags

  • @param and @return for all methods
  • Preconditions and Postconditions for non-trivial logic
  • @throws when exceptions can be raised
  • @author, @version, and @since for classes

Example Template

/**
 * Calculates the area of a rectangle.
 *
 * @param length the length of the rectangle
 * @param width  the width of the rectangle
 * @return the calculated area
 */
public double calculateArea(double length, double width) { ... }

Common Mistakes to Avoid

  • Over-documenting obvious code (like getName() or setAge()).
  • Using vague phrases such as “does stuff” or “handles data.”
  • Forgetting to update documentation after making code changes.
  • Leaving out @param or @return tags.
  • Writing preconditions or postconditions that don’t match the actual code.
  • Not explaining why the code works, only what it does.

Challenge 3

Project Selected

Repository: Data-Structures-In-Java by Deepak Malik
File: src/com/deepak/data/structures/Cache/LRUCache.java

This class implements a simple Least Recently Used (LRU) cache using a LinkedHashMap, but the original version lacks detailed Javadoc and clear explanations of how the cache works, its eviction policy, and complexity.


Before

public class LRUCache<K, V> {
    private final int capacity;
    private final LinkedHashMap<K, V> map;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.map = new LinkedHashMap<>(capacity, 0.75f, true);
    }

    public void put(K key, V value) {
        map.put(key, value);
        if (map.size() > capacity) {
            Iterator<K> it = map.keySet().iterator();
            it.next();
            it.remove();
        }
    }

    public V get(K key) {
        return map.get(key);
    }
}

After

/**
 * A fixed-capacity Least Recently Used (LRU) cache that evicts the oldest entry
 * when the maximum size is exceeded.
 *
 * <p>This implementation uses a {@code LinkedHashMap} in access-order mode so
 * that recently accessed items move to the end of the map. When the cache
 * exceeds its capacity, the least-recently-used entry (the oldest) is removed.</p>
 *
 * <p><b>Complexity:</b> O(1) average time for both {@code get()} and {@code put()}.</p>
 *
 * <p><b>Preconditions:</b> Capacity must be greater than 0.</p>
 * <p><b>Postconditions:</b> The cache size never exceeds the defined capacity.</p>
 *
 * <p><b>Example:</b></p>
 * <pre>
 * LRUCache<String, Integer> cache = new LRUCache<>(2);
 * cache.put("A", 1);
 * cache.put("B", 2);
 * cache.get("A");  // refreshes "A" as most-recent
 * cache.put("C", 3); // evicts "B"
 * </pre>
 *
 * @param <K> the key type
 * @param <V> the value type
 * @since 2025-10-13
 */
public class LRUCache<K, V> {
    private final int capacity;
    private final LinkedHashMap<K, V> map;

    /**
     * Creates an LRU cache with a specified positive capacity.
     *
     * @param capacity the maximum number of entries allowed
     * @throws IllegalArgumentException if capacity <= 0
     */
    public LRUCache(int capacity) {
        if (capacity <= 0) {
            throw new IllegalArgumentException("capacity must be > 0");
        }
        this.capacity = capacity;
        this.map = new LinkedHashMap<>(capacity, 0.75f, true);
    }

    /**
     * Inserts or updates a key-value pair and evicts the least-recently-used entry
     * if capacity is exceeded.
     *
     * @param key the key (cannot be null)
     * @param value the value associated with the key
     * @throws NullPointerException if key is null
     */
    public void put(K key, V value) {
        if (key == null) throw new NullPointerException("key must not be null");
        map.put(key, value);
        if (map.size() > capacity) {
            Iterator<K> it = map.keySet().iterator();
            it.next();   // oldest key
            it.remove(); // evict
        }
    }

    /**
     * Retrieves the value associated with the given key and updates its recency.
     *
     * @param key the key to retrieve
     * @return the value mapped to the key, or null if not present
     * @throws NullPointerException if key is null
     */
    public V get(K key) {
        if (key == null) throw new NullPointerException("key must not be null");
        return map.get(key);
    }

    /**
     * Returns the current number of entries in the cache.
     *
     * @return the number of entries
     */
    public int size() {
        return map.size();
    }
}