Skip to content

Commit

Permalink
beta
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissdelaney committed May 17, 2024
1 parent 7202add commit 4a08806
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 51 deletions.
43 changes: 38 additions & 5 deletions app/spreadsheet_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def get_course_assignments_teacher(self, course_id:str) -> list:
# now, get the assignments from the sheet
assignment_sheet = self.get_sheet("ASSIGNMENT_MASTER")
assignments = assignment_sheet.get_all_records()
assignments_names_points = [{'NAME': a['NAME'], 'POINTS':a['POINTS'], 'DUE_DATE':a['DUE_DATE']} for a in assignments]
assignments_names_points = [{'NAME': a['NAME'], 'POINTS':a['POINTS'], 'DUE_DATE':a['DUE_DATE'], 'SHEET_NAME':a['SHEET_NAME']} for a in assignments]

#get student_grade
gradebook_sheet = self.get_sheet("GRADEBOOK")
Expand All @@ -172,6 +172,40 @@ def get_course_assignments_teacher(self, course_id:str) -> list:

print(assignments_names_points)
return assignments_names_points

def get_assignment_grades_teacher(self, course_id:str, assignment_id:str):
#if coming from "courses" page, the active document will be "MASTER"
#we want to change that to the document ID of the specific course
if self.doc.id == GOOGLE_SHEETS_MASTER_DOCUMENT_ID:
courses_sheet = self.get_sheet("courses")
courses_records = courses_sheet.get_all_records()

course_document_id_list = [c["SHEETS_DOCUMENT_ID"] for c in courses_records if c["COURSE_ID"] == int(course_id)]

if len(course_document_id_list) == 0:
raise Exception("course not found...")
#TODO: handle within the route
if len(course_document_id_list) > 1:
raise Exception("course duplicate found...error")
#TODO: handle within the route

self.set_active_document(course_document_id_list[0])

# now, get the assignments from the sheet
assignment_sheet = self.get_sheet("ASSIGNMENT_MASTER")
assignments = assignment_sheet.get_all_records()
assignment_matches = [a for a in assignments if a['SHEET_NAME'] == assignment_id]

if len(assignment_matches) == 0:
raise Exception("Assignment not found!")

assignment_name = assignment_matches[0].get('NAME')

gradebook_sheet = self.get_sheet("GRADEBOOK")
all_grades_df = pd.DataFrame(gradebook_sheet.get_all_records()).dropna()
all_grades_df = all_grades_df[['Last', 'First', 'Email', assignment_name]]

return assignment_name, all_grades_df.to_dict(orient='records')


def get_course_roster(self, course_id:str):
Expand Down Expand Up @@ -401,6 +435,7 @@ def get_user_courses(self, email:str) -> list:
c['COURSE_NAME'] = course_info['COURSE_NAME']
c['CHECK_IN_SHEET_NAME'] = course_info['CHECK_IN_SHEET_NAME']
c['CHECK_IN_FORM_ID'] = course_info['CHECK_IN_FORM_ID']
c['PROFESSOR'] = course_info['PROFESSOR']

return courses_list

Expand All @@ -412,8 +447,6 @@ def get_user_courses(self, email:str) -> list:

ss = SpreadsheetService()

data = ss.get_weekly_check_ins("12345", "[email protected]", "TA", "check-ins-aggregate")
name, data = ss.get_assignment_grades_teacher("12345", "rps-mjr")
print(name)
print(data)
#ss.get_student_courses("[email protected]")

#ss.get_assignment_scores("[email protected]", "12345", "onboarding")
96 changes: 71 additions & 25 deletions web_app/routes/courses_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ def course(course_id):

courses_info = [c for c in current_user.get('user_courses') if int(c['COURSE_ID']) == int(course_id)]

print(courses_info)

if len(courses_info) == 0:
flash(str(courses_info))
return redirect('/user/courses')
Expand All @@ -25,8 +27,9 @@ def course(course_id):

role = courses_info[0].get('USER_TYPE')
course_name = courses_info[0].get('COURSE_NAME')
professor = courses_info[0].get('PROFESSOR')

return render_template("course.html", ROLE=role, COURSE_ID=course_id, COURSE_NAME = course_name)
return render_template("course.html", ROLE=role, COURSE_ID=course_id, COURSE_NAME=course_name, PROFESSOR=professor)


@courses_routes.route("/courses/<course_id>/assignments")
Expand All @@ -48,8 +51,22 @@ def course_assignments(course_id):
return redirect('/user/courses')

role = courses_info[0].get('USER_TYPE')
assignments_list = ss.get_course_assignments(email, course_id)
return render_template("assignments.html", assignments=assignments_list, course_id=course_id)

if role == "STUDENT":
try:
assignments_list = ss.get_course_assignments(email, course_id)
return render_template("assignments.html", assignments=assignments_list, course_id=course_id)
except Exception as e:
flash(str(e))
return redirect("/user/courses")

else:
try:
assignments_list = ss.get_course_assignments_teacher(course_id)
return render_template("assignments_teacher.html", assignments=assignments_list, course_id=course_id)
except Exception as e:
flash(str(e))
return redirect("/user/courses")



Expand All @@ -60,21 +77,34 @@ def assignment(course_id, assignment_id):
print(f"COURSE {course_id}: ASSIGNMENT {assignment_id}")
ss = current_app.config["SPREADSHEET_SERVICE"]
current_user = session.get("current_user")
email = current_user["email"]
courses_info = [c for c in current_user.get('user_courses') if int(c['COURSE_ID']) == int(course_id)]

#TODO: CHANGE THIS ####
email = "[email protected]"
#######################
if len(courses_info) == 0:
flash(str(courses_info))
return redirect('/user/courses')

try:
assignment_details = ss.get_assignment_scores(email, course_id, assignment_id)
role = courses_info[0].get('USER_TYPE')

except Exception as e:
flash('Error, could not fetch assignment details')
flash(str(e))
return redirect(f'/courses/{course_id}')
if role == "STUDENT":

email = current_user["email"]

return render_template("assignment.html", assignment_details=assignment_details)
#TODO: CHANGE THIS ####
email = "[email protected]"
#######################

try:
assignment_details = ss.get_assignment_scores(email, course_id, assignment_id)
return render_template("assignment.html", assignment_details=assignment_details)

except Exception as e:
flash('Error, could not fetch assignment details')
flash(str(e))
return redirect(f'/courses/{course_id}')

else:
assignment_name, assignment_grades = ss.get_assignment_grades_teacher(course_id, assignment_id)
return render_template("assignment_grades_teacher.html", assignment_grades=assignment_grades, assignment_name=assignment_name, assignment_id=assignment_id, course_id=course_id)


#TA/TEACHER ROUTES
Expand All @@ -101,17 +131,36 @@ def courses_teacher_roster(course_id):



@courses_routes.route("/courses/<course_id>/students/<student_info>")
@courses_routes.route("/courses/<course_id>/students/<student_email>/assignments")
@authenticated_route
@ta_route()
def student_grades(course_id, student_info):
student_info_list = student_info.split("__")
last_name = student_info_list[0]
first_name = student_info_list[1]
student_email = student_info_list[2]
def student_grades(course_id, student_email):
ss = current_app.config["SPREADSHEET_SERVICE"]
assignments_list = ss.get_course_assignments(student_email, course_id)
return render_template("assignments_teacher.html", assignments=assignments_list, course_id=course_id, student_email=student_email, first_name=first_name, last_name=last_name)
try:
assignments_list = ss.get_course_assignments(student_email, course_id)
except:
flash('Error, could not fetch student details')
return redirect("/courses/<course_id>/roster")

return render_template("student_assignments_teacher.html", assignments=assignments_list, course_id=course_id, student_email=student_email)


@courses_routes.route("/courses/<course_id>/students/<student_email>/assignments/<assignment_id>")
@authenticated_route
@ta_route()
def assignment_details(course_id, student_email, assignment_id):
ss = current_app.config["SPREADSHEET_SERVICE"]
#try:
assignment_details = ss.get_assignment_scores(student_email, course_id, assignment_id)

"""
except Exception as e:
flash('Error, could not fetch assignment details')
flash(str(e))
return redirect(f'/courses/{course_id}')
"""

return render_template("assignment_teacher.html", assignment_details=assignment_details, student_email=student_email)


@courses_routes.route("/courses/<course_id>/check_ins")
Expand All @@ -137,9 +186,6 @@ def check_ins(course_id):
check_in_sheet_name = courses_info[0].get('CHECK_IN_SHEET_NAME')
check_in_form_id = courses_info[0].get('CHECK_IN_FORM_ID')

print("-----")
print(courses_info[0])

if user_role == "STUDENT":
check_in_data, check_in_headers = ss.get_weekly_check_ins(course_id=course_id, email=email, user_role=user_role, check_in_sheet_name=check_in_sheet_name)
return render_template("check_ins_student.html", course_id=course_id, course_name=course_name, check_in_data=check_in_data, check_in_headers=check_in_headers, check_in_form_id=check_in_form_id)
Expand Down
2 changes: 1 addition & 1 deletion web_app/templates/assignment.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ <h4>
</h4>
<hr>
<h3>DETAILS:</h3>
<div id="boxPlotChart" style="width:100%;height:600px;"></div>
<div id="boxPlotChart" style="width:60%;height:200px;"></div>
<p>Mean: {{ assignment_details.CLASS_MEAN }}</p>
<p>High: {{ assignment_details.CLASS_HIGH }}</p>
<p>Low: {{ assignment_details.CLASS_LOW }}</p>
Expand Down
41 changes: 41 additions & 0 deletions web_app/templates/assignment_grades_teacher.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{% extends "bootstrap_5_layout.html" %}
{% set active_page = "assignments" %}

{% block content %}

<h1>Grades: {{ assignment_name }} -- {{ course_id }}</h1>

<table class="table table-hover text-center">
<thead>
<tr>
<th scope="col">Last</th>
<th scope="col">First</th>
<th scope="col">Email</th>
<th scope="col">Grade</th>
</tr>
</thead>
<tbody>
{% for a in assignment_grades %}
<tr class="clickable-row" data-href="/courses/{{ course_id }}/students/{{ a.Email }}/assignments/{{ assignment_id }}">
<td>{{ a.Last }}</td>
<td>{{ a.First }}</td>
<td>{{ a.Email }}</td>
<td>{{ a[assignment_name] }}</td>
</tr>
{% endfor %}
</tbody>
</table>


<script>
document.addEventListener("DOMContentLoaded", function() {
const rows = document.querySelectorAll('.clickable-row');
rows.forEach(row => {
row.addEventListener('click', function() {
window.location.href = this.getAttribute('data-href');
});
});
});
</script>

{% endblock %}
71 changes: 60 additions & 11 deletions web_app/templates/assignment_teacher.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
{% set active_page = "assignment" %}

{% block content %}
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<h2>{{ first_name }} {{ last_name }}: {{assignment_details.NAME}}</h2>
<h4>Due: {{assignment_details.DUE_DATE}}</h4>
<h1>{{assignment_details.NAME}} -- {{ student_email }}</h1>
<h3>Due: {{assignment_details.DUE_DATE}}</h3>
<hr>

{% if assignment_details.STUDENT_DETAILS is defined and assignment_details.STUDENT_DETAILS|length > 0 %}
Expand All @@ -18,15 +19,9 @@ <h4>Due: {{assignment_details.DUE_DATE}}</h4>
<tbody>
{% for a in assignment_details.STUDENT_DETAILS %}
<tr>
<td>
{{ a.metric }}
</td>
<td>
{{ a.score }}
</td>
<td>
{{ a.comments }}
</td>
<td>{{ a.metric }}</td>
<td>{{ a.score }}</td>
<td>{{ a.comments }}</td>
</tr>
{% endfor %}
</tbody>
Expand All @@ -39,8 +34,62 @@ <h4>
</h4>
<hr>
<h3>DETAILS:</h3>
<div id="boxPlotChart" style="width:60%;height:200px;"></div>
<p>Mean: {{ assignment_details.CLASS_MEAN }}</p>
<p>High: {{ assignment_details.CLASS_HIGH }}</p>
<p>Low: {{ assignment_details.CLASS_LOW }}</p>
<p>Lower Quartile: {{ assignment_details.CLASS_LOWER_QUARTILE }}</p>
<p>Upper Quartile: {{ assignment_details.CLASS_UPPER_QUARTILE }}</p>

<script>
document.addEventListener('DOMContentLoaded', function () {
const trace1 = {
y: ['Scores'],
type: 'box',
q1: [{{ assignment_details.CLASS_LOWER_QUARTILE }}],
median: [{{ assignment_details.CLASS_MEAN }}],
q3: [{{ assignment_details.CLASS_UPPER_QUARTILE }}],
lowerfence: [{{ assignment_details.CLASS_LOW }}],
upperfence: [{{ assignment_details.CLASS_HIGH }}],
marker: {color: 'blue'},
boxpoints: false,
orientation: 'h',
hoverinfo: 'none' // Disable hover info for this trace
};

const trace2 = {
x: [{{ assignment_details.FINAL_SCORE }}],
y: ['Scores'],
mode: 'markers',
type: 'scatter',
marker: {color: 'red', size: 12},
orientation: 'h',
hoverinfo: 'none' // Disable hover info for this trace
};

const layout = {
xaxis: {
title: 'Scores',
range: [{{ assignment_details.CLASS_LOW - 1 }}, {{ assignment_details.CLASS_HIGH + 1 }}] // Add some padding
},
yaxis: {
visible: false // Hide the y-axis
},
showlegend: false, // Hide the legend
margin: {
l: 50,
r: 50,
t: 50,
b: 50
},
hovermode: false // Disable hover interactions
};

const config = {
displayModeBar: false // Disable the mode bar
};

Plotly.newPlot('boxPlotChart', [trace1, trace2], layout, config);
});
</script>
{% endblock %}
7 changes: 3 additions & 4 deletions web_app/templates/assignments_teacher.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@

{% block content %}


<h1>Assignments: {{personal_course_info.DEPARTMENT}}-{{personal_course_info.NUMBER}} {{personal_course_info.COURSE_NAME}}</h1>
<h1>Assignments:</h1>

<table class="table table-hover text-center">
<thead>
<tr>
<th scope="col">Assignment</th>
<th scope="col">Due Date</th>
<th scope="col">Points</th>
<th scope="col">Average Score</th>
<th scope="col">Average Grade</th>
</tr>
</thead>
<tbody>
Expand All @@ -28,7 +27,7 @@ <h1>Assignments: {{personal_course_info.DEPARTMENT}}-{{personal_course_info.NUMB
{{ a.POINTS }}
</td>
<td>
{{ a.AVERAGE_SCORE }} ({{ a.AVERAGE_PCT }})
{{ a.AVERAGE_SCORE}}/{{ a.POINTS }} ({{ a.AVERAGE_PCT }})
</td>
</tr>
{% endfor %}
Expand Down
Loading

0 comments on commit 4a08806

Please sign in to comment.