PPR Notebook
PPR 1:
- Defines the procedure’s name and return type (if necessary).
- Contains and uses one or more parameters that have an effect on the functionality of the procedure.
- Implements an algorithm that includes:
- Sequencing
- Selection
- Iteration
function renderCalendar() {
const monthYear = document.getElementById("month-year");
const calendarDays = document.getElementById("calendar-days");
monthYear.textContent = `${new Date(currentYear, currentMonth).toLocaleString('default', { month: 'long' })} ${currentYear}`;
calendarDays.innerHTML = "";
const firstDay = new Date(currentYear, currentMonth, 1).getDay();
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
for (let i = 0; i < firstDay; i++) {
calendarDays.appendChild(document.createElement("div"));
}
for (let day = 1; day <= daysInMonth; day++) {
const dayCell = document.createElement("div");
dayCell.classList.add("day");
dayCell.textContent = day;
const formattedDate = `${currentYear}-${String(currentMonth + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
const eventsOnDay = events.filter(event => new Date(event.date).toISOString().split("T")[0] === formattedDate);
if (eventsOnDay.length > 0) {
dayCell.classList.add("event-day");
eventsOnDay.forEach(event => {
const emoji = document.createElement("div");
emoji.classList.add("event-emoji");
emoji.textContent = "❗";
emoji.title = `${event.name} @ ${event.location}`;
dayCell.appendChild(emoji);
});
}
dayCell.addEventListener("click", () => {
document.getElementById("startDate").value = formattedDate;
});
calendarDays.appendChild(dayCell);
}
}
Why This Works
Defines a Student-Developed Procedure
- The function
renderCalendar()
is a student-developed procedure with a meaningful name. - It is responsible for dynamically generating a calendar layout based on the current month and year.
Uses Parameters That Affect Functionality
- The function relies on two global parameters:
currentYear
andcurrentMonth
. - These parameters determine which month’s calendar is displayed, affecting the output.
Implements an Algorithm That Includes:
Sequencing (Step-by-step execution)
- The function first updates the month-year display.
- Then, it clears the previous calendar content.
- It determines the number of days in the month and iterates to create the calendar structure.
Selection (Conditional logic)
- The
if (eventsOnDay.length > 0)
statement checks if there are events on a particular day. - If events exist, it marks the day and adds an emoji to indicate an event.
Iteration (Loops)
- A
for
loop (for (let i = 0; i < firstDay; i++)
) adds empty placeholders for days before the first of the month. - Another
for
loop (for (let day = 1; day <= daysInMonth; day++)
) iterates through all the days in the month, generating a calendar cell for each. - The
.forEach(event => {...})
inside the selection statement iterates through events occurring on a given day.
This function effectively meets all rubric requirements for the AP CSP PPR submission.
PPR 2
The second program code segment must show where your student-developed procedure is being called in your program.
window.changeMonth = function (direction) {
currentMonth += direction;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
} else if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
fetchEvents(); // Fetch events for the new month
renderCalendar(); // Update the calendar view immediately
};
Why This Works:
renderCalendar()
is called insidechangeMonth()
, ensuring that the calendar updates dynamically when the user navigates between months.- This demonstrates how the student-developed procedure is integrated into the program’s functionality.
- The function updates
currentMonth
andcurrentYear
, fetches events for the new month, and then callsrenderCalendar()
to reflect the changes.
PPR 3
The first program code segment must show how data have been stored in the list.
document.getElementById("eventForm").addEventListener("submit", async function(event) {
event.preventDefault();
const postData = {
name: document.getElementById("eventName").value,
location: document.getElementById("eventLocation").value,
date: document.getElementById("startDate").value, // YYYY-MM-DD format
};
console.log("Event Data:", postData); // Log event data for debugging
try {
const response = await fetch(`${pythonURI}/api/event`, {
...fetchOptions,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(postData)
});
if (!response.ok) {
const errorMessage = await response.text();
throw new Error(`Failed to add event: ${response.statusText} - ${errorMessage}`);
}
const createdEvent = await response.json();
alert("Event added successfully!");
if (createdEvent.id) {
events.push(createdEvent); // ✅ Storing the new event in the list
renderCalendar(); // Update calendar display
displayEvents(); // Show updated event list
} else {
console.error("Error: Event created but no ID returned from API");
}
this.reset(); // Clear the form
} catch (error) {
console.error("Error:", error);
alert("Error adding event. Please try again.");
}
});
Why This Works:
- The
events
list is used to store newly added events. - The
push()
method adds new events to the list. - The stored events are later displayed in the calendar and event list.
PPR 4
The second program code segment must show the data in the same list being used, such as creating new data from the existing data or accessing multiple elements in the list, as part of fulfilling the program’s purpose.
const eventsOnDay = events.filter(event =>
new Date(event.date).toISOString().split("T")[0] === formattedDate
);
if (eventsOnDay.length > 0) {
dayCell.classList.add("event-day");
eventsOnDay.forEach(event => {
const emoji = document.createElement("div");
emoji.classList.add("event-emoji");
emoji.textContent = "❗";
emoji.title = `${event.name} @ ${event.location}`;
dayCell.appendChild(emoji);
});
}
Why This Works:
- The
events
list is used to retrieve events occurring on a specific day. - The
.filter()
method accesses multiple elements in the list to check for matching dates. - The retrieved events are then displayed in the calendar, fulfilling the program’s purpose of tracking and visualizing events.