Developing Procedures
Help Questions
AP Computer Science Principles › Developing Procedures
Based on the scenario, a student writes a procedure to find the maximum value in a non-empty list of integers. Input: list nums (length 1 to 50,000). Output: the largest integer in the list. Constraint: must work for negative numbers.
PROCEDURE maxValue(nums)
max ← 0
FOR EACH n IN nums
IF n > max
max ← n
ENDIF
ENDFOR
RETURN max
ENDPROCEDURE
Which step is necessary to ensure the procedure works correctly for all valid inputs?
Change the comparison to IF n < max so smaller values update max.
Sort nums and return the first element to get the maximum quickly.
Initialize max to the first element of nums before the loop.
Add a second loop to confirm that max appears at least twice.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on proper initialization for finding extrema. Developing procedures involves choosing appropriate initial values that work for all possible inputs, including edge cases like all-negative lists. In this scenario, initializing max to 0 fails when all numbers in the list are negative, as no value would ever be greater than 0. Choice A is correct because initializing max to the first element ensures the procedure works for any non-empty list, including lists with all negative numbers. Choice C is incorrect because changing the comparison to find smaller values would find the minimum, not the maximum, demonstrating a fundamental misunderstanding of the algorithm's purpose. To help students: Emphasize the importance of choosing neutral initial values or using the first element for extrema problems. Practice tracing through code with various inputs including all-negative, all-positive, and mixed lists.
Based on the scenario, a teacher needs to count how many times each letter grade appears in a list grades containing strings from the set {"A","B","C","D","F"}. Input: list grades of length $n$. Output: a dictionary-like mapping from grade to count. Constraints: $n$ up to 200,000; only these five possible values; AP-style pseudocode.
A student writes:
PROCEDURE CountGrades(grades)
counts <- {"A":0,"B":0,"C":0,"D":0,"F":0}
FOR EACH g IN grades
FOR EACH key IN counts
IF g = key
counts<u>key</u> <- counts<u>key</u> + 1
RETURN counts
How can the procedure be optimized for better performance?
Use three nested loops so each grade is checked multiple times for accuracy.
Sort grades first, then run the same nested loops to count faster.
Replace the inner loop with a direct update: counts[g] <- counts[g] + 1.
Remove the initialization of counts and create keys only at the end.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on algorithm optimization and eliminating unnecessary nested loops. The student's code uses nested loops where the outer loop iterates through each grade and the inner loop iterates through all possible grade keys to find a match, resulting in inefficient O(n×5) time complexity. Since the grade is already known from the outer loop, we can directly access and update the corresponding count without searching through all keys. Choice A is correct because replacing the inner loop with a direct update counts[g] <- counts[g] + 1 eliminates the unnecessary searching and reduces the time complexity to O(n), making it much more efficient for large datasets. Choice B is incorrect because sorting wouldn't help with counting and would add unnecessary overhead, and the nested loops would still be inefficient. To help students: Teach recognition of unnecessary nested loops and how to use direct access with dictionaries/maps. Practice analyzing time complexity and identifying opportunities to eliminate redundant operations, especially when working with known key sets.
Based on the scenario, an app uses a simple weather API helper procedure GetWeather(city) that returns either a record {tempF, condition} or the value NULL if the city is not found. Input: string city. Output: a formatted string like "72F Clear" or "City not found". Constraints: do not crash on NULL; AP-style pseudocode only.
A student writes:
PROCEDURE WeatherLine(city)
w <- GetWeather(city)
RETURN w.tempF + "F " + w.condition
Which part of the procedure handles errors effectively?
Add a check IF w = NULL THEN RETURN "City not found" before accessing fields.
Call GetWeather(city) twice to confirm the API result is consistent.
Change the return to RETURN w so the caller can format the record.
Return "City not found" for every city to avoid runtime errors.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on error handling and null value management. The procedure needs to format weather data from an API that might return NULL for unknown cities, but the student's code doesn't handle this case and would crash when trying to access fields of a NULL value. The current code immediately tries to access w.tempF and w.condition without checking if w is NULL, which would cause a runtime error. Choice A is correct because adding a check IF w = NULL THEN RETURN "City not found" before accessing fields would prevent the crash and provide appropriate error handling. Choice C is incorrect because returning "City not found" for every city would make the procedure useless and wouldn't actually use the weather data. To help students: Teach defensive programming practices and the importance of checking for null/invalid values before using them. Practice identifying potential runtime errors and implementing appropriate error handling strategies, especially when working with external APIs or user input.
Based on the scenario, a student is optimizing a procedure that checks whether a username is already taken. Input: sorted list takenNames (strings, ascending) and string query. Output: Boolean indicating whether query appears in the list. Constraints: list length up to 200,000; list is already sorted; AP-style pseudocode.
A student currently uses:
PROCEDURE IsTaken(takenNames, query)
FOR EACH name IN takenNames
IF name = query
RETURN TRUE
RETURN FALSE
How can the procedure be optimized for better performance?
Reverse the list first, then scan from the beginning for the query.
Use binary search on the sorted list to reduce the number of comparisons.
Check only the first and last elements; if neither matches, return FALSE.
Sort the list again each time the procedure is called to ensure correctness.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on algorithm optimization for searching in sorted data. The current implementation uses linear search, checking every element sequentially, which has O(n) time complexity and is inefficient for large sorted lists of up to 200,000 elements. Since the list is already sorted in ascending order, binary search can dramatically improve performance by repeatedly dividing the search space in half. Choice A is correct because using binary search on the sorted list would reduce the number of comparisons from potentially 200,000 to at most log₂(200,000) ≈ 18, providing O(log n) time complexity. Choice D is incorrect because checking only first and last elements would miss all usernames in between, producing incorrect results. To help students: Teach the advantages of binary search for sorted data and how to recognize when linear search can be replaced with more efficient algorithms. Practice implementing and comparing different search algorithms to understand their trade-offs and appropriate use cases.
Based on the scenario, a school app must display the top 10 highest quiz scores from a list of integers. Input: an array scores of length $n$ (may include duplicates). Output: an array of up to 10 integers sorted in descending order. Constraints: $1 \le n \le 50{,}000$; scores are 0–100; avoid non-standard libraries; use AP-style pseudocode. A student proposes:
PROCEDURE TopTen(scores)
SORT(scores) // sorts ascending
result <- []
FOR i <- LENGTH(scores) - 1 TO MAX(LENGTH(scores) - 10, 0) STEP -1
APPEND(result, scores<u>i</u>)
RETURN result
What is the most efficient way to implement the procedure described while still producing the correct output under the constraints?
Convert scores to a string, sort characters, and then parse the last 10 characters as numbers.
Use nested loops to swap elements until the list is fully sorted, then take the last 10 items.
Scan for the maximum 10 times without removing used values, appending the same max repeatedly.
Sort the list once using a built-in SORT, then iterate from the end to collect up to 10 values.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on algorithm efficiency and correct implementation for finding top values. The task requires creating a procedure that returns the top 10 highest quiz scores from a potentially large array, which involves sorting and selecting elements efficiently. The student's proposed solution sorts the entire array in ascending order using SORT(), then iterates backwards from the end to collect up to 10 values, which correctly produces the top 10 scores in descending order. Choice B is correct because it accurately describes the student's approach: sort the list once using a built-in SORT function, then iterate from the end to collect up to 10 values, which is both efficient and correct. Choice A is incorrect because nested loops for sorting would be much less efficient than using a built-in sort function, especially for arrays up to 50,000 elements. To help students: Emphasize the importance of using built-in functions when available for efficiency, and practice tracing through array indices to ensure correct boundary handling. Teach students to verify their procedures handle edge cases like arrays with fewer than 10 elements.
Based on the scenario, an online store keeps an array prices of decimal numbers. The program must compute the average price of items that cost at least 10.00. Input: list prices. Output: the average of qualifying prices, or 0 if none qualify. Constraints: $n$ up to 100,000; one pass preferred; AP-style pseudocode.
PROCEDURE AvgAtLeastTen(prices)
sum <- 0
count <- 0
FOR EACH p IN prices
IF p >= 10.00
sum <- sum + p
count <- count + 1
IF count = 0
RETURN 0
RETURN sum / count
What is the expected output of the procedure given the input prices = <u>9.99, 10.00, 12.50, 7.00</u>?
0
9.87
10.83
11.25
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on conditional aggregation and calculating averages with filters. The procedure calculates the average price of items costing at least $10.00, handling the edge case where no items qualify. Given prices = [9.99, 10.00, 12.50, 7.00], the procedure processes each price: 9.99 < 10 (skipped), 10.00 >= 10 (sum=10.00, count=1), 12.50 >= 10 (sum=22.50, count=2), 7.00 < 10 (skipped), resulting in sum=22.50 and count=2. Choice B is correct because 22.50 / 2 = 11.25, which is the average of the two qualifying prices (10.00 and 12.50). Choice C (10.83) might result from incorrectly including 9.99, and Choice D (9.87) might come from averaging all prices regardless of the condition. To help students: Emphasize the importance of carefully applying conditions before aggregating values, and practice tracing through calculations step by step. Teach students to verify their filtering logic by listing which values pass the condition before calculating.
Based on the scenario, a classroom tool merges two lists of student IDs. Input: list a and list b, each containing integers (IDs may repeat across lists). Output: a new list containing all IDs from a followed by all IDs from b. Constraints: do not change a or b; preserve order within each list; AP-style pseudocode.
A student writes:
PROCEDURE MergeLists(a, b)
merged <- a
FOR EACH id IN b
APPEND(a, id)
RETURN merged
Which step is necessary to ensure the procedure works correctly?
Sort a and b before merging so the output is always in numeric order.
Initialize merged as an empty list and append items from a and then b into merged.
Append all items from a into b instead, then return b to save memory.
Remove duplicates while merging so each ID appears only once.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on list manipulation and avoiding unintended side effects. The procedure should merge two lists by creating a new list containing all elements from list a followed by all elements from list b, without modifying the original lists. The student's code has a critical error: it sets merged <- a (which creates a reference, not a copy) and then appends to a directly, which modifies the original list a and violates the constraint. Choice A is correct because initializing merged as an empty list and then appending items from both a and b would create a new list without modifying the originals, satisfying all requirements. Choice D is incorrect because appending to b would modify the original list b, violating the constraint not to change the input lists. To help students: Teach the difference between creating references and copies of lists, and emphasize the importance of preserving input data when specifications require it. Practice identifying when procedures have unintended side effects and how to create independent copies of data structures.
Based on the scenario, a game awards points when a player collects coins. Input: integer coinsCollected (may be 0 or more). Output: integer score added for this event. Rules: each coin is worth 10 points; if coinsCollected is at least 5, add a 50-point bonus once. Constraints: handle all nonnegative integers; AP-style pseudocode.
A student writes:
PROCEDURE CoinScore(coinsCollected)
score <- 0
score <- coinsCollected * 10
IF coinsCollected > 5
score <- score + 50
RETURN score
Which step is necessary to ensure the procedure works correctly?
Replace multiplication with repeated addition to avoid arithmetic errors.
Change the condition to IF coinsCollected >= 5 to match the bonus rule.
Initialize score to 50 so the bonus is included by default.
Return coinsCollected instead of score to keep the output small.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on boundary conditions and correct implementation of bonus rules. The procedure calculates a score based on coins collected, with each coin worth 10 points and a bonus of 50 points if at least 5 coins are collected. The student's code has an off-by-one error: it checks if coinsCollected > 5 instead of >= 5, which means the bonus won't be applied when exactly 5 coins are collected. Choice B is correct because changing the condition to IF coinsCollected >= 5 ensures the bonus is applied when the player collects 5 or more coins, matching the stated rule. Choice A is incorrect because initializing score to 50 would give the bonus even when fewer than 5 coins are collected, violating the game rules. To help students: Emphasize the importance of carefully translating 'at least' into >= rather than >, and practice identifying boundary cases in conditional logic. Encourage testing procedures with boundary values (like exactly 5 coins) to catch off-by-one errors.
Based on the scenario, a messaging app must remove blocked users from a list. Input: list usernames (strings) and list blocked (strings). Output: a new list containing only usernames not in blocked, preserving original order. Constraints: $n$ up to 30,000; blocked up to 5,000; do not modify usernames; AP-style pseudocode.
A student writes:
PROCEDURE FilterBlocked(usernames, blocked)
allowed <- []
FOR EACH name IN usernames
IF NOT (name IN blocked)
APPEND(allowed, name)
RETURN allowed
What is the expected output of the procedure given the input usernames = <u>"ava","li","sam","li"</u> and blocked = <u>"li"</u>?
["li", "li"]
["ava", "li", "sam", "li"]
["ava", "sam"]
["sam", "ava"]
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on list filtering and understanding how the IN operator works with lists. The procedure filters out usernames that appear in the blocked list, preserving the order of allowed users. Given usernames = ["ava","li","sam","li"] and blocked = ["li"], the procedure checks each username: "ava" is not in blocked (added), "li" is in blocked (skipped), "sam" is not in blocked (added), and the second "li" is also in blocked (skipped). Choice A is correct because the output would be ["ava", "sam"], containing only the usernames not found in the blocked list, in their original order. Choice B is incorrect because it includes "li" which should be filtered out, and Choice C is incorrect because it shows the blocked users instead of the allowed ones. To help students: Practice tracing through filtering algorithms step by step, and emphasize the importance of understanding what NOT (name IN blocked) means. Teach students to verify their understanding by working through small examples manually before coding.
Based on the scenario, a library system processes a large list of book records books, where each record has fields title (string) and checkedOut (Boolean). Input: list books. Output: list of titles for books that are not checked out, in the same order they appear. Constraints: $n$ can be up to 100,000; do not modify the original books list; use AP-style pseudocode.
A student writes:
PROCEDURE AvailableTitles(books)
titles <- []
FOR EACH book IN books
IF book.checkedOut = TRUE
APPEND(titles, book.title)
RETURN titles
Which step is necessary to ensure the procedure works correctly?
Sort books by title before filtering to avoid missing any records.
Change the condition to append titles only when book.checkedOut = FALSE.
Replace the loop with recursion to reduce the time required for large lists.
Set titles <- NULL so the procedure can detect when no books are available.
Explanation
This question tests AP Computer Science Principles skills in developing procedures, specifically focusing on logical conditions and filtering data correctly. The task requires creating a procedure that returns titles of books that are NOT checked out, but the student's code has a logical error in the condition. The student's code currently checks if book.checkedOut = TRUE and appends those titles, which would return checked-out books instead of available books. Choice A is correct because changing the condition to append titles only when book.checkedOut = FALSE would fix the logical error and return the correct list of available books. Choice B is incorrect because sorting wouldn't fix the logical error, and the problem specification requires preserving the original order anyway. To help students: Teach careful reading of requirements and the importance of testing conditions with sample data. Practice converting English requirements like 'not checked out' into proper Boolean expressions, and encourage students to trace through their code with example inputs to verify correctness.