CPT
College Board Performance Task
NOTE: OUTDATED
Outline of CPT Written response
3 a. 3.a.i. The program provides a game helps create a people know who has played games and when they have played so that they can also see who plays frequently or wins the most.
3.a.ii. The function of the program is to to all the past pong games from most recent to oldest.
3.a.iii. The input will be the usernames of the two players, the score each player earned, the result of each player, and the date the game was played. The output will be the json data that can later be used to create a table sorted from most recent to oldest.
3.b.i.
game1 = Pong('AAA', 'BBB', '1', '5', 'Loss', 'Win', date(2023, 1, 22))
game2 = Pong('AAB', 'ABC', '2', '5', 'Loss', 'Win', date(2023, 1, 21))
game3 = Pong('AAC', 'GHI', '5', '4', 'Win', 'Loss', date(2023, 1, 20))
game4 = Pong('AAD', 'FGH', '5', '1', 'Win', 'Loss', date(2023, 1, 19))
game5 = Pong('AAE', 'TYU', '3','5', 'Loss', 'Win', date(2023, 1, 22))
games = [game1, game2, game3, game4, game5]
3.b.ii.
"""Builds sample user/note(s) data"""
for game in games:
try:
user.create()
except IntegrityError:
'''fails with bad or duplicate data'''
db.session.remove()
print(f"Records exist, duplicate email, or error in {game.user1} and/or {game.user2}")
3.b.iii.
The variable being used to store the list is games
3.b.iv. The data that my list contains represents a game that was played in pong.
3.b.v. The dictionary in the variable body helps to create separate, distinct packets of information specifically for each game played. Without the use of this dictionary, the database would not be able to distinguish which game users participate in. This can make the program code harder to create as there would have to be a separate, more complex algorithm which manually sorts the data already present in the database.
3.c.i.
class PongAPI:
class PongCreate(Resource):
def post(self):
data = request.get_json()
user1 = data.get('user1')
if user1 is None or len(user1) != 3:
return {'message': f'username 1 is missing or longer than 3 characters'}, 210
user2 = data.get('user2')
if user2 is None or len(user2) != 3:
return {'message': f'username 2 is missing or longer than 3 characters'}, 210
# Change later to exclude negative scores
score1 = data.get('score1')
if score1 is None or len(score1) <= 0:
return {'message': f'Score 1 does not exist, is missing, or is invalid'}, 210
score2 = data.get('score2')
if score2 is None or len(score2) <= 0:
return {'message': f'Score 2 does not exist, is missing, or is invalid'}, 210
result1 = data.get('result1')
if result1 is None:
return {'message': f'Game result does not exist or is missing'}, 210
result2 = data.get('result2')
if result2 is None:
return {'message': f'Game result does not exist or is missing'}, 210
scoreDate = data.get('scoreDate')
pongProfile = Pong(user1=user1, user2=user2, score1=score1, score2=score2, result1=result1, result2=result2)
if scoreDate is not None:
try:
pongProfile.scoreDate = datetime.strptime(scoreDate, '%m-%d-%Y').date()
except:
return {'message': f'Date obtained score format error {scoreDate}, must be mm-dd-yyyy'}, 210
user = pongProfile.create()
if user:
return jsonify(user.make_dict())
return {'message': f'Processed {user1} and/or {user2}, either a format error or Usernames {user1} and/or {user2} is duplicate'}, 210
3.c.ii.
function read_users() {
// prepare fetch options
const read_options = {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'default', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'omit', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
},
};
// fetch the data from API
fetch(read_fetch, read_options)
// response is a RESTful "promise" on any successful fetch
.then(response => {
// check for response errors
if (response.status !== 200) {
const errorMsg = 'Database read error: ' + response.status;
console.log(errorMsg);
const tr = document.createElement("tr");
const td = document.createElement("td");
td.innerHTML = errorMsg;
tr.appendChild(td);
resultContainer.appendChild(tr);
return;
}
// valid response will have json data
response.json().then(data => {
console.log(data);
data.sort(function(a, b) {
return new Date(b.scoreDate) - new Date(a.scoreDate);
});
for (let i = 0; i < data.length; i++) {
const row = data[i];
console.log(row);
add_row(row);
}
})
})
// catch fetch errors (ie ACCESS to server blocked)
.catch(err => {
console.error(err);
const tr = document.createElement("tr");
const td = document.createElement("td");
td.innerHTML = err;
tr.appendChild(td);
resultContainer.appendChild(tr);
});
}
function add_row(data) {
const tr = document.createElement("tr");
const user1 = document.createElement("td");
const user2 = document.createElement("td");
const score1 = document.createElement("td");
const score2 = document.createElement("td");
const result1 = document.createElement("td");
const result2 = document.createElement("td");
const scoreDate = document.createElement("td");
// obtain data that is specific to the API
user1.innerHTML = data.user1;
user2.innerHTML = data.user2;
score1.innerHTML = data.score1;
score2.innerHTML = data.score2;
result1.innerHTML = data.result1;
result2.innerHTML = data.result2;
scoreDate.innerHTML = data.scoreDate;
// add HTML to container
tr.appendChild(user1);
tr.appendChild(user2);
tr.appendChild(score1);
tr.appendChild(score2);
tr.appendChild(result1);
tr.appendChild(result2);
tr.appendChild(scoreDate);
resultContainer.appendChild(tr);
}
3.c.iii. The procedure add_row() adds a row on the table of the game history, and displays the user1, user2, score1, score2, result1, result2, and date based on the user’s inputs and the data from the API or the pong game. This helps to display the data from user inputs and other inputs onto the game history so that other users are able to see the past games.
3.c.iv. The algorithm fetches the API using its URL to execute the GET method. It then checks that a successful fetch will be guaranteed, and if it is, then a response is carried out. An if statement is used to check if the response has an error with reading the database. If there is an error, an error message is displayed on the table of the game history, and the entire function fetching the API is stopped. However, if there is no error, the algorithm proceeds to check that the response contains JSON data. If it does contain JSON data, the algorithm proceeds to sort the users, where the most recent game is displayed first and the oldest game is displayed last. Finally, the algorithm checks for any fetch errors, and if there is a fetch error, an error message is displayed onto the table of the game history.
3.d.i. First Call: The first call is when the user clicks submit to submit information from the completed game.
Second Call: The second call is when the user clicks on the game history page, which calls the read_games function that displays the past games from most recent to oldest
3.d.ii Condition(s) tested by first call: The first call checks the errors and successfully determines that there are no errors with fetching the data. If there are no errors, the API will add the game to the database.
Condition(s) tested by second call: The second call checks fetch errors using the .catch() command. Since if no errors are found, it will use the database and the arguments of the data to create the table.
3.d.iii Results of first call: The first call displays that the game has successfully been added to the database games
Results of the second call: The page shows sorts the database from the newest game recorded to the oldest.