5 Great AP CSP Create Task Project Ideas | Easy AP Computer Science Principles Projects

AP CSP Create Performance Task 2025

5 AP CSP Create Task Project Ideas That Score Full Marks

Beginner-friendly project ideas with rubric mapping, starter code in Python, JavaScript, and Code.org App Lab, plus step-by-step guidance from an AP CS teacher with 11+ years of experience.

5 Proven Project Ideas
100% Rubric Coverage
30% Of Your AP Score
9 hrs In-Class Time

The AP Computer Science Principles Create Performance Task counts for 30% of your AP score, making it one of the highest-impact assignments of the year. You get 9 hours of in-class time to build a program, record a video, and create your Personalized Project Reference (PPR).

The biggest mistake students make is choosing a project that is too complex. The College Board graders follow a strict rubric, and they only give credit for what you explicitly show and explain. A simple, well-documented project beats an ambitious but unclear one every time.

Below are five project ideas that naturally satisfy every rubric requirement while being straightforward enough to complete, test, and explain within the time limit. Each includes a rubric mapping, starter code in Python, JavaScript, and Code.org App Lab, and specific tips for the video and written responses.

What the Create Task Rubric Actually Requires

Before picking a project, you need to understand exactly what the graders are looking for. The Create Task has three components you submit to the AP Digital Portfolio, plus written responses you answer on exam day using your Personalized Project Reference.

The 3 Submission Components

  1. Program Code — Your complete, working program
  2. Video — 1 minute max showing your program running with input and output
  3. Personalized Project Reference (PPR) — Screenshots of your procedure and list code segments (no comments allowed)

Your code must include all of the following technical elements. If even one is missing or unclear, you will lose points:

Requirement What It Means Where You Show It
Input Your program accepts data from the user (text input, button click, slider, etc.) Video + Code
Output Your program displays a result based on the input Video + Code
List (or collection) Data is stored in a list, array, dictionary, or database and used meaningfully PPR + Code
Procedure with parameter A function/procedure you wrote that takes at least one parameter PPR + Code
Algorithm with sequencing, selection, AND iteration Your procedure must contain all three: steps in order, an if/else, and a loop PPR + Written Response
Critical: The algorithm with sequencing, selection, and iteration must be inside your procedure. If your loop is outside the function, or your if-statement is in a different part of the code, you will not earn full credit. Plan this carefully before writing any code.

Which Language Should You Use?

The College Board accepts any programming language. Every project below includes starter code in three options. Use the tabs to switch between them:

  • Python — Best if your class uses IDLE, Replit, or a text-based environment. Cleanest syntax for beginners.
  • Code.org App Lab — Best if your class uses Code.org. Uses event-driven programming with onEvent(), getText(), setText(), and appendItem(). You build the UI in Design Mode and write logic in Code Mode.
  • JavaScript — Best if you are using a standalone editor or want standard JS syntax with prompt() and console.log().
App Lab users: The App Lab examples use Code.org-specific functions like onEvent(), setText(), getText(), getNumber(), and appendItem(). These only work inside Code.org App Lab. The examples include comments showing which UI elements to create in Design Mode before writing code.

Project 1: Personal Budget Tracker

1 Easy

Personal Budget Tracker

Users input expenses and income, and the program calculates savings, flags overspending, and displays a summary.

How It Meets the Rubric

Input / Output
User enters expense categories and amounts → program outputs total savings and budget status
List
Stores all expense amounts in a list to process later
Procedure + Parameter
calculateSavings(income, expenses) takes income and expense list as parameters
Sequencing + Selection + Iteration
Loops through expense list (iteration), checks if total exceeds income (selection), calculates result (sequencing)

Starter Code

def calculateSavings(income, expenses):
    total_spent = 0
    for expense in expenses:
        total_spent = total_spent + expense
    savings = income - total_spent
    if savings < 0:
        return "Over budget by $" + str(abs(savings))
    else:
        return "You saved $" + str(savings)

# --- Main Program ---
income = float(input("Enter your monthly income: "))
expenses = []
num = int(input("How many expenses? "))
for i in range(num):
    amt = float(input("Enter expense amount: "))
    expenses.append(amt)

result = calculateSavings(income, expenses)
print(result)
// Use Design Mode to create:
// textInput "incomeInput", textInput "expenseInput"
// button "addBtn", button "calcBtn"
// textLabel "resultLabel"
var expenses = [];
function calculateSavings(income, expenseList) {
var totalSpent = 0;
for (var i = 0; i < expenseList.length; i++) {
totalSpent = totalSpent + expenseList[i];
}
var savings = income - totalSpent;
if (savings < 0) {
setText("resultLabel", "Over budget by $" + Math.abs(savings));
} else {
setText("resultLabel", "You saved $" + savings);
}
}
onEvent("addBtn", "click", function() {
var amt = getNumber("expenseInput");
appendItem(expenses, amt);
setText("expenseInput", "");
});
onEvent("calcBtn", "click", function() {
var income = getNumber("incomeInput");
calculateSavings(income, expenses);
});
App Lab tip: Use Design Mode to drag in your UI elements (text inputs, buttons, labels), then switch to Code Mode to write the logic. The element IDs in Design Mode must match the IDs in your code.
function calculateSavings(income, expenses) {
  var totalSpent = 0;
  for (var i = 0; i < expenses.length; i++) {
    totalSpent = totalSpent + expenses[i];
  }
  var savings = income - totalSpent;
  if (savings < 0) {
    return "Over budget by $" + Math.abs(savings);
  } else {
    return "You saved $" + savings;
  }
}

// --- Main Program ---
var income = parseFloat(prompt("Enter your monthly income:"));
var expenses = [];
var num = parseInt(prompt("How many expenses?"));
for (var i = 0; i < num; i++) {
  var amt = parseFloat(prompt("Enter expense amount:"));
  expenses.push(amt);
}

var result = calculateSavings(income, expenses);
console.log(result);
Why this scores well: Real-world relevance makes the video easy to narrate. The procedure naturally contains all three algorithmic elements (the for loop, the if/else, and the sequential math). Simple to test with different inputs and demonstrate edge cases like zero expenses or negative savings.

Project 2: Trivia Quiz Game

2 Easy

Trivia Quiz Game

Users answer multiple-choice questions stored in a list, and the program tracks their score and provides feedback after each question.

How It Meets the Rubric

Input / Output
User selects an answer → program outputs correct/incorrect and final score
List
Stores questions and correct answers in parallel lists
Procedure + Parameter
runQuiz(questions, answers) takes question and answer lists as parameters
Sequencing + Selection + Iteration
Loops through each question (iteration), compares user input to correct answer (selection), tallies score (sequencing)

Starter Code

def runQuiz(questions, answers):
    score = 0
    for i in range(len(questions)):
        print(questions[i])
        userAnswer = input("Your answer: ")
        if userAnswer.lower() == answers[i].lower():
            print("Correct!")
            score = score + 1
        else:
            print("Wrong. Answer: " + answers[i])
    return score

# --- Main Program ---
questions = [
    "What does CPU stand for?",
    "What number system do computers use?",
    "What does HTML stand for?"
]
answers = [
    "Central Processing Unit",
    "Binary",
    "HyperText Markup Language"
]

finalScore = runQuiz(questions, answers)
print("You got " + str(finalScore) + "/" + str(len(questions)))
// Use Design Mode to create:
// textLabel "questionLabel", textInput "answerInput"
// button "submitBtn", textLabel "feedbackLabel"
// textLabel "scoreLabel"
var questions = ["What does CPU stand for?",
"What number system do computers use?",
"What does HTML stand for?"];
var answers = ["Central Processing Unit",
"Binary", "HyperText Markup Language"];
var currentQ = 0;
var score = 0;
function checkAnswer(userAnswer, questionIndex) {
var correct = answers[questionIndex];
if (userAnswer.toLowerCase() == correct.toLowerCase()) {
setText("feedbackLabel", "Correct!");
score = score + 1;
} else {
setText("feedbackLabel", "Wrong. Answer: " + correct);
}
}
function showQuestion() {
if (currentQ < questions.length) {
setText("questionLabel", questions[currentQ]);
setText("answerInput", "");
setText("feedbackLabel", "");
} else {
setText("questionLabel", "Quiz Complete!");
setText("scoreLabel", score + "/" + questions.length);
}
}
onEvent("submitBtn", "click", function() {
var userAns = getText("answerInput");
checkAnswer(userAns, currentQ);
currentQ = currentQ + 1;
showQuestion();
});
showQuestion();
App Lab tip: This uses an event-driven pattern with onEvent instead of a simple loop, which is the natural way to build apps in App Lab. Each button click advances to the next question.
function runQuiz(questions, answers) {
  var score = 0;
  for (var i = 0; i < questions.length; i++) {
    var userAnswer = prompt(questions[i]);
    if (userAnswer.toLowerCase() == answers[i].toLowerCase()) {
      console.log("Correct!");
      score = score + 1;
    } else {
      console.log("Wrong. Answer: " + answers[i]);
    }
  }
  return score;
}

// --- Main Program ---
var questions = [
  "What does CPU stand for?",
  "What number system do computers use?",
  "What does HTML stand for?"
];
var answers = [
  "Central Processing Unit",
  "Binary",
  "HyperText Markup Language"
];

var finalScore = runQuiz(questions, answers);
console.log("You got " + finalScore + "/" + questions.length);
Why this scores well: The video is engaging and easy to follow since the grader can see each question and answer cycle. The parallel lists demonstrate meaningful data storage. Adding more questions is trivial, making it easy to show thorough testing with different inputs.

Project 3: Weather Clothing Recommender

3 Easy

Weather Clothing Recommender

Users enter the current temperature and weather conditions, and the program recommends appropriate clothing from a stored list of options.

How It Meets the Rubric

Input / Output
User enters temperature and condition → program outputs clothing recommendations
List
Stores clothing items as a list, filtered by weather conditions
Procedure + Parameter
recommendClothing(temp, condition, clothingList) takes multiple parameters
Sequencing + Selection + Iteration
Loops through clothing list (iteration), filters by temperature range (selection), builds recommendation (sequencing)

Starter Code

def recommendClothing(temp, condition, clothingList):
    recommendations = []
    for item in clothingList:
        if temp < 40 and item["warmth"] == "heavy":
            recommendations.append(item["name"])
        elif temp >= 40 and temp < 70 and item["warmth"] == "medium":
            recommendations.append(item["name"])
        elif temp >= 70 and item["warmth"] == "light":
            recommendations.append(item["name"])
    if condition == "rainy":
        recommendations.append("Umbrella")
    return recommendations

# --- Main Program ---
clothing = [
    {"name": "Winter Coat", "warmth": "heavy"},
    {"name": "Hoodie", "warmth": "medium"},
    {"name": "T-shirt", "warmth": "light"},
    {"name": "Scarf", "warmth": "heavy"},
    {"name": "Light Jacket", "warmth": "medium"},
    {"name": "Shorts", "warmth": "light"}
]

temp = int(input("Current temperature (F): "))
condition = input("Weather (sunny/rainy/cloudy): ")
result = recommendClothing(temp, condition, clothing)
print("Wear: " + ", ".join(result))
// Use Design Mode to create:
// textInput "tempInput", dropdown "conditionDrop"
// button "recommendBtn", textLabel "resultLabel"
var clothingNames = ["Winter Coat", "Hoodie", "T-shirt",
"Scarf", "Light Jacket", "Shorts"];
var clothingWarmth = ["heavy", "medium", "light",
"heavy", "medium", "light"];
function recommendClothing(temp, condition) {
var recommendations = [];
for (var i = 0; i < clothingNames.length; i++) {
if (temp < 40 && clothingWarmth[i] == "heavy") {
appendItem(recommendations, clothingNames[i]);
} else if (temp >= 40 && temp < 70 &&
clothingWarmth[i] == "medium") {
appendItem(recommendations, clothingNames[i]);
} else if (temp >= 70 && clothingWarmth[i] == "light") {
appendItem(recommendations, clothingNames[i]);
}
}
if (condition == "rainy") {
appendItem(recommendations, "Umbrella");
}
var output = "";
for (var j = 0; j < recommendations.length; j++) {
output = output + recommendations[j] + ", ";
}
setText("resultLabel", "Wear: " + output);
}
onEvent("recommendBtn", "click", function() {
var temp = getNumber("tempInput");
var cond = getText("conditionDrop");
recommendClothing(temp, cond);
});
App Lab tip: App Lab does not support dictionaries/objects in lists well. Use parallel lists instead (one for names, one for warmth levels). This is a common pattern in Code.org projects and is perfectly valid for the Create Task.
function recommendClothing(temp, condition, clothingList) {
  var recommendations = [];
  for (var i = 0; i < clothingList.length; i++) {
    var item = clothingList[i];
    if (temp < 40 && item.warmth == "heavy") {
      recommendations.push(item.name);
    } else if (temp >= 40 && temp < 70 &&
               item.warmth == "medium") {
      recommendations.push(item.name);
    } else if (temp >= 70 && item.warmth == "light") {
      recommendations.push(item.name);
    }
  }
  if (condition == "rainy") {
    recommendations.push("Umbrella");
  }
  return recommendations;
}

// --- Main Program ---
var clothing = [
  {name: "Winter Coat", warmth: "heavy"},
  {name: "Hoodie", warmth: "medium"},
  {name: "T-shirt", warmth: "light"},
  {name: "Scarf", warmth: "heavy"},
  {name: "Light Jacket", warmth: "medium"},
  {name: "Shorts", warmth: "light"}
];

var temp = parseInt(prompt("Current temperature (F):"));
var condition = prompt("Weather (sunny/rainy/cloudy):");
var result = recommendClothing(temp, condition, clothing);
console.log("Wear: " + result.join(", "));
Why this scores well: The dictionary-based list shows sophistication beyond a basic list of strings. Multiple parameters demonstrate strong procedural abstraction. Easy to test with extreme temperatures (0, 50, 100) and different weather conditions for your video.

Project 4: Grade Analyzer App

4 Easy

Grade Analyzer App

Students input their grades, and the program calculates the average, assigns a letter grade, and identifies the highest and lowest scores.

How It Meets the Rubric

Input / Output
User enters numeric grades → program outputs average, letter grade, and min/max
List
Stores all entered grades in a list for processing
Procedure + Parameter
analyzeGrades(gradeList) takes the list of grades as a parameter
Sequencing + Selection + Iteration
Loops through grades to sum them (iteration), checks thresholds for letter grade (selection), computes average (sequencing)

Starter Code

def analyzeGrades(gradeList):
    total = 0
    highest = gradeList[0]
    lowest = gradeList[0]
    for grade in gradeList:
        total = total + grade
        if grade > highest:
            highest = grade
        if grade < lowest:
            lowest = grade
    average = total / len(gradeList)
    if average >= 90:
        letter = "A"
    elif average >= 80:
        letter = "B"
    elif average >= 70:
        letter = "C"
    elif average >= 60:
        letter = "D"
    else:
        letter = "F"
    return str(average) + " (" + letter + ") | High: " + str(highest) + " Low: " + str(lowest)

# --- Main Program ---
grades = []
num = int(input("How many grades? "))
for i in range(num):
    g = float(input("Enter grade: "))
    grades.append(g)

print(analyzeGrades(grades))
// Use Design Mode to create:
// textInput "gradeInput", button "addGradeBtn"
// button "analyzeBtn", textLabel "resultLabel"
// textLabel "gradeListLabel"
var grades = [];
function analyzeGrades(gradeList) {
var total = 0;
var highest = gradeList[0];
var lowest = gradeList[0];
for (var i = 0; i < gradeList.length; i++) {
total = total + gradeList[i];
if (gradeList[i] > highest) {
highest = gradeList[i];
}
if (gradeList[i] < lowest) {
lowest = gradeList[i];
}
}
var average = total / gradeList.length;
var letter;
if (average >= 90) {
letter = "A";
} else if (average >= 80) {
letter = "B";
} else if (average >= 70) {
letter = "C";
} else if (average >= 60) {
letter = "D";
} else {
letter = "F";
}
setText("resultLabel", average + " (" + letter +
") | High: " + highest + " Low: " + lowest);
}
onEvent("addGradeBtn", "click", function() {
var g = getNumber("gradeInput");
appendItem(grades, g);
setText("gradeListLabel", "Grades: " + grades);
setText("gradeInput", "");
});
onEvent("analyzeBtn", "click", function() {
analyzeGrades(grades);
});
App Lab tip: Use getNumber() instead of getText() when you need numeric input. This avoids having to convert strings to numbers manually.
function analyzeGrades(gradeList) {
  var total = 0;
  var highest = gradeList[0];
  var lowest = gradeList[0];
  for (var i = 0; i < gradeList.length; i++) {
    total = total + gradeList[i];
    if (gradeList[i] > highest) {
      highest = gradeList[i];
    }
    if (gradeList[i] < lowest) {
      lowest = gradeList[i];
    }
  }
  var average = total / gradeList.length;
  var letter;
  if (average >= 90) { letter = "A"; }
  else if (average >= 80) { letter = "B"; }
  else if (average >= 70) { letter = "C"; }
  else if (average >= 60) { letter = "D"; }
  else { letter = "F"; }
  return average + " (" + letter + ") | High: "
    + highest + " Low: " + lowest;
}

// --- Main Program ---
var grades = [];
var num = parseInt(prompt("How many grades?"));
for (var i = 0; i < num; i++) {
  var g = parseFloat(prompt("Enter grade:"));
  grades.push(g);
}

console.log(analyzeGrades(grades));
Why this scores well: The procedure is rich with algorithmic complexity (loop, multiple if/elif branches, sequential calculations) all in one function, which is exactly what the rubric requires. Relatable to every student, so the written response about purpose and functionality practically writes itself.

Project 5: Fitness Step Tracker

5 Medium

Fitness Step Tracker

Users log daily step counts over a week, and the program analyzes progress against a goal, showing which days met the target and calculating the overall completion rate.

How It Meets the Rubric

Input / Output
User inputs daily step counts → program outputs progress report and goal status
List
Stores each day's step count in a list
Procedure + Parameter
analyzeSteps(stepList, dailyGoal) takes steps and goal as parameters
Sequencing + Selection + Iteration
Loops through each day (iteration), checks if steps met goal (selection), calculates percentage (sequencing)

Starter Code

def analyzeSteps(stepList, dailyGoal):
    daysMetGoal = 0
    totalSteps = 0
    for i in range(len(stepList)):
        totalSteps = totalSteps + stepList[i]
        if stepList[i] >= dailyGoal:
            print("Day " + str(i + 1) + ": " + str(stepList[i]) + " - Goal met!")
            daysMetGoal = daysMetGoal + 1
        else:
            print("Day " + str(i + 1) + ": " + str(stepList[i]) + " - Below goal")
    percentage = (daysMetGoal / len(stepList)) * 100
    return str(daysMetGoal) + "/" + str(len(stepList)) + " days (" + str(percentage) + "%)"

# --- Main Program ---
steps = []
goal = int(input("Enter your daily step goal: "))
days = int(input("How many days to log? "))
for i in range(days):
    s = int(input("Steps for day " + str(i + 1) + ": "))
    steps.append(s)

summary = analyzeSteps(steps, goal)
print("Summary: " + summary)
// Use Design Mode to create:
// textInput "goalInput", textInput "stepsInput"
// button "addDayBtn", button "analyzeBtn"
// textLabel "logLabel", textLabel "resultLabel"
var steps = [];
var dayCount = 0;
function analyzeSteps(stepList, dailyGoal) {
var daysMetGoal = 0;
var totalSteps = 0;
var report = "";
for (var i = 0; i < stepList.length; i++) {
totalSteps = totalSteps + stepList[i];
if (stepList[i] >= dailyGoal) {
report = report + "Day " + (i + 1) + ": " +
stepList[i] + " - Goal met!\n";
daysMetGoal = daysMetGoal + 1;
} else {
report = report + "Day " + (i + 1) + ": " +
stepList[i] + " - Below goal\n";
}
}
var pct = (daysMetGoal / stepList.length) * 100;
setText("logLabel", report);
setText("resultLabel", daysMetGoal + "/" +
stepList.length + " days (" + pct + "%)");
}
onEvent("addDayBtn", "click", function() {
dayCount = dayCount + 1;
var s = getNumber("stepsInput");
appendItem(steps, s);
setText("stepsInput", "");
setText("logLabel", "Days logged: " + dayCount);
});
onEvent("analyzeBtn", "click", function() {
var goal = getNumber("goalInput");
analyzeSteps(steps, goal);
});
App Lab tip: Build the UI so students add one day at a time, then click "Analyze" when done. This event-driven approach works naturally with App Lab and makes for a clear, step-by-step video demonstration.
function analyzeSteps(stepList, dailyGoal) {
  var daysMetGoal = 0;
  var totalSteps = 0;
  for (var i = 0; i < stepList.length; i++) {
    totalSteps = totalSteps + stepList[i];
    if (stepList[i] >= dailyGoal) {
      console.log("Day " + (i + 1) + ": " +
        stepList[i] + " - Goal met!");
      daysMetGoal = daysMetGoal + 1;
    } else {
      console.log("Day " + (i + 1) + ": " +
        stepList[i] + " - Below goal");
    }
  }
  var pct = (daysMetGoal / stepList.length) * 100;
  return daysMetGoal + "/" + stepList.length +
    " days (" + pct + "%)";
}

// --- Main Program ---
var steps = [];
var goal = parseInt(prompt("Enter daily step goal:"));
var days = parseInt(prompt("How many days to log?"));
for (var i = 0; i < days; i++) {
  var s = parseInt(prompt("Steps for day " + (i+1) + ":"));
  steps.push(s);
}

var summary = analyzeSteps(steps, goal);
console.log("Summary: " + summary);
Why this scores well: Great for personalization since every student can relate to fitness goals. The per-day output in the video makes the program visually engaging and clearly demonstrates the loop running. Multiple test cases are intuitive: try a low goal everyone meets, a high goal nobody meets, and a mixed result.

Complete Rubric Checklist: Verify Before You Submit

Use this table to map every rubric requirement to a specific location in your project. If you cannot point to explicit evidence for each row, fix it before submitting.

Rubric Row Requirement Evidence Location Status
Row 1 Program accepts input from user Video shows user typing/clicking input
Row 2 Program produces output based on input Video shows result after input
Row 3 Program uses a list (or collection type) PPR screenshot of list code
Row 4 Data stored in list is used to fulfill the program purpose PPR + Written Response
Row 5 Student-developed procedure with at least one parameter PPR screenshot of procedure
Row 6 Procedure contains an algorithm with sequencing, selection, AND iteration PPR + Written Response
Pro Tip from 11 Years of AP CS Teaching: Print this checklist and tape it next to your screen while you work. After finishing your code, go row by row and confirm each requirement is explicitly met. Do not assume the grader will interpret or connect dots for you.

5 Mistakes That Cost Students Points Every Year

Mistake 1: Algorithm is outside the procedure. Your loop and if-statement must be inside the function you submit in your PPR. If you have a loop in your main program but your function only does simple math, you will not earn the algorithm point.
Mistake 2: List is only initialized but never used meaningfully. Creating a list is not enough. Your program must traverse the list (loop through it) and use the data to produce the output. The grader needs to see the list connected to your program's purpose.
Mistake 3: Video does not show both input AND output. You have 1 minute. Plan your video to clearly show: the program starts, you provide input, the program processes it, and the output appears. No background music, no long introductions.
Mistake 4: PPR includes comments in code segments. The College Board explicitly states that your Personalized Project Reference code segments must not include comments. Remove all comments before taking your screenshots.
Mistake 5: Project is too ambitious and unfinished. A complete, simple program will always outscore an incomplete, complex one. If your program crashes or has untested features, you lose points. Keep it simple and make it bulletproof.

Video and Written Response Tips

Recording Your 1-Minute Video

Your video is the primary proof that your program works. Follow this structure:

  1. 0:00-0:05 — Show the program launching (screen recording, not phone recording of screen)
  2. 0:05-0:25 — Demonstrate the input: type values, click buttons, or select options
  3. 0:25-0:45 — Show the output: the result of your program running with that input
  4. 0:45-0:60 — Optionally show a second run with different input to demonstrate versatility
Keep it simple: No voice narration is required (but is allowed). No title slides. No transitions. Just a clean screen recording of your program running. Use a free tool like OBS Studio or the built-in screen recorder on your device.

Preparing for Written Response Questions on Exam Day

On exam day, you will answer written response questions about your Create Task using your Personalized Project Reference. You need to be ready to explain:

  • The purpose of your program and what problem it solves
  • How your list manages complexity (why a list instead of separate variables)
  • How your procedure contributes to the program and what it does
  • How your algorithm works step by step (sequencing, selection, iteration)
  • How you tested your program and what different inputs you tried
Language tip: Mirror the rubric language in your written responses. If the rubric says "manages complexity," use that exact phrase. If it says "sequencing, selection, and iteration," use those exact words. Do not force the grader to translate your language.

Want the Full Interactive Create Task Guide?

Get complete working code for 3 projects in Python and JavaScript, a rubric mapping tool, and video recording tips.

View Complete Guide Strategy and Execution Tips

Frequently Asked Questions

Can I use one of these exact project ideas for my Create Task?

Yes, you can use any of these ideas. However, you must write all the code yourself during the designated in-class time. You cannot copy code from this page or any other source and submit it as your own. Use these as inspiration and starting frameworks, then build your own version.

What programming language should I use?

The College Board accepts any programming language. The most common choices are Python and JavaScript (especially if you use Code.org). The examples on this page use Python because it is the most readable, but all five projects work in any language. Choose the language you know best.

How long should my program be?

There is no minimum or maximum length. A well-written program that clearly satisfies all rubric requirements might be 30-50 lines of code. Do not pad your code with unnecessary features. Complexity does not earn extra points; clarity does.

Can I use AI tools like ChatGPT to help write my code?

The College Board allows the use of AI tools but requires full disclosure. You must acknowledge any AI assistance and be able to explain every line of code in your written responses. If you cannot explain what your code does, you will struggle on exam day. The safest approach is to write your own code and use AI only for debugging help.

What is the Personalized Project Reference (PPR)?

The PPR is a document you create containing screenshots of two specific code segments from your program: one showing your list and how it is used, and one showing your procedure. These screenshots must not include comments. You submit the PPR to the AP Digital Portfolio, and a printed version is given to you on exam day to reference while answering written response questions.

When is the Create Task due?

Your teacher sets the exact deadline, but all Create Task components must be submitted as final in the AP Digital Portfolio before the College Board deadline (typically late April). Check with your teacher for your school's specific due date and plan accordingly.

Can I work with a partner on the Create Task?

No. The Create Performance Task is an individual assessment. You must write all code, record your video, and create your PPR independently. You may discuss general concepts with classmates, but the work you submit must be entirely your own.

More AP CSP Resources

Written by Tanner Crow

AP Computer Science teacher at Blue Valley North High School with 11+ years of classroom experience. Tanner has completed 1,800+ verified tutoring hours on Wyzant with a 5.0 rating from 440+ reviews. His students consistently outperform national averages: 54.5% score 5s on the AP CSA exam compared to 25.5% nationally.

11+ years teaching | 1,800+ tutoring hours | 5.0 rating (440+ reviews)

Need 1-on-1 Help With Your Create Task?

Get personalized tutoring from an AP CS teacher with a 98.4% 5-star rating and 1,800+ hours of verified experience.

Schedule Tutoring ($150/hr) Browse Free CSP Resources
Back to blog

Leave a comment

Please note, comments need to be approved before they are published.