Skip to content

Commit

Permalink
Merge pull request #113 from avantifellows/feat/sess-metrics
Browse files Browse the repository at this point in the history
Adds metrics model
  • Loading branch information
suryabulusu authored Apr 25, 2024
2 parents ca6f6b4 + 49f8926 commit e0d189d
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 43 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ jobs:
name: Pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: pre-commit/action@v2.0.3
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: pre-commit/action@v3.0.0

unit-tests:
name: Test cases
Expand Down
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,16 @@ static/admin/*
zappa_settings.json

templates/staging-test.yaml

*.log.*
deployment/.terraform/*
deployment/.terraform
deployment/.terraform.lock.hcl
deployment/terraform.tfstate.backup
deployment/terraform.tfstate
deployment/terraform.tfstate.d
terraform.tfstate
deployment/.env.staging
deployment/.env.production

app/scripts/dump
64 changes: 36 additions & 28 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
- id: check-yaml
exclude: "templates/*"
- id: check-merge-conflict
- id: check-added-large-files
- repo: https://github.com/aws-cloudformation/cfn-python-lint
rev: v0.58.4
hooks:
- id: cfn-python-lint
files: templates/.*\.(json|yml|yaml)$
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: "3.9.0"
hooks:
- id: flake8
args:
# these are errors that will be ignored by flake8
# check out their meaning here
# https://flake8.pycqa.org/en/latest/user/error-codes.html
- "--ignore=E501,E203,W503"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
- id: check-yaml
exclude: "templates/*"
- id: check-merge-conflict
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 23.10.1
hooks:
- id: black
exclude: ^psycopg2/
- repo: https://github.com/pycqa/flake8
rev: '6.1.0'
hooks:
- id: flake8
exclude: ^psycopg2/
args:
# these are errors that will be ignored by flake8
# check out their meaning here
# https://flake8.pycqa.org/en/latest/user/error-codes.html
- "--ignore=E501,E203,W503"

- repo: https://github.com/terraform-linters/tflint
rev: v0.30.0
hooks:
- id: tflint
files: \.tf$
- repo: https://github.com/aws-cloudformation/cfn-python-lint
rev: v0.58.4
hooks:
- id: cfn-python-lint
files: templates/.*\.(json|yml|yaml)$
25 changes: 25 additions & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,29 @@ class Event(BaseModel):
updated_at: datetime = Field(default_factory=datetime.utcnow)


class QuestionSetMetric(BaseModel):
name: str
qset_id: str
marks_scored: int
num_answered: int
num_skipped: int
num_correct: int
num_wrong: int
num_partially_correct: int
attempt_rate: float
accuracy_rate: float


class SessionMetrics(BaseModel):
qset_metrics: List[QuestionSetMetric]
total_answered: int
total_skipped: int
total_correct: int
total_wrong: int
total_partially_correct: int
total_marks: int


class QuestionMetadata(BaseModel):
grade: Optional[str]
subject: Optional[str]
Expand Down Expand Up @@ -423,6 +446,7 @@ class Session(BaseModel):
created_at: datetime = Field(default_factory=datetime.utcnow)
events: List[Event] = []
has_quiz_ended: bool = False
metrics: Optional[SessionMetrics] = None # gets updated when quiz ends

class Config:
allow_population_by_field_name = True
Expand All @@ -440,6 +464,7 @@ class UpdateSession(BaseModel):
"""Model for the body of the request that updates a session"""

event: EventType
metrics: Optional[SessionMetrics]

class Config:
schema_extra = {"example": {"event": "start-quiz"}}
Expand Down
1 change: 0 additions & 1 deletion app/routers/quizzes.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ async def get_quiz(quiz_id: str):
)

for question_set_index, question_set in enumerate(quiz["question_sets"]):

updated_subset_without_details = []
options_count_per_set = options_count_across_sets[question_set_index][
"options_count_per_set"
Expand Down
15 changes: 12 additions & 3 deletions app/routers/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ async def create_session(session: Session):
current_session["events"] = last_session.get("events", [])
current_session["time_remaining"] = last_session.get("time_remaining", None)
current_session["has_quiz_ended"] = last_session.get("has_quiz_ended", False)
current_session["metrics"] = last_session.get("metrics", None)

# restore the answers from the last (previous) sessions
session_answers_of_the_last_session = last_session["session_answers"]
Expand Down Expand Up @@ -161,6 +162,8 @@ async def update_session(session_id: str, session_updates: UpdateSession):
* resume button is clicked (resume-quiz event)
* end button is clicked (end-quiz event)
* dummy event logic added for JNV -- will be removed!
when end-quiz event is sent, session_updates also contains netrics
"""
new_event = jsonable_encoder(session_updates)["event"]
log_message = f"Updating session with id {session_id} and event {new_event}"
Expand Down Expand Up @@ -192,7 +195,6 @@ async def update_session(session_id: str, session_updates: UpdateSession):
else:
session_update_query["$set"].update({"events": [new_event_obj]})
else:

if (
new_event == EventType.dummy_event
and session["events"][-1]["event_type"] == EventType.dummy_event
Expand Down Expand Up @@ -274,10 +276,17 @@ async def update_session(session_id: str, session_updates: UpdateSession):

# update the document in the sessions collection
if new_event == EventType.end_quiz:
session_metrics = jsonable_encoder(session_updates)["metrics"]

if "$set" not in session_update_query:
session_update_query["$set"] = {"has_quiz_ended": True}
session_update_query["$set"] = {
"has_quiz_ended": True,
"metrics": session_metrics,
}
else:
session_update_query["$set"].update({"has_quiz_ended": True})
session_update_query["$set"].update(
{"has_quiz_ended": True, "metrics": session_metrics}
)

update_result = client.quiz.sessions.update_one(
{"_id": session_id}, session_update_query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
settings = Settings()

if __name__ == "__main__":

if "MONGO_AUTH_CREDENTIALS" not in os.environ:
from dotenv import load_dotenv

Expand Down
1 change: 0 additions & 1 deletion app/scripts/find_and_replace_some_text_in_all_quizzes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os

if __name__ == "__main__":

if "MONGO_AUTH_CREDENTIALS" not in os.environ:
from dotenv import load_dotenv

Expand Down
3 changes: 0 additions & 3 deletions app/scripts/remove_extra_dummy_events_in_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# test session["_id"] in prod: 633646b0639829dad5a896b4

if __name__ == "__main__":

if "MONGO_AUTH_CREDENTIALS" not in os.environ:
from dotenv import load_dotenv

Expand All @@ -16,7 +15,6 @@
for session in session_collection.find(
{"events": {"$exists": True}, "$expr": {"$gt": [{"$size": "$events"}, 1000]}}
):

print(session["_id"])

if session["events"] is None:
Expand All @@ -29,7 +27,6 @@

# Loop through all events in the session
for event in session["events"]:

# Check if the event is a dummy event
if event["event_type"] == "dummy-event":
# Check if we've already seen a dummy event
Expand Down
1 change: 0 additions & 1 deletion app/scripts/tag_all_questions_with_question_set_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os

if __name__ == "__main__":

if "MONGO_AUTH_CREDENTIALS" not in os.environ:
from dotenv import load_dotenv

Expand Down
1 change: 0 additions & 1 deletion app/scripts/update_specific_user_ids.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import json

if __name__ == "__main__":

if "MONGO_AUTH_CREDENTIALS" not in os.environ:
from dotenv import load_dotenv

Expand Down
2 changes: 1 addition & 1 deletion app/tests/test_questions.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ def test_get_questions_for_multiple_question_sets(self):

assert response.status_code == 200
response = response.json()
assert type(response) == list
assert isinstance(response, list)
assert len(response) == settings.subset_size

0 comments on commit e0d189d

Please sign in to comment.