Skip to the content.

PPR

Leaderboard

1. List Creation

def get(self):
    try:
        competition_entries = Time.query.all() 
        result = {}

The list creation part is where the competition_entries list is created by querying the Time table.

2. List Processing

        for word in result:
            result[word] = sorted(
                result[word],
                key=lambda x: x['score'],
                reverse=True
            )

        return result

    except Exception as e:
        print(f"Error in get method: {str(e)}")
        return {}

This code segment is part of the list processing in the get method of the LeaderboardAPI class. It processes the result dictionary by sorting the lists of leaderboard entries for each word by their scores in descending order.

A function

def post(self):
    current_user = g.current_user
    data = request.get_json()

    if not data or "drawing_name" not in data:
        return {
            "message": "Missing drawing name",
            "error": "Bad Request"
        }, 400

    try:
        if "score" in data:
            score = int(data['score'])
        else:
            competition_entry = Time.query.filter_by(
                created_by=current_user.id,
                drawn_word=data['drawing_name']
            ).first()

            if not competition_entry:
                return {
                    "message": "No competition entry found for this drawing",
                    "error": "Not Found"
                }, 404

            speed_factor = competition_entry.timer_duration / competition_entry.time_taken
            score = min(1000, int(speed_factor * 500))

        existing_entry = LeaderboardEntry.query.filter_by(
            created_by=current_user.id,
            drawing_name=data['drawing_name']
        ).first()

        if existing_entry:
            if score > existing_entry.score:
                existing_entry.score = score
                existing_entry.update()
            return existing_entry.read(), 200
        else:
            entry = LeaderboardEntry(
                profile_name=current_user.name,
                drawing_name=data['drawing_name'],
                score=score,
                created_by=current_user.id
            )
            entry.create()
            return entry.read(), 201

    except Exception as e:
        return {
            "message": "Failed to create/update entry",
            "error": str(e)
        }, 500

Explanation

  • Retrieves the current user and request data.
  • Validates the input data for the presence of drawing_name.
  • Calculates the score:
    • Uses the provided score if available.
    • Otherwise, fetches competition data and calculates the score based on the speed factor.
  • Checks if a leaderboard entry exists for the user and drawing word:
    • Updates the score if the new score is higher.
    • Creates a new entry if none exists.
  • Handles exceptions and returns appropriate error messages.

4. Call to the function

document.getElementById('score-form').addEventListener('submit', async function(event) {
    event.preventDefault();
    const drawingName = document.getElementById('drawingName').value.trim();
    const score = document.getElementById('score').value;
    
    try {
        const body = { drawing_name: drawingName };
        if (score) {
            const scoreNum = parseInt(score);
            if (scoreNum < 0 || scoreNum > 1000) {
                showMessage('Score must be between 0 and 1000', 'error');
                return;
            }
            body.score = scoreNum;
        }

        const response = await fetch(`${pythonURI}/api/leaderboard`, {
            method: 'POST',
            credentials: 'include',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(body)
        });

        const data = await response.json();
        
        if (!response.ok) throw new Error(data.message);
        
        showMessage('Score submitted successfully!', 'success');
        this.reset();
        await fetchLeaderboard();
    } catch (error) {
        console.error('Error:', error);
        showMessage(error.message, 'error');
    }
});

Explanation

  • Retrieves the drawing name and score from the form inputs.
  • Validates the score to ensure it is between 0 and 1000.
  • Prepares the request body with the drawing name and score.
  • Sends a POST request to the api with the request body.
  • Handles the response:
    • If successful, displays a success message, resets the form, and fetches the updated leaderboard data.
    • If unsuccessful, displays an error message.