---
title: "Getting Started with autoharp"
description: >
  Learn how to install autoharp and use it to grade your first R or
  R Markdown student submission in minutes.
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting Started with autoharp}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  collapse  = TRUE,
  comment   = "#>",
  eval      = FALSE,
  fig.align = "center"
)
```

## What is autoharp?

`autoharp` is an R package for **semi-automatic grading** of R and R Markdown
(Rmd/qmd) scripts. It was designed at the National University of Singapore to
handle the practical challenges of grading programming assignments at scale:

- Students submit **complete, reproducible documents** (not isolated code snippets)
- Instructors need to check both *output correctness* and *code quality*
- The same workflow must work for 10 or 1,000 submissions
- Some checks must go beyond outputs: e.g., "did the student avoid using a `for` loop?"

`autoharp` achieves this through four complementary layers:

| Layer | What it Checks |
|-------|---------------|
| **Output correctness** | Objects match the reference solution (typed, tolerance-aware) |
| **Static code analysis** | AST structure: e.g., no `for` loops, correct function signature |
| **Runtime profiling** | Execution time and peak memory usage per submission |
| **Code style (lint)** | `lintr`-based style violations count |

---

## The Big Picture: Four-Phase Workflow

```{r workflow-img, echo=FALSE, eval=TRUE, out.width="90%", fig.cap="The four-phase autoharp grading workflow: Prepare → Distribute → Grade → Review"}
knitr::include_graphics("figs/workflow.png")
```

The typical `autoharp` workflow has four phases:

1. **Prepare**: Write a question sheet and a *solution template* (an Rmd with
   special `autoharp.objs`/`autoharp.scalars` chunk options)
2. **Distribute**: Share the question PDF and a blank student template
3. **Grade**: Run `populate_soln_env()` then `render_one()` per student;
   each runs in a **sandboxed R process**
4. **Review**: Inspect logs, thumbnail galleries, and the Grading App

---

## Installation

You can install **autoharp** from CRAN with:

```{r install, eval=FALSE}
install.packages("autoharp")
```

You can also install the development version from GitHub:

```{r installdev}
# install.packages("devtools")
devtools::install_github("namanlab/autoharp")
```

Then load the package:

```{r load}
library(autoharp)
```

---

## Core Concepts

### Solution Templates

The heart of `autoharp` is the **solution template** - an R Markdown file
that does two things simultaneously:

1. Contains the **reference solution** to the problem
2. Defines **test code** using special knitr chunk options

Two special chunk options are used in **test chunks** (chunks whose names match a pattern, default "test"):

| Chunk Option | Purpose |
|--------|---------|
| `autoharp.objs` | Lists object names to copy from the solution environment so tests can compare student objects against solution objects |
| `autoharp.scalars` | Lists scalar variable names that will be created by the test code; these become columns in the output data frame |

> **Why Rmd?** Grading complete documents (rather than isolated snippets)
> ensures students practice good scientific computing habits: their entire
> analysis must render cleanly.

### The Grading Pipeline

```
Solution Template (.Rmd)
        │
        ▼
populate_soln_env()  --> Solution Environment + Test Script
        │
        ▼
render_one(student.Rmd)  --> Grading Results Data Frame
        │
        ▼
log_summary()  --> Summary Report
```

Each `render_one()` call:
1. Launches a **fresh, sandboxed R process** (via `parallel::makePSOCKcluster`)
2. Checks for forbidden calls (`system()`, `setwd()`, etc.)
3. Knits the student's Rmd with `autoharp` hooks active
4. Runs the test script in the student's environment
5. Returns a data frame with status, runtime, memory, and test results

---

## Motivating Example

### The Problem

Suppose you assign students the following problem:

> Write a function `rf(n)` that generates `n` random variates from the
> density $f(x) = 4x^3$, $0 < x < 1$. Use the inverse transform method.
> Then create a vector `X` of 10,000 variates using `rf()`.

### Step 1: Create a Solution Template

Create `solution_template.Rmd`:

````{verbatim}
---
title: "Solution Template"
output: html_document
---


```{r solution}
rf <- function(n) {
  u <- runif(n)
  u^(1/4)  # inverse CDF of f(x) = 4x^3
}
X <- rf(10000)
```

```{r test01, autoharp.objs=c("rf", "X"), autoharp.scalars=c("lenX", "lenfn", "meanX", "sdX")}

# Compare student objects with solution objects
lenX <- (length(X) == length(.X))
lenfn <- (length(formals(rf)) == length(formals(.rf)))

# Check statistical properties
meanX <- (abs(mean(X) - 0.8) < 0.02)
sdX <- (abs(sd(X) - 0.163) < 0.02)
```

````

### Step 2: Populate the Solution Environment

```{r populate}
soln <- populate_soln_env("solution_template.Rmd", pattern = "test")

# soln is a list with two elements:
# $env: the solution environment (contains .rf, .X and other solution objects)
# $test_fname: path to the extracted test script (code from test chunks)
str(soln)
```

### Step 3: Grade a Student Submission

Suppose a student submits `student01.Rmd`:

```{r render}
result <- render_one(
  rmd_name      = "student01.Rmd",
  out_dir       = "output/",
  knit_root_dir = getwd(),
  soln_stuff    = soln
)

# The result is a one-row data frame
print(result)
```

The output data frame contains:

| Column | Description |
|--------|-------------|
| `fname` | Student's filename |
| `time_stamp` | Timestamp of the grading run |
| `run_status` | `"SUCCESS"`, `"FAIL"`, or `"UNKNOWN"` |
| `run_time` | Total execution time (seconds) |
| `run_mem` | Memory usage of the environment |
| `lenX`, `lenfn`, ... | Scalar test results defined in `autoharp.scalars` |

### Step 4: Summarise Results Across All Students

```{r summarise}
# Grade all students in a directory
student_files <- list.files("submissions/", pattern = "\\.Rmd$", full.names = TRUE)

results_list <- lapply(student_files, function(f) {
  render_one(rmd_name = f, out_dir = "output/", knit_root_dir = getwd(),
             soln_stuff = soln)
})

all_results <- do.call(rbind, results_list)

# Print a summary from the log file
log_summary("output/render_one.log")
```

---

## Checking Code Style

`autoharp` integrates with the `lintr` package to count style violations:

```{r lints}
# Count lint violations in a single script
lint_count <- count_lints_one("student01.R")

# Count across all submissions
all_lints <- count_lints_all(
  file_names = list.files("submissions/", pattern = "\\.R$", full.names = TRUE)
)
print(all_lints)
```

You can run lint checks separately from the main grading pipeline using these functions.

---

## Checking Rmd Structure

For R Markdown submissions, verify that the file is a valid Rmd:

```{r check-rmd}
# Check that the submitted file is a valid Rmd
# Returns TRUE if file has .Rmd extension, YAML header, and R chunks
rmd_check <- check_rmd(fname = "student01.Rmd")
print(rmd_check)
```

---

## Interactive Grading with Shiny Apps

For large classes, the **Grading App** provides a browser-based interface
that wraps the entire workflow:

```{r grading-app, eval=FALSE}
# Launch the full grading GUI
shiny::runApp(system.file("shiny/grading_app", package = "autoharp"))
```

The Grading App has five tabs:

1. **Session**: start/resume a grading session. 
2. **Object Testing**: auto-generate and run correctness tests. 
3. **Template**: generate a solution template from a script. 
4. **Autoharp**: run `render_one()` for all submissions with progress tracking. 
5. **Plots**: review student plots side-by-side with the solution. 

See the [Shiny Apps Guide](https://namanlab.github.io/autoharp/articles/shiny_grading.html) for full details.

---

## Next Steps

- **[TreeHarp Tutorial](https://namanlab.github.io/autoharp/articles/treeharp_class.html)**: learn AST-based static
  analysis: detect `for` loops, check function signatures, and more
- **[Complete Workflow](https://namanlab.github.io/autoharp/articles/demo_workflow.html)**: a detailed end-to-end walkthrough
  with a real data analysis assignment
- **[Shiny Apps](https://namanlab.github.io/autoharp/articles/shiny_grading.html)**: use the Grading App, Similarity App, and Student Solution Checker
- **[Function Reference](https://namanlab.github.io/autoharp/reference/index.html)**: full API documentation

---

## Getting Help

- 📋 [GitHub Issues](https://github.com/namanlab/autoharp/issues): bug reports and feature requests
- 📖 [Full Documentation](https://namanlab.github.io/autoharp/): pkgdown site
