Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .github/.keep
Empty file.
67 changes: 67 additions & 0 deletions .github/workflows/classroom.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Autograding Tests
'on':
- workflow_dispatch
- repository_dispatch
permissions:
checks: write
actions: read
contents: read
jobs:
run-autograding-tests:
runs-on: ubuntu-latest
if: github.actor != 'github-classroom[bot]'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup
id: setup
uses: classroom-resources/autograding-command-grader@v1
with:
test-name: Setup
setup-command: sudo -H pip3 install -qr requirements.txt; sudo -H pip3 install
flake8==5.0.4
command: flake8 --ignore "N801, E203, E266, E501, W503, F812, E741, N803,
N802, N806" minitorch/ tests/ project/; mypy minitorch/*
timeout: 10
- name: Task 0.1
id: task-0-1
uses: classroom-resources/autograding-command-grader@v1
with:
test-name: Task 0.1
setup-command: sudo -H pip3 install -qr requirements.txt
command: pytest -m task0_1
timeout: 10
- name: Task 0.2
id: task-0-2
uses: classroom-resources/autograding-command-grader@v1
with:
test-name: Task 0.2
setup-command: sudo -H pip3 install -qr requirements.txt
command: pytest -m task0_2
timeout: 10
- name: Task 0.3
id: task-0-3
uses: classroom-resources/autograding-command-grader@v1
with:
test-name: Task 0.3
setup-command: sudo -H pip3 install -qr requirements.txt
command: pytest -m task0_3
timeout: 10
- name: Task 0.4
id: task-0-4
uses: classroom-resources/autograding-command-grader@v1
with:
test-name: Task 0.4
setup-command: sudo -H pip3 install -qr requirements.txt
command: pytest -m task0_4
timeout: 10
- name: Autograding Reporter
uses: classroom-resources/autograding-grading-reporter@v1
env:
SETUP_RESULTS: "${{steps.setup.outputs.result}}"
TASK-0-1_RESULTS: "${{steps.task-0-1.outputs.result}}"
TASK-0-2_RESULTS: "${{steps.task-0-2.outputs.result}}"
TASK-0-3_RESULTS: "${{steps.task-0-3.outputs.result}}"
TASK-0-4_RESULTS: "${{steps.task-0-4.outputs.result}}"
with:
runners: setup,task-0-1,task-0-2,task-0-3,task-0-4
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[![Open in Visual Studio Code](https://classroom.github.com/assets/open-in-vscode-2e0aaae1b6195c2367325f4f02e2d04e9abb55f0b24a779b69b11b9e10269abc.svg)](https://classroom.github.com/online_ide?assignment_repo_id=19910318&assignment_repo_type=AssignmentRepo)
# MiniTorch Module 0

<img src="https://minitorch.github.io/minitorch.svg" width="50%">
Expand Down
24 changes: 17 additions & 7 deletions minitorch/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,29 @@ def circle(N):


def spiral(N):

def x(t):
return t * math.cos(t) / 20.0

def y(t):
return t * math.sin(t) / 20.0
X = [(x(10.0 * (float(i) / (N // 2))) + 0.5, y(10.0 * (float(i) / (N //
2))) + 0.5) for i in range(5 + 0, 5 + N // 2)]
X = X + [(y(-10.0 * (float(i) / (N // 2))) + 0.5, x(-10.0 * (float(i) /
(N // 2))) + 0.5) for i in range(5 + 0, 5 + N // 2)]

X = [
(x(10.0 * (float(i) / (N // 2))) + 0.5, y(10.0 * (float(i) / (N // 2))) + 0.5)
for i in range(5 + 0, 5 + N // 2)
]
X = X + [
(y(-10.0 * (float(i) / (N // 2))) + 0.5, x(-10.0 * (float(i) / (N // 2))) + 0.5)
for i in range(5 + 0, 5 + N // 2)
]
y2 = [0] * (N // 2) + [1] * (N // 2)
return Graph(N, X, y2)


datasets = {'Simple': simple, 'Diag': diag, 'Split': split, 'Xor': xor,
'Circle': circle, 'Spiral': spiral}
datasets = {
"Simple": simple,
"Diag": diag,
"Split": split,
"Xor": xor,
"Circle": circle,
"Spiral": spiral,
}
100 changes: 98 additions & 2 deletions minitorch/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,71 @@
# $f(x) = |x - y| < 1e-2$


# TODO: Implement for Task 0.1.
def mul(x: float, y: float) -> float:
return x * y


def id(x: float) -> float:
return x


def add(x: float, y: float) -> float:
return x + y


def neg(x: float) -> float:
return -x


def lt(x: float, y: float) -> bool:
return x < y


def eq(x: float, y: float) -> bool:
return x == y


def max(x: float, y: float) -> float:
return x if x > y else y


def is_close(x: float, y: float) -> bool:
return abs(x - y) < 1e-2


def sigmoid(x: float) -> float:
if x >= 0:
return 1.0 / (1.0 + math.exp(-x))
else:
return math.exp(x) / (1.0 + math.exp(x))


def relu(x: float) -> float:
return x if x > 0 else 0.0


def log(x: float) -> float:
return math.log(x)


def exp(x: float) -> float:
return math.exp(x)


def log_back(x: float, y: float) -> float:
return y / x


def inv(x: float) -> float:
return 1.0 / x


def inv_back(x: float, y: float) -> float:
return -y / (x * x)


def relu_back(x: float, y: float) -> float:
return y if x > 0 else 0.0


# ## Task 0.3
Expand All @@ -51,4 +115,36 @@
# - prod: take the product of lists


# TODO: Implement for Task 0.3.
def map(fn: Callable[[float], float], ls: Iterable[float]) -> Iterable[float]:
return [fn(x) for x in ls]


def zipWith(
fn: Callable[[float, float], float], ls1: Iterable[float], ls2: Iterable[float]
) -> Iterable[float]:
return [fn(x, y) for x, y in zip(ls1, ls2)]


def reduce(
fn: Callable[[float, float], float], ls: Iterable[float], start: float
) -> float:
res = start
for x in ls:
res = fn(res, x)
return res


def negList(ls: Iterable[float]) -> Iterable[float]:
return map(neg, ls)


def addLists(ls1: Iterable[float], ls2: Iterable[float]) -> Iterable[float]:
return zipWith(add, ls1, ls2)


def sum(ls: Iterable[float]) -> float:
return reduce(add, ls, 0.0)


def prod(ls: Iterable[float]) -> float:
return reduce(mul, ls, 1.0)
28 changes: 14 additions & 14 deletions tests/test_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,41 +107,42 @@ def test_sigmoid(a: float) -> None:
* It crosses 0 at 0.5
* It is strictly increasing.
"""
# TODO: Implement for Task 0.2.
raise NotImplementedError("Need to implement for Task 0.2")
assert 0.0 <= sigmoid(a) <= 1.0
assert_close(sigmoid(-a), 1.0 - sigmoid(a))
assert_close(sigmoid(0.0), 0.5)
assert sigmoid(a) >= sigmoid(a - 1.0)


@pytest.mark.task0_2
@given(small_floats, small_floats, small_floats)
def test_transitive(a: float, b: float, c: float) -> None:
"""Test the transitive property of less-than (a < b and b < c implies a < c)"""
# TODO: Implement for Task 0.2.
raise NotImplementedError("Need to implement for Task 0.2")
if lt(a, b) and lt(b, c):
assert lt(a, c)


@pytest.mark.task0_2
def test_symmetric() -> None:
@given(small_floats, small_floats)
def test_symmetric(a: float, b: float) -> None:
"""Write a test that ensures that :func:`minitorch.operators.mul` is symmetric, i.e.
gives the same value regardless of the order of its input.
"""
# TODO: Implement for Task 0.2.
raise NotImplementedError("Need to implement for Task 0.2")
assert_close(mul(a, b), mul(b, a))


@pytest.mark.task0_2
def test_distribute() -> None:
@given(small_floats, small_floats, small_floats)
def test_distribute(x: float, y: float, z: float) -> None:
r"""Write a test that ensures that your operators distribute, i.e.
:math:`z \times (x + y) = z \times x + z \times y`
"""
# TODO: Implement for Task 0.2.
raise NotImplementedError("Need to implement for Task 0.2")
assert_close(mul(z, add(x, y)), add(mul(z, x), mul(z, y)))


@pytest.mark.task0_2
def test_other() -> None:
"""Write a test that ensures some other property holds for your functions."""
# TODO: Implement for Task 0.2.
raise NotImplementedError("Need to implement for Task 0.2")
assert_close(mul(0.0, 0.0), 0.0)


# ## Task 0.3 - Higher-order functions
Expand All @@ -168,8 +169,7 @@ def test_sum_distribute(ls1: List[float], ls2: List[float]) -> None:
"""Write a test that ensures that the sum of `ls1` plus the sum of `ls2`
is the same as the sum of each element of `ls1` plus each element of `ls2`.
"""
# TODO: Implement for Task 0.3.
raise NotImplementedError("Need to implement for Task 0.3")
assert_close(sum(addLists(ls1, ls2)), sum(ls1) + sum(ls2))


@pytest.mark.task0_3
Expand Down