## Content 💾 Fix #3: Implement (local) persistence ♻️ Implement DRY on weighted average calculation 🐛 Fix #6 : Prevent subjects from getting updated when user cancels editing Reviewed-on: #8main
parent
efa89c4d3d
commit
97582d0008
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// UnitsStore.swift
|
||||||
|
// Graduator
|
||||||
|
//
|
||||||
|
// Created by etudiant on 2023-06-10.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
|
||||||
|
class UnitsStore: ObservableObject {
|
||||||
|
|
||||||
|
private static func fileURL() throws -> URL {
|
||||||
|
try FileManager.default.url(
|
||||||
|
for: .documentDirectory,
|
||||||
|
in: .userDomainMask,
|
||||||
|
appropriateFor: nil,
|
||||||
|
create: false
|
||||||
|
).appendingPathComponent("dat.data.tho")
|
||||||
|
}
|
||||||
|
|
||||||
|
func load<T: Codable>(defaultValue: [T]) async throws -> [T] {
|
||||||
|
|
||||||
|
let task = Task<[T], Error> {
|
||||||
|
let fileURL = try Self.fileURL()
|
||||||
|
let data = try? Data(contentsOf: fileURL)
|
||||||
|
var elements: [T] = defaultValue
|
||||||
|
if let validData = data, !validData.isEmpty {
|
||||||
|
elements = try JSONDecoder().decode([T].self, from: validData)
|
||||||
|
}
|
||||||
|
return elements
|
||||||
|
}
|
||||||
|
|
||||||
|
return try await task.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func save<T: Codable>(elements: [T]) async throws {
|
||||||
|
|
||||||
|
let task = Task {
|
||||||
|
let data = try JSONEncoder().encode(elements)
|
||||||
|
let outfile = try Self.fileURL()
|
||||||
|
try data.write(to: outfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = try await task.value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// WeightedAverageCalculator.swift
|
||||||
|
// Graduator
|
||||||
|
//
|
||||||
|
// Created by etudiant on 2023-06-10.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct WeightedAverageCalculator {
|
||||||
|
static func average<T: WeightedGrade>(elements: [T]) -> Double? {
|
||||||
|
var totalWeight = 0
|
||||||
|
var weightedSum = 0.0
|
||||||
|
|
||||||
|
for element in elements {
|
||||||
|
if let grade = element.grade {
|
||||||
|
totalWeight += element.weight
|
||||||
|
weightedSum += grade * Double(element.weight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guard totalWeight > 0 else { return nil }
|
||||||
|
|
||||||
|
return weightedSum / Double(totalWeight)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// WeightedGrade.swift
|
||||||
|
// Graduator
|
||||||
|
//
|
||||||
|
// Created by etudiant on 2023-06-10.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol WeightedGrade {
|
||||||
|
var weight: Int { get }
|
||||||
|
var grade: Double? { get }
|
||||||
|
}
|
Loading…
Reference in new issue