Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ An example of how a user and its details is stored in the database:
}
}
}
```
```

# Questions Database

Expand Down Expand Up @@ -179,3 +179,36 @@ An example of how a question and its details is stored in the database:

As shown in the above example, one question can be answered by many users and each user is represented by his ID


## leaderboard points collection:

```json
{
"topic": topic,
"hard": {
user_1_id: points,
user_2_id: points
},
"easy": {
user_1_id: points,
user_2_id: points
}
}
```
### example:
```json
{
"topic": "python",
"hard": {
"1": 0,
"2": 15
},
"easy": {
"3": 77
},
"medium": {
"3": 20
}
}
```

71 changes: 71 additions & 0 deletions data_access_layer/leaderboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from data_access_layer.setup_mongodb import setup_mongodb
from pymongo.errors import PyMongoError


def add_user_points(user_id: str, points: int, topic: str, difficulty: str, client=None):
try:
collection = setup_mongodb(client, 'points')
db_topic = collection.find_one({'topic': topic})

if db_topic:
if difficulty not in db_topic:
db_topic[difficulty] = {user_id: points}
else:
if user_id in db_topic[difficulty]:
db_topic[difficulty][user_id] += points
else:
db_topic[difficulty][user_id] = points
collection.replace_one({'topic': topic}, db_topic)
else:
db_topic = {"topic": topic, difficulty: {user_id: points}}
collection.insert_one(db_topic)

if '_id' in db_topic:
del db_topic['_id']

return db_topic

except PyMongoError as e:
print(f"Database error: {str(e)}")
raise PyMongoError(f"Database error: {str(e)}")

except Exception as e:
print(f"Unexpected error: {str(e)}")
raise Exception(f"Unexpected error: {str(e)}")


def check_user_points_existence(data, client=None):
collection = setup_mongodb(client, 'points')
db_topic = collection.find_one({'topic': data['topic']})

if not db_topic or data['difficulty'] not in db_topic or data['user_id'] not in db_topic[data['difficulty']]:
return False
previous_points = db_topic[data['difficulty']][data['user_id']] - data['points']
if previous_points < 0:
return False
return True


def restore_db(data, client=None):
collection = setup_mongodb(client, 'points')
db_topic = collection.find_one({'topic': data['topic']})
previous_points = db_topic[data['difficulty']][data['user_id']] - data['points']
if previous_points == 0:
del db_topic[data['difficulty']][data['user_id']]

if not db_topic[data['difficulty']]:
del db_topic[data['difficulty']]
if len(db_topic) == 1:
collection.delete_one({'topic': data['topic']})
return True
else:
db_topic[data['difficulty']][data['user_id']] = previous_points

collection.replace_one({'topic': data['topic']}, db_topic)
return True


def get_user_points(data, client=None):
collection = setup_mongodb(client, 'points')
db_topic = collection.find_one({'topic': data['topic']})
return db_topic[data['difficulty']][data['user_id']]
29 changes: 29 additions & 0 deletions tests/test_leaderboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from data_access_layer.leaderboard import add_user_points, check_user_points_existence, get_user_points, restore_db
import pytest


def test_add_user_points_success():
data = {
'user_id': '123',
'topic': 'python',
'difficulty': 'hard',
'points': 8,
}
user_exist = check_user_points_existence(data)
previous_points = 0
if user_exist:
previous_points = get_user_points(data)
add_user_points(user_id=data['user_id'], topic=data['topic'], difficulty=data['difficulty'],
points=data['points'])
assert check_user_points_existence(data)
assert get_user_points(data) == 8 + previous_points
data['points'] = 3
add_user_points(user_id=data['user_id'], topic=data['topic'], difficulty=data['difficulty'],
points=data['points'])
assert check_user_points_existence(data)
assert get_user_points(data) == 11 + previous_points
data['points'] = 11
assert restore_db(data=data)
if previous_points != 0:
assert get_user_points(data) == previous_points
assert check_user_points_existence(data) == user_exist