Skip to content
mtaiboPublic

About

An iOS tracker for your subjects, grades and assignments

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

197 Commits

Folders and files

Repository files navigation

🧮 Grade

A tracker for your subjects, grades and assignments.


Version Made with Platform


Grade is a tracker for your subjects, grades, assignments and deadlines in one place, built to model any grading scheme instead of a generic one. It's my first project aimed at the App Store: a minimal version first, tested with real students, then grown into something I'd pay for myself.

Why I'm building it

The grade-tracking apps that exist are generic agendas, usually in English, that don't understand how Spanish universities actually grade: minimum scores to average in, exam parts that exempt you from the final, non-recoverable coursework, ordinary and extraordinary sittings, weights that change depending on another part's grade.

  • Validate fast — a minimal version tested with real students before building months of features nobody asked for
  • A real portfolio piece — published, with real users, built with clean architecture, tests and native Apple frameworks
  • Modest income — free with a small paid tier, enough to cover the Apple Developer Program fee
  • My own use — I track my own subjects with it every day

The app

For each subject, it answers one question: "what do I need on the final?"

📚 Subjects

The home screen, one course at a time (switched from the title). A card per subject with the grade secured so far, a 0–10 bar from worst to best case with the pass mark, and what's still needed: "Necesitas un 4,2 en lo que falta".

SwiftUI · Observation

📝 Subject

Ordinary and extraordinary sittings, each with its exam date. One card per part showing its weight and the points it has earned, with an input that matches how the teacher grades it: points out of anything, a percentage, letters (A, B, C…), or a compact grid for many small tests.

SwiftUI

🧩 Editor

Reshape any subject to match its real syllabus: parts and nested groups, weights, how they combine (weighted average, sum, best N…), scale, pass mark, input style, whether a grade carries over to the extraordinary sitting, and due dates.

SwiftUI

📅 Calendar

A month view with a dot on every day something is due — lab hand-ins and both exam sittings — and the list of what's coming, each with the grade if it's in or how many days are left.

SwiftUI · UICalendarView

🎓 Record

The credit-weighted average and credits passed, over the subjects whose grades are all in.

SwiftUI

⚙️ Engine

The calculation library: the evaluation tree, current grade, best case, pass status and grade needed (binary search). No UI dependency, value types only, tested against 9 real syllabi.

Swift Package · Swift Testing

Architecture

┌─────────────────────── App (SwiftUI) ───────────────────────┐
│  Calendar   ·   Subjects   ·   Subject / Editor   ·  Record  │
│                         │                                   │
│                 Library (@Observable)                       │
│    courses → subjects → tree + grades per sitting           │
│                 saved as one JSON file                      │
└─────────────────────────┬───────────────────────────────────┘
                          │  grades converted to each part's scale
┌─────────────────────────▼───────────────────────────────────┐
│  Engine (Swift Package, no SwiftUI)                         │
│  Node tree: Grade · Group · Formula · Alternatives · …      │
│  evaluate · neededFraction · status · minimums · caps       │
└─────────────────────────────────────────────────────────────┘

The engine knows nothing about screens or storage: it takes a subject's tree and the grades entered so far and returns numbers. Everything about how a grade is typed (out of 2, 85 %, a "B") is converted in the app before it gets there. Each device keeps a local JSON file. CloudKit keeps it in the user's private iCloud, one record per subject, and the Apple Watch app gets the current study from the iPhone and sends grades back to it.

How it works

Syllabus (guía docente, PDF)
        │  read the evaluation section
        ▼
Evaluation rules as JSON (guide/extracted/), citing the original text
        │  build the tree in Swift
        ▼
Subject tree  ──►  tests with hand-calculated grades
        │
        ▼
Grades entered (ordinary / extraordinary)
        │
        ▼
evaluate(pending = 0) → what you have     evaluate(pending = 1) → best case
        │
        ▼
binary search over "same grade on everything pending" → what you need

Modelling real syllabi

Every rule found so far comes from an actual syllabus in guide/: continuous weights that depend on another grade (Formula, e.g. Estadística's P + C + 0.1 · (8 − C) · F), minimums on one part that fail the subject regardless of the average (Sistemas Operativos), and minimums that cap the final grade at 4.5 or 4.9 (Diseño Software, Informática Básica). When a syllabus doesn't fit, the model changes instead of the syllabus being forced into it. The plan is to keep adding syllabi in batches until 10 in a row need no change. Decisions and open gaps are in docs/modelo.md (in Spanish).

Ordinary and extraordinary sittings

Each subject keeps both sittings' grades. In the extraordinary one, parts the syllabus keeps (labs, usually) carry over and can be overridden; the rest, usually the exam, starts empty. 🚧 Both sittings share one structure, so a syllabus that reweights the exam in the extraordinary sitting is approximated.

Tech stack

Layer Technology
Engine Swift Package, no SwiftUI/SwiftData dependency, value types
UI SwiftUI
Persistence Local JSON, synced through the private iCloud database with CKSyncEngine
Mac The iPhone's SwiftUI screens in a native macOS target, with a sidebar and a menu bar
Watch SwiftUI on watchOS, talking to the iPhone over WatchConnectivity
Project XcodeGen (App/project.yml), the .xcodeproj is generated
Tests Swift Testing: one suite per syllabus, every mix of evaluations against the engine's invariants, and the app's model (saving, backups, studies) run on the Mac

How to run

Requires Xcode and XcodeGen.

git clone https://github.com/mtaibo/grade.git
cd grade
make test                                              # engine and app model tests
cp App/Config/Local.xcconfig.example App/Config/Local.xcconfig
# set DEVELOPMENT_TEAM in Local.xcconfig to your Apple team ID
make open                                              # generates and opens the Xcode project
make device                                            # builds, installs and opens it on a paired iPhone
make mac                                               # builds and opens the Mac app
make testflight                                        # archives and uploads a build to App Store Connect

Website

web/ is the small site at grade.migueltaibo.com: what the app does, with a live "what do you need in the exam" example, plus the privacy policy and support pages the App Store asks for. Plain HTML and CSS served by Cloudflare as a Worker's static assets (web/wrangler.jsonc, security headers in web/site/_headers): every push to main that touches web/ deploys it, and nothing else in the repo does. To see it locally:

make web                                               # cd web && npx wrangler dev, at localhost:8787

The full brief and roadmap are in guide/proyect.md (in Spanish). The first milestone is a TestFlight build tried with ~20 students before the January exams.

About

An iOS tracker for your subjects, grades and assignments

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages