Open rachit-j opened 2 months ago
For this checkpoint I addressed all the goals I had from last time.
The problem here is that my API would display the score correctly given an integer input, however my implementation/request in JS on the frontend would return with NaN
I did some debugging and created testing.html on frontend and got requests to become functional
I had to research and consult chatGPT about this because I had not received an error like this before, especially when postman was functional
I found that the issue wasn't that the return was a double, it was because my url was initialized incorrectly to take inputs of csaPoints . So the return was of null type not int type.
Here are the changes I made:
Backend (PredictionController.java)
@GetMapping("/api/predictAPScore")
public double predictAPScore(@RequestParam int csaPoints) {
// Call predictAPScore method of the prediction model
return predictionModel.predictAPScore(csaPoints);
}
Frontend (testing and dashboard)
function predictAndDisplayAPScore(csaPoints) {
console.log("Sending request with csaPoints:", csaPoints);
fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints)
.then(response => {
console.log("Received response:", response);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log("Received data:", data);
// Ensure the predicted AP score is between 1 and 5
const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5);
document.getElementById("predictedAPScoreDisplay").innerText =
Predicted AP Score: ${predictedAPScore}
;
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.';
});
}
function predictAndDisplayAPScore(csaPoints) {
console.log("Sending request with csaPoints:", csaPoints);
fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints)
.then(response => {
console.log("Received response:", response);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log("Received data:", data);
// Ensure the predicted AP score is between 1 and 5
const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5);
document.getElementById("predictedAPScoreDisplay").innerText =
Predicted AP Score: ${predictedAPScore}
;
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.';
});
}
years = [int(year) for year in data.keys()]
x = [entry["y"] for entry in data.values()]
y = [entry["x"] for entry in data.values()]
trace_temperature = go.Scatter( x=x, y=y, mode='markers', name='A' )
trace_rainfall = go.Scatter( x=x, y=y, mode='markers', name='B' )
layout = go.Layout( title='Title', xaxis=dict(title='x'), yaxis=dict(title='y'), hovermode='closest' )
fig = go.Figure(data=[x, y], layout=layout)
plotly.offline.plot(fig, filename='tester.html', auto_open=False)
parsed_data = json.loads(data)
years = list(parsed_data['Data'].keys()) populations = list(parsed_data['Data'].values())
fig = go.Figure(data=[go.Bar( x=x, y=y, marker=dict(color='rgb(138, 174, 235)', line=dict(color='rgb(8, 8, 97)', width=1.5)), )]) fig.update_layout( title='TITLE', xaxis=dict(title='X'), yaxis=dict(title='Y'), plot_bgcolor='rgba(0,0,0,0)', showlegend=False, ) fig.write_html('test.html')
Final implementation :
The testing in the frontend python chart files to add this functionality coupled with the final implementation in the frontend with differing js took ___ hours
I also added a slider which calls the predict function again in the backend so players can understand how much more progress they must make
const csaPointsSlider = document.getElementById('csaPointsSlider');
const csaPointsValue = document.getElementById('csaPointsValue');
csaPointsSlider.addEventListener('input', function (event) { const value = parseInt(event.target.value); csaPointsValue.innerText = value; predictAndDisplayAPScore(value); });
For MyHandler.java I wrote this function
private void handleGetPlayerPosition(WebSocketSession session, String playerName) throws IOException {
try {
// Log request
log.info("Fetching position for player: {}", playerName);
String position = getPlayerPositionFromDatabase(playerName);
session.sendMessage(new TextMessage("Position for " + playerName + ": " + position));
} catch (Exception e) {
log.error("Error fetching player position: ", e);
session.sendMessage(new TextMessage("Error fetching player position"));
}
}
private String getPlayerPositionFromDatabase(String playerName) { return "X: 100, Y: 200"; }
But Through testing and trying to add x and y instance variables to the original person class I discovered some errors:
The issue came from the absence of x and y parameters in the table/person class. I attempted to initialize them, but i had the complication of retrieving x and y coordinates from the frontend, which are locally stored but relative to individual users' screens, which is impractical for WebSocket functionality. So, an alternative solution is the tiled approach, as initially explored by Luna and me, where we would implement a standardized coordinate system enabling collision detection within the map file itself. So, updates would be sent to the conventional backend, which, in turn, would update the table in connections, which would allow for WebSocket updates. But because the coordinate system will still be on the local frontend we may have to reconsider or do some additional planninng on websockets. I have discusses this with rachit and we will be planning going forward.
Here I was trying to log the error in chatGPT
For this checkpoint I addressed all the goals I had from last time.
The problem here is that my API would display the score correctly given an integer input, however my implementation/request in JS on the frontend would return with NaN
I did some debugging and created testing.html on frontend and got requests to become functional
I had to research and consult chatGPT about this because I had not received an error like this before, especially when postman was functional
I found that the issue wasn't that the return was a double, it was because my url was initialized incorrectly to take inputs of csaPoints . So the return was of null type not int type.
Here are the changes I made:
Backend (PredictionController.java)
@GetMapping("/api/predictAPScore")
public double predictAPScore(@RequestParam int csaPoints) {
// Call predictAPScore method of the prediction model
return predictionModel.predictAPScore(csaPoints);
}
Frontend (testing and dashboard)
function predictAndDisplayAPScore(csaPoints) {
console.log("Sending request with csaPoints:", csaPoints);
fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints)
.then(response => {
console.log("Received response:", response);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log("Received data:", data);
// Ensure the predicted AP score is between 1 and 5
const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5);
document.getElementById("predictedAPScoreDisplay").innerText =
Predicted AP Score: ${predictedAPScore}
;
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.';
});
}
function predictAndDisplayAPScore(csaPoints) {
console.log("Sending request with csaPoints:", csaPoints);
fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints)
.then(response => {
console.log("Received response:", response);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log("Received data:", data);
// Ensure the predicted AP score is between 1 and 5
const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5);
document.getElementById("predictedAPScoreDisplay").innerText =
Predicted AP Score: ${predictedAPScore}
;
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.';
});
}
years = [int(year) for year in data.keys()]
x = [entry["y"] for entry in data.values()]
y = [entry["x"] for entry in data.values()]
trace_temperature = go.Scatter( x=x, y=y, mode='markers', name='A' )
trace_rainfall = go.Scatter( x=x, y=y, mode='markers', name='B' )
layout = go.Layout( title='Title', xaxis=dict(title='x'), yaxis=dict(title='y'), hovermode='closest' )
fig = go.Figure(data=[x, y], layout=layout)
plotly.offline.plot(fig, filename='tester.html', auto_open=False)
parsed_data = json.loads(data)
years = list(parsed_data['Data'].keys()) populations = list(parsed_data['Data'].values())
fig = go.Figure(data=[go.Bar( x=x, y=y, marker=dict(color='rgb(138, 174, 235)', line=dict(color='rgb(8, 8, 97)', width=1.5)), )]) fig.update_layout( title='TITLE', xaxis=dict(title='X'), yaxis=dict(title='Y'), plot_bgcolor='rgba(0,0,0,0)', showlegend=False, ) fig.write_html('test.html')
Final implementation :
The testing in the frontend python chart files to add this functionality coupled with the final implementation in the frontend with differing js took 15 hours
I also added a slider which calls the predict function again in the backend so players can understand how much more progress they must make
const csaPointsSlider = document.getElementById('csaPointsSlider');
const csaPointsValue = document.getElementById('csaPointsValue');
csaPointsSlider.addEventListener('input', function (event) { const value = parseInt(event.target.value); csaPointsValue.innerText = value; predictAndDisplayAPScore(value); });
For MyHandler.java I wrote this function
private void handleGetPlayerPosition(WebSocketSession session, String playerName) throws IOException {
try {
// Log request
log.info("Fetching position for player: {}", playerName);
String position = getPlayerPositionFromDatabase(playerName);
session.sendMessage(new TextMessage("Position for " + playerName + ": " + position));
} catch (Exception e) {
log.error("Error fetching player position: ", e);
session.sendMessage(new TextMessage("Error fetching player position"));
}
}
private String getPlayerPositionFromDatabase(String playerName) { return "X: 100, Y: 200"; }
But Through testing and trying to add x and y instance variables to the original person class I discovered some errors:
The issue came from the absence of x and y parameters in the table/person class. I attempted to initialize them, but i had the complication of retrieving x and y coordinates from the frontend, which are locally stored but relative to individual users' screens, which is impractical for WebSocket functionality. So, an alternative solution is the tiled approach, as initially explored by Luna and me, where we would implement a standardized coordinate system enabling collision detection within the map file itself. So, updates would be sent to the conventional backend, which, in turn, would update the table in connections, which would allow for WebSocket updates. But because the coordinate system will still be on the local frontend we may have to reconsider or do some additional planninng on websockets. I have discusses this with rachit and we will be planning going forward.
Here I was trying to log the error in chatGPT
Rachit
As stated, did lots of research and digging into websockets to make them work. Now, they work with different commands and a framework to run them, which was also created by rachit.
To deploy on nginx, did lots of research into why nginx was blocking websockets through postman. Found new nginx configurations had to be placed for deployment.
Specific settings for websockets in nginx
w/out certbot config
w/ certbot config...
For more, ask for live demo. Rachit will explain everything he has done in more detail.
Luna