Add multiple solution blocks example to NBGrader assignment

- Add complex_calculation() function demonstrating multiple solution blocks within single function
- Shows how NBGrader can guide students through step-by-step implementation
- Each solution block replaced with '# YOUR CODE HERE' + 'raise NotImplementedError()' in student version
- Update total points from 85 to 95 to account for new 10-point problem
- Add comprehensive test coverage for multi-step function
- Demonstrate educational pattern: Step 1 → Step 2 → Step 3 within one function
- Perfect example of NBGrader's guided learning capabilities
This commit is contained in:
Vijay Janapa Reddi
2025-07-12 12:47:30 -04:00
parent 3d81f76897
commit 84c4f54dd5
6 changed files with 1044 additions and 171 deletions

View File

@@ -2,20 +2,35 @@
"cells": [
{
"cell_type": "markdown",
"id": "fc1bae4e",
"id": "71411c2b",
"metadata": {
"cell_marker": "\"\"\""
},
"source": [
"# Assignment 0: Setup - TinyTorch Development Environment (INSTRUCTOR VERSION)\n",
"# Assignment 0: Setup - TinyTorch Development Environment\n",
"\n",
"This is the instructor solution version showing how solutions are filled in."
"Welcome to TinyTorch! In this assignment, you'll set up your development environment and create your first utilities for the TinyTorch ML framework.\n",
"\n",
"## Learning Objectives\n",
"- Set up and verify your TinyTorch development environment\n",
"- Create utility functions for the framework\n",
"- Learn the development workflow: implement \u2192 export \u2192 test \u2192 use\n",
"- Get familiar with the TinyTorch CLI tools\n",
"\n",
"## Assignment Overview\n",
"You'll implement 4 core utilities that will be used throughout the TinyTorch framework:\n",
"1. A welcome function with ASCII art loading\n",
"2. A simple math utility function\n",
"3. A system information collector\n",
"4. A developer profile manager\n",
"\n",
"Let's get started!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "876aef2e",
"id": "c55c229f",
"metadata": {},
"outputs": [],
"source": [
@@ -25,7 +40,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "e9d346d7",
"id": "596b9d04",
"metadata": {},
"outputs": [],
"source": [
@@ -40,21 +55,34 @@
},
{
"cell_type": "markdown",
"id": "687b365f",
"id": "3ea55764",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 1: Hello Function (10 points)\n",
"## Problem 1: Hello Function (5 points)\n",
"\n",
"Write a function that displays a welcome message for TinyTorch."
"Create a function that displays a welcome message for TinyTorch. This function should try to load ASCII art from a file, but gracefully fall back to a simple banner if the file doesn't exist.\n",
"\n",
"**Requirements:**\n",
"- Try to read 'tinytorch_flame.txt' from the current directory\n",
"- If the file exists, print its contents\n",
"- If the file doesn't exist, print a simple \"TinyTorch\" banner\n",
"- Always print \"Build ML Systems from Scratch!\" after the banner\n",
"- Handle any file reading errors gracefully\n",
"\n",
"**Example Output:**\n",
"```\n",
"TinyTorch\n",
"Build ML Systems from Scratch!\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c8f5870e",
"id": "72997c78",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
@@ -85,10 +113,114 @@
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "d9bc4a93",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 2: Multi-Step Math Function (10 points)\n",
"\n",
"Create a function that demonstrates multiple solution blocks within one function. This shows how NBGrader can guide you through step-by-step implementation.\n",
"\n",
"**Requirements:**\n",
"- Step 1: Add 2 to each input variable\n",
"- Step 2: Sum the modified variables \n",
"- Step 3: Multiply the result by 10\n",
"- Return the final result\n",
"\n",
"**Example:**\n",
"```python\n",
"complex_calculation(3, 4) # Step 1: 5, 6 Step 2: 11 Step 3: 110\n",
"```\n",
"\n",
"**Note:** This function demonstrates how you can have multiple solution blocks within a single function for guided learning!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a6d8a5a",
"id": "a522e76a",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
"grade": false,
"grade_id": "multi_step_function",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"#| export\n",
"def complex_calculation(a, b):\n",
" \"\"\"\n",
" Perform a multi-step calculation with guided implementation.\n",
" \n",
" Args:\n",
" a: First number\n",
" b: Second number\n",
" \n",
" Returns:\n",
" Result of multi-step calculation\n",
" \"\"\"\n",
" # Step 1: Add 2 to each input variable\n",
" # a_plus_2 = ...\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" ### END SOLUTION\n",
" \n",
" # Step 2: Sum everything\n",
" # everything_summed = ...\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" ### END SOLUTION\n",
" \n",
" # Step 3: Multiply your previous result by 10\n",
" # Hint: you can use np.multiply if you want people to hate you\n",
" # everything_summed_times_10 = ...\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" ### END SOLUTION\n",
" \n",
" return everything_summed_times_10"
]
},
{
"cell_type": "markdown",
"id": "063a9433",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 3: Basic Math Function (5 points)\n",
"\n",
"Create a simple addition function. This might seem trivial, but it's important to verify our basic development workflow is working correctly.\n",
"\n",
"**Requirements:**\n",
"- Accept two parameters (a and b)\n",
"- Return their sum\n",
"- Handle both integers and floats\n",
"\n",
"**Example:**\n",
"```python\n",
"add_numbers(3, 4) # Returns 7\n",
"add_numbers(2.5, 1.5) # Returns 4.0\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe31465d",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
@@ -120,10 +252,34 @@
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "371fa64f",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 4: System Information Class (20 points)\n",
"\n",
"Create a class that collects and displays system information. This will help us understand the environment where TinyTorch is running.\n",
"\n",
"**Requirements:**\n",
"- Collect Python version, platform, and machine architecture in `__init__`\n",
"- Implement `__str__` to return formatted system info\n",
"- Implement `is_compatible()` to check if Python version >= 3.8\n",
"- Store information as instance variables\n",
"\n",
"**Example Output:**\n",
"```\n",
"Python 3.9.7 on Darwin (arm64)\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "693d10ea",
"id": "177d04a8",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
@@ -174,11 +330,38 @@
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "973d993c",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 5: Developer Profile Class (30 points)\n",
"\n",
"Create a class to manage developer profiles. This will be used to track who's working on different parts of the TinyTorch framework.\n",
"\n",
"**Requirements:**\n",
"- Store developer information (name, email, affiliation, specialization)\n",
"- Implement `__str__` for basic representation\n",
"- Implement `get_signature()` for formatted signature\n",
"- Implement `get_profile_info()` to return all info as a dictionary\n",
"\n",
"**Example:**\n",
"```python\n",
"dev = DeveloperProfile(\"Alice\", \"alice@example.com\", \"University\", \"Neural Networks\")\n",
"print(dev) # \"Alice (alice@example.com)\"\n",
"print(dev.get_signature()) # Formatted signature with all info\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "77e585a9",
"id": "dc9efa71",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
"grade": false,
"grade_id": "developer_profile_class",
@@ -238,7 +421,94 @@
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" ### END SOLUTION "
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "36d68622",
"metadata": {
"cell_marker": "\"\"\""
},
"source": [
"## Testing Your Implementation\n",
"\n",
"Once you've implemented all the functions above, run the cells below to test your work!\n",
"\n",
"Remember the TinyTorch workflow:\n",
"1. **Implement** the functions above\n",
"2. **Export** to package: `tito module export 00_setup`\n",
"3. **Test** your work: `pytest tests/ -v`\n",
"4. **Use** your code: `from tinytorch.core.utils import hello_tinytorch`"
]
},
{
"cell_type": "markdown",
"id": "69d475e2",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 6: Integration Test (30 points)\n",
"\n",
"Test that all your components work together correctly. This ensures your implementation is complete and ready for export to the TinyTorch package.\n",
"\n",
"**Requirements:**\n",
"- Test all functions and classes work correctly\n",
"- Test the multi-step function with multiple solution blocks\n",
"- Verify system compatibility \n",
"- Display a complete developer profile\n",
"- Show successful framework initialization\n",
"\n",
"**Total Points: 95/95**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "de9fabc9",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
"grade": true,
"grade_id": "integration_test",
"locked": false,
"points": 30,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"def test_integration():\n",
" \"\"\"\n",
" Integration test to verify all components work together.\n",
" This function tests the complete TinyTorch setup workflow.\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "fe968fb0",
"metadata": {
"cell_marker": "\"\"\""
},
"source": [
"## Next Steps\n",
"\n",
"After completing this assignment:\n",
"1. Export your code to the TinyTorch package\n",
"2. Run the tests to verify everything works\n",
"3. Try importing and using your functions\n",
"4. Move on to the next assignment!\n",
"\n",
"You've just created the foundation utilities for TinyTorch. Great job! \ud83c\udf89"
]
}
],

View File

@@ -2,20 +2,35 @@
"cells": [
{
"cell_type": "markdown",
"id": "fc1bae4e",
"id": "71411c2b",
"metadata": {
"cell_marker": "\"\"\""
},
"source": [
"# Assignment 0: Setup - TinyTorch Development Environment (INSTRUCTOR VERSION)\n",
"# Assignment 0: Setup - TinyTorch Development Environment\n",
"\n",
"This is the instructor solution version showing how solutions are filled in."
"Welcome to TinyTorch! In this assignment, you'll set up your development environment and create your first utilities for the TinyTorch ML framework.\n",
"\n",
"## Learning Objectives\n",
"- Set up and verify your TinyTorch development environment\n",
"- Create utility functions for the framework\n",
"- Learn the development workflow: implement → export → test → use\n",
"- Get familiar with the TinyTorch CLI tools\n",
"\n",
"## Assignment Overview\n",
"You'll implement 4 core utilities that will be used throughout the TinyTorch framework:\n",
"1. A welcome function with ASCII art loading\n",
"2. A simple math utility function\n",
"3. A system information collector\n",
"4. A developer profile manager\n",
"\n",
"Let's get started!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "876aef2e",
"id": "c55c229f",
"metadata": {},
"outputs": [],
"source": [
@@ -25,7 +40,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "e9d346d7",
"id": "596b9d04",
"metadata": {},
"outputs": [],
"source": [
@@ -40,21 +55,34 @@
},
{
"cell_type": "markdown",
"id": "687b365f",
"id": "3ea55764",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 1: Hello Function (10 points)\n",
"## Problem 1: Hello Function (5 points)\n",
"\n",
"Write a function that displays a welcome message for TinyTorch."
"Create a function that displays a welcome message for TinyTorch. This function should try to load ASCII art from a file, but gracefully fall back to a simple banner if the file doesn't exist.\n",
"\n",
"**Requirements:**\n",
"- Try to read 'tinytorch_flame.txt' from the current directory\n",
"- If the file exists, print its contents\n",
"- If the file doesn't exist, print a simple \"TinyTorch\" banner\n",
"- Always print \"Build ML Systems from Scratch!\" after the banner\n",
"- Handle any file reading errors gracefully\n",
"\n",
"**Example Output:**\n",
"```\n",
"TinyTorch\n",
"Build ML Systems from Scratch!\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c8f5870e",
"id": "72997c78",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
@@ -80,15 +108,128 @@
" 4. Handle any exceptions gracefully\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" try:\n",
" # Try to read the ASCII art file\n",
" flame_file = Path('tinytorch_flame.txt')\n",
" if flame_file.exists():\n",
" print(flame_file.read_text().strip())\n",
" else:\n",
" print(\"TinyTorch\")\n",
" except (FileNotFoundError, OSError, UnicodeDecodeError):\n",
" # If file doesn't exist or can't be read, show simple banner\n",
" print(\"TinyTorch\")\n",
" \n",
" # Always print the tagline\n",
" print(\"Build ML Systems from Scratch!\")\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "d9bc4a93",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 2: Multi-Step Math Function (10 points)\n",
"\n",
"Create a function that demonstrates multiple solution blocks within one function. This shows how NBGrader can guide you through step-by-step implementation.\n",
"\n",
"**Requirements:**\n",
"- Step 1: Add 2 to each input variable\n",
"- Step 2: Sum the modified variables \n",
"- Step 3: Multiply the result by 10\n",
"- Return the final result\n",
"\n",
"**Example:**\n",
"```python\n",
"complex_calculation(3, 4) # Step 1: 5, 6 Step 2: 11 Step 3: 110\n",
"```\n",
"\n",
"**Note:** This function demonstrates how you can have multiple solution blocks within a single function for guided learning!"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3a6d8a5a",
"id": "a522e76a",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
"grade": false,
"grade_id": "multi_step_function",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"#| export\n",
"def complex_calculation(a, b):\n",
" \"\"\"\n",
" Perform a multi-step calculation with guided implementation.\n",
" \n",
" Args:\n",
" a: First number\n",
" b: Second number\n",
" \n",
" Returns:\n",
" Result of multi-step calculation\n",
" \"\"\"\n",
" # Step 1: Add 2 to each input variable\n",
" # a_plus_2 = ...\n",
" ### BEGIN SOLUTION\n",
" a_plus_2 = a + 2\n",
" b_plus_2 = b + 2\n",
" ### END SOLUTION\n",
" \n",
" # Step 2: Sum everything\n",
" # everything_summed = ...\n",
" ### BEGIN SOLUTION\n",
" everything_summed = a_plus_2 + b_plus_2\n",
" ### END SOLUTION\n",
" \n",
" # Step 3: Multiply your previous result by 10\n",
" # Hint: you can use np.multiply if you want people to hate you\n",
" # everything_summed_times_10 = ...\n",
" ### BEGIN SOLUTION\n",
" everything_summed_times_10 = everything_summed * 10\n",
" ### END SOLUTION\n",
" \n",
" return everything_summed_times_10"
]
},
{
"cell_type": "markdown",
"id": "063a9433",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 3: Basic Math Function (5 points)\n",
"\n",
"Create a simple addition function. This might seem trivial, but it's important to verify our basic development workflow is working correctly.\n",
"\n",
"**Requirements:**\n",
"- Accept two parameters (a and b)\n",
"- Return their sum\n",
"- Handle both integers and floats\n",
"\n",
"**Example:**\n",
"```python\n",
"add_numbers(3, 4) # Returns 7\n",
"add_numbers(2.5, 1.5) # Returns 4.0\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe31465d",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
@@ -115,15 +256,38 @@
" Sum of a and b\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" return a + b\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "371fa64f",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 4: System Information Class (20 points)\n",
"\n",
"Create a class that collects and displays system information. This will help us understand the environment where TinyTorch is running.\n",
"\n",
"**Requirements:**\n",
"- Collect Python version, platform, and machine architecture in `__init__`\n",
"- Implement `__str__` to return formatted system info\n",
"- Implement `is_compatible()` to check if Python version >= 3.8\n",
"- Store information as instance variables\n",
"\n",
"**Example Output:**\n",
"```\n",
"Python 3.9.7 on Darwin (arm64)\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "693d10ea",
"id": "177d04a8",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
@@ -149,8 +313,15 @@
" Collect Python version, platform, and machine information.\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" # Get Python version info\n",
" version_info = sys.version_info\n",
" self.python_version = f\"{version_info.major}.{version_info.minor}.{version_info.micro}\"\n",
" \n",
" # Get platform information\n",
" self.platform = platform.system()\n",
" \n",
" # Get machine architecture\n",
" self.machine = platform.machine()\n",
" ### END SOLUTION\n",
" \n",
" def __str__(self):\n",
@@ -159,8 +330,7 @@
" Format: \"Python X.Y.Z on Platform (Architecture)\"\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" return f\"Python {self.python_version} on {self.platform} ({self.machine})\"\n",
" ### END SOLUTION\n",
" \n",
" def is_compatible(self):\n",
@@ -169,16 +339,42 @@
" Returns True if compatible, False otherwise.\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" return sys.version_info[:2] >= (3, 8)\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "973d993c",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 5: Developer Profile Class (30 points)\n",
"\n",
"Create a class to manage developer profiles. This will be used to track who's working on different parts of the TinyTorch framework.\n",
"\n",
"**Requirements:**\n",
"- Store developer information (name, email, affiliation, specialization)\n",
"- Implement `__str__` for basic representation\n",
"- Implement `get_signature()` for formatted signature\n",
"- Implement `get_profile_info()` to return all info as a dictionary\n",
"\n",
"**Example:**\n",
"```python\n",
"dev = DeveloperProfile(\"Alice\", \"alice@example.com\", \"University\", \"Neural Networks\")\n",
"print(dev) # \"Alice (alice@example.com)\"\n",
"print(dev.get_signature()) # Formatted signature with all info\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "77e585a9",
"id": "dc9efa71",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
"grade": false,
"grade_id": "developer_profile_class",
@@ -207,8 +403,10 @@
" specialization: Developer's area of specialization\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" self.name = name\n",
" self.email = email\n",
" self.affiliation = affiliation\n",
" self.specialization = specialization\n",
" ### END SOLUTION\n",
" \n",
" def __str__(self):\n",
@@ -217,8 +415,7 @@
" Format: \"Name (email)\"\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" return f\"{self.name} ({self.email})\"\n",
" ### END SOLUTION\n",
" \n",
" def get_signature(self):\n",
@@ -227,8 +424,7 @@
" Should include name, affiliation, and specialization.\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" return f\"{self.name}\\n{self.affiliation}\\nSpecialization: {self.specialization}\"\n",
" ### END SOLUTION\n",
" \n",
" def get_profile_info(self):\n",
@@ -236,9 +432,133 @@
" Return comprehensive profile information as a dictionary.\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # YOUR CODE HERE\n",
" raise NotImplementedError()\n",
" ### END SOLUTION "
" return {\n",
" 'name': self.name,\n",
" 'email': self.email,\n",
" 'affiliation': self.affiliation,\n",
" 'specialization': self.specialization\n",
" }\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "36d68622",
"metadata": {
"cell_marker": "\"\"\""
},
"source": [
"## Testing Your Implementation\n",
"\n",
"Once you've implemented all the functions above, run the cells below to test your work!\n",
"\n",
"Remember the TinyTorch workflow:\n",
"1. **Implement** the functions above\n",
"2. **Export** to package: `tito module export 00_setup`\n",
"3. **Test** your work: `pytest tests/ -v`\n",
"4. **Use** your code: `from tinytorch.core.utils import hello_tinytorch`"
]
},
{
"cell_type": "markdown",
"id": "69d475e2",
"metadata": {
"cell_marker": "\"\"\"",
"lines_to_next_cell": 1
},
"source": [
"## Problem 6: Integration Test (30 points)\n",
"\n",
"Test that all your components work together correctly. This ensures your implementation is complete and ready for export to the TinyTorch package.\n",
"\n",
"**Requirements:**\n",
"- Test all functions and classes work correctly\n",
"- Test the multi-step function with multiple solution blocks\n",
"- Verify system compatibility \n",
"- Display a complete developer profile\n",
"- Show successful framework initialization\n",
"\n",
"**Total Points: 95/95**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "de9fabc9",
"metadata": {
"lines_to_next_cell": 1,
"nbgrader": {
"grade": true,
"grade_id": "integration_test",
"locked": false,
"points": 30,
"schema_version": 3,
"solution": true,
"task": false
}
},
"outputs": [],
"source": [
"def test_integration():\n",
" \"\"\"\n",
" Integration test to verify all components work together.\n",
" This function tests the complete TinyTorch setup workflow.\n",
" \"\"\"\n",
" ### BEGIN SOLUTION\n",
" # Test 1: Welcome function\n",
" print(\"🧪 Testing hello_tinytorch()...\")\n",
" hello_tinytorch()\n",
" print(\"✅ Welcome function works!\\n\")\n",
" \n",
" # Test 2: Multi-step calculation (demonstrates multiple solution blocks)\n",
" print(\"🧪 Testing complex_calculation() with multiple solution blocks...\")\n",
" result = complex_calculation(3, 4)\n",
" expected = 110 # (3+2) + (4+2) = 11, 11*10 = 110\n",
" assert result == expected, f\"Expected {expected}, got {result}\"\n",
" print(f\"✅ Multi-step calculation: complex_calculation(3, 4) = {result}\")\n",
" print(\"✅ Multiple solution blocks working correctly!\\n\")\n",
" \n",
" # Test 3: Simple math function\n",
" print(\"🧪 Testing add_numbers()...\")\n",
" result = add_numbers(2.5, 1.5)\n",
" assert result == 4.0, f\"Expected 4.0, got {result}\"\n",
" print(f\"✅ Math function: add_numbers(2.5, 1.5) = {result}\\n\")\n",
" \n",
" # Test 4: System information\n",
" print(\"🧪 Testing SystemInfo class...\")\n",
" sys_info = SystemInfo()\n",
" print(f\"✅ System info: {sys_info}\")\n",
" print(f\"✅ Python compatible: {sys_info.is_compatible()}\\n\")\n",
" \n",
" # Test 5: Developer profile\n",
" print(\"🧪 Testing DeveloperProfile class...\")\n",
" dev = DeveloperProfile(\"TinyTorch Student\", \"student@tinytorch.edu\", \"TinyTorch University\", \"ML Systems\")\n",
" print(f\"✅ Developer: {dev}\")\n",
" print(f\"✅ Profile info: {dev.get_profile_info()}\\n\")\n",
" \n",
" # Test 6: Complete workflow\n",
" print(\"🎉 All components working together!\")\n",
" print(\"✅ Ready for module export and package building!\")\n",
" return True\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"id": "fe968fb0",
"metadata": {
"cell_marker": "\"\"\""
},
"source": [
"## Next Steps\n",
"\n",
"After completing this assignment:\n",
"1. Export your code to the TinyTorch package\n",
"2. Run the tests to verify everything works\n",
"3. Try importing and using your functions\n",
"4. Move on to the next assignment!\n",
"\n",
"You've just created the foundation utilities for TinyTorch. Great job! 🎉"
]
}
],

View File

@@ -10,9 +10,24 @@
# %% [markdown]
"""
# Assignment 0: Setup - TinyTorch Development Environment (INSTRUCTOR VERSION)
# Assignment 0: Setup - TinyTorch Development Environment
This is the instructor solution version showing how solutions are filled in.
Welcome to TinyTorch! In this assignment, you'll set up your development environment and create your first utilities for the TinyTorch ML framework.
## Learning Objectives
- Set up and verify your TinyTorch development environment
- Create utility functions for the framework
- Learn the development workflow: implement → export → test → use
- Get familiar with the TinyTorch CLI tools
## Assignment Overview
You'll implement 4 core utilities that will be used throughout the TinyTorch framework:
1. A welcome function with ASCII art loading
2. A simple math utility function
3. A system information collector
4. A developer profile manager
Let's get started!
"""
# %%
@@ -29,9 +44,22 @@ from pathlib import Path
# %% [markdown]
"""
## Problem 1: Hello Function (10 points)
## Problem 1: Hello Function (5 points)
Write a function that displays a welcome message for TinyTorch.
Create a function that displays a welcome message for TinyTorch. This function should try to load ASCII art from a file, but gracefully fall back to a simple banner if the file doesn't exist.
**Requirements:**
- Try to read 'tinytorch_flame.txt' from the current directory
- If the file exists, print its contents
- If the file doesn't exist, print a simple "TinyTorch" banner
- Always print "Build ML Systems from Scratch!" after the banner
- Handle any file reading errors gracefully
**Example Output:**
```
TinyTorch
Build ML Systems from Scratch!
```
"""
# %% nbgrader={"grade": false, "grade_id": "hello_function", "locked": false, "schema_version": 3, "solution": true, "task": false}
@@ -47,10 +75,94 @@ def hello_tinytorch():
4. Handle any exceptions gracefully
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
try:
# Try to read the ASCII art file
flame_file = Path('tinytorch_flame.txt')
if flame_file.exists():
print(flame_file.read_text().strip())
else:
print("TinyTorch")
except (FileNotFoundError, OSError, UnicodeDecodeError):
# If file doesn't exist or can't be read, show simple banner
print("TinyTorch")
# Always print the tagline
print("Build ML Systems from Scratch!")
### END SOLUTION
# %% [markdown]
"""
## Problem 2: Multi-Step Math Function (10 points)
Create a function that demonstrates multiple solution blocks within one function. This shows how NBGrader can guide you through step-by-step implementation.
**Requirements:**
- Step 1: Add 2 to each input variable
- Step 2: Sum the modified variables
- Step 3: Multiply the result by 10
- Return the final result
**Example:**
```python
complex_calculation(3, 4) # Step 1: 5, 6 Step 2: 11 Step 3: 110
```
**Note:** This function demonstrates how you can have multiple solution blocks within a single function for guided learning!
"""
# %% nbgrader={"grade": false, "grade_id": "multi_step_function", "locked": false, "schema_version": 3, "solution": true, "task": false}
#| export
def complex_calculation(a, b):
"""
Perform a multi-step calculation with guided implementation.
Args:
a: First number
b: Second number
Returns:
Result of multi-step calculation
"""
# Step 1: Add 2 to each input variable
# a_plus_2 = ...
### BEGIN SOLUTION
a_plus_2 = a + 2
b_plus_2 = b + 2
### END SOLUTION
# Step 2: Sum everything
# everything_summed = ...
### BEGIN SOLUTION
everything_summed = a_plus_2 + b_plus_2
### END SOLUTION
# Step 3: Multiply your previous result by 10
# Hint: you can use np.multiply if you want people to hate you
# everything_summed_times_10 = ...
### BEGIN SOLUTION
everything_summed_times_10 = everything_summed * 10
### END SOLUTION
return everything_summed_times_10
# %% [markdown]
"""
## Problem 3: Basic Math Function (5 points)
Create a simple addition function. This might seem trivial, but it's important to verify our basic development workflow is working correctly.
**Requirements:**
- Accept two parameters (a and b)
- Return their sum
- Handle both integers and floats
**Example:**
```python
add_numbers(3, 4) # Returns 7
add_numbers(2.5, 1.5) # Returns 4.0
```
"""
# %% nbgrader={"grade": false, "grade_id": "add_function", "locked": false, "schema_version": 3, "solution": true, "task": false}
#| export
def add_numbers(a, b):
@@ -65,10 +177,27 @@ def add_numbers(a, b):
Sum of a and b
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
return a + b
### END SOLUTION
# %% [markdown]
"""
## Problem 4: System Information Class (20 points)
Create a class that collects and displays system information. This will help us understand the environment where TinyTorch is running.
**Requirements:**
- Collect Python version, platform, and machine architecture in `__init__`
- Implement `__str__` to return formatted system info
- Implement `is_compatible()` to check if Python version >= 3.8
- Store information as instance variables
**Example Output:**
```
Python 3.9.7 on Darwin (arm64)
```
"""
# %% nbgrader={"grade": false, "grade_id": "systeminfo_class", "locked": false, "schema_version": 3, "solution": true, "task": false}
#| export
class SystemInfo:
@@ -82,8 +211,15 @@ class SystemInfo:
Collect Python version, platform, and machine information.
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
# Get Python version info
version_info = sys.version_info
self.python_version = f"{version_info.major}.{version_info.minor}.{version_info.micro}"
# Get platform information
self.platform = platform.system()
# Get machine architecture
self.machine = platform.machine()
### END SOLUTION
def __str__(self):
@@ -92,8 +228,7 @@ class SystemInfo:
Format: "Python X.Y.Z on Platform (Architecture)"
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
return f"Python {self.python_version} on {self.platform} ({self.machine})"
### END SOLUTION
def is_compatible(self):
@@ -102,10 +237,29 @@ class SystemInfo:
Returns True if compatible, False otherwise.
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
return sys.version_info[:2] >= (3, 8)
### END SOLUTION
# %% [markdown]
"""
## Problem 5: Developer Profile Class (30 points)
Create a class to manage developer profiles. This will be used to track who's working on different parts of the TinyTorch framework.
**Requirements:**
- Store developer information (name, email, affiliation, specialization)
- Implement `__str__` for basic representation
- Implement `get_signature()` for formatted signature
- Implement `get_profile_info()` to return all info as a dictionary
**Example:**
```python
dev = DeveloperProfile("Alice", "alice@example.com", "University", "Neural Networks")
print(dev) # "Alice (alice@example.com)"
print(dev.get_signature()) # Formatted signature with all info
```
"""
# %% nbgrader={"grade": false, "grade_id": "developer_profile_class", "locked": false, "schema_version": 3, "solution": true, "task": false}
#| export
class DeveloperProfile:
@@ -124,8 +278,10 @@ class DeveloperProfile:
specialization: Developer's area of specialization
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
self.name = name
self.email = email
self.affiliation = affiliation
self.specialization = specialization
### END SOLUTION
def __str__(self):
@@ -134,8 +290,7 @@ class DeveloperProfile:
Format: "Name (email)"
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
return f"{self.name} ({self.email})"
### END SOLUTION
def get_signature(self):
@@ -144,8 +299,7 @@ class DeveloperProfile:
Should include name, affiliation, and specialization.
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
return f"{self.name}\n{self.affiliation}\nSpecialization: {self.specialization}"
### END SOLUTION
def get_profile_info(self):
@@ -153,6 +307,96 @@ class DeveloperProfile:
Return comprehensive profile information as a dictionary.
"""
### BEGIN SOLUTION
# YOUR CODE HERE
raise NotImplementedError()
### END SOLUTION
return {
'name': self.name,
'email': self.email,
'affiliation': self.affiliation,
'specialization': self.specialization
}
### END SOLUTION
# %% [markdown]
"""
## Testing Your Implementation
Once you've implemented all the functions above, run the cells below to test your work!
Remember the TinyTorch workflow:
1. **Implement** the functions above
2. **Export** to package: `tito module export 00_setup`
3. **Test** your work: `pytest tests/ -v`
4. **Use** your code: `from tinytorch.core.utils import hello_tinytorch`
"""
# %% [markdown]
"""
## Problem 6: Integration Test (30 points)
Test that all your components work together correctly. This ensures your implementation is complete and ready for export to the TinyTorch package.
**Requirements:**
- Test all functions and classes work correctly
- Test the multi-step function with multiple solution blocks
- Verify system compatibility
- Display a complete developer profile
- Show successful framework initialization
**Total Points: 95/95**
"""
# %% nbgrader={"grade": true, "grade_id": "integration_test", "locked": false, "points": 30, "schema_version": 3, "solution": true, "task": false}
def test_integration():
"""
Integration test to verify all components work together.
This function tests the complete TinyTorch setup workflow.
"""
### BEGIN SOLUTION
# Test 1: Welcome function
print("🧪 Testing hello_tinytorch()...")
hello_tinytorch()
print("✅ Welcome function works!\n")
# Test 2: Multi-step calculation (demonstrates multiple solution blocks)
print("🧪 Testing complex_calculation() with multiple solution blocks...")
result = complex_calculation(3, 4)
expected = 110 # (3+2) + (4+2) = 11, 11*10 = 110
assert result == expected, f"Expected {expected}, got {result}"
print(f"✅ Multi-step calculation: complex_calculation(3, 4) = {result}")
print("✅ Multiple solution blocks working correctly!\n")
# Test 3: Simple math function
print("🧪 Testing add_numbers()...")
result = add_numbers(2.5, 1.5)
assert result == 4.0, f"Expected 4.0, got {result}"
print(f"✅ Math function: add_numbers(2.5, 1.5) = {result}\n")
# Test 4: System information
print("🧪 Testing SystemInfo class...")
sys_info = SystemInfo()
print(f"✅ System info: {sys_info}")
print(f"✅ Python compatible: {sys_info.is_compatible()}\n")
# Test 5: Developer profile
print("🧪 Testing DeveloperProfile class...")
dev = DeveloperProfile("TinyTorch Student", "student@tinytorch.edu", "TinyTorch University", "ML Systems")
print(f"✅ Developer: {dev}")
print(f"✅ Profile info: {dev.get_profile_info()}\n")
# Test 6: Complete workflow
print("🎉 All components working together!")
print("✅ Ready for module export and package building!")
return True
### END SOLUTION
# %% [markdown]
"""
## Next Steps
After completing this assignment:
1. Export your code to the TinyTorch package
2. Run the tests to verify everything works
3. Try importing and using your functions
4. Move on to the next assignment!
You've just created the foundation utilities for TinyTorch. Great job! 🎉
"""

View File

@@ -4,13 +4,11 @@ This tests the student implementations to ensure they work correctly.
"""
import pytest
import numpy as np
import sys
import os
from pathlib import Path
# Import from the main package (rock solid foundation)
from tinytorch.core.utils import hello_tinytorch, add_numbers, SystemInfo, DeveloperProfile
# Import from the main package
from tinytorch.core.utils import hello_tinytorch, add_numbers, SystemInfo, DeveloperProfile, complex_calculation
class TestSetupFunctions:
@@ -26,10 +24,39 @@ class TestSetupFunctions:
hello_tinytorch()
captured = capsys.readouterr()
# Should print the branding text (flexible matching for unicode)
assert "TinyTorch" in captured.out or "Tiny🔥Torch" in captured.out
# Should print the branding text
assert "TinyTorch" in captured.out
assert "Build ML Systems from Scratch!" in captured.out
def test_complex_calculation_basic(self):
"""Test multi-step calculation with multiple solution blocks."""
# Test the example from the assignment: complex_calculation(3, 4)
# Step 1: a_plus_2 = 3+2 = 5, b_plus_2 = 4+2 = 6
# Step 2: everything_summed = 5+6 = 11
# Step 3: everything_summed_times_10 = 11*10 = 110
result = complex_calculation(3, 4)
expected = 110
assert result == expected, f"Expected {expected}, got {result}"
def test_complex_calculation_different_inputs(self):
"""Test multi-step calculation with different inputs."""
# Test with different numbers
result = complex_calculation(1, 2)
# Step 1: 1+2=3, 2+2=4
# Step 2: 3+4=7
# Step 3: 7*10=70
expected = 70
assert result == expected, f"Expected {expected}, got {result}"
def test_complex_calculation_negative(self):
"""Test multi-step calculation with negative numbers."""
result = complex_calculation(-1, -2)
# Step 1: -1+2=1, -2+2=0
# Step 2: 1+0=1
# Step 3: 1*10=10
expected = 10
assert result == expected, f"Expected {expected}, got {result}"
def test_add_numbers_basic(self):
"""Test basic addition functionality."""
assert add_numbers(2, 3) == 5
@@ -62,11 +89,9 @@ class TestSystemInfo:
"""Test SystemInfo properties."""
info = SystemInfo()
# Check python_version is a version tuple
assert hasattr(info.python_version, 'major')
assert hasattr(info.python_version, 'minor')
assert isinstance(info.python_version.major, int)
assert isinstance(info.python_version.minor, int)
# Check python_version is a string
assert isinstance(info.python_version, str)
assert len(info.python_version) > 0
# Check platform is a string
assert isinstance(info.platform, str)
@@ -83,8 +108,7 @@ class TestSystemInfo:
assert isinstance(str_repr, str)
assert "Python" in str_repr
assert str(info.python_version.major) in str_repr
assert str(info.python_version.minor) in str_repr
assert info.python_version in str_repr
assert info.platform in str_repr
assert info.machine in str_repr
@@ -108,101 +132,59 @@ class TestDeveloperProfile:
profile = DeveloperProfile()
# Check default values
assert profile.name == "Vijay Janapa Reddi"
assert profile.affiliation == "Harvard University"
assert profile.email == "vj@eecs.harvard.edu"
assert profile.github_username == "profvjreddi"
assert profile.ascii_art is not None # Should have default flame
assert profile.name == "Student"
assert profile.email == "student@example.com"
assert profile.affiliation == "TinyTorch Community"
assert profile.specialization == "ML Systems"
def test_developer_profile_creation_custom(self):
"""Test DeveloperProfile with custom values."""
custom_art = """
Custom ASCII Art
****************
"""
profile = DeveloperProfile(
name="Test Student",
affiliation="Test University",
email="test@example.com",
github_username="teststudent",
ascii_art=custom_art
affiliation="Test University",
specialization="Deep Learning"
)
assert profile.name == "Test Student"
assert profile.affiliation == "Test University"
assert profile.email == "test@example.com"
assert profile.github_username == "teststudent"
assert profile.ascii_art == custom_art
assert profile.affiliation == "Test University"
assert profile.specialization == "Deep Learning"
def test_developer_profile_str(self):
"""Test DeveloperProfile string representation."""
profile = DeveloperProfile()
profile = DeveloperProfile("Alice", "alice@example.com")
str_repr = str(profile)
assert isinstance(str_repr, str)
assert "👨‍💻" in str_repr
assert "Vijay Janapa Reddi" in str_repr
assert "Harvard University" in str_repr
assert "@profvjreddi" in str_repr
assert "Alice" in str_repr
assert "alice@example.com" in str_repr
def test_developer_profile_signature(self):
"""Test DeveloperProfile signature method."""
profile = DeveloperProfile()
profile = DeveloperProfile("Bob", "bob@example.com", "Test University", "Neural Networks")
signature = profile.get_signature()
assert isinstance(signature, str)
assert "Built by" in signature
assert "Vijay Janapa Reddi" in signature
assert "@profvjreddi" in signature
assert "Bob" in signature
assert "Test University" in signature
assert "Neural Networks" in signature
def test_developer_profile_ascii_art(self):
"""Test DeveloperProfile ASCII art functionality."""
# Test default ASCII art
profile = DeveloperProfile()
ascii_art = profile.get_ascii_art()
def test_developer_profile_info(self):
"""Test DeveloperProfile get_profile_info method."""
profile = DeveloperProfile("Charlie", "charlie@example.com", "AI Lab", "Computer Vision")
info = profile.get_profile_info()
assert isinstance(ascii_art, str)
assert "Tiny🔥Torch" in ascii_art
assert "Build ML Systems from Scratch!" in ascii_art
assert len(ascii_art) > 100 # Should be substantial ASCII art
# Test custom ASCII art
custom_art = "My Custom Art!"
custom_profile = DeveloperProfile(ascii_art=custom_art)
assert custom_profile.get_ascii_art() == custom_art
def test_developer_profile_full_profile(self):
"""Test DeveloperProfile full profile display."""
profile = DeveloperProfile()
full_profile = profile.get_full_profile()
assert isinstance(full_profile, str)
assert "Tiny🔥Torch" in full_profile
assert "Build ML Systems from Scratch!" in full_profile
assert "👨‍💻 Developer: Vijay Janapa Reddi" in full_profile
assert "🏛️ Affiliation: Harvard University" in full_profile
assert "📧 Email: vj@eecs.harvard.edu" in full_profile
assert "🐙 GitHub: @profvjreddi" in full_profile
assert "🔥 Ready to build ML systems from scratch!" in full_profile
assert isinstance(info, dict)
assert info['name'] == "Charlie"
assert info['email'] == "charlie@example.com"
assert info['affiliation'] == "AI Lab"
assert info['specialization'] == "Computer Vision"
class TestFileOperations:
"""Test file-related operations."""
def test_ascii_art_file_exists(self):
"""Test that the ASCII art file exists."""
art_file = Path(__file__).parent.parent / "tinytorch_flame.txt"
assert art_file.exists(), "ASCII art file should exist"
assert art_file.is_file(), "ASCII art should be a file"
def test_ascii_art_file_has_content(self):
"""Test that the ASCII art file has content."""
art_file = Path(__file__).parent.parent / "tinytorch_flame.txt"
content = art_file.read_text()
assert len(content) > 0, "ASCII art file should not be empty"
assert len(content.splitlines()) > 10, "ASCII art should have multiple lines"
def test_hello_tinytorch_handles_missing_file(self, monkeypatch, capsys):
"""Test that hello_tinytorch handles missing ASCII art file gracefully."""
# Mock Path.exists to return False
@@ -216,7 +198,7 @@ class TestFileOperations:
captured = capsys.readouterr()
# Should still print the branding text
assert "🔥 TinyTorch 🔥" in captured.out
assert "TinyTorch" in captured.out
assert "Build ML Systems from Scratch!" in captured.out
@@ -228,6 +210,7 @@ class TestModuleIntegration:
# Test functions
hello_tinytorch() # Should not raise
sum_result = add_numbers(5, 10)
calc_result = complex_calculation(1, 1)
# Test classes
info = SystemInfo()
@@ -235,15 +218,16 @@ class TestModuleIntegration:
# All should work without errors
assert sum_result == 15
assert calc_result == 60 # (1+2) + (1+2) = 6, 6*10 = 60
assert str(info) # Should not be empty
assert str(profile) # Should not be empty
assert profile.get_signature() # Should not be empty
assert profile.get_ascii_art() # Should not be empty
def test_no_import_errors(self):
"""Test that imports work correctly."""
# If we got here, imports worked
assert callable(hello_tinytorch)
assert callable(add_numbers)
assert callable(complex_calculation)
assert callable(SystemInfo)
assert callable(DeveloperProfile)