mirror of
https://github.com/MLSysBook/TinyTorch.git
synced 2026-04-29 02:27:31 -05:00
- Move development artifacts to development/archived/ directory
- Remove NBGrader artifacts (assignments/, testing/, gradebook.db, logs)
- Update root README.md to match actual repository structure
- Provide clear navigation paths for instructors and students
- Remove outdated documentation references
- Clean root directory while preserving essential files
- Maintain all functionality while improving organization
Repository is now optimally structured for classroom use with clear entry points:
- Instructors: docs/INSTRUCTOR_GUIDE.md
- Students: docs/STUDENT_GUIDE.md
- Developers: docs/development/
✅ All functionality verified working after restructuring
774 lines
28 KiB
Plaintext
774 lines
28 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "cbc9ef5f",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\""
|
|
},
|
|
"source": [
|
|
"# Module 0: Setup - Tiny🔥Torch Development Workflow (Enhanced for NBGrader)\n",
|
|
"\n",
|
|
"Welcome to TinyTorch! This module teaches you the development workflow you'll use throughout the course.\n",
|
|
"\n",
|
|
"## Learning Goals\n",
|
|
"- Understand the nbdev notebook-to-Python workflow\n",
|
|
"- Write your first TinyTorch code\n",
|
|
"- Run tests and use the CLI tools\n",
|
|
"- Get comfortable with the development rhythm\n",
|
|
"\n",
|
|
"## The TinyTorch Development Cycle\n",
|
|
"\n",
|
|
"1. **Write code** in this notebook using `#| export` \n",
|
|
"2. **Export code** with `python bin/tito.py sync --module setup`\n",
|
|
"3. **Run tests** with `python bin/tito.py test --module setup`\n",
|
|
"4. **Check progress** with `python bin/tito.py info`\n",
|
|
"\n",
|
|
"## New: NBGrader Integration\n",
|
|
"This module is also configured for automated grading with **100 points total**:\n",
|
|
"- Basic Functions: 30 points\n",
|
|
"- SystemInfo Class: 35 points \n",
|
|
"- DeveloperProfile Class: 35 points\n",
|
|
"\n",
|
|
"Let's get started!"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "43560ba3",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| default_exp core.utils"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "516d08d6",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| export\n",
|
|
"# Setup imports and environment\n",
|
|
"import sys\n",
|
|
"import platform\n",
|
|
"from datetime import datetime\n",
|
|
"import os\n",
|
|
"from pathlib import Path\n",
|
|
"\n",
|
|
"print(\"🔥 TinyTorch Development Environment\")\n",
|
|
"print(f\"Python {sys.version}\")\n",
|
|
"print(f\"Platform: {platform.system()} {platform.release()}\")\n",
|
|
"print(f\"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "97f21ddb",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\"",
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"source": [
|
|
"## Step 1: Basic Functions (30 Points)\n",
|
|
"\n",
|
|
"Let's start with simple functions that form the foundation of TinyTorch."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "caeb1865",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| export\n",
|
|
"def hello_tinytorch():\n",
|
|
" \"\"\"\n",
|
|
" A simple hello world function for TinyTorch.\n",
|
|
" \n",
|
|
" Display TinyTorch ASCII art and welcome message.\n",
|
|
" Load the flame art from tinytorch_flame.txt file with graceful fallback.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Load ASCII art from tinytorch_flame.txt file with graceful fallback\n",
|
|
" #| solution_test: Function should display ASCII art and welcome message\n",
|
|
" #| difficulty: easy\n",
|
|
" #| points: 10\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" try:\n",
|
|
" # Get the directory containing this file\n",
|
|
" current_dir = Path(__file__).parent\n",
|
|
" art_file = current_dir / \"tinytorch_flame.txt\"\n",
|
|
" \n",
|
|
" if art_file.exists():\n",
|
|
" with open(art_file, 'r') as f:\n",
|
|
" ascii_art = f.read()\n",
|
|
" print(ascii_art)\n",
|
|
" print(\"Tiny🔥Torch\")\n",
|
|
" print(\"Build ML Systems from Scratch!\")\n",
|
|
" else:\n",
|
|
" print(\"🔥 TinyTorch 🔥\")\n",
|
|
" print(\"Build ML Systems from Scratch!\")\n",
|
|
" except NameError:\n",
|
|
" # Handle case when running in notebook where __file__ is not defined\n",
|
|
" try:\n",
|
|
" art_file = Path(os.getcwd()) / \"tinytorch_flame.txt\"\n",
|
|
" if art_file.exists():\n",
|
|
" with open(art_file, 'r') as f:\n",
|
|
" ascii_art = f.read()\n",
|
|
" print(ascii_art)\n",
|
|
" print(\"Tiny🔥Torch\")\n",
|
|
" print(\"Build ML Systems from Scratch!\")\n",
|
|
" else:\n",
|
|
" print(\"🔥 TinyTorch 🔥\")\n",
|
|
" print(\"Build ML Systems from Scratch!\")\n",
|
|
" except:\n",
|
|
" print(\"🔥 TinyTorch 🔥\")\n",
|
|
" print(\"Build ML Systems from Scratch!\")\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
"\n",
|
|
"def add_numbers(a, b):\n",
|
|
" \"\"\"\n",
|
|
" Add two numbers together.\n",
|
|
" \n",
|
|
" This is the foundation of all mathematical operations in ML.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Use the + operator to add two numbers\n",
|
|
" #| solution_test: add_numbers(2, 3) should return 5\n",
|
|
" #| difficulty: easy\n",
|
|
" #| points: 10\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return a + b\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "053a090e",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\"",
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"source": [
|
|
"## Hidden Tests: Basic Functions (10 Points)\n",
|
|
"\n",
|
|
"These tests verify the basic functionality and award points automatically."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "347431b1",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"### BEGIN HIDDEN TESTS\n",
|
|
"def test_hello_tinytorch():\n",
|
|
" \"\"\"Test hello_tinytorch function (5 points)\"\"\"\n",
|
|
" import io\n",
|
|
" import sys\n",
|
|
" \n",
|
|
" # Capture output\n",
|
|
" captured_output = io.StringIO()\n",
|
|
" sys.stdout = captured_output\n",
|
|
" \n",
|
|
" try:\n",
|
|
" hello_tinytorch()\n",
|
|
" output = captured_output.getvalue()\n",
|
|
" \n",
|
|
" # Check that some output was produced\n",
|
|
" assert len(output) > 0, \"Function should produce output\"\n",
|
|
" assert \"TinyTorch\" in output, \"Output should contain 'TinyTorch'\"\n",
|
|
" \n",
|
|
" finally:\n",
|
|
" sys.stdout = sys.__stdout__\n",
|
|
"\n",
|
|
"def test_add_numbers():\n",
|
|
" \"\"\"Test add_numbers function (5 points)\"\"\"\n",
|
|
" # Test basic addition\n",
|
|
" assert add_numbers(2, 3) == 5, \"add_numbers(2, 3) should return 5\"\n",
|
|
" assert add_numbers(0, 0) == 0, \"add_numbers(0, 0) should return 0\"\n",
|
|
" assert add_numbers(-1, 1) == 0, \"add_numbers(-1, 1) should return 0\"\n",
|
|
" \n",
|
|
" # Test with floats\n",
|
|
" assert add_numbers(2.5, 3.5) == 6.0, \"add_numbers(2.5, 3.5) should return 6.0\"\n",
|
|
" \n",
|
|
" # Test with negative numbers\n",
|
|
" assert add_numbers(-5, -3) == -8, \"add_numbers(-5, -3) should return -8\"\n",
|
|
"### END HIDDEN TESTS"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "300543ef",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\"",
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"source": [
|
|
"## Step 2: SystemInfo Class (35 Points)\n",
|
|
"\n",
|
|
"Let's create a class that collects and displays system information."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f3d01818",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| export\n",
|
|
"class SystemInfo:\n",
|
|
" \"\"\"\n",
|
|
" Simple system information class.\n",
|
|
" \n",
|
|
" Collects and displays Python version, platform, and machine information.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" def __init__(self):\n",
|
|
" \"\"\"\n",
|
|
" Initialize system information collection.\n",
|
|
" \n",
|
|
" Collect Python version, platform, and machine information.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Use sys.version_info, platform.system(), and platform.machine()\n",
|
|
" #| solution_test: Should store Python version, platform, and machine info\n",
|
|
" #| difficulty: medium\n",
|
|
" #| points: 15\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" self.python_version = sys.version_info\n",
|
|
" self.platform = platform.system()\n",
|
|
" self.machine = platform.machine()\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
" \n",
|
|
" def __str__(self):\n",
|
|
" \"\"\"\n",
|
|
" Return human-readable system information.\n",
|
|
" \n",
|
|
" Format system info as a readable string.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Format as \"Python X.Y on Platform (Machine)\"\n",
|
|
" #| solution_test: Should return formatted string with version and platform\n",
|
|
" #| difficulty: easy\n",
|
|
" #| points: 10\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return f\"Python {self.python_version.major}.{self.python_version.minor} on {self.platform} ({self.machine})\"\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
" \n",
|
|
" def is_compatible(self):\n",
|
|
" \"\"\"\n",
|
|
" Check if system meets minimum requirements.\n",
|
|
" \n",
|
|
" Check if Python version is >= 3.8\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Compare self.python_version with (3, 8) tuple\n",
|
|
" #| solution_test: Should return True for Python >= 3.8\n",
|
|
" #| difficulty: medium\n",
|
|
" #| points: 10\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return self.python_version >= (3, 8)\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "70543e35",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\"",
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"source": [
|
|
"## Hidden Tests: SystemInfo Class (35 Points)\n",
|
|
"\n",
|
|
"These tests verify the SystemInfo class implementation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a837a39f",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"### BEGIN HIDDEN TESTS\n",
|
|
"def test_systeminfo_init():\n",
|
|
" \"\"\"Test SystemInfo initialization (15 points)\"\"\"\n",
|
|
" info = SystemInfo()\n",
|
|
" \n",
|
|
" # Check that attributes are set\n",
|
|
" assert hasattr(info, 'python_version'), \"Should have python_version attribute\"\n",
|
|
" assert hasattr(info, 'platform'), \"Should have platform attribute\"\n",
|
|
" assert hasattr(info, 'machine'), \"Should have machine attribute\"\n",
|
|
" \n",
|
|
" # Check types\n",
|
|
" assert isinstance(info.python_version, tuple), \"python_version should be tuple\"\n",
|
|
" assert isinstance(info.platform, str), \"platform should be string\"\n",
|
|
" assert isinstance(info.machine, str), \"machine should be string\"\n",
|
|
" \n",
|
|
" # Check values are reasonable\n",
|
|
" assert len(info.python_version) >= 2, \"python_version should have at least major.minor\"\n",
|
|
" assert len(info.platform) > 0, \"platform should not be empty\"\n",
|
|
"\n",
|
|
"def test_systeminfo_str():\n",
|
|
" \"\"\"Test SystemInfo string representation (10 points)\"\"\"\n",
|
|
" info = SystemInfo()\n",
|
|
" str_repr = str(info)\n",
|
|
" \n",
|
|
" # Check that the string contains expected elements\n",
|
|
" assert \"Python\" in str_repr, \"String should contain 'Python'\"\n",
|
|
" assert str(info.python_version.major) in str_repr, \"String should contain major version\"\n",
|
|
" assert str(info.python_version.minor) in str_repr, \"String should contain minor version\"\n",
|
|
" assert info.platform in str_repr, \"String should contain platform\"\n",
|
|
" assert info.machine in str_repr, \"String should contain machine\"\n",
|
|
"\n",
|
|
"def test_systeminfo_compatibility():\n",
|
|
" \"\"\"Test SystemInfo compatibility check (10 points)\"\"\"\n",
|
|
" info = SystemInfo()\n",
|
|
" compatibility = info.is_compatible()\n",
|
|
" \n",
|
|
" # Check that it returns a boolean\n",
|
|
" assert isinstance(compatibility, bool), \"is_compatible should return boolean\"\n",
|
|
" \n",
|
|
" # Check that it's reasonable (we're running Python >= 3.8)\n",
|
|
" assert compatibility == True, \"Should return True for Python >= 3.8\"\n",
|
|
"### END HIDDEN TESTS"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "4884a585",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\"",
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"source": [
|
|
"## Step 3: DeveloperProfile Class (35 Points)\n",
|
|
"\n",
|
|
"Let's create a personalized developer profile system."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "446836a3",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| export\n",
|
|
"class DeveloperProfile:\n",
|
|
" \"\"\"\n",
|
|
" Developer profile for personalizing TinyTorch experience.\n",
|
|
" \n",
|
|
" Stores and displays developer information with ASCII art.\n",
|
|
" \"\"\"\n",
|
|
" \n",
|
|
" @staticmethod\n",
|
|
" def _load_default_flame():\n",
|
|
" \"\"\"\n",
|
|
" Load the default TinyTorch flame ASCII art from file.\n",
|
|
" \n",
|
|
" Load from tinytorch_flame.txt with graceful fallback.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Use Path and file operations with try/except for fallback\n",
|
|
" #| solution_test: Should load ASCII art from file or provide fallback\n",
|
|
" #| difficulty: hard\n",
|
|
" #| points: 5\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" try:\n",
|
|
" # Try to get the directory of the current file\n",
|
|
" try:\n",
|
|
" current_dir = os.path.dirname(__file__)\n",
|
|
" except NameError:\n",
|
|
" current_dir = os.getcwd()\n",
|
|
" \n",
|
|
" flame_path = os.path.join(current_dir, 'tinytorch_flame.txt')\n",
|
|
" \n",
|
|
" with open(flame_path, 'r', encoding='utf-8') as f:\n",
|
|
" flame_art = f.read()\n",
|
|
" \n",
|
|
" return f\"\"\"{flame_art}\n",
|
|
" \n",
|
|
" Tiny🔥Torch\n",
|
|
" Build ML Systems from Scratch!\n",
|
|
" \"\"\"\n",
|
|
" except (FileNotFoundError, IOError):\n",
|
|
" # Fallback to simple flame if file not found\n",
|
|
" return \"\"\"\n",
|
|
" 🔥 TinyTorch Developer 🔥\n",
|
|
" . . . . . .\n",
|
|
" . . . . . .\n",
|
|
" . . . . . . .\n",
|
|
" . . . . . . . .\n",
|
|
" . . . . . . . . .\n",
|
|
" . . . . . . . . . .\n",
|
|
" . . . . . . . . . . .\n",
|
|
" . . . . . . . . . . . .\n",
|
|
" . . . . . . . . . . . . .\n",
|
|
". . . . . . . . . . . . . .\n",
|
|
" \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ \\\\ \\\\ \\\\ \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ \\\\ \\\\ \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ \\\\ \\\\ \\\\ / / / / /\n",
|
|
" \\\\ \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ \\\\ / / / / / /\n",
|
|
" \\\\ / / / / / /\n",
|
|
" \\\\/ / / / / /\n",
|
|
" \\\\/ / / / /\n",
|
|
" \\\\/ / / /\n",
|
|
" \\\\/ / /\n",
|
|
" \\\\/ /\n",
|
|
" \\\\/\n",
|
|
" \n",
|
|
" Tiny🔥Torch\n",
|
|
" Build ML Systems from Scratch!\n",
|
|
" \"\"\"\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
" \n",
|
|
" def __init__(self, name=\"Vijay Janapa Reddi\", affiliation=\"Harvard University\", \n",
|
|
" email=\"vj@eecs.harvard.edu\", github_username=\"profvjreddi\", ascii_art=None):\n",
|
|
" \"\"\"\n",
|
|
" Initialize developer profile.\n",
|
|
" \n",
|
|
" Store developer information with sensible defaults.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Store all parameters as instance attributes, use _load_default_flame for ascii_art if None\n",
|
|
" #| solution_test: Should store all developer information\n",
|
|
" #| difficulty: medium\n",
|
|
" #| points: 15\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" self.name = name\n",
|
|
" self.affiliation = affiliation\n",
|
|
" self.email = email\n",
|
|
" self.github_username = github_username\n",
|
|
" self.ascii_art = ascii_art or self._load_default_flame()\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
" \n",
|
|
" def __str__(self):\n",
|
|
" \"\"\"\n",
|
|
" Return formatted developer information.\n",
|
|
" \n",
|
|
" Format as professional signature.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Format as \"👨💻 Name | Affiliation | @username\"\n",
|
|
" #| solution_test: Should return formatted string with name, affiliation, and username\n",
|
|
" #| difficulty: easy\n",
|
|
" #| points: 5\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return f\"👨💻 {self.name} | {self.affiliation} | @{self.github_username}\"\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
" \n",
|
|
" def get_signature(self):\n",
|
|
" \"\"\"\n",
|
|
" Get a short signature for code headers.\n",
|
|
" \n",
|
|
" Return concise signature like \"Built by Name (@github)\"\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Format as \"Built by Name (@username)\"\n",
|
|
" #| solution_test: Should return signature with name and username\n",
|
|
" #| difficulty: easy\n",
|
|
" #| points: 5\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return f\"Built by {self.name} (@{self.github_username})\"\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
" \n",
|
|
" def get_ascii_art(self):\n",
|
|
" \"\"\"\n",
|
|
" Get ASCII art for the profile.\n",
|
|
" \n",
|
|
" Return custom ASCII art or default flame.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Simply return self.ascii_art\n",
|
|
" #| solution_test: Should return stored ASCII art\n",
|
|
" #| difficulty: easy\n",
|
|
" #| points: 5\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return self.ascii_art\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end\n",
|
|
"\n",
|
|
" def get_full_profile(self):\n",
|
|
" \"\"\"\n",
|
|
" Get complete profile with ASCII art.\n",
|
|
" \n",
|
|
" Return full profile display including ASCII art and all details.\n",
|
|
" \"\"\"\n",
|
|
" #| exercise_start\n",
|
|
" #| hint: Format with ASCII art, then developer details with emojis\n",
|
|
" #| solution_test: Should return complete profile with ASCII art and details\n",
|
|
" #| difficulty: medium\n",
|
|
" #| points: 10\n",
|
|
" \n",
|
|
" ### BEGIN SOLUTION\n",
|
|
" return f\"\"\"{self.ascii_art}\n",
|
|
" \n",
|
|
"👨💻 Developer: {self.name}\n",
|
|
"🏛️ Affiliation: {self.affiliation}\n",
|
|
"📧 Email: {self.email}\n",
|
|
"🐙 GitHub: @{self.github_username}\n",
|
|
"🔥 Ready to build ML systems from scratch!\n",
|
|
"\"\"\"\n",
|
|
" ### END SOLUTION\n",
|
|
" \n",
|
|
" #| exercise_end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "be5ec710",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\"",
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"source": [
|
|
"## Hidden Tests: DeveloperProfile Class (35 Points)\n",
|
|
"\n",
|
|
"These tests verify the DeveloperProfile class implementation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "29f9103e",
|
|
"metadata": {
|
|
"lines_to_next_cell": 1
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"### BEGIN HIDDEN TESTS\n",
|
|
"def test_developer_profile_init():\n",
|
|
" \"\"\"Test DeveloperProfile initialization (15 points)\"\"\"\n",
|
|
" # Test with defaults\n",
|
|
" profile = DeveloperProfile()\n",
|
|
" \n",
|
|
" assert hasattr(profile, 'name'), \"Should have name attribute\"\n",
|
|
" assert hasattr(profile, 'affiliation'), \"Should have affiliation attribute\"\n",
|
|
" assert hasattr(profile, 'email'), \"Should have email attribute\"\n",
|
|
" assert hasattr(profile, 'github_username'), \"Should have github_username attribute\"\n",
|
|
" assert hasattr(profile, 'ascii_art'), \"Should have ascii_art attribute\"\n",
|
|
" \n",
|
|
" # Check default values\n",
|
|
" assert profile.name == \"Vijay Janapa Reddi\", \"Should have default name\"\n",
|
|
" assert profile.affiliation == \"Harvard University\", \"Should have default affiliation\"\n",
|
|
" assert profile.email == \"vj@eecs.harvard.edu\", \"Should have default email\"\n",
|
|
" assert profile.github_username == \"profvjreddi\", \"Should have default username\"\n",
|
|
" assert profile.ascii_art is not None, \"Should have ASCII art\"\n",
|
|
" \n",
|
|
" # Test with custom values\n",
|
|
" custom_profile = DeveloperProfile(\n",
|
|
" name=\"Test User\",\n",
|
|
" affiliation=\"Test University\",\n",
|
|
" email=\"test@test.com\",\n",
|
|
" github_username=\"testuser\",\n",
|
|
" ascii_art=\"Custom Art\"\n",
|
|
" )\n",
|
|
" \n",
|
|
" assert custom_profile.name == \"Test User\", \"Should store custom name\"\n",
|
|
" assert custom_profile.affiliation == \"Test University\", \"Should store custom affiliation\"\n",
|
|
" assert custom_profile.email == \"test@test.com\", \"Should store custom email\"\n",
|
|
" assert custom_profile.github_username == \"testuser\", \"Should store custom username\"\n",
|
|
" assert custom_profile.ascii_art == \"Custom Art\", \"Should store custom ASCII art\"\n",
|
|
"\n",
|
|
"def test_developer_profile_str():\n",
|
|
" \"\"\"Test DeveloperProfile string representation (5 points)\"\"\"\n",
|
|
" profile = DeveloperProfile()\n",
|
|
" str_repr = str(profile)\n",
|
|
" \n",
|
|
" assert \"👨💻\" in str_repr, \"Should contain developer emoji\"\n",
|
|
" assert profile.name in str_repr, \"Should contain name\"\n",
|
|
" assert profile.affiliation in str_repr, \"Should contain affiliation\"\n",
|
|
" assert f\"@{profile.github_username}\" in str_repr, \"Should contain @username\"\n",
|
|
"\n",
|
|
"def test_developer_profile_signature():\n",
|
|
" \"\"\"Test DeveloperProfile signature (5 points)\"\"\"\n",
|
|
" profile = DeveloperProfile()\n",
|
|
" signature = profile.get_signature()\n",
|
|
" \n",
|
|
" assert \"Built by\" in signature, \"Should contain 'Built by'\"\n",
|
|
" assert profile.name in signature, \"Should contain name\"\n",
|
|
" assert f\"@{profile.github_username}\" in signature, \"Should contain @username\"\n",
|
|
"\n",
|
|
"def test_developer_profile_ascii_art():\n",
|
|
" \"\"\"Test DeveloperProfile ASCII art (5 points)\"\"\"\n",
|
|
" profile = DeveloperProfile()\n",
|
|
" ascii_art = profile.get_ascii_art()\n",
|
|
" \n",
|
|
" assert isinstance(ascii_art, str), \"ASCII art should be string\"\n",
|
|
" assert len(ascii_art) > 0, \"ASCII art should not be empty\"\n",
|
|
" assert \"TinyTorch\" in ascii_art, \"ASCII art should contain 'TinyTorch'\"\n",
|
|
"\n",
|
|
"def test_default_flame_loading():\n",
|
|
" \"\"\"Test default flame loading (5 points)\"\"\"\n",
|
|
" flame_art = DeveloperProfile._load_default_flame()\n",
|
|
" \n",
|
|
" assert isinstance(flame_art, str), \"Flame art should be string\"\n",
|
|
" assert len(flame_art) > 0, \"Flame art should not be empty\"\n",
|
|
" assert \"TinyTorch\" in flame_art, \"Flame art should contain 'TinyTorch'\"\n",
|
|
"### END HIDDEN TESTS"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f5335cd2",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\""
|
|
},
|
|
"source": [
|
|
"## Test Your Implementation\n",
|
|
"\n",
|
|
"Run these cells to test your implementation:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d979356d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Test basic functions\n",
|
|
"print(\"Testing Basic Functions:\")\n",
|
|
"try:\n",
|
|
" hello_tinytorch()\n",
|
|
" print(f\"2 + 3 = {add_numbers(2, 3)}\")\n",
|
|
" print(\"✅ Basic functions working!\")\n",
|
|
"except Exception as e:\n",
|
|
" print(f\"❌ Error: {e}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "f07fe977",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Test SystemInfo\n",
|
|
"print(\"\\nTesting SystemInfo:\")\n",
|
|
"try:\n",
|
|
" info = SystemInfo()\n",
|
|
" print(f\"System: {info}\")\n",
|
|
" print(f\"Compatible: {info.is_compatible()}\")\n",
|
|
" print(\"✅ SystemInfo working!\")\n",
|
|
"except Exception as e:\n",
|
|
" print(f\"❌ Error: {e}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "92619faf",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Test DeveloperProfile\n",
|
|
"print(\"\\nTesting DeveloperProfile:\")\n",
|
|
"try:\n",
|
|
" profile = DeveloperProfile()\n",
|
|
" print(f\"Profile: {profile}\")\n",
|
|
" print(f\"Signature: {profile.get_signature()}\")\n",
|
|
" print(\"✅ DeveloperProfile working!\")\n",
|
|
"except Exception as e:\n",
|
|
" print(f\"❌ Error: {e}\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "eb20d3cd",
|
|
"metadata": {
|
|
"cell_marker": "\"\"\""
|
|
},
|
|
"source": [
|
|
"## 🎉 Module Complete!\n",
|
|
"\n",
|
|
"You've successfully implemented the setup module with **100 points total**:\n",
|
|
"\n",
|
|
"### Point Breakdown:\n",
|
|
"- **hello_tinytorch()**: 10 points\n",
|
|
"- **add_numbers()**: 10 points \n",
|
|
"- **Basic function tests**: 10 points\n",
|
|
"- **SystemInfo.__init__()**: 15 points\n",
|
|
"- **SystemInfo.__str__()**: 10 points\n",
|
|
"- **SystemInfo.is_compatible()**: 10 points\n",
|
|
"- **DeveloperProfile.__init__()**: 15 points\n",
|
|
"- **DeveloperProfile methods**: 20 points\n",
|
|
"\n",
|
|
"### What's Next:\n",
|
|
"1. Export your code: `tito sync --module setup`\n",
|
|
"2. Run tests: `tito test --module setup`\n",
|
|
"3. Generate assignment: `tito nbgrader generate --module setup`\n",
|
|
"4. Move to Module 1: Tensor!\n",
|
|
"\n",
|
|
"### NBGrader Features:\n",
|
|
"- ✅ Automatic grading with 100 points\n",
|
|
"- ✅ Partial credit for each component\n",
|
|
"- ✅ Hidden tests for comprehensive validation\n",
|
|
"- ✅ Immediate feedback for students\n",
|
|
"- ✅ Compatible with existing TinyTorch workflow\n",
|
|
"\n",
|
|
"Happy building! 🔥"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"jupytext": {
|
|
"main_language": "python"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|