Learning assessments

To directly assess your mastery of the learning objectives of this course, we will conduct a series learning assessments (LAs) over the course of the semester. The use LAs of this course is inspired by mastery-based testing practices found in mathematics. The LAs will appear as in-class paper-based ten-minute quiz, given at the start or end of class each Friday. In addition to new LAs, new versions of past LAs will also be available each Friday so that you can complete those you missed or failed to complete satisfactorily.

As described in the syllabus, LA problems are graded on a binary (Satisfactory/Not-yet-satisfactory) scale. Once you receive a satisfactory on a problem tied to a particular learning objective, you do not need to attempt additional LAS tied to that learning objective in subsequent weeks.

Each Friday, you may choose to attempt as many of the individual assessment problems as you wish.

Rubrics for learning assessments

Programming problems

For programming problems in learning assessments, we are concerned with correctness and design. Pay attention to the prompt for guidance about what aspects of design you need to include in your program, e.g., documentation or explicit test suites.

Because you will not have access to a computer while solving programming problems, we will not expect perfect code; a mismatched parenthesis or two will be fine. However, you should do your best to use correct syntax and correct procedure names.

Other written problems

For problems with written responses, we are looking for responses that address the prompt directly and concisely. In particular, if a written problems asks you to solve a problem in a certain style or show your work, e.g., the trace of the execution of a program, make sure to include this information in the style presented in class.

Sample LAs

  • Collaboration. Explain best practices for solving problems in a collaborative setting.

  • Conditionals. Use Boolean expressions and conditional operations to produce conditional behavior.

  • Data abstraction. Design data structures to separate interface from implementation.

  • Decomposition. Decompose a computational problem into smaller sub-problems amenable to implementation with procedures.

  • Diagramming structures. Use our mental model of memory to describe or diagram the layout of memory for lists, pairs, and vectors/arrays.

  • Dictionaries. Design and write functions that use dictionaries.

  • Documentation. Document programs according to good software engineering principles.

  • Higher-order programming. Write procedures that take other procedures as parameters or return prodedures as results.

  • Lambda-free anonymous procedures. Use cut and composition to simplify computations.

  • List recursion. Design and write recursive functions over lists.

  • Lists. Manipulate lists with fundamental higher-order list functions.

  • Local bindings. Refactor redundancy and add clarity in computations with let-bindings.

  • Numeric recursion. Design and write recursive functions over the natural numbers

  • Procedural abstraction. Take a concrete set of instructions and create a procedure that generalizes that behavior

  • Program style. Write and structure code in ways that make it easier to understand.

  • Randomness. Write programs that produce predictably unpredictable output.

  • Testing. Test programs according to good software engineering principles.

  • Tracing. Trace the execution of a Racket program using a substitutive model of computation.

  • Tree recursion. Design and write recursive functions over trees.

  • Vectors. Design and write functions—potentially, recursive functions—that use vectors.