API Reference#
Annotations#
- class pybryt.annotations.annotation.Annotation(name: Optional[str] = None, limit: Optional[int] = None, group: Optional[str] = None, success_message: Optional[str] = None, failure_message: Optional[str] = None)#
Abstract base class for annotating a reference implementation.
Defines an API and global configurations for all annotations used for marking-up reference implementations. All instances of this class, or any of its subclasses, are added to a singleton list that PyBryt maintains to track all annotations for simple reference creation. Supports bitwise logical operators and contains methods for creating relational annotations (see
RelationalAnnotation
).- Parameters
name (
str
, optional) – the name of the annotationlimit (
int
, optional) – the maximum number of annotations with namename
to track in_TRACKED_ANNOTATIONS
group (
str
, optional) – the name of the group that this annotation belongs tosuccess_message (
str
, optional) – a message to relay to the student if satisfiedfailure_message (
str
, optional) – a message to relay to the student if not satisfied
- after(other_annotation: pybryt.annotations.annotation.Annotation, **kwargs) pybryt.annotations.relation.BeforeAnnotation #
Creates an annotation asserting that this annotation is satisfied after another (i.e. that the satisfying timestamp of this annotation is greater than or equal to that of
other_annotation
).- Parameters
other_annotation (
Annotation
) – the annotation that should be satisfied before this onekwargs – other keyword arguments passed to the
BeforeAnnotation
constructor
- Returns
the annotation asserting the before condition
- Return type
BeforeAnnotation
- before(other_annotation: pybryt.annotations.annotation.Annotation, **kwargs) pybryt.annotations.relation.BeforeAnnotation #
Creates an annotation asserting that this annotation is satisfied before another (i.e. that the satisfying timestamp of this annotation is less than or equal to that of
other_annotation
).- Parameters
other_annotation (
Annotation
) – the annotation that should be satisfied after this onekwargs – other keyword arguments passed to the
BeforeAnnotation
constructor
- Returns
the annotation asserting the before condition
- Return type
BeforeAnnotation
- abstract check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Run the check on the condition asserted by this annotation and return a results object.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
- abstract property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations of this annotation. If this annotation has no children, an empty list.
- Type
list[Annotation]
- failure_message: Optional[str]#
a message to relay to the student if not satisfied
- static get_tracked_annotations() List[pybryt.annotations.annotation.Annotation] #
Returns the list of tracked annotations.
- Returns
the list of tracked annotations
- Return type
list[Annotation]
- group: Optional[str]#
the name of the group that this annotation belongs to
- limit: Optional[int]#
the maximum number of annotations with this name to track in
_TRACKED_ANNOTATIONS
- name: str#
the name of the annotation
- static reset_tracked_annotations() None #
Resets the list of tracked annotations and the mapping of group names to indices in that list.
- success_message: Optional[str]#
a message to relay to the student if satisfied
- to_dict() Dict[str, Any] #
Converts this annotation’s details to a JSON-friendly dictionary format.
Output dictionary contains the annotation’s name, group, limit number, success message, and failure message.
- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
Value Annotations#
Annotations for asserting the presence of a value
- class pybryt.annotations.value.Attribute(obj: Any, attrs: Union[str, List[str]], enforce_type: bool = False, **kwargs)#
Annotation for asserting that an object has an attribute value matching that of another object.
Uses a
Value
annotation to check there exists an object in the students’ code which as a specific attribute, or a series of attributes, with values matching those in the object passed to the constructor. The constructor taks in the object in question and the name of the attribute(s) being studied.- Parameters
obj (
object
) – the object being checkedattrs (
str
orlist[str]
) – the attribute or attributes that should be checkedenforce_type (
bool
, optional) – whether to ensure that the satisfying value has the same type as the initial value**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks whether any of the values in the memory footprint has all of the required attributes, each matching the values expected.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- check_against(other_value: Any) bool #
Check whether an object satisfies this annotation.
- Parameters
other_value (
object
) – the value to check against- Returns
whether this annotation is satisfied by the provided value
- Return type
bool
- property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations of this annotation. If this annotation has no children, an empty list.
- Type
list[Annotation]
- enforce_type: bool#
whether to ensure that the satisfying value has the same type as the initial value
- to_dict() Dict[str, Any] #
Converts this annotation’s details to a JSON-friendly dictionary format.
Output dictionary contains the annotation’s name, group, limit number, success message, and failure message, as well as an
invariants
key with a list of the names of all invariants used in this value annotation, aatol
key with this annotation’s tolerance, and a key for the attributes being checked. This dictionary does not contain the value being tracked.- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
- class pybryt.annotations.value.ReturnValue(value: Any, atol: Optional[Union[float, int]] = None, rtol: Optional[Union[float, int]] = None, invariants: List[pybryt.annotations.invariants.invariant] = [], equivalence_fn: Optional[Callable[[Any, Any], bool]] = None, **kwargs)#
Annotation class for asserting that a value should be returned by a student-written function.
Indicates that a value passed to the constructor should be returned by a call to a student’s function. Values can be of any type that is pickleable by
dill
. Values can specify a list of invariants that will allow objects to be considered “equal.” For values that support arithmetic operators, absolute tolerances can be specified as well.Numeric tolerances are computed as with
numpy.allcose
, where the value is considered “equal enough” if it is within \(v \pm (\texttt{atol} + \texttt{rtol} \cdot |v|)\), where \(v\) is the value of the annotation.- Parameters
value (
object
) – the value that should be observedatol (
float
orint
, optional) – absolute tolerance for numeric valuesrtol (
float
orint
, optional) – relative tolerance for numeric valuesinvariants (
list[invariant]
) – invariants for this valueequivalence_fn (
callable[[object, object], bool]
) – an optional function to check for equivalence between two values, overriding the default provided byValue
**kwargs – additional keyword arguments passed to the
Annotation
constructor
- atol: Optional[Union[float, int]]#
absolute tolerance for numeric values
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that the value tracked by this annotation occurs in the memory footprint.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- equivalence_fn: Optional[Callable[[Any, Any], bool]]#
a function that compares two values and returns True if they’re “equal enough” and False otherwise
- invariants: List[pybryt.annotations.invariants.invariant]#
the invariants for this value
- rtol: Optional[Union[float, int]]#
relative tolerance for numeric values
- value: Any#
a copy of the value passed to the constructor
- class pybryt.annotations.value.Value(value: Any, atol: Optional[Union[float, int]] = None, rtol: Optional[Union[float, int]] = None, invariants: List[pybryt.annotations.invariants.invariant] = [], equivalence_fn: Optional[Callable[[Any, Any], bool]] = None, **kwargs)#
Annotation class for asserting that a value should be observed.
Indicates that a value passed to the constructor should be observed while tracing through the students’ code. Values can be of any type that is pickleable by
dill
. Values can specify a list of invariants that will allow objects to be considered “equal.” For values that support arithmetic operators, absolute tolerances can be specified as well.Numeric tolerances are computed as with
numpy.allcose
, where the value is considered “equal enough” if it is within \(v \pm (\texttt{atol} + \texttt{rtol} \cdot |v|)\), where \(v\) is the value of the annotation.- Parameters
value (
object
) – the value that should be observedatol (
float
orint
, optional) – absolute tolerance for numeric valuesrtol (
float
orint
, optional) – relative tolerance for numeric valuesinvariants (
list[invariant]
) – invariants for this valueequivalence_fn (
callable[[object, object], bool]
) – an optional function to check for equivalence between two values, overriding the default provided byValue
**kwargs – additional keyword arguments passed to the
Annotation
constructor
- atol: Optional[Union[float, int]]#
absolute tolerance for numeric values
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that the value tracked by this annotation occurs in the memory footprint.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- check_against(other_value: Any) bool #
Check whether an object satisfies this annotation.
- Parameters
other_value (
object
) – the value to check against- Returns
whether this annotation is satisfied by the provided value
- Return type
bool
- static check_values_equal(value, other_value, atol=None, rtol=None, equivalence_fn=None) bool #
Checks whether two objects are equal.
If the values are both numeric (numerics, arrays, etc.) and
atol
and/orrtol
are specified, the values are considered equal ifother_value
is within the tolerance bounds ofvalue
.The equivalence check provided by this function can be overridden by providing a custom function to check equivalence. If provided, the value returned by this function is returned, unless an error is thrown, in which case
False
is returned.- Parameters
value (
object
) – the first object to compareother_value (
object
) – the second object to compareatol (
float
, optional) – the absolute tolerance for numeric valuesrtol (
float
, optional) – the relative tolerance for numeric valuesequivalence_fn (
callable[[object, object], bool]
) – an optional function to check for equivalence between two values, overriding the default provided byValue
- property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations of this annotation. If this annotation has no children, an empty list.
- Type
list[Annotation]
- equivalence_fn: Optional[Callable[[Any, Any], bool]]#
a function that compares two values and returns True if they’re “equal enough” and False otherwise
- invariants: List[pybryt.annotations.invariants.invariant]#
the invariants for this value
- rtol: Optional[Union[float, int]]#
relative tolerance for numeric values
- to_dict() Dict[str, Any] #
Converts this annotation’s details to a JSON-friendly dictionary format.
Output dictionary contains the annotation’s name, group, limit number, success message, and failure message, as well as an
invariants
key with a list of the names of all invariants used in this value annotation and aatol
key with this annotation’s tolerance. This dictionary does not contain the value being tracked.- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
- value: Any#
a copy of the value passed to the constructor
Structural Patterns#
- pybryt.annotations.structural.structural#
A singleton that can be used for structural pattern matching.
Structural patterns can be created by accessing attributes of this singleton and calling them with attribute-value pairs as arguments. For example, if you’re matching an instance of
mypackage.Foo
with attributebar
set to2
, a structural pattern for this could be created withpybryt.structural.mypackage.Foo(bar=2)
If there are attributes you want to look for without a specific name, you can pass these as positional arguments:
pybryt.structural.mypackage.Foo(3, bar=2)
To determine whether an object matches the structural pattern, PyBryt imports the package and retrieves the specified class. In the examples above, this would look like
getattr(importlib.import_module("mypackage"), "Foo")
If the provided object is an instance of this class and has the specified attributes, the object matches. You can determine if an object matches a structural pattern using an
==
comparison.If no package is specified for the class, the pattern just checks that the name of the class matches the name of the class in the structural pattern, without importing any modules. For example:
df_pattern = pybryt.structural.DataFrame() df_pattern == pd.DataFrame() # returns True class DataFrame: pass df_pattern == DataFrame() # returns True
Attribute values are matched using the same algorithm as
Value
annotations. If you would like to make use of the options available toValue
annotations, you can also pass an annotation as an attribute value:pybryt.structural.mypackage.Foo(pi=pybryt.Value(np.pi, atol=1e-5))
For checking whether an object contains specific members (determined via the use of Python’s
in
operator), use thecontains_
method:pybryt.structural.mypackage.MyList().contains_(1, 2, 3)
Invariants#
Invariants for value annotations
- class pybryt.annotations.invariants.invariant(*args, **kwargs)#
Abstract base class for invariants.
All subclasses should implement the
run
static method for generating values that this invariant accepts as “correct”. Invariants have a custom__new__
method that returns the value of calling therun
method, making them function as callables.- abstract static run(values: List[Any], **kwargs) List[Any] #
Returns a list of values that this invariant accepts as correct.
Takes in a list of acceptable values from a
Value
annotation and returns a list of values that would evaluate as “the same” under the conditions of this invariant.For example, if
values
as a list with a single element, a numpy matrix, and the invariant was matrix transposition, this method would return a length-2 list containing the original matrix and its transpose.- Parameters
values (
list[object]
) – acceptable values, either from the initial constructor call of the annotation or from the results of other invariantskwargs – additional keyword arguments
- Returns
the values that would evaluate as “the same” under the conditions of this invariant
- Return type
list[object]
- class pybryt.annotations.invariants.list_permutation(*args, **kwargs)#
An invariant that compares iterables (except strings) ignoring ordering, using
sorted
.- static run(values: List[Any]) List[Any] #
Returns a list of values in which all iterables have been sorted.
- Parameters
values (
list[object]
) – acceptable values, either from the initial constructor call of the annotation or from the results of other invariants- Returns
the transformed values
- Return type
list[object]
- class pybryt.annotations.invariants.matrix_transpose(*args, **kwargs)#
An invariant that compares 2-dimensional arrays ignoring transposition.
- static run(values: List[Any]) List[Any] #
Returns a list of values in which all 2D iterables have been converted to NumPy arrays and have had their transpose added
- Parameters
values (
list[object]
) – acceptable values, either from the initial constructor call of the annotation or from the results of other invariants- Returns
the transformed values
- Return type
list[object]
- class pybryt.annotations.invariants.string_capitalization(*args, **kwargs)#
An invariant that compares strings ignoring the capitalization of letters.
- static run(values: List[Any]) List[Any] #
Returns a list of values in which all strings have been lowercased.
- Parameters
values (
list[object]
) – acceptable values, either from the initial constructor call of the annotation or from the results of other invariants- Returns
the transformed values
- Return type
list[object]
Relational Annotations#
Relational annotations for asserting conditions on other annotations
- class pybryt.annotations.relation.AndAnnotation(*annotations, **kwargs)#
Annotation for asserting that a series of annotations are all satisfied.
- Parameters
*annotations (
Annotation
) – the child annotations being operated on**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that all child annotations are satisfied by the values in the memory footprint.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- class pybryt.annotations.relation.BeforeAnnotation#
Annotation for asserting that one annotation occurs before another.
When being
check
is called, ensures that all child annotations are satisfied and then checks that for the \(i^\text{th}\) annotation the \((i+1)^\text{th}\) annotation has a timestamp greater than or equal to its own. Annotations must be passed to the constructor in the order in which they are expected to appear.- Parameters
*annotations (
Annotation
) – the child annotations being operated on**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that all child annotations are satisfied by the memory footprint and that the timestamps of the satisfying values occur in non-decreasing order.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- class pybryt.annotations.relation.NotAnnotation(*annotations, **kwargs)#
Annotation for asserting that a single annotation should not be satisfied.
- Parameters
*annotations (
Annotation
) – the child annotation being operated on**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that the child annotation is not satisfied by the values in the memory footprint.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- class pybryt.annotations.relation.OrAnnotation(*annotations, **kwargs)#
Annotation for asserting that, of a series of annotations, any are satisfied.
- Parameters
*annotations (
Annotation
) – the child annotations being operated on**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that any of the child annotations are satisfied by the memory footprint.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- class pybryt.annotations.relation.RelationalAnnotation(*annotations, **kwargs)#
Abstract base class for annotations that assert some kind of condition (temporal or boolean) on one or more other annotations.
All relational annotations should inherit from this class, which defines a constructor that takes in a list of annotations and any necessary keyword arguments and populates the fields needed for tracking child annotations.
- Parameters
*annotations (
Annotation
) – the child annotations being operated on**kwargs – additional keyword arguments passed to the
Annotation
constructor
- abstract check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Run the check on the condition asserted by this annotation and return a results object.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- property children#
the child annotations that this annotation operates on
- Type
list[Annotation]
- class pybryt.annotations.relation.XorAnnotation(*annotations)#
Annotation for asserting that, of two annotations, one is satisfied and the other is not.
- Parameters
*annotations (
Annotation
) – the child annotations being operated on**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that one child annotation is satisfied and one is not by the memory footprint.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
Complexity Annotations#
Annotation classes for complexity assertions
- class pybryt.annotations.complexity.annotation.ComplexityAnnotation(complexity: Union[pybryt.annotations.complexity.complexities.complexity, pybryt.annotations.complexity.complexities.ComplexityUnion], addl_complexities: List[pybryt.annotations.complexity.complexities.complexity] = [], **kwargs)#
Abstract base class for annotations that assert a condition on the complexity of a student’s code.
All complexity annotations should inherit from this class, which defines a constructor that takes in a complexity class and any necessary keyword arguments. Note that all compelxity annotations require a
name
keyword argument so that they can be matched with their results from the student’s memory footprint.- Parameters
complexity (
complexity
orComplexityUnion
) – the complexity class being assertedaddl_complexities (
list[complexity]
) – additional custom complexity classes to consider**kwargs – additional keyword arguments passed to the
Annotation
constructor
- addl_complexities: List[pybryt.annotations.complexity.complexities.complexity]#
additional complexity classes to consider
- property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations of this annotation. If this annotation has no children, an empty list.
- Type
list[Annotation]
- complexity: Union[pybryt.annotations.complexity.complexities.complexity, pybryt.annotations.complexity.complexities.ComplexityUnion]#
the complexity class of this annotation
- class pybryt.annotations.complexity.annotation.TimeComplexity(complexity: Union[pybryt.annotations.complexity.complexities.complexity, pybryt.annotations.complexity.complexities.ComplexityUnion], addl_complexities: List[pybryt.annotations.complexity.complexities.complexity] = [], **kwargs)#
Annotation for asserting the time complexity of a block of student code.
Time complexity here is defined as the number of execution steps taken while executing the code block, which is determined using the number of calls to PyBryt’s trace function. Use the
check_time_complexity
context manager to check time complexity in student’s code. Thename
of this annotation should be the same as thename
passed to the context manager or this annotation will not be able to find the results of the check.- addl_complexities: List[pybryt.annotations.complexity.complexities.complexity]#
additional complexity classes to consider
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks the time complexity of a block of student code and returns a results object.
Finds all instances of the
TimeComplexityResult
class in the student’s memory footprint and selects all those with matching names. Collects the timing data from each into a dictionary and runs each complexity class incomplexities.complexity_classes
against this data. Returns a result indicating whether the closest-matched complexity class was the one asserted in this annotation’scomplexity
field. Thevalue
of the result object is set to the matching complexity class.- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- complexity: Union[pybryt.annotations.complexity.complexities.complexity, pybryt.annotations.complexity.complexities.ComplexityUnion]#
the complexity class of this annotation
- failure_message: Optional[str]#
a message to relay to the student if not satisfied
- group: Optional[str]#
the name of the group that this annotation belongs to
- limit: Optional[int]#
the maximum number of annotations with this name to track in
_TRACKED_ANNOTATIONS
- name: str#
the name of the annotation
- success_message: Optional[str]#
a message to relay to the student if satisfied
Complexity Classes#
Complexity classes for complexity annotations
- class pybryt.annotations.complexity.complexities.ComplexityClassResult(complexity_class: pybryt.annotations.complexity.complexities.complexity, residual: float)#
A container class for the results of complexity checks.
- complexity_class: pybryt.annotations.complexity.complexities.complexity#
the complexity class associated with this result
- residual: float#
the residual from the least-squares fit
- class pybryt.annotations.complexity.complexities.ComplexityUnion(*complexity_classes: pybryt.annotations.complexity.complexities.complexity)#
A complexity class that represents a union of multiple complexity classes.
Complexity unions can be used to write annotations but cannot be used as classes to determine the complexity of a block of code; they are simply collections of acceptable complexity classes.
This class does not ensure the uniqueness of the complexity classes it tracks; that is, if the same complexity class is added twice, it will be tracked twice.
- Parameters
*complexity_classes (
complexity
) – the complexity classes in the union
- add_complexity(complexity_class: pybryt.annotations.complexity.complexities.complexity) None #
Add another complexity class to this union.
- Parameters
complexity_class (
complexity
) – the complexity class to add
- classmethod from_or(left: Union[pybryt.annotations.complexity.complexities.complexity, pybryt.annotations.complexity.complexities.ComplexityUnion], right: Union[pybryt.annotations.complexity.complexities.complexity, pybryt.annotations.complexity.complexities.ComplexityUnion]) pybryt.annotations.complexity.complexities.ComplexityUnion #
Create a complexity union from two operands.
- Parameters
left (
complexity
orComplexityUnion
) – the left operandright (
complexity
orComplexityUnion
) – the right operand
- Returns
the union containing both operands
- Return type
- Raises
TypeError – if either operand is not a complexity class or complexity union
- get_complexities() List[pybryt.annotations.complexity.complexities.complexity] #
Return a list of the complexity classes in this union.
- Returns
the complexity classes
- Return type
list[complexity]
- class pybryt.annotations.complexity.complexities.complexity#
Abstract base class for a complexity. Subclassses should implement the
transform_n
method, which transforms the input lengths array so that least squares can be used. If needed, thetransform_t
method can also be overwritten to transform the step counter values.The architecture for these and the algorithm for determining the optimal complexity is borrowed from https://github.com/pberkes/big_O.
- abstract static transform_n(n: numpy.ndarray) numpy.ndarray #
Transforms the array of input lengths for performing least squares.
- Parameters
n (
np.ndarray
) – the array of input lengths- Returns
the transformed array of input lengths
- Return type
np.ndarray
- static transform_t(t: numpy.ndarray) numpy.ndarray #
Transforms the array of timings for performing least squares.
- Parameters
n (
np.ndarray
) – the array of timings- Returns
the transformed array of timings
- Return type
np.ndarray
Type Annotations#
Annotations for checking type presence, or lack thereof, within memory footprints
- class pybryt.annotations.type_.ForbidType(type_, **kwargs)#
Annotation class for asserting there are no objects of a specific type in the memory footprint.
Indicates that the student’s memory footprint should not have any values of a certain type. Uses the
isinstance
function to determine if any values match the specified type. The type itself must be pickleable bydill
.- Parameters
type_ (
type
) – the type to forbid**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that there are no values of type
self.type_
in the memory footprint.- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations of this annotation. If this annotation has no children, an empty list.
- Type
list[Annotation]
- to_dict() Dict[str, Any] #
Converts this annotation’s details to a JSON-friendly dictionary format.
Output dictionary contains the annotation’s name, group, limit number, success message, and failure message, as well as the type as a string.
- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
- type_: type#
the type to forbid
Import Annotations#
Annotations for checking imported modules within memory footprints
- class pybryt.annotations.import_.ForbidImport(module, **kwargs)#
Annotation class for asserting that a specific module was not imported.
- Parameters
module (
str
) – the module name to forbid in importable form**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that the memory footprint’s imports don’t contain the specified module.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- module: str#
the module name to forbid
- class pybryt.annotations.import_.ImportAnnotation(module, **kwargs)#
Annotation class for asserting conditions on the set of imported modules
The set of modules imported in the student implementation is determined using
sys.modules
, meaning that subclasses count any modules imported by third-party libaries, not just directly by the student’s code.- Parameters
module (
str
) – the module name to forbid in importable form**kwargs – additional keyword arguments passed to the
Annotation
constructor
- abstract check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Run the check on the condition asserted by this annotation and return a results object.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations of this annotation. If this annotation has no children, an empty list.
- Type
list[Annotation]
- module: str#
the module name to forbid
- to_dict() Dict[str, Any] #
Converts this annotation’s details to a JSON-friendly dictionary format.
Output dictionary contains the annotation’s name, group, limit number, success message, and failure message, as well as the module name.
- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
- class pybryt.annotations.import_.RequireImport(module, **kwargs)#
Annotation class for asserting that a specific module was imported.
- Parameters
module (
str
) – the module name to forbid in importable form**kwargs – additional keyword arguments passed to the
Annotation
constructor
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that the memory footprint’s imports contain the specified module.
- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- failure_message: Optional[str]#
a message to relay to the student if not satisfied
- group: Optional[str]#
the name of the group that this annotation belongs to
- limit: Optional[int]#
the maximum number of annotations with this name to track in
_TRACKED_ANNOTATIONS
- module: str#
the module name to forbid
- name: str#
the name of the annotation
- success_message: Optional[str]#
a message to relay to the student if satisfied
Annotation Collections#
Class for gathering and operating on collections of annotations
- class pybryt.annotations.collection.Collection(*annotations: pybryt.annotations.annotation.Annotation, enforce_order: bool = False, **kwargs)#
A class for collecting and operating on multiple annotations.
If
enforce_order
is true, this collection will only be satisfied if all of its children are satisfied and the satisfying timestamps are in non-decreasing order (for those that have them).- Parameters
*annotations (
Annotation
) – the child annotations being operated onenforce_order (
bool
, optional) – whether to enforce the ordering of annotations as added to this collection**kwargs – additional keyword arguments passed to the
Annotation
constructor
- add(annotation: pybryt.annotations.annotation.Annotation) None #
Adds an annotation to this collection.
- Parameters
annotation (
Annotation
) – the annotation to add
- check(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.annotations.annotation.AnnotationResult #
Checks that all child annotations are satisfied by the values in the memory footprint, and that the timestamps of the satisfying values occur in non-decreasing order if
self.enforce_order
is true.- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check against- Returns
the results of this annotation against
footprint
- Return type
AnnotationResult
- property children: List[pybryt.annotations.annotation.Annotation]#
the child annotations that this annotation operates on
- Type
list[Annotation]
- enforce_order: bool#
whether to enforce the ordering of annotations as added to this collection
- remove(annotation: pybryt.annotations.annotation.Annotation) None #
Removes an annotation from this collection.
- Parameters
annotation (
Annotation
) – the annotation to remove
- to_dict() Dict[str, Any] #
Converts this annotation’s details to a JSON-friendly dictionary format.
- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
Initial Conditions#
Placeholders for student-set initial conditions
- class pybryt.annotations.initial_condition.InitialCondition(name: str, transforms: Optional[List[Callable[[Any], Any]]] = None)#
A placeholder for initial conditions set in the submission.
- Parameters
name (
str
) – the name of the initial conditiontransforms (
list[callable[[object], object]]
, optional) – a list of transformations (single-argument functions) to apply to the value in sequence
- apply(transform: Callable[[Any], Any]) pybryt.annotations.initial_condition.InitialCondition #
Apply an additional transformation to this initial condition, returning a new one.
This instance is not modified; instead, a new initial condition instances is created with all transforms copied from this one but with the addition of the new transformation.
- Parameters
transform (
callable[[object], object]
) – the transformation to add- Returns
the new initial condition instance
- Return type
- name: str#
the name of the initial condition
- supply_footprint(footprint: pybryt.execution.memory_footprint.MemoryFootprint) Any #
Calculate the value of this initial condition with all transformations applied based on the value stored in the provided memory footprint.
- Parameters
initial_conditions (
dict[str, object]
) – the initial conditions- Returns
the value after applying all transformations to it in sequence
- Return type
object
- supply_value(val: Any) Any #
Calculate the value of this initial condition with all transformations applied.
Applies all transformations in this initial condition to the supplied value and returns the result.
- Parameters
val (
object
) – the value to use as the initial condition- Returns
the value after applying all transformations to it in sequence
- Return type
object
- supply_values(vals: Dict[str, Any]) Any #
Calculate the value of this initial condition with all transformations applied using the provided initial condition values.
Applies all transformations in this initial condition to the supplied value and returns the result. If the result is itself an
InitialCondition
, the values dictionary is supplied to that initial condition.- Parameters
vals (
dict[str, object]
) – the values to use as the initial conditions by name- Returns
the value after applying all transformations to it in sequence
- Return type
object
- transforms: List[Callable[[Any], Any]]#
transformations that should be applied to the value, in order
Annotation Results#
- class pybryt.annotations.annotation.AnnotationResult(satisfied: Optional[bool], annotation: pybryt.annotations.annotation.Annotation, value: Optional[Any] = None, timestamp: int = - 1, children: List[pybryt.annotations.annotation.AnnotationResult] = [])#
Class that manages and defines an API for interacting with the results of an annotation.
Created when an annotation calls its
check<pybryt.Annotation.check()
method and wrangles the results of that annotation. Contains fields for tracking child annotation results, values satisfying annotations, and messages returned by this annotation and its children.- Parameters
satisfied (
bool
orNone
) – whether the condition of the annotation was satisfied; if child annotation results should be used to determine this value, set toNone
annotation (
Annotation
) – the annotation that this result is forvalue (
object
, optional) – the value that satisfied the condition of this annotationtimestamp (
int
, optional) – the step counter value at which this annotation was satisfiedchildren (
list[AnnotationResult]
, optional) – child annotation results of this annotation result
- annotation: pybryt.annotations.annotation.Annotation#
the annotation that this result is for
- children: List[pybryt.annotations.annotation.AnnotationResult]#
child annotation results of this annotation result
- property group: Optional[str]#
the group name of the annotation that these results track
- Type
str
orNone
- property messages: List[pybryt.annotations.annotation.AnnotationResultMessage]#
the messages returned by this annotation and its children based on whether or not the annotations were satisfied
- Type
list[AnnotationResultMessage]
- property name: Optional[str]#
the name of the annotation that these results track
- Type
str
orNone
- property satisfied: bool#
whether this annotation was satisfied
- Type
bool
- property satisfied_at: int#
the step counter value at which this annotation was satisfied; if child results are present, this is the maximum satisfying timestamp of all child results; if this annotation was not satisfied, returns -1
- Type
int
- timestamp: int#
the step counter value at which this annotation was satisfied
- to_dict() Dict[str, Any] #
Converts this annotation result’s details to a JSON-friendly dictionary format.
Output dictionary contains the annotation, whether it was satisfied, when it was satisfied, and any child results.
- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
- property value: Any#
the value that satisfied the condition of this annotation
- Type
object
Reference Implementations#
- class pybryt.reference.ReferenceImplementation(name: str, annotations: List[pybryt.annotations.annotation.Annotation], display_name: Optional[str] = None)#
A reference implementation class for managing collections of annotations. Defines methods for creating, running, and storing reference implementations.
- Parameters
name (
str
) – the name of the reference implementationannotations (
list[Annotation]
) – the annotations comprising this reference implementation
- annotations: List[pybryt.annotations.annotation.Annotation]#
the annotations comprising this reference implementation
- classmethod compile(path_or_nb: Union[str, nbformat.notebooknode.NotebookNode], **kwargs) Union[pybryt.reference.ReferenceImplementation, List[pybryt.reference.ReferenceImplementation]] #
Compiles a notebook or Python script into a single or list of reference implementations.
Creates a reference implementation by executing a Jupyter Notebook or Python script and collecting all
ReferenceImplementation
objects created, if any, or allAnnotation
objects otherwise.- Parameters
path_or_nb (
str
ornbformat.NotebookNode
) – the file to be executed**kwargs – additional keyword arguments passed to constructor
- Returns
the reference(s) created by executing the file
- Return type
ReferenceImplementation
orlist[ReferenceImplementation]
- display_name: Optional[str]#
a name to use for this reference in text reports generated by PyBryt
- get(name: str) Union[pybryt.annotations.annotation.Annotation, List[pybryt.annotations.annotation.Annotation]] #
Retrieves and returns annotation(s) using their
name
attribute.Returns a single annotation if there is only one annotation with that name, otherwise returns a list of annotations with that name.
- Parameters
name (
str
) – the name of look up- Returns
the annotation(s) with that name
- Return type
Annotation
orlist[Annotation]
- Raises
ValueError – if there are no annotations with that name
- get_name_for_report() str #
Get the name to use for the report in this reference.
- Returns
the name
- Return type
str
- name: str#
the name of the reference implementation
- run(footprint: pybryt.execution.memory_footprint.MemoryFootprint, group: Optional[str] = None) pybryt.reference.ReferenceResult #
Runs the annotations tracked by this reference implementation against a memory footprint.
Can run only specific annotations by specifying the
group
argument. Returns aReferenceResult
object.- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint to check againstgroup (
str
, optional) – if specified, only annotations in this group will be run
- Returns
the results of this check
- Return type
ReferenceResult
- Raises
ValueError – if
group
is specified but there are no annotations with that group
Reference Results#
- class pybryt.reference.ReferenceResult(reference: pybryt.reference.ReferenceImplementation, annotation_results: List[pybryt.annotations.annotation.AnnotationResult], group: Optional[str] = None)#
Class for wrangling and managing the results of a reference implementation. Collects a series of
AnnotationResult
objects and provides an API for managing those results collectively.- Parameters
reference (
ReferenceImplementation
) – the reference implementationannotation_results (
list[AnnotationResult]
) – the annotation results from running the reference implementationgroup (
str
, optional) – the name of the group of annotations executed, if applicable
- property correct: bool#
whether the reference implementation was satisfied
- Type
bool
- property display_name: str#
the display name of the underlying reference implementation
- Type
str
- group: Optional[str]#
the name of the group of annotations executed, if applicable
- property messages: List[str]#
the list of messages returned by all annotations in the reference implementation; if
self.group
is notNone
, only messages from annotations in that group are returned- Type
list[str]
- property name: str#
the name of the underlying reference implementation
- Type
str
- reference: pybryt.reference.ReferenceImplementation#
the reference implementation executed
- results: List[pybryt.annotations.annotation.AnnotationResult]#
the annotation results from running the reference implementation
- to_array() numpy.ndarray #
Converts this result into a numpy array of integers, where
1
indicates a satisfied annotation and0
is unsatisfied.- Returns
indicator array for the passage of annotations
- Return type
numpy.ndarray
- to_dict() Dict[str, Any] #
Converts this reference result’s details to a JSON-friendly dictionary format.
Output dictionary contains the group name run, if present, and the dictionary representations of all child annotation results.
- Returns
the dictionary representation of this annotation
- Return type
dict[str, object]
- pybryt.reference.generate_report(results: Union[pybryt.reference.ReferenceResult, List[pybryt.reference.ReferenceResult]], show_only: Optional[str] = None, fill_empty: bool = True) str #
Collects a series of reference result objects and returns a summary of these results with any messages from the annotations.
show_only
should be in the set{'satisfied', 'unsatisfied', None}
. If"satisfied"
, the summary will contain only the results of satisfied reference implementations. If"unsatisfied"
, the summary will contain only the results of unsatisfied reference implementations. IfNone
, all reference implementations will be included.If
show_only
is set to a value that would result in an empty report (e.g. it is set to"satisfied"
but no reference was satisfied) andfill_empty
isTrue
, the report will be filled with any references that would normally be excluded byshow_only
.- Parameters
results (
Union[ReferenceResult, list[ReferenceResult]]
) – the result(s) being collectedshow_only (
{'satisfied', 'unsatisfied', None}
) – which results to reportfill_empty (
bool
) – if the resulting report would be empty, include results of the type not specified byshow_only
- Returns
the summary report
- Return type
str
Debug mode#
Debug mode
- pybryt.debug.debug_mode() None #
A context in which debug mode is enabled.
When the context exits, debug mode is disabled globally. This means debug mode will be disabled even if it was enabled before the context was entered.
- pybryt.debug.disable_debug_mode() None #
Disable PyBryt’s debug mode.
- pybryt.debug.enable_debug_mode() None #
Enable PyBryt’s debug mode.
Student Implementations#
Student implementations for PyBryt
- class pybryt.student.StudentImplementation(path_or_nb: Optional[Union[str, nbformat.notebooknode.NotebookNode]], addl_filenames: List[str] = [], output: Optional[str] = None, timeout: Optional[int] = 1200)#
A student implementation class for handling the execution of student work and manging the memory footprint generated by that execution.
- Parameters
path_or_nb (
str
ornbformat.NotebookNode
) – the submission notebook or the path to itaddl_filenames (
list[str]
, optional) – additional filenames to trace inside during executionoutput (
str
, optional) – a path at which to write executed notebooktimeout (
int
, optional) – number of seconds to allow for notebook execution; set toNone
for no time limit
- check(ref: Union[pybryt.reference.ReferenceImplementation, List[pybryt.reference.ReferenceImplementation]], group=None) Union[pybryt.reference.ReferenceResult, List[pybryt.reference.ReferenceResult]] #
Checks this student implementation against a single or list of reference implementations. Returns the
ReferenceResult
object(s) resulting from those checks.- Parameters
ref (
ReferenceImplementation
orlist[ReferenceImplementation]
) – the reference(s) to run againstgroup (
str
, optional) – if specified, only annotations in this group will be run
- Returns
the results of the reference implementation checks
- Return type
ReferenceResult
orlist[ReferenceResult]
- check_plagiarism(student_impls: List[pybryt.student.StudentImplementation], **kwargs) List[pybryt.reference.ReferenceResult] #
Checks this student implementation against a list of other student implementations for plagiarism. Uses
create_references
to create a randomly-generated reference implementation from this student implementation and runs it against each of the implementations instudent_impls
usingget_impl_results
.- Parameters
student_impls (
list[StudentImplementation]
) – other student implementations to run against**kwargs – keyword arguments passed to
create_references
andget_impl_results
- Returns
the results of each student implementation in
student_impls
when run against this student implementation- Return type
list[ReferenceResult]
ornumpy.ndarray
- classmethod combine(impls: List[pybryt.student.StudentImplementation]) pybryt.student.StudentImplementation #
Combine a series of student implementations into a single student implementation.
Collects the memory footprint of each implementation into a single list and offsets the timestamp of each object by the total number of steps for each preceding student implementation in the list.
Assumes that the student implementations are provided in sorted order. Filters out duplicate values present in multiple implementations by keeping the earliest.
- Parameters
impls (
list[StudentImplementation]
) – the list of implementations to combine- Returns
the combined implementation
- Return type
StudentImplementation
- property errors: List[Dict[str, Union[str, List[str]]]]#
a list of error outputs from the executed notebook if present
- Type
list[dict[str, Union[str, list[str]]]]:
- footprint: pybryt.execution.memory_footprint.MemoryFootprint#
the memory footprint
- classmethod from_cache(cache_dir='.pybryt_cache', combine=True) Union[pybryt.student.StudentImplementation, List[pybryt.student.StudentImplementation]] #
Load one or more student implementations from a cache.
All files are combined into a single student implementation by default, but a list can be returned instead by setting
combine=False
.- Parameters
cache_dir (
str
, optional) – the path to the cache directorycombine (
bool
, optional) – whether to combine the implementations
- Returns
the student implementations loaded from the cache.
- Return type
StudentImplementation
orlist[StudentImplementation]
- classmethod from_footprint(footprint: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.student.StudentImplementation #
Create a student implementation object from a memory footprint directly, rather than by executing a notebook. Leaves the
nb
andnb_path
instance variables of the resulting object empty.- Parameters
footprint (
pybryt.execution.memory_footprint.MemoryFootprint
) – the memory footprint
- nb: Optional[nbformat.notebooknode.NotebookNode]#
the submission notebook
- nb_path: Optional[str]#
the path to the notebook file
- class pybryt.student.check(ref: Union[str, pybryt.reference.ReferenceImplementation, List[str], List[pybryt.reference.ReferenceImplementation]], group: Optional[str] = None, report_on_error: bool = True, show_only: Optional[str] = None, cache: bool = True, **kwargs)#
A context manager for running a block of student code against a reference implementation.
This context manager, designed to be used in students’ notebooks, can be used to check a block of student code against one or a series of reference implementations. The context manager turns on tracing before launching the block and captures the memory footprint that is created while the block is executed. It prints out a report upon exiting with information about the passing or failing of each reference and the messages returned.
As an example, the block below uses this context manager to test a student’s implementation of a Fibonacci generator
fiberator
:with pybryt.check("fiberator.pkl"): fib = fiberator() for _ in range(100): next(fib)
- Parameters
ref (
Union[str, ReferenceImplementation, list[str], list[ReferenceImplementation]]
) – the reference(s) to check against or the path(s) to themgroup (
str
, optional) – the name of the group of annotations to run in each referencereport_on_error (
bool
, optional) – whether to print the report when an error is thrown by the blockshow_only (one of
{'satisfied', 'unsatisfied', None}
, optional) – which types of reference results to include in the report; ifNone
, all are included**kwargs – additional keyword arguments passed to
pybryt.execution.create_collector
- pybryt.student.generate_student_impls(paths_or_nbs: List[Union[str, nbformat.notebooknode.NotebookNode]], parallel: bool = False, **kwargs) List[pybryt.student.StudentImplementation] #
Generates multiple student implementations from a list of file paths or notebooks.
Can optionally generate the student implementations in parallel processes using Python’s
multiprocessing
library to reduce the runtime.- Parameters
paths_or_nbs (
list[Union[str, nbformat.NotebookNode]]
) – the notebooks or paths to themparallel (
bool
, optional) – whether to execute in parallel**kwargs – additional keyword arguments passed to the
StudentImplementation
constructor
- Returns
the student implementations
- Return type
list[StudentImplementation]
Execution#
Submission execution internals for PyBryt
- class pybryt.execution.MemoryFootprint(counter: Optional[pybryt.execution.memory_footprint.Counter] = None)#
A memory footprint for an executed notebook.
- Parameters
counter (
pybryt.execution.memory_footprint.Counter
, optional) – a counter to use for this footprint; if unprovided, a new one is initialized
- add_call(filename: str, fn_name: str) None #
Add a function call.
- Parameters
filename (
str
) – the filename of the functionfn_name (
str
) – the name of the function
- add_imports(*modules: str) None #
Add imports to the set of imports
- Parameters
*modules (
str
) – the modules to add
- add_value(val: Any, timestamp: Optional[int] = None, event: Optional[pybryt.execution.memory_footprint.Event] = None, allow_duplicates: bool = False) None #
Add a value to the memory footprint.
If the timestamp is unspeficied, the step counter is polled for the current value. By default, this method does not allow duplicate values to be entered into the footprint; this can be disabled using
allow_duplicates
.- Parameters
value (
object
) – the value to addtimestamp (
int
, optional) – the timestampevent (
Event
, optional) – the event that produced the valueallow_duplicates (
bool
) – whether duplicate values should be allowed in the footprint
- calls: List[Tuple[str, str]]#
the list of function calls tracked by the trace function
- clear() None #
- classmethod combine(*footprints: pybryt.execution.memory_footprint.MemoryFootprint) pybryt.execution.memory_footprint.MemoryFootprint #
Generate a memory footprint by combining memory footprints in-sequence.
Duplicate values in different footprints are removed, keeping the first instance seen. The timestmaps of each footprint are offset by the number of steps in all preceding footprints.
- Parameters
*footprints (
pybryt.execution.memory_footprint.MemoryFootprint
) – the footprints- Returns
the memory footprint
- Return type
- counter: pybryt.execution.memory_footprint.Counter#
the counter used to construct this footprint
- executed_notebook: Optional[nbformat.notebooknode.NotebookNode]#
the final (pre-processed) notebook that was executed, with outputs
- filter_out_unpickleable_values() None #
Filter any unpickleable objects out of the list of value-timestamp tuples in-place.
- classmethod from_values(*values: pybryt.execution.memory_footprint.MemoryFootprintValue) pybryt.execution.memory_footprint.MemoryFootprint #
Generate a memory footprint from values and their timestamps. :param values_and_timestamps: the values :type values_and_timestamps:
MemoryFootprintValue
- Returns
the memory footprint
- Return type
- Raises
TypeError – if any of the values is of the wrong type
- get_initial_conditions() Dict[str, Any] #
Return the initial conditions dictionary.
- Returns
the initial conditions dictionary
- Return type
dict[str, object]
- get_value(index: int) pybryt.execution.memory_footprint.MemoryFootprintValue #
Get the value at the specified index.
- Parameters
index (
int
) – the index- Returns
the value
- Return type
MemoryFootprintValue
- imports: Set[str]#
the set of modules imported during execution
- increment_counter() None #
Increment the step counter by one.
- initial_conditions: Dict[str, Any]#
initial conditions set during execution
- property num_steps: int#
the total number of steps this implementation took
- Type
int
- offset_counter(val: int) None #
Offset the step counter by a specific amount.
- Parameters
val (
int
) – the amount to offset by
- set_executed_notebook(nb: nbformat.notebooknode.NotebookNode) None #
Set the executed notebook of this memory footprint.
- Parameters
nb (
nbformat.NotebookNode
) – the notebook
- set_initial_conditions(initial_conditions: Dict[str, Any]) None #
Update the initial conditions with a dictionary.
- Parameters
initial_conditions (
dict[str, object]
) – a dictionary of initial conditions
- values: List[Tuple[Any, int, Optional[pybryt.execution.memory_footprint.Event]]]#
the values, timestamps, and event types in the footprint
- class pybryt.execution.TimeComplexityResult(name, n, start, stop)#
A class for collecting the results of time complexity check blocks.
- Parameters
name (
str
) – the name of the blockn (
int
) – the input lengthstart (
int
) – the step counter value at the start of the blockstop (
int
) – the step counter value at the end of the block
- n: int#
the input length or the input itself
- name: str#
the name of the block
- start: int#
the step counter value at the start of the block
- stop: int#
the step counter value at the end of the block
- class pybryt.execution.check_time_complexity(name: str, n: Union[int, float, collections.abc.Sized])#
A context manager for checking the time complexity of student code.
Halts tracking of values in memory and sets the trace function to only increment the step counter. When the block exits, the step counter is checked an a
TimeComplexityResult
object is appended to the student’s memory footprint.If the current call stack is not being traced by PyBryt, no action is taken.
- Parameters
name (
str
) – the name of the check; should match with the name of an annotation in the reference implementationn (
Union[int, float, Sized]
) – the input length or the input itself if it supportslen
- footprint: Optional[pybryt.execution.memory_footprint.MemoryFootprint]#
- n: int#
- name: str#
- start_steps: Optional[int]#
- class pybryt.execution.no_tracing#
A context manager for turning tracing off for a block of code in a submission.
If PyBryt is tracing code, any code inside this context will not be traced for values in memory. If PyBryt is not tracing, no action is taken.
with pybryt.no_tracing(): # this code is not traced foo(1) # this code is traced foo(2)
- pybryt.execution.set_initial_conditions(conditions: Dict[str, Any]) None #
Update the initial conditions stored in the active memory footprint if it exists.
- Parameters
conditions (
dict[str, object]
) – a dictionary of initial conditions
Complexity Analysis#
Time complexity analysis utilities
- class pybryt.complexity.TimeComplexityChecker(name: Optional[str] = None)#
A utility class for using PyBryt’s tracing functionality to check the time complexity of a block of code.
Uses PyBryt’s tracing internals to set a trace function that counts the number of steps taken to execute a block of code, and then uses the complexity annotation framework to determine the best-matched complexity class of the block.
- add_result(result: pybryt.execution.complexity.TimeComplexityResult) None #
Add a time complexity result to the collection of results.
- Parameters
result (
TimeComplexityResult
) – the result object
- determine_complexity() pybryt.annotations.complexity.complexities.complexity #
Determine the best-matched complexity class based on the results collected.
- Returns
the complexity class corresponding to the best-matched complexity
- Return type
- name: str#
the name to use for the annotation
- results: List[pybryt.execution.complexity.TimeComplexityResult]#
the result objects holding the step data for each input length