diff --git a/assignments/source/00_setup/setup_dev.py b/assignments/source/00_setup/setup_dev.py index 5c6e2829..95665a9d 100644 --- a/assignments/source/00_setup/setup_dev.py +++ b/assignments/source/00_setup/setup_dev.py @@ -10,726 +10,402 @@ # %% [markdown] """ -# Assignment 0: Setup - TinyTorch Development Environment +# Assignment 0: Setup - Student Information Configuration -Welcome to TinyTorch! In this assignment, you'll set up your development environment and create your first utilities for the TinyTorch ML framework. +Welcome to TinyTorch! This setup assignment configures your personal information for the course and validates your development environment. ## ๐ŸŽฏ Learning Objectives By the end of this assignment, you will: -- โœ… Set up and verify your TinyTorch development environment -- โœ… Create utility functions using proper Python practices -- โœ… Learn the development workflow: implement โ†’ export โ†’ test โ†’ use -- โœ… Get familiar with the TinyTorch CLI tools -- โœ… Understand NBGrader solution blocks and guided implementation -- โœ… Practice error handling and graceful fallbacks +- โœ… Configure your student profile information +- โœ… Validate information formats are correct +- โœ… Verify your development environment is ready +- โœ… Understand the NBGrader workflow ## ๐Ÿ“‹ Assignment Overview -You'll implement **5 core utilities** that demonstrate different programming concepts: +Simple configuration tasks to get you started: -| Problem | Points | Concept | Difficulty | -|---------|--------|---------|------------| -| 1. Hello Function | 5 | File I/O, Error Handling | โญ Easy | -| 2. Multi-Step Function | 10 | Guided Implementation | โญโญ Medium | -| 3. Basic Math | 5 | Simple Functions | โญ Easy | -| 4. System Info Class | 20 | OOP, System APIs | โญโญ Medium | -| 5. Developer Profile | 30 | Advanced OOP | โญโญโญ Hard | -| 6. Integration Test | 25 | Testing, Workflow | โญโญ Medium | -| **Total** | **95** | **Complete Workflow** | | +| Problem | Points | Description | +|---------|--------|-------------| +| 1. Student Profile | 40 | Configure your name, email, institution, student ID | +| 2. Email Validation | 20 | Implement email format validation | +| 3. Environment Check | 20 | Verify Python and system compatibility | +| 4. Configuration Test | 20 | Test that all information is valid | +| **Total** | **100** | **Complete Setup** | -## ๐Ÿ› ๏ธ Development Workflow -1. **Implement** functions in this notebook -2. **Test** your work locally: `python -c "from setup_dev import function_name; function_name()"` -3. **Export** to package: `tito module export 00_setup` -4. **Verify** with tests: `pytest tests/ -v` -5. **Use** your code: `from tinytorch.core.utils import function_name` - -## ๐Ÿ’ก General Tips -- **Read error messages carefully** - they often tell you exactly what's wrong -- **Test incrementally** - don't wait until everything is done to test -- **Use print statements** for debugging - they're your friend! -- **Check the examples** - they show exactly what output is expected -- **Ask for help** - if you're stuck for >30 minutes, reach out! +## ๐Ÿ’ก Instructions +- Replace the example information with **your actual details** +- Make sure all validation functions work correctly +- Test your setup before submitting --- -Let's get started! ๐Ÿš€ +Let's configure your TinyTorch profile! ๐Ÿš€ """ # %% -#| default_exp core.utils +#| default_exp core.setup # %% #| export -# Required imports for TinyTorch utilities +# Required imports for setup utilities import sys import platform +import re from datetime import datetime -import os -from pathlib import Path # %% [markdown] """ -## Problem 1: Hello Function (5 points) ๐Ÿ‘‹ +## Problem 1: Student Profile Configuration (40 points) ๐Ÿ‘ค -**Goal**: Create a function that displays a welcome message for TinyTorch with graceful error handling. +**Goal**: Configure your personal information for the TinyTorch course. ### ๐Ÿ“ Requirements -- Try to read 'tinytorch_flame.txt' from the current directory -- If the file exists, print its contents (without extra newlines) -- 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 (no crashes!) +- Return a dictionary with your student information +- Use your actual name, email, institution, and student ID +- Follow the exact format shown in the example -### ๐Ÿ’ก Approach & Hints -1. **Use Path from pathlib** - it's more robust than raw file operations -2. **Try-except pattern** - wrap file operations to catch errors -3. **Check file existence** - use `Path.exists()` before reading -4. **Strip whitespace** - use `.strip()` to remove extra newlines from file content -5. **Multiple exception types** - catch `FileNotFoundError`, `OSError`, `UnicodeDecodeError` - -### ๐ŸŽฏ Expected Behavior +### ๐Ÿ’ก Example ```python -# Case 1: File exists and readable -hello_tinytorch() -# Prints: [ASCII art from file] -# Build ML Systems from Scratch! - -# Case 2: File missing or unreadable -hello_tinytorch() -# Prints: TinyTorch -# Build ML Systems from Scratch! +{ + 'name': 'Vijay Janapa Reddi', + 'email': 'vj@eecs.harvard.edu', + 'institution': 'Harvard University', + 'student_id': '406737410' +} ``` -### ๐Ÿšจ Common Pitfalls -- โŒ Not handling exceptions (your function crashes) -- โŒ Forgetting to print the tagline -- โŒ Not stripping whitespace (extra blank lines) -- โŒ Using hardcoded file paths instead of Path - -### ๐Ÿงช Quick Test -```python -# Test your function -hello_tinytorch() # Should print welcome message without crashing -``` +### ๐Ÿšจ Important +- Use **your actual information** (not the example) +- Double-check spelling and formatting +- Student ID should be a string, not integer """ -# %% -# nbgrader: grade, solution +# %% +# === BEGIN MARK SCHEME === +# Award full 40 points if: +# - All fields are present and non-empty +# - Email contains @ symbol and domain +# - Information appears to be real (not placeholder text) +# - Dictionary format is correct +# +# Deduct 10 points per missing/invalid field. +# === END MARK SCHEME === + #| export -def hello_tinytorch(): +def get_student_profile(): """ - Display a welcome message for TinyTorch. + Return student profile information. - This function should: - 1. Try to load ASCII art from 'tinytorch_flame.txt' if it exists - 2. If the file doesn't exist, display a simple text banner - 3. Print "TinyTorch" and "Build ML Systems from Scratch!" - 4. Handle any exceptions gracefully + Returns: + dict: Student information with keys 'name', 'email', 'institution', 'student_id' """ - 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!") + ### BEGIN SOLUTION + return { + 'name': 'Vijay Janapa Reddi', + 'email': 'vj@eecs.harvard.edu', + 'institution': 'Harvard University', + 'student_id': '406737410' + } + ### END SOLUTION -# %% -# nbgrader: tests -# Test hello_tinytorch function -def test_hello_tinytorch(): - """Test that hello_tinytorch runs without crashing.""" - import io - import sys - - # Capture output - old_stdout = sys.stdout - sys.stdout = captured_output = io.StringIO() - - try: - hello_tinytorch() - output = captured_output.getvalue() - - # Should have some output - assert len(output.strip()) > 0, "Function should produce output" - - # Should contain the tagline - assert "Build ML Systems from Scratch!" in output, "Should contain tagline" - - # Should contain either ASCII art or simple banner - assert "TinyTorch" in output or len(output.split('\n')) > 2, "Should contain banner" - - finally: - sys.stdout = old_stdout +# %% +### BEGIN HIDDEN TESTS +profile = get_student_profile() -test_hello_tinytorch() # Run the test +# Test dictionary structure +assert isinstance(profile, dict), "Should return a dictionary" +assert 'name' in profile, "Dictionary should have 'name' key" +assert 'email' in profile, "Dictionary should have 'email' key" +assert 'institution' in profile, "Dictionary should have 'institution' key" +assert 'student_id' in profile, "Dictionary should have 'student_id' key" + +# Test non-empty values +assert len(profile['name']) > 0, "Name cannot be empty" +assert len(profile['email']) > 0, "Email cannot be empty" +assert len(profile['institution']) > 0, "Institution cannot be empty" +assert len(profile['student_id']) > 0, "Student ID cannot be empty" + +# Test basic email format +assert '@' in profile['email'], "Email should contain @ symbol" +assert '.' in profile['email'], "Email should contain domain" + +print("โœ… Student profile configuration tests passed!") +### END HIDDEN TESTS # %% [markdown] """ -## Problem 2: Multi-Step Math Function (10 points) ๐Ÿ”ข +## Problem 2: Email Validation (20 points) ๐Ÿ“ง -**Goal**: Create a function with **multiple solution blocks** to demonstrate guided implementation. +**Goal**: Implement a function to validate email format. ### ๐Ÿ“ 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 +- Check if email contains @ symbol +- Check if email has a domain (contains . after @) +- Check if email is not empty +- Return True if valid, False otherwise -### ๐Ÿ’ก Approach & Hints -This problem demonstrates **multiple solution blocks** within one function: -- Each step has its own solution block -- Complete each step before moving to the next -- Use descriptive variable names as suggested in comments -- Follow the math carefully: `(a+2) + (b+2) = a+b+4`, then `ร—10` - -### ๐ŸŽฏ Step-by-Step Walkthrough +### ๐Ÿ’ก Examples ```python -# Example: 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 -# Return: 110 +is_valid_email('vj@eecs.harvard.edu') # True +is_valid_email('student@university.edu') # True +is_valid_email('invalid-email') # False +is_valid_email('no@domain') # False +is_valid_email('') # False ``` - -### ๐Ÿงฎ More Examples -```python -complex_calculation(1, 2) # (1+2)+(2+2) = 7, 7*10 = 70 -complex_calculation(0, 0) # (0+2)+(0+2) = 4, 4*10 = 40 -complex_calculation(-1, 1) # (-1+2)+(1+2) = 4, 4*10 = 40 -``` - -### ๐Ÿšจ Common Pitfalls -- โŒ Using wrong variable names (doesn't match the comments) -- โŒ Skipping intermediate variables (storing directly in final result) -- โŒ Math errors (forgetting to add 2 to both variables) -- โŒ Not following the exact steps in order - -### ๐Ÿงช Quick Test -```python -result = complex_calculation(3, 4) -print(f"Result: {result}") # Should print: Result: 110 -``` - -**Note**: This demonstrates how NBGrader can guide you through complex functions step-by-step! """ -# %% -# nbgrader: grade, solution +# %% +# === BEGIN MARK SCHEME === +# Award 20 points if: +# - Correctly validates emails with @ and domain +# - Rejects invalid formats +# - Handles empty strings +# - Returns boolean values +# +# Deduct 5 points for each test case that fails. +# === END MARK SCHEME === + #| export -def complex_calculation(a, b): +def is_valid_email(email): """ - Perform a multi-step calculation with guided implementation. - - This function demonstrates multiple solution blocks: - 1. Add 2 to both input variables - 2. Sum the modified variables - 3. Multiply by 10 + Validate email format. Args: - a (int): First number - b (int): Second number + email (str): Email address to validate Returns: - int: Result of (a+2) + (b+2), then multiplied by 10 + bool: True if valid email format, False otherwise """ - # Step 1: Add 2 to each variable - a_plus_2 = a + 2 - b_plus_2 = b + 2 + ### BEGIN SOLUTION + if not email or not isinstance(email, str): + return False - # Step 2: Sum the modified variables - everything_summed = a_plus_2 + b_plus_2 + # Check for @ symbol + if '@' not in email: + return False - # Step 3: Multiply by 10 - everything_summed_times_10 = everything_summed * 10 + # Split on @ and check parts + parts = email.split('@') + if len(parts) != 2: + return False - return everything_summed_times_10 + local_part, domain_part = parts + + # Check non-empty parts + if not local_part or not domain_part: + return False + + # Check domain has at least one dot + if '.' not in domain_part: + return False + + return True + ### END SOLUTION -# %% -# nbgrader: tests -# Test complex_calculation function -assert complex_calculation(3, 4) == 110, "complex_calculation(3, 4) should equal 110" -assert complex_calculation(1, 2) == 70, "complex_calculation(1, 2) should equal 70" -assert complex_calculation(0, 0) == 40, "complex_calculation(0, 0) should equal 40" -assert complex_calculation(-1, 1) == 40, "complex_calculation(-1, 1) should equal 40" -print("โœ… complex_calculation tests passed!") +# %% +### BEGIN HIDDEN TESTS +# Test valid emails +assert is_valid_email('vj@eecs.harvard.edu') == True, "Should accept valid email" +assert is_valid_email('student@university.edu') == True, "Should accept valid email" +assert is_valid_email('test@example.com') == True, "Should accept valid email" + +# Test invalid emails +assert is_valid_email('invalid-email') == False, "Should reject email without @" +assert is_valid_email('no@domain') == False, "Should reject email without domain" +assert is_valid_email('') == False, "Should reject empty email" +assert is_valid_email('@domain.com') == False, "Should reject email without local part" +assert is_valid_email('user@') == False, "Should reject email without domain" +assert is_valid_email('user@@domain.com') == False, "Should reject email with multiple @" + +print("โœ… Email validation tests passed!") +### END HIDDEN TESTS # %% [markdown] """ -## Problem 3: Basic Math Function (5 points) โž• +## Problem 3: Environment Check (20 points) ๐Ÿ–ฅ๏ธ -**Goal**: Create a simple function that adds two numbers. +**Goal**: Check that your development environment is ready for TinyTorch. ### ๐Ÿ“ Requirements -- Take two parameters: `a` and `b` -- Return their sum -- Handle any numeric types (int, float) +- Return a dictionary with system information +- Include Python version, platform, and compatibility status +- Mark compatible if Python >= 3.8 -### ๐Ÿ’ก Approach & Hints -1. **Simple addition** - just use the `+` operator -2. **No type conversion needed** - Python handles int + float automatically -3. **One line implementation** - this is straightforward! - -### ๐ŸŽฏ Expected Behavior +### ๐Ÿ’ก Expected Output ```python -add_numbers(2, 3) # Returns: 5 -add_numbers(1.5, 2.5) # Returns: 4.0 -add_numbers(-1, 1) # Returns: 0 -``` - -### ๐Ÿšจ Common Pitfalls -- โŒ Overthinking it - this is really simple! -- โŒ Forgetting to return the result -- โŒ Trying to do type conversion (not needed) - -### ๐Ÿงช Quick Test -```python -result = add_numbers(5, 7) -print(f"5 + 7 = {result}") # Should print: 5 + 7 = 12 +{ + 'python_version': '3.9.7', + 'platform': 'Darwin', + 'compatible': True +} ``` """ -# %% -# nbgrader: grade, solution +# %% +# === BEGIN MARK SCHEME === +# Award 20 points if: +# - Returns dictionary with correct keys +# - Python version is extracted correctly +# - Platform is identified +# - Compatibility check works (True for Python >= 3.8) +# +# Deduct 5 points per missing/incorrect field. +# === END MARK SCHEME === + #| export -def add_numbers(a, b): +def check_environment(): """ - Add two numbers together. + Check development environment compatibility. - Args: - a (int or float): First number - b (int or float): Second number - Returns: - int or float: Sum of a and b + dict: System information with python_version, platform, compatible """ - return a + b + ### BEGIN SOLUTION + # Get Python version + version_info = sys.version_info + python_version = f"{version_info.major}.{version_info.minor}.{version_info.micro}" + + # Get platform + system_platform = platform.system() + + # Check compatibility (Python >= 3.8) + compatible = version_info >= (3, 8) + + return { + 'python_version': python_version, + 'platform': system_platform, + 'compatible': compatible + } + ### END SOLUTION -# %% -# nbgrader: tests -# Test add_numbers function -assert add_numbers(2, 3) == 5, "add_numbers(2, 3) should equal 5" -assert add_numbers(1.5, 2.5) == 4.0, "add_numbers(1.5, 2.5) should equal 4.0" -assert add_numbers(-1, 1) == 0, "add_numbers(-1, 1) should equal 0" -assert add_numbers(0, 0) == 0, "add_numbers(0, 0) should equal 0" -print("โœ… add_numbers tests passed!") +# %% +### BEGIN HIDDEN TESTS +env_info = check_environment() + +# Test dictionary structure +assert isinstance(env_info, dict), "Should return a dictionary" +assert 'python_version' in env_info, "Should have python_version key" +assert 'platform' in env_info, "Should have platform key" +assert 'compatible' in env_info, "Should have compatible key" + +# Test value types +assert isinstance(env_info['python_version'], str), "Python version should be string" +assert isinstance(env_info['platform'], str), "Platform should be string" +assert isinstance(env_info['compatible'], bool), "Compatible should be boolean" + +# Test version format +version_parts = env_info['python_version'].split('.') +assert len(version_parts) >= 2, "Version should have at least major.minor" + +print("โœ… Environment check tests passed!") +### END HIDDEN TESTS # %% [markdown] """ -## Problem 4: System Info Class (20 points) ๐Ÿ–ฅ๏ธ +## Problem 4: Configuration Test (20 points) ๐Ÿ”ง -**Goal**: Create a class that gathers and displays system information. +**Goal**: Test that all your configuration is valid and ready for TinyTorch. ### ๐Ÿ“ Requirements -- Create a class called `SystemInfo` -- `__init__()`: Store system information (Python version, platform, timestamp) -- `__str__()`: Return a formatted string with all system info -- `is_compatible()`: Return True if Python version >= 3.8 +- Validate your student profile using the email validation function +- Check that your environment is compatible +- Return a summary of the validation results +- Print a success message if everything is valid -### ๐Ÿ’ก Approach & Hints -1. **Use sys.version** - gets Python version string -2. **Use platform.system()** - gets OS name (Windows, Darwin, Linux) -3. **Use datetime.now()** - gets current timestamp -4. **Parse version string** - extract major.minor version for compatibility check -5. **String formatting** - use f-strings for clean output - -### ๐ŸŽฏ Expected Behavior +### ๐Ÿ’ก Expected Behavior ```python -info = SystemInfo() -print(info) -# Output: -# TinyTorch System Info -# Python Version: 3.9.7 -# Platform: Darwin -# Timestamp: 2024-01-15 10:30:45.123456 - -print(info.is_compatible()) # True (if Python >= 3.8) -``` - -### ๐Ÿšจ Common Pitfalls -- โŒ Not storing data in __init__ (computing it in __str__ instead) -- โŒ Version parsing errors (handling edge cases in version string) -- โŒ Incorrect string formatting (missing newlines or proper spacing) -- โŒ Not using instance variables (self.variable_name) - -### ๐Ÿงช Quick Test -```python -info = SystemInfo() -print(f"Compatible: {info.is_compatible()}") # Should print: Compatible: True -print(info) # Should print formatted system info +test_configuration() +# Should print: "โœ… TinyTorch setup complete! Ready for ML systems development." +# Returns: True if all tests pass, False otherwise ``` """ -# %% -# nbgrader: grade, solution -#| export -class SystemInfo: +# %% +# === BEGIN MARK SCHEME === +# Award 20 points if: +# - Uses both previously defined functions +# - Validates student profile email +# - Checks environment compatibility +# - Returns correct boolean +# - Prints appropriate message +# +# Deduct 5 points for each missing validation check. +# === END MARK SCHEME === + +#| export +def test_configuration(): """ - A class for gathering and displaying system information. + Test that all configuration is valid. - This class collects Python version, platform, and timestamp information - when instantiated and provides methods to display and check compatibility. + Returns: + bool: True if all tests pass, False otherwise """ - - def __init__(self): - """Initialize system info by collecting current system data.""" - self.python_version = sys.version.split()[0] # Get clean version string - self.platform = platform.system() - self.timestamp = datetime.now() - - def __str__(self): - """Return formatted system information string.""" - return f"""TinyTorch System Info -Python Version: {self.python_version} -Platform: {self.platform} -Timestamp: {self.timestamp}""" - - def is_compatible(self): - """Check if Python version is compatible (>= 3.8).""" - try: - version_parts = self.python_version.split('.') - major = int(version_parts[0]) - minor = int(version_parts[1]) - return major > 3 or (major == 3 and minor >= 8) - except (ValueError, IndexError): + ### BEGIN SOLUTION + try: + # Get student profile + profile = get_student_profile() + + # Validate email + email_valid = is_valid_email(profile['email']) + if not email_valid: + print("โŒ Invalid email format") return False - -# %% -# nbgrader: tests -# Test SystemInfo class -info = SystemInfo() - -# Test that attributes exist -assert hasattr(info, 'python_version'), "SystemInfo should have python_version attribute" -assert hasattr(info, 'platform'), "SystemInfo should have platform attribute" -assert hasattr(info, 'timestamp'), "SystemInfo should have timestamp attribute" - -# Test string representation -info_str = str(info) -assert "TinyTorch System Info" in info_str, "String should contain title" -assert "Python Version:" in info_str, "String should contain Python version" -assert "Platform:" in info_str, "String should contain platform" -assert "Timestamp:" in info_str, "String should contain timestamp" - -# Test compatibility check -compatibility = info.is_compatible() -assert isinstance(compatibility, bool), "is_compatible should return boolean" - -print("โœ… SystemInfo tests passed!") - -# %% [markdown] -""" -## Problem 5: Developer Profile Class (30 points) ๐Ÿ‘จโ€๐Ÿ’ป - -**Goal**: Create an advanced class representing a developer profile with multiple methods. - -### ๐Ÿ“ Requirements -- Create a class called `DeveloperProfile` -- `__init__()`: Accept name, email, affiliation, specialization (with defaults) -- `__str__()`: Return a formatted profile card -- `get_signature()`: Return a signature line with name and specialization -- `get_profile_info()`: Return a dictionary with all profile information - -### ๐Ÿ’ก Approach & Hints -1. **Default parameters** - use defaults in __init__ method signature -2. **Instance variables** - store all parameters as self.variable_name -3. **String formatting** - create a nice "business card" format -4. **Dictionary creation** - return all instance variables as key-value pairs -5. **Method chaining** - each method should work independently - -### ๐ŸŽฏ Expected Behavior -```python -dev = DeveloperProfile("Alice", "alice@example.com", "MIT", "Deep Learning") -print(dev) -# Output: -# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• -# ๐Ÿš€ DEVELOPER PROFILE -# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• -# Name: Alice -# Email: alice@example.com -# Affiliation: MIT -# Specialization: Deep Learning -# โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• - -print(dev.get_signature()) -# Output: Alice - Deep Learning Specialist - -profile_dict = dev.get_profile_info() -print(profile_dict['name']) # Output: Alice -``` - -### ๐Ÿšจ Common Pitfalls -- โŒ Not using default parameters correctly -- โŒ Missing the decorative formatting (borders, emoji) -- โŒ Incorrect dictionary key names -- โŒ Not storing all parameters as instance variables -- โŒ String formatting issues (missing newlines, spacing) - -### ๐Ÿงช Quick Test -```python -dev = DeveloperProfile() # Should work with defaults -print(dev.get_signature()) # Should print default signature -``` -""" - -# %% -# nbgrader: grade, solution -#| export -class DeveloperProfile: - """ - A class representing a developer profile with personal and professional information. - - This class stores developer information and provides methods to display - and access the profile data in various formats. - """ - - def __init__(self, name="Student", email="student@example.com", - affiliation="TinyTorch Community", specialization="ML Systems"): - """ - Initialize a developer profile. - Args: - name (str): Developer's name - email (str): Developer's email address - affiliation (str): Developer's organization or school - specialization (str): Developer's area of expertise - """ - self.name = name - self.email = email - self.affiliation = affiliation - self.specialization = specialization - - def __str__(self): - """Return a formatted developer profile card.""" - return f"""โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• -๐Ÿš€ DEVELOPER PROFILE -โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• -Name: {self.name} -Email: {self.email} -Affiliation: {self.affiliation} -Specialization: {self.specialization} -โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•""" - - def get_signature(self): - """Return a signature line with name and specialization.""" - return f"{self.name} - {self.specialization} Specialist" - - def get_profile_info(self): - """Return profile information as a dictionary.""" - return { - 'name': self.name, - 'email': self.email, - 'affiliation': self.affiliation, - 'specialization': self.specialization - } - -# %% -# nbgrader: tests -# Test DeveloperProfile class -dev = DeveloperProfile("Alice", "alice@example.com", "MIT", "Deep Learning") - -# Test attributes -assert dev.name == "Alice", "Name should be stored correctly" -assert dev.email == "alice@example.com", "Email should be stored correctly" -assert dev.affiliation == "MIT", "Affiliation should be stored correctly" -assert dev.specialization == "Deep Learning", "Specialization should be stored correctly" - -# Test string representation -dev_str = str(dev) -assert "DEVELOPER PROFILE" in dev_str, "String should contain title" -assert "Alice" in dev_str, "String should contain name" -assert "alice@example.com" in dev_str, "String should contain email" -assert "MIT" in dev_str, "String should contain affiliation" -assert "Deep Learning" in dev_str, "String should contain specialization" - -# Test signature -signature = dev.get_signature() -assert "Alice - Deep Learning Specialist" == signature, "Signature should be formatted correctly" - -# Test profile info dictionary -profile_info = dev.get_profile_info() -assert isinstance(profile_info, dict), "get_profile_info should return dict" -assert profile_info['name'] == "Alice", "Profile info should contain correct name" -assert profile_info['email'] == "alice@example.com", "Profile info should contain correct email" -assert profile_info['affiliation'] == "MIT", "Profile info should contain correct affiliation" -assert profile_info['specialization'] == "Deep Learning", "Profile info should contain correct specialization" - -# Test default initialization -default_dev = DeveloperProfile() -assert default_dev.name == "Student", "Default name should be 'Student'" -assert default_dev.email == "student@example.com", "Default email should be correct" - -print("โœ… DeveloperProfile tests passed!") - -# %% [markdown] -""" -## Problem 6: Integration Test (25 points) ๐Ÿ”ง - -**Goal**: Create a comprehensive test function that verifies all previous functions work together. - -### ๐Ÿ“ Requirements -- Create a function called `test_integration()` -- Test all previously implemented functions -- Use proper assertions with descriptive error messages -- Handle any exceptions gracefully -- Return a success message if all tests pass - -### ๐Ÿ’ก Approach & Hints -1. **Test each function systematically** - call each function with known inputs -2. **Use assert statements** - verify expected outputs -3. **Descriptive error messages** - help debug what went wrong -4. **Exception handling** - catch and report any unexpected errors -5. **Comprehensive coverage** - test both normal and edge cases - -### ๐ŸŽฏ Expected Behavior -```python -test_integration() -# Output: -# โœ… Testing hello_tinytorch... passed -# โœ… Testing complex_calculation... passed -# โœ… Testing add_numbers... passed -# โœ… Testing SystemInfo... passed -# โœ… Testing DeveloperProfile... passed -# ๐ŸŽ‰ All integration tests passed! TinyTorch setup is complete. -``` - -### ๐Ÿšจ Common Pitfalls -- โŒ Not testing all functions thoroughly -- โŒ Missing error handling for unexpected exceptions -- โŒ Unclear error messages (hard to debug failures) -- โŒ Not returning a success indicator -- โŒ Testing only happy path (not edge cases) - -### ๐Ÿงช Quick Test -```python -result = test_integration() -print(result) # Should print success message -``` -""" - -# %% -# nbgrader: grade, solution -#| export -def test_integration(): - """ - Comprehensive integration test for all TinyTorch setup functions. - - This function tests all implemented functions to ensure they work - correctly together and individually. - - Returns: - str: Success message if all tests pass - - Raises: - AssertionError: If any test fails - Exception: If any unexpected error occurs - """ - try: - # Test hello_tinytorch - print("โœ… Testing hello_tinytorch... ", end="") - import io - import sys - old_stdout = sys.stdout - sys.stdout = io.StringIO() - hello_tinytorch() - output = sys.stdout.getvalue() - sys.stdout = old_stdout - assert len(output.strip()) > 0, "hello_tinytorch should produce output" - assert "Build ML Systems from Scratch!" in output, "hello_tinytorch should contain tagline" - print("passed") - - # Test complex_calculation - print("โœ… Testing complex_calculation... ", end="") - result = complex_calculation(3, 4) - assert result == 110, f"complex_calculation(3, 4) should return 110, got {result}" - result = complex_calculation(0, 0) - assert result == 40, f"complex_calculation(0, 0) should return 40, got {result}" - print("passed") - - # Test add_numbers - print("โœ… Testing add_numbers... ", end="") - result = add_numbers(5, 7) - assert result == 12, f"add_numbers(5, 7) should return 12, got {result}" - result = add_numbers(1.5, 2.5) - assert result == 4.0, f"add_numbers(1.5, 2.5) should return 4.0, got {result}" - print("passed") - - # Test SystemInfo - print("โœ… Testing SystemInfo... ", end="") - info = SystemInfo() - assert hasattr(info, 'python_version'), "SystemInfo should have python_version attribute" - assert hasattr(info, 'platform'), "SystemInfo should have platform attribute" - assert hasattr(info, 'timestamp'), "SystemInfo should have timestamp attribute" - info_str = str(info) - assert "TinyTorch System Info" in info_str, "SystemInfo string should contain title" - assert isinstance(info.is_compatible(), bool), "is_compatible should return boolean" - print("passed") - - # Test DeveloperProfile - print("โœ… Testing DeveloperProfile... ", end="") - dev = DeveloperProfile("Test User", "test@example.com", "Test Org", "Testing") - assert dev.name == "Test User", "DeveloperProfile should store name correctly" - assert dev.email == "test@example.com", "DeveloperProfile should store email correctly" - dev_str = str(dev) - assert "DEVELOPER PROFILE" in dev_str, "DeveloperProfile string should contain title" - signature = dev.get_signature() - assert "Test User - Testing Specialist" == signature, "Signature should be formatted correctly" - profile_info = dev.get_profile_info() - assert isinstance(profile_info, dict), "get_profile_info should return dict" - assert profile_info['name'] == "Test User", "Profile info should contain correct name" - print("passed") + # Check environment + env_info = check_environment() + if not env_info['compatible']: + print("โŒ Python version incompatible (need >= 3.8)") + return False # All tests passed - success_msg = "๐ŸŽ‰ All integration tests passed! TinyTorch setup is complete." - print(success_msg) - return success_msg + print("โœ… TinyTorch setup complete! Ready for ML systems development.") + return True except Exception as e: - error_msg = f"โŒ Integration test failed: {str(e)}" - print(error_msg) - raise + print(f"โŒ Configuration test failed: {e}") + return False + ### END SOLUTION -# %% -# nbgrader: tests -# Test integration function -try: - result = test_integration() - assert "All integration tests passed" in result, "Integration test should return success message" - print("โœ… Integration test verification passed!") -except Exception as e: - print(f"โŒ Integration test verification failed: {e}") - raise +# %% +### BEGIN HIDDEN TESTS +# Test configuration +result = test_configuration() + +# Should return boolean +assert isinstance(result, bool), "Should return boolean" + +# Test components work together +profile = get_student_profile() +email_valid = is_valid_email(profile['email']) +env_info = check_environment() + +# Profile should be valid +assert email_valid, "Student profile email should be valid" +assert env_info['compatible'], "Environment should be compatible" + +print("โœ… Configuration test passed!") +### END HIDDEN TESTS # %% [markdown] """ -## ๐ŸŽ‰ Assignment Complete! +## ๐ŸŽ‰ Setup Complete! -Congratulations! You've successfully completed the TinyTorch setup assignment. +Congratulations! You've successfully configured your TinyTorch development environment. ### What You've Accomplished: -โœ… **File I/O & Error Handling** - Created robust file reading with graceful fallbacks -โœ… **Multi-Step Implementation** - Learned NBGrader's guided solution approach -โœ… **Basic Functions** - Implemented fundamental mathematical operations -โœ… **Object-Oriented Programming** - Built classes with multiple methods -โœ… **System Integration** - Created comprehensive testing workflows -โœ… **Real-World Skills** - Practiced debugging, testing, and validation +โœ… **Student Profile** - Configured your personal information +โœ… **Email Validation** - Implemented format checking +โœ… **Environment Check** - Verified system compatibility +โœ… **Integration Test** - Confirmed everything works together ### Next Steps: 1. **Export your code**: `tito module export 00_setup` -2. **Run the tests**: `pytest tests/ -v` -3. **Use your functions**: `from tinytorch.core.utils import hello_tinytorch` +2. **Move to Assignment 1**: Start building your first tensors! ### Key Takeaways: -- **Error handling is crucial** - Always plan for things to go wrong -- **Testing saves time** - Comprehensive tests catch bugs early -- **Documentation matters** - Clear docstrings help future you -- **Incremental development** - Build and test one piece at a time +- **Validation is important** - Always check data formats +- **Environment compatibility** - Verify system requirements +- **Testing integration** - Make sure components work together -**Welcome to the TinyTorch journey! ๐Ÿš€** +**Welcome to TinyTorch - let's build ML systems from scratch! ๐Ÿš€** """ \ No newline at end of file