Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IGC: Grade Calculator (v1) #144

Closed
wants to merge 7 commits into from
Closed

IGC: Grade Calculator (v1) #144

wants to merge 7 commits into from

Conversation

rahulon12
Copy link
Member

@rahulon12 rahulon12 commented Dec 20, 2024

  • Built-in Grade Calculator
  • Value should be the same as you would see on Canvas.

Known Issues

  • Cannot access Grade Calculator through "Grades" view on iOS, access through "Assignments" instead.
  • "Done" button above Keyboard disappears after keyboard disappears the first time on iOS

EDIT: It seems like we cannot fetch the official "grade" value for completed courses, but assignment grades still work.

Screenshot 2024-12-20 at 7 47 41 PM Simulator Screenshot - iPhone 16 Pro - 2024-12-20 at 19 50 05

@rahulon12 rahulon12 self-assigned this Dec 20, 2024
@rahulon12 rahulon12 linked an issue Dec 20, 2024 that may be closed by this pull request
@rahulon12
Copy link
Member Author

@azooz2003-bit this is ready to review.

@rahulon12 rahulon12 requested a review from iwatger December 26, 2024 13:31
@rahulon12
Copy link
Member Author

@azooz2003-bit @iwatger if possible, please confirm whether the values you get from the grade calc is the same as what you see on canvas

Comment on lines +30 to +39
static func getAssignmentsForCourse(courseID: String) async -> [Assignment] {
await CourseAssignmentManager.fetchAssignments(courseID: courseID)
}

private static func fetchAssignments(courseID: String) async -> [Assignment] {
guard let (data, _) = try? await CanvasService.shared.fetchResponse(CanvasRequest.getAssignments(courseId: courseID)) else {
print("Failed to fetch assignments.")
return []
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the getAssignmentsForCourse redundant? Other than the name making more sense

@azooz2003-bit
Copy link
Contributor

There's a small push to the left when typing. Very trivial tho.

CleanShot 2025-01-02 at 11 53 22


/* MARK: Request Caching (Optional Implementation)
var requestId: Int? { courseId.asInt }
var requestIdKey: ParentKeyPath<AssignmentGroup, Int?> { .createReadable(\.courseId) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should note now, use createWritable when the property (courseId in this case) doesn't come with fetch result. This allows the service layer to set that property before returning it. e.g. Since courseId isn't in assignment group by default, you probs wanna make it createWritable.

guard let courseID = courseID, let (data, _) = try? await CanvasService.shared.fetchResponse(CanvasRequest.getAssignments(courseId: courseID)) else {
print("Failed to fetch assignments.")
func fetchAssignmentGroups() async {
guard let courseID = courseID, let (data, _) = try? await CanvasService.shared.fetchResponse(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use fetch instead of fetchResponse. Handles the decoding and returns an array of assignment groups.


import Foundation

struct CourseGradeCalculator {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Divide by 0 doesn't seem to be handled, in one of my classes, there are assignments out of 0, and they bring the whole overall to 0.
CleanShot 2025-01-02 at 11 54 56@2x

Comment on lines +72 to +85
var totalPossible: Double = 0
let earned: Double = assignmentGroups.reduce(0) { total, group in
total + group.assignments.reduce(0) { total, assignment in
guard let score = assignment.score, let pointsPossible = assignment.pointsPossible else {
return total
}

totalPossible += pointsPossible

return Double(total + score)
}
}

return earned / totalPossible
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not weighting per assignment right? Wouldn't it be more correct to take each assignment as a percentage instead of total points. (quiz out of 8 has same weight as quiz out of 6)

Comment on lines +90 to +95
private func setEnrollment(enrollments: [Enrollment], currentUserID: Int) {
guard enrollments.count == 1,
let first = enrollments.first,
first.userID == currentUserID else {
return
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS, I think a user may have multiple enrollments if they have multiple roles (i.e. both TA and Student), so we should remove that count == 1 check and find the enrollment with a student role.

@rahulon12
Copy link
Member Author

Needs more thinking, closing for now.

@rahulon12 rahulon12 closed this Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IGC: Implement Grade Calculation Logic
2 participants