mirror of
https://github.com/MLSysBook/TinyTorch.git
synced 2026-06-03 03:45:52 -05:00
Simplify setup module to only display ASCII art
- Replace complex setup module with simple hello_tinytorch() function - Keep only the ASCII art file (tinytorch_flame.txt) for visual appeal - Simplify tests to just verify function runs and file exists - Update README to reflect simplified purpose and usage - Remove complex developer profiles and system info classes - Focus on minimal introduction to TinyTorch workflow
This commit is contained in:
@@ -1,71 +1,55 @@
|
||||
# Module 0: Setup
|
||||
# Setup Module
|
||||
|
||||
## Learning Objectives
|
||||
Welcome to TinyTorch! This is your first module in the Machine Learning Systems course.
|
||||
|
||||
This module teaches you the **TinyTorch development workflow**. By the end, you'll be comfortable with:
|
||||
## Overview
|
||||
|
||||
- Writing code in Jupyter notebooks using nbdev conventions
|
||||
- Exporting notebook code to Python modules
|
||||
- Running tests and using the TinyTorch CLI
|
||||
- Understanding the development rhythm you'll use for all modules
|
||||
The setup module is a simple introduction to TinyTorch that displays beautiful ASCII art to get you started on your ML systems journey.
|
||||
|
||||
## What You'll Build
|
||||
## Files
|
||||
|
||||
A simple "Hello World" system that demonstrates the complete development cycle:
|
||||
- `setup_dev.py` - Main development file with the hello_tinytorch() function
|
||||
- `setup_dev.ipynb` - Jupyter notebook version (auto-generated)
|
||||
- `tinytorch_flame.txt` - ASCII art file containing the TinyTorch flame design
|
||||
- `tests/test_setup.py` - Simple tests for the module
|
||||
- `README.md` - This file
|
||||
|
||||
- Basic utility functions
|
||||
- A simple `SystemInfo` class
|
||||
- Tests to verify everything works
|
||||
- Experience with the full notebook → export → test workflow
|
||||
## Usage
|
||||
|
||||
## Module Structure
|
||||
### Python Script
|
||||
```python
|
||||
from setup_dev import hello_tinytorch
|
||||
|
||||
```
|
||||
modules/setup/
|
||||
├── setup_dev.ipynb # 📓 Main development notebook
|
||||
├── README.md # 📖 This guide
|
||||
└── __init__.py # 📦 Module marker
|
||||
hello_tinytorch()
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
### Jupyter Notebook
|
||||
Open `setup_dev.ipynb` and run the cells to see the ASCII art displayed.
|
||||
|
||||
## Testing
|
||||
|
||||
Run the tests to verify everything works:
|
||||
|
||||
### 1. Work in the Notebook
|
||||
```bash
|
||||
cd modules/setup
|
||||
jupyter lab setup_dev.ipynb
|
||||
python3 tests/test_setup.py
|
||||
```
|
||||
|
||||
### 2. Export Your Code
|
||||
```bash
|
||||
python bin/tito.py sync
|
||||
```
|
||||
## ASCII Art Customization
|
||||
|
||||
### 3. Test Your Implementation
|
||||
```bash
|
||||
python bin/tito.py test --module setup
|
||||
```
|
||||
The ASCII art is loaded from `tinytorch_flame.txt`. You can customize it by:
|
||||
|
||||
### 4. Check Your Progress
|
||||
```bash
|
||||
python bin/tito.py info
|
||||
```
|
||||
1. **Edit the file directly**: Modify `tinytorch_flame.txt` with your own ASCII art
|
||||
2. **Create your own design**: Replace the flame with your initials, logo, or any design you like
|
||||
|
||||
## Key Concepts
|
||||
## What You'll Learn
|
||||
|
||||
- **nbdev workflow**: Write in notebooks, export to Python
|
||||
- **Export directive**: Use `#| export` to mark code for export
|
||||
- **Module → Package mapping**: This module exports to `tinytorch/core/utils.py`
|
||||
- **Teaching vs. Building**: Learn by modules, build by function (see VISION.md)
|
||||
- **Test integration**: Tests run automatically via CLI
|
||||
- **Module development**: Each module is self-contained
|
||||
This simple module introduces:
|
||||
- Basic Python file structure
|
||||
- File I/O operations
|
||||
- Error handling (fallback when file not found)
|
||||
- Testing with simple assertions
|
||||
- The TinyTorch development workflow
|
||||
|
||||
## Success Criteria
|
||||
## Next Steps
|
||||
|
||||
✅ All tests pass
|
||||
✅ Code exports cleanly to `tinytorch/core/utils.py`
|
||||
✅ You understand the development rhythm
|
||||
✅ Ready to tackle the Tensor module
|
||||
|
||||
---
|
||||
|
||||
**Next Module**: [Tensor](../tensor/) - Core data structures and operations
|
||||
Once you've explored this module, you're ready to move on to the tensor module where you'll build the core data structures for TinyTorch!
|
||||
@@ -2,176 +2,88 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1bc7eb6f",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"id": "8de2eafa",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Module 0: Setup - Tiny🔥Torch Development Workflow\n",
|
||||
"# TinyTorch Setup Module\n",
|
||||
"\n",
|
||||
"Welcome to TinyTorch! This module teaches you the development workflow you'll use throughout the course.\n",
|
||||
"Welcome to TinyTorch! This is your first module in the Machine Learning Systems 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",
|
||||
"Let's get started!"
|
||||
"This module simply displays our beautiful ASCII art to get you started."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "de9a1cf3",
|
||||
"id": "4d47a76e",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.075213Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.075056Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.079728Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.079298Z"
|
||||
}
|
||||
"iopub.execute_input": "2025-07-10T23:21:19.056010Z",
|
||||
"iopub.status.busy": "2025-07-10T23:21:19.055652Z",
|
||||
"iopub.status.idle": "2025-07-10T23:21:19.073438Z",
|
||||
"shell.execute_reply": "2025-07-10T23:21:19.072589Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"🔥 TinyTorch Development Environment\n",
|
||||
"Python 3.13.3 (v3.13.3:6280bb54784, Apr 8 2025, 10:47:54) [Clang 15.0.0 (clang-1500.3.9.4)]\n",
|
||||
"Platform: Darwin 24.5.0\n",
|
||||
"Started: 2025-07-10 19:18:38\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| default_exp core.utils\n",
|
||||
"import os\n",
|
||||
"from pathlib import Path\n",
|
||||
"\n",
|
||||
"# Setup imports and environment\n",
|
||||
"import sys\n",
|
||||
"import platform\n",
|
||||
"from datetime import datetime\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')}\")"
|
||||
"def hello_tinytorch():\n",
|
||||
" \"\"\"Display the TinyTorch ASCII art\"\"\"\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!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3e7e584b",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\"",
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"id": "885e6df3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Step 1: Understanding the Module → Package Structure\n",
|
||||
"## Test the Setup\n",
|
||||
"\n",
|
||||
"**🎓 Teaching vs. 🔧 Building**: This course has two sides:\n",
|
||||
"- **Teaching side**: You work in `modules/setup/setup_dev.ipynb` (learning-focused)\n",
|
||||
"- **Building side**: Your code exports to `tinytorch/core/utils.py` (production package)\n",
|
||||
"\n",
|
||||
"**Key Concept**: The `#| default_exp core.utils` directive at the top tells nbdev to export all `#| export` cells to `tinytorch/core/utils.py`.\n",
|
||||
"\n",
|
||||
"This separation allows us to:\n",
|
||||
"- Organize learning by **concepts** (modules) \n",
|
||||
"- Organize code by **function** (package structure)\n",
|
||||
"- Build a real ML framework while learning systematically\n",
|
||||
"\n",
|
||||
"Let's write a simple \"Hello World\" function with the `#| export` directive:"
|
||||
"Let's run our hello function to see the ASCII art:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "76b6bd6d",
|
||||
"id": "bfe5bac0",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.081710Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.081576Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.083719Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.083440Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| export\n",
|
||||
"def hello_tinytorch():\n",
|
||||
" \"\"\"\n",
|
||||
" A simple hello world function for TinyTorch.\n",
|
||||
" \n",
|
||||
" TODO: Implement this function to return a welcoming message about TinyTorch.\n",
|
||||
" Make it encouraging and mention what students will build.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\n",
|
||||
"\n",
|
||||
"def add_numbers(a, b):\n",
|
||||
" \"\"\"\n",
|
||||
" Add two numbers together.\n",
|
||||
" \n",
|
||||
" TODO: Implement addition of two numbers.\n",
|
||||
" This is the foundation of all mathematical operations in ML.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "6632ced8",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.085296Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.085017Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.087739Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.087361Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| hide\n",
|
||||
"#| export\n",
|
||||
"def hello_tinytorch():\n",
|
||||
" \"\"\"A simple hello world function for TinyTorch.\"\"\"\n",
|
||||
" return \"🔥 Welcome to TinyTorch! Ready to build ML systems from scratch? Let's go! 🔥\"\n",
|
||||
"\n",
|
||||
"def add_numbers(a, b):\n",
|
||||
" \"\"\"Add two numbers together.\"\"\"\n",
|
||||
" return a + b"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "49886309",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"### 🧪 Test Your Implementation\n",
|
||||
"\n",
|
||||
"Once you implement the functions above, run this cell to test them:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "7b3b94c5",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.089472Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.089338Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.091773Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.091522Z"
|
||||
"iopub.execute_input": "2025-07-10T23:21:19.077086Z",
|
||||
"iopub.status.busy": "2025-07-10T23:21:19.076813Z",
|
||||
"iopub.status.idle": "2025-07-10T23:21:19.080935Z",
|
||||
"shell.execute_reply": "2025-07-10T23:21:19.080437Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
@@ -179,392 +91,6 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Testing hello_tinytorch():\n",
|
||||
"🔥 Welcome to TinyTorch! Ready to build ML systems from scratch? Let's go! 🔥\n",
|
||||
"\n",
|
||||
"Testing add_numbers():\n",
|
||||
"2 + 3 = 5\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Test the functions in the notebook (will fail until implemented)\n",
|
||||
"try:\n",
|
||||
" print(\"Testing hello_tinytorch():\")\n",
|
||||
" print(hello_tinytorch())\n",
|
||||
" print()\n",
|
||||
" print(\"Testing add_numbers():\")\n",
|
||||
" print(f\"2 + 3 = {add_numbers(2, 3)}\")\n",
|
||||
"except NotImplementedError as e:\n",
|
||||
" print(f\"⚠️ {e}\")\n",
|
||||
" print(\"Implement the functions above first!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5ed16f85",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\"",
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"source": [
|
||||
"## Step 2: A Simple Class\n",
|
||||
"\n",
|
||||
"Let's create a simple class that will help us understand system information. This is still basic, but shows how to structure classes in TinyTorch."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "b29bb137",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.093020Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.092910Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.095233Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.094958Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| export\n",
|
||||
"class SystemInfo:\n",
|
||||
" \"\"\"\n",
|
||||
" Simple system information class.\n",
|
||||
" \n",
|
||||
" TODO: Implement this class to collect and display system information.\n",
|
||||
" \"\"\"\n",
|
||||
" \n",
|
||||
" def __init__(self):\n",
|
||||
" \"\"\"\n",
|
||||
" Initialize system information collection.\n",
|
||||
" \n",
|
||||
" TODO: Collect Python version, platform, and machine information.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\n",
|
||||
" \n",
|
||||
" def __str__(self):\n",
|
||||
" \"\"\"\n",
|
||||
" Return human-readable system information.\n",
|
||||
" \n",
|
||||
" TODO: Format system info as a readable string.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\n",
|
||||
" \n",
|
||||
" def is_compatible(self):\n",
|
||||
" \"\"\"\n",
|
||||
" Check if system meets minimum requirements.\n",
|
||||
" \n",
|
||||
" TODO: Check if Python version is >= 3.8\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "182bdfa7",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.096679Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.096549Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.099068Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.098840Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| hide\n",
|
||||
"#| export\n",
|
||||
"class SystemInfo:\n",
|
||||
" \"\"\"Simple system information class.\"\"\"\n",
|
||||
" \n",
|
||||
" def __init__(self):\n",
|
||||
" self.python_version = sys.version_info\n",
|
||||
" self.platform = platform.system()\n",
|
||||
" self.machine = platform.machine()\n",
|
||||
" \n",
|
||||
" def __str__(self):\n",
|
||||
" return f\"Python {self.python_version.major}.{self.python_version.minor} on {self.platform} ({self.machine})\"\n",
|
||||
" \n",
|
||||
" def is_compatible(self):\n",
|
||||
" \"\"\"Check if system meets minimum requirements.\"\"\"\n",
|
||||
" return self.python_version >= (3, 8)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8b274155",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"### 🧪 Test Your SystemInfo Class\n",
|
||||
"\n",
|
||||
"Once you implement the SystemInfo class above, run this cell to test it:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "852c0835",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.100400Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.100273Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.102537Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.102258Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Testing SystemInfo class:\n",
|
||||
"System: Python 3.13 on Darwin (arm64)\n",
|
||||
"Compatible: True\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Test the SystemInfo class (will fail until implemented)\n",
|
||||
"try:\n",
|
||||
" print(\"Testing SystemInfo class:\")\n",
|
||||
" info = SystemInfo()\n",
|
||||
" print(f\"System: {info}\")\n",
|
||||
" print(f\"Compatible: {info.is_compatible()}\")\n",
|
||||
"except NotImplementedError as e:\n",
|
||||
" print(f\"⚠️ {e}\")\n",
|
||||
" print(\"Implement the SystemInfo class above first!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1f605f22",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\"",
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"source": [
|
||||
"## Step 3: Developer Personalization\n",
|
||||
"\n",
|
||||
"Let's make TinyTorch yours! Create a developer profile that will identify you throughout your ML systems journey."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "d2471b77",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.104097Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.103977Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.106621Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.106327Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| export\n",
|
||||
"class DeveloperProfile:\n",
|
||||
" \"\"\"\n",
|
||||
" Developer profile for personalizing TinyTorch experience.\n",
|
||||
" \n",
|
||||
" TODO: Implement this class to store and display developer information.\n",
|
||||
" Default to course instructor but allow students to personalize.\n",
|
||||
" \"\"\"\n",
|
||||
" \n",
|
||||
" @staticmethod\n",
|
||||
" def _load_default_flame():\n",
|
||||
" \"\"\"\n",
|
||||
" Load the default TinyTorch flame ASCII art from file.\n",
|
||||
" \n",
|
||||
" TODO: Implement file loading for tinytorch_flame.txt with fallback.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\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",
|
||||
" TODO: Store developer information with sensible defaults.\n",
|
||||
" Students should be able to customize this with their own info and ASCII art.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\n",
|
||||
" \n",
|
||||
" def __str__(self):\n",
|
||||
" \"\"\"\n",
|
||||
" Return formatted developer information.\n",
|
||||
" \n",
|
||||
" TODO: Format developer info as a professional signature with optional ASCII art.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\n",
|
||||
" \n",
|
||||
" def get_signature(self):\n",
|
||||
" \"\"\"\n",
|
||||
" Get a short signature for code headers.\n",
|
||||
" \n",
|
||||
" TODO: Return a concise signature like \"Built by Name (@github)\"\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")\n",
|
||||
" \n",
|
||||
" def get_ascii_art(self):\n",
|
||||
" \"\"\"\n",
|
||||
" Get ASCII art for the profile.\n",
|
||||
" \n",
|
||||
" TODO: Return custom ASCII art or default flame loaded from file.\n",
|
||||
" \"\"\"\n",
|
||||
" raise NotImplementedError(\"Student implementation required\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "b61db25b",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.107876Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.107776Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.111841Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.111397Z"
|
||||
},
|
||||
"lines_to_next_cell": 1
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"#| hide\n",
|
||||
"#| export\n",
|
||||
"class DeveloperProfile:\n",
|
||||
" \"\"\"Developer profile for personalizing TinyTorch experience.\"\"\"\n",
|
||||
" \n",
|
||||
" @staticmethod\n",
|
||||
" def _load_default_flame():\n",
|
||||
" \"\"\"Load the default TinyTorch flame ASCII art from file.\"\"\"\n",
|
||||
" try:\n",
|
||||
" # Try to load from the same directory as this module\n",
|
||||
" import os\n",
|
||||
" try:\n",
|
||||
" # Try to get the directory of the current file\n",
|
||||
" current_dir = os.path.dirname(__file__)\n",
|
||||
" except NameError:\n",
|
||||
" # If __file__ is not defined (e.g., in notebook), use current directory\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",
|
||||
" # Add the Tiny🔥Torch text below the flame\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",
|
||||
" \n",
|
||||
" def __init__(self, name=\"Vijay Janapa Reddi\", affiliation=\"Harvard University\", \n",
|
||||
" email=\"vj@eecs.harvard.edu\", github_username=\"profvjreddi\", ascii_art=None):\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",
|
||||
" \n",
|
||||
" def __str__(self):\n",
|
||||
" return f\"👨💻 {self.name} | {self.affiliation} | @{self.github_username}\"\n",
|
||||
" \n",
|
||||
" def get_signature(self):\n",
|
||||
" \"\"\"Get a short signature for code headers.\"\"\"\n",
|
||||
" return f\"Built by {self.name} (@{self.github_username})\"\n",
|
||||
" \n",
|
||||
" def get_ascii_art(self):\n",
|
||||
" \"\"\"Get ASCII art for the profile.\"\"\"\n",
|
||||
" return self.ascii_art\n",
|
||||
" \n",
|
||||
" def get_full_profile(self):\n",
|
||||
" \"\"\"Get complete profile with ASCII art.\"\"\"\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",
|
||||
"\"\"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "3e3b2101",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"### 🧪 Test Your Developer Profile\n",
|
||||
"\n",
|
||||
"Customize your developer profile! Replace the default information with your own:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "600b26a5",
|
||||
"metadata": {
|
||||
"execution": {
|
||||
"iopub.execute_input": "2025-07-10T23:18:38.113502Z",
|
||||
"iopub.status.busy": "2025-07-10T23:18:38.113365Z",
|
||||
"iopub.status.idle": "2025-07-10T23:18:38.116672Z",
|
||||
"shell.execute_reply": "2025-07-10T23:18:38.116443Z"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Testing DeveloperProfile (with defaults):\n",
|
||||
"Profile: 👨💻 Vijay Janapa Reddi | Harvard University | @profvjreddi\n",
|
||||
"Signature: Built by Vijay Janapa Reddi (@profvjreddi)\n",
|
||||
"\n",
|
||||
"🎨 ASCII Art Preview:\n",
|
||||
". . ... ....... .... ... . . .. .... . .. . . . . . .... \n",
|
||||
". . .. .++. .. . . . .. ... . . . .. ... .. \n",
|
||||
" . . . .=++=.. . . . .. . . .. . ... .. . . \n",
|
||||
@@ -591,265 +117,22 @@
|
||||
" ....-+=======+-...... .. . . ... . . .. ... . . .... . . . . ..... . ... ..... .\n",
|
||||
" .... . ......:..... ... . .. . ... . . ... . . . ... . . . ... .. ..... . . \n",
|
||||
"\n",
|
||||
" \n",
|
||||
" Tiny🔥Torch\n",
|
||||
" Build ML Systems from Scratch!\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"🔥 Full Profile Display:\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",
|
||||
" \n",
|
||||
" Tiny🔥Torch\n",
|
||||
" Build ML Systems from Scratch!\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"👨💻 Developer: Vijay Janapa Reddi\n",
|
||||
"🏛️ Affiliation: Harvard University\n",
|
||||
"📧 Email: vj@eecs.harvard.edu\n",
|
||||
"🐙 GitHub: @profvjreddi\n",
|
||||
"🔥 Ready to build ML systems from scratch!\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"🎯 YOUR TURN: Create your own profile!\n",
|
||||
"Uncomment and modify the lines below:\n",
|
||||
"# my_profile = DeveloperProfile(\n",
|
||||
"# name='Your Name',\n",
|
||||
"# affiliation='Your University/Company',\n",
|
||||
"# email='your.email@example.com',\n",
|
||||
"# github_username='yourgithub',\n",
|
||||
"# ascii_art='''\n",
|
||||
"# Your Custom ASCII Art Here!\n",
|
||||
"# Maybe your initials, a logo, or something fun!\n",
|
||||
"# '''\n",
|
||||
"# )\n",
|
||||
"# print(f'My Profile: {my_profile}')\n",
|
||||
"# print(f'My Signature: {my_profile.get_signature()}')\n",
|
||||
"# print(my_profile.get_full_profile())\n"
|
||||
"Tiny🔥Torch\n",
|
||||
"Build ML Systems from Scratch!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Test the DeveloperProfile class\n",
|
||||
"try:\n",
|
||||
" print(\"Testing DeveloperProfile (with defaults):\")\n",
|
||||
" # Default profile (instructor)\n",
|
||||
" default_profile = DeveloperProfile()\n",
|
||||
" print(f\"Profile: {default_profile}\")\n",
|
||||
" print(f\"Signature: {default_profile.get_signature()}\")\n",
|
||||
" print()\n",
|
||||
" \n",
|
||||
" print(\"🎨 ASCII Art Preview:\")\n",
|
||||
" print(default_profile.get_ascii_art())\n",
|
||||
" print()\n",
|
||||
" \n",
|
||||
" print(\"🔥 Full Profile Display:\")\n",
|
||||
" print(default_profile.get_full_profile())\n",
|
||||
" print()\n",
|
||||
" \n",
|
||||
" # TODO: Students should customize this with their own information!\n",
|
||||
" print(\"🎯 YOUR TURN: Create your own profile!\")\n",
|
||||
" print(\"Uncomment and modify the lines below:\")\n",
|
||||
" print(\"# my_profile = DeveloperProfile(\")\n",
|
||||
" print(\"# name='Your Name',\")\n",
|
||||
" print(\"# affiliation='Your University/Company',\")\n",
|
||||
" print(\"# email='your.email@example.com',\")\n",
|
||||
" print(\"# github_username='yourgithub',\")\n",
|
||||
" print(\"# ascii_art='''\")\n",
|
||||
" print(\"# Your Custom ASCII Art Here!\")\n",
|
||||
" print(\"# Maybe your initials, a logo, or something fun!\")\n",
|
||||
" print(\"# '''\")\n",
|
||||
" print(\"# )\")\n",
|
||||
" print(\"# print(f'My Profile: {my_profile}')\")\n",
|
||||
" print(\"# print(f'My Signature: {my_profile.get_signature()}')\")\n",
|
||||
" print(\"# print(my_profile.get_full_profile())\")\n",
|
||||
" \n",
|
||||
"except NotImplementedError as e:\n",
|
||||
" print(f\"⚠️ {e}\")\n",
|
||||
" print(\"Implement the DeveloperProfile class above first!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "f07fb565",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"### 🎨 Personalization Challenge\n",
|
||||
"\n",
|
||||
"**For Students**: Make TinyTorch truly yours by:\n",
|
||||
"\n",
|
||||
"1. **Update your profile** in the cell above with your real information\n",
|
||||
"2. **Create custom ASCII art** - your initials, a simple logo, or something that represents you\n",
|
||||
"3. **Customize the flame file** - edit `tinytorch_flame.txt` to create your own default art\n",
|
||||
"4. **Add your signature** to code you write throughout the course\n",
|
||||
"5. **Show off your full profile** with the `get_full_profile()` method\n",
|
||||
"\n",
|
||||
"This isn't just about customization - it's about taking ownership of your learning journey in ML systems!\n",
|
||||
"\n",
|
||||
"**ASCII Art Customization Options:**\n",
|
||||
"\n",
|
||||
"**Option 1: Custom ASCII Art Parameter**\n",
|
||||
"```python\n",
|
||||
"my_profile = DeveloperProfile(\n",
|
||||
" name=\"Your Name\",\n",
|
||||
" ascii_art='''\n",
|
||||
" Your Custom ASCII Art Here!\n",
|
||||
" Maybe your initials, a logo, or something fun!\n",
|
||||
" '''\n",
|
||||
")\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"**Option 2: Edit the Default Flame File**\n",
|
||||
"- Edit `tinytorch_flame.txt` in this directory\n",
|
||||
"- Replace with your own ASCII art design\n",
|
||||
"- All students using defaults will see your custom art!\n",
|
||||
"\n",
|
||||
"**ASCII Art Ideas:**\n",
|
||||
"- Your initials in block letters\n",
|
||||
"- A simple logo or symbol that represents you\n",
|
||||
"- Your university mascot in ASCII\n",
|
||||
"- A coding-themed design\n",
|
||||
"- Something that motivates you!\n",
|
||||
"\n",
|
||||
"**Example custom ASCII art:**\n",
|
||||
"```\n",
|
||||
" A L I C E\n",
|
||||
" /\\\\ | | | | /\\\\ |\n",
|
||||
" / \\\\| | | |/ \\\\|\n",
|
||||
" / \\\\ | | / \\\\\n",
|
||||
"/ \\\\|_|/ \\\\\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"**Pro Tip**: The `tinytorch_flame.txt` file contains the beautiful default flame art. You can:\n",
|
||||
"- Edit it directly for a personalized default\n",
|
||||
"- Create your own `.txt` file and modify the code to load it\n",
|
||||
"- Use online ASCII art generators for inspiration\n",
|
||||
"\n",
|
||||
"**Example personalized hello:**\n",
|
||||
"```python\n",
|
||||
"def my_hello_tinytorch():\n",
|
||||
" profile = DeveloperProfile(name=\"Your Name\", github_username=\"yourgithub\")\n",
|
||||
" return f\"🔥 Welcome to TinyTorch! I'm {profile.name} and I'm ready to build ML systems from scratch! Let's go! 🔥\"\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a851b417",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"## Step 4: Try the Export Process\n",
|
||||
"\n",
|
||||
"Now let's export our code! In your terminal, run:\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"python bin/tito.py sync --module setup\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will export the code marked with `#| export` to `tinytorch/core/utils.py`.\n",
|
||||
"\n",
|
||||
"**What happens during export:**\n",
|
||||
"1. nbdev scans this notebook for `#| export` cells\n",
|
||||
"2. Extracts the Python code \n",
|
||||
"3. Writes it to `tinytorch/core/utils.py` (because of `#| default_exp core.utils`)\n",
|
||||
"4. Handles imports and dependencies automatically\n",
|
||||
"\n",
|
||||
"**🔍 Verification**: After export, check `tinytorch/core/utils.py` - you'll see your functions there with auto-generated headers pointing back to this notebook!\n",
|
||||
"\n",
|
||||
"**Note**: The export process will use the instructor solutions (from `#|hide` cells) so the package will have working implementations even if you haven't completed the exercises yet."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "400d5760",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"## Step 5: Run Tests\n",
|
||||
"\n",
|
||||
"After exporting, run the tests:\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"python bin/tito.py test --module setup\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will run all tests for the setup module and verify your implementation works correctly.\n",
|
||||
"\n",
|
||||
"## Step 6: Check Your Progress\n",
|
||||
"\n",
|
||||
"See your overall progress:\n",
|
||||
"\n",
|
||||
"```bash\n",
|
||||
"python bin/tito.py info\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This shows which modules are complete and which are pending."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6159a978",
|
||||
"metadata": {
|
||||
"cell_marker": "\"\"\""
|
||||
},
|
||||
"source": [
|
||||
"## 🎉 Congratulations!\n",
|
||||
"\n",
|
||||
"You've learned the TinyTorch development workflow:\n",
|
||||
"\n",
|
||||
"1. ✅ Write code in notebooks with `#| export`\n",
|
||||
"2. ✅ Export with `tito sync --module setup` \n",
|
||||
"3. ✅ Test with `tito test --module setup`\n",
|
||||
"4. ✅ Check progress with `tito info`\n",
|
||||
"\n",
|
||||
"**This is the rhythm you'll use for every module in TinyTorch.**\n",
|
||||
"\n",
|
||||
"### Next Steps\n",
|
||||
"\n",
|
||||
"Ready for the real work? Head to **Module 1: Tensor** where you'll build the core data structures that power everything else in TinyTorch.\n",
|
||||
"\n",
|
||||
"**Development Tips:**\n",
|
||||
"- Always test your code in the notebook first\n",
|
||||
"- Export frequently to catch issues early \n",
|
||||
"- Read error messages carefully - they're designed to help\n",
|
||||
"- When stuck, check if your code exports cleanly first\n",
|
||||
"\n",
|
||||
"Happy building! 🔥"
|
||||
"if __name__ == \"__main__\":\n",
|
||||
" hello_tinytorch()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"jupytext": {
|
||||
"main_language": "python"
|
||||
"cell_metadata_filter": "-all",
|
||||
"main_language": "python",
|
||||
"notebook_metadata_filter": "-all"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
@@ -861,7 +144,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.3"
|
||||
"version": "3.8.19"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -1,521 +1,52 @@
|
||||
# ---
|
||||
# jupyter:
|
||||
# jupytext:
|
||||
# text_representation:
|
||||
# extension: .py
|
||||
# format_name: percent
|
||||
# format_version: '1.3'
|
||||
# jupytext_version: 1.17.1
|
||||
# ---
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
# Module 0: Setup - Tiny🔥Torch Development Workflow
|
||||
|
||||
Welcome to TinyTorch! This module teaches you the development workflow you'll use throughout the course.
|
||||
|
||||
## Learning Goals
|
||||
- Understand the nbdev notebook-to-Python workflow
|
||||
- Write your first TinyTorch code
|
||||
- Run tests and use the CLI tools
|
||||
- Get comfortable with the development rhythm
|
||||
|
||||
## The TinyTorch Development Cycle
|
||||
|
||||
1. **Write code** in this notebook using `#| export`
|
||||
2. **Export code** with `python bin/tito.py sync --module setup`
|
||||
3. **Run tests** with `python bin/tito.py test --module setup`
|
||||
4. **Check progress** with `python bin/tito.py info`
|
||||
|
||||
Let's get started!
|
||||
"""
|
||||
# # TinyTorch Setup Module
|
||||
#
|
||||
# Welcome to TinyTorch! This is your first module in the Machine Learning Systems course.
|
||||
#
|
||||
# This module simply displays our beautiful ASCII art to get you started.
|
||||
|
||||
# %%
|
||||
#| default_exp core.utils
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Setup imports and environment
|
||||
import sys
|
||||
import platform
|
||||
from datetime import datetime
|
||||
|
||||
print("🔥 TinyTorch Development Environment")
|
||||
print(f"Python {sys.version}")
|
||||
print(f"Platform: {platform.system()} {platform.release()}")
|
||||
print(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
## Step 1: Understanding the Module → Package Structure
|
||||
|
||||
**🎓 Teaching vs. 🔧 Building**: This course has two sides:
|
||||
- **Teaching side**: You work in `modules/setup/setup_dev.ipynb` (learning-focused)
|
||||
- **Building side**: Your code exports to `tinytorch/core/utils.py` (production package)
|
||||
|
||||
**Key Concept**: The `#| default_exp core.utils` directive at the top tells nbdev to export all `#| export` cells to `tinytorch/core/utils.py`.
|
||||
|
||||
This separation allows us to:
|
||||
- Organize learning by **concepts** (modules)
|
||||
- Organize code by **function** (package structure)
|
||||
- Build a real ML framework while learning systematically
|
||||
|
||||
Let's write a simple "Hello World" function with the `#| export` directive:
|
||||
"""
|
||||
|
||||
# %%
|
||||
#| export
|
||||
def hello_tinytorch():
|
||||
"""
|
||||
A simple hello world function for TinyTorch.
|
||||
|
||||
TODO: Implement this function to return a welcoming message about TinyTorch.
|
||||
Make it encouraging and mention what students will build.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def add_numbers(a, b):
|
||||
"""
|
||||
Add two numbers together.
|
||||
|
||||
TODO: Implement addition of two numbers.
|
||||
This is the foundation of all mathematical operations in ML.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
# %%
|
||||
#| hide
|
||||
#| export
|
||||
def hello_tinytorch():
|
||||
"""A simple hello world function for TinyTorch."""
|
||||
return "🔥 Welcome to TinyTorch! Ready to build ML systems from scratch? Let's go! 🔥"
|
||||
|
||||
def add_numbers(a, b):
|
||||
"""Add two numbers together."""
|
||||
return a + b
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
### 🧪 Test Your Implementation
|
||||
|
||||
Once you implement the functions above, run this cell to test them:
|
||||
"""
|
||||
|
||||
# %%
|
||||
# Test the functions in the notebook (will fail until implemented)
|
||||
try:
|
||||
print("Testing hello_tinytorch():")
|
||||
print(hello_tinytorch())
|
||||
print()
|
||||
print("Testing add_numbers():")
|
||||
print(f"2 + 3 = {add_numbers(2, 3)}")
|
||||
except NotImplementedError as e:
|
||||
print(f"⚠️ {e}")
|
||||
print("Implement the functions above first!")
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
## Step 2: A Simple Class
|
||||
|
||||
Let's create a simple class that will help us understand system information. This is still basic, but shows how to structure classes in TinyTorch.
|
||||
"""
|
||||
|
||||
# %%
|
||||
#| export
|
||||
class SystemInfo:
|
||||
"""
|
||||
Simple system information class.
|
||||
|
||||
TODO: Implement this class to collect and display system information.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize system information collection.
|
||||
"""Display the TinyTorch ASCII art"""
|
||||
try:
|
||||
# Get the directory containing this file
|
||||
current_dir = Path(__file__).parent
|
||||
art_file = current_dir / "tinytorch_flame.txt"
|
||||
|
||||
TODO: Collect Python version, platform, and machine information.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Return human-readable system information.
|
||||
|
||||
TODO: Format system info as a readable string.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def is_compatible(self):
|
||||
"""
|
||||
Check if system meets minimum requirements.
|
||||
|
||||
TODO: Check if Python version is >= 3.8
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
# %%
|
||||
#| hide
|
||||
#| export
|
||||
class SystemInfo:
|
||||
"""Simple system information class."""
|
||||
|
||||
def __init__(self):
|
||||
self.python_version = sys.version_info
|
||||
self.platform = platform.system()
|
||||
self.machine = platform.machine()
|
||||
|
||||
def __str__(self):
|
||||
return f"Python {self.python_version.major}.{self.python_version.minor} on {self.platform} ({self.machine})"
|
||||
|
||||
def is_compatible(self):
|
||||
"""Check if system meets minimum requirements."""
|
||||
return self.python_version >= (3, 8)
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
### 🧪 Test Your SystemInfo Class
|
||||
|
||||
Once you implement the SystemInfo class above, run this cell to test it:
|
||||
"""
|
||||
|
||||
# %%
|
||||
# Test the SystemInfo class (will fail until implemented)
|
||||
try:
|
||||
print("Testing SystemInfo class:")
|
||||
info = SystemInfo()
|
||||
print(f"System: {info}")
|
||||
print(f"Compatible: {info.is_compatible()}")
|
||||
except NotImplementedError as e:
|
||||
print(f"⚠️ {e}")
|
||||
print("Implement the SystemInfo class above first!")
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
## Step 3: Developer Personalization
|
||||
|
||||
Let's make TinyTorch yours! Create a developer profile that will identify you throughout your ML systems journey.
|
||||
"""
|
||||
|
||||
# %%
|
||||
#| export
|
||||
class DeveloperProfile:
|
||||
"""
|
||||
Developer profile for personalizing TinyTorch experience.
|
||||
|
||||
TODO: Implement this class to store and display developer information.
|
||||
Default to course instructor but allow students to personalize.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def _load_default_flame():
|
||||
"""
|
||||
Load the default TinyTorch flame ASCII art from file.
|
||||
|
||||
TODO: Implement file loading for tinytorch_flame.txt with fallback.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def __init__(self, name="Vijay Janapa Reddi", affiliation="Harvard University",
|
||||
email="vj@eecs.harvard.edu", github_username="profvjreddi", ascii_art=None):
|
||||
"""
|
||||
Initialize developer profile.
|
||||
|
||||
TODO: Store developer information with sensible defaults.
|
||||
Students should be able to customize this with their own info and ASCII art.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Return formatted developer information.
|
||||
|
||||
TODO: Format developer info as a professional signature with optional ASCII art.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def get_signature(self):
|
||||
"""
|
||||
Get a short signature for code headers.
|
||||
|
||||
TODO: Return a concise signature like "Built by Name (@github)"
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
def get_ascii_art(self):
|
||||
"""
|
||||
Get ASCII art for the profile.
|
||||
|
||||
TODO: Return custom ASCII art or default flame loaded from file.
|
||||
"""
|
||||
raise NotImplementedError("Student implementation required")
|
||||
|
||||
# %%
|
||||
#| hide
|
||||
#| export
|
||||
class DeveloperProfile:
|
||||
"""Developer profile for personalizing TinyTorch experience."""
|
||||
|
||||
@staticmethod
|
||||
def _load_default_flame():
|
||||
"""Load the default TinyTorch flame ASCII art from file."""
|
||||
if art_file.exists():
|
||||
with open(art_file, 'r') as f:
|
||||
ascii_art = f.read()
|
||||
print(ascii_art)
|
||||
print("Tiny🔥Torch")
|
||||
print("Build ML Systems from Scratch!")
|
||||
else:
|
||||
print("🔥 TinyTorch 🔥")
|
||||
print("Build ML Systems from Scratch!")
|
||||
except NameError:
|
||||
# Handle case when running in notebook where __file__ is not defined
|
||||
try:
|
||||
# Try to load from the same directory as this module
|
||||
import os
|
||||
try:
|
||||
# Try to get the directory of the current file
|
||||
current_dir = os.path.dirname(__file__)
|
||||
except NameError:
|
||||
# If __file__ is not defined (e.g., in notebook), use current directory
|
||||
current_dir = os.getcwd()
|
||||
|
||||
flame_path = os.path.join(current_dir, 'tinytorch_flame.txt')
|
||||
|
||||
with open(flame_path, 'r', encoding='utf-8') as f:
|
||||
flame_art = f.read()
|
||||
|
||||
# Add the Tiny🔥Torch text below the flame
|
||||
return f"""{flame_art}
|
||||
|
||||
Tiny🔥Torch
|
||||
Build ML Systems from Scratch!
|
||||
"""
|
||||
except (FileNotFoundError, IOError):
|
||||
# Fallback to simple flame if file not found
|
||||
return """
|
||||
🔥 TinyTorch Developer 🔥
|
||||
. . . . . .
|
||||
. . . . . .
|
||||
. . . . . . .
|
||||
. . . . . . . .
|
||||
. . . . . . . . .
|
||||
. . . . . . . . . .
|
||||
. . . . . . . . . . .
|
||||
. . . . . . . . . . . .
|
||||
. . . . . . . . . . . . .
|
||||
. . . . . . . . . . . . . .
|
||||
\\ \\ \\ \\ \\ \\ \\ \\ \\ / / / / / /
|
||||
\\ \\ \\ \\ \\ \\ \\ \\ / / / / / /
|
||||
\\ \\ \\ \\ \\ \\ \\ / / / / / /
|
||||
\\ \\ \\ \\ \\ \\ / / / / / /
|
||||
\\ \\ \\ \\ \\ / / / / / /
|
||||
\\ \\ \\ \\ / / / / / /
|
||||
\\ \\ \\ / / / / / /
|
||||
\\ \\ / / / / / /
|
||||
\\ / / / / / /
|
||||
\\/ / / / / /
|
||||
\\/ / / / /
|
||||
\\/ / / /
|
||||
\\/ / /
|
||||
\\/ /
|
||||
\\/
|
||||
|
||||
Tiny🔥Torch
|
||||
Build ML Systems from Scratch!
|
||||
"""
|
||||
|
||||
def __init__(self, name="Vijay Janapa Reddi", affiliation="Harvard University",
|
||||
email="vj@eecs.harvard.edu", github_username="profvjreddi", ascii_art=None):
|
||||
self.name = name
|
||||
self.affiliation = affiliation
|
||||
self.email = email
|
||||
self.github_username = github_username
|
||||
self.ascii_art = ascii_art or self._load_default_flame()
|
||||
|
||||
def __str__(self):
|
||||
return f"👨💻 {self.name} | {self.affiliation} | @{self.github_username}"
|
||||
|
||||
def get_signature(self):
|
||||
"""Get a short signature for code headers."""
|
||||
return f"Built by {self.name} (@{self.github_username})"
|
||||
|
||||
def get_ascii_art(self):
|
||||
"""Get ASCII art for the profile."""
|
||||
return self.ascii_art
|
||||
|
||||
def get_full_profile(self):
|
||||
"""Get complete profile with ASCII art."""
|
||||
return f"""{self.ascii_art}
|
||||
|
||||
👨💻 Developer: {self.name}
|
||||
🏛️ Affiliation: {self.affiliation}
|
||||
📧 Email: {self.email}
|
||||
🐙 GitHub: @{self.github_username}
|
||||
🔥 Ready to build ML systems from scratch!
|
||||
"""
|
||||
art_file = Path(os.getcwd()) / "tinytorch_flame.txt"
|
||||
if art_file.exists():
|
||||
with open(art_file, 'r') as f:
|
||||
ascii_art = f.read()
|
||||
print(ascii_art)
|
||||
print("Tiny🔥Torch")
|
||||
print("Build ML Systems from Scratch!")
|
||||
else:
|
||||
print("🔥 TinyTorch 🔥")
|
||||
print("Build ML Systems from Scratch!")
|
||||
except:
|
||||
print("🔥 TinyTorch 🔥")
|
||||
print("Build ML Systems from Scratch!")
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
### 🧪 Test Your Developer Profile
|
||||
|
||||
Customize your developer profile! Replace the default information with your own:
|
||||
"""
|
||||
# ## Test the Setup
|
||||
#
|
||||
# Let's run our hello function to see the ASCII art:
|
||||
|
||||
# %%
|
||||
# Test the DeveloperProfile class
|
||||
try:
|
||||
print("Testing DeveloperProfile (with defaults):")
|
||||
# Default profile (instructor)
|
||||
default_profile = DeveloperProfile()
|
||||
print(f"Profile: {default_profile}")
|
||||
print(f"Signature: {default_profile.get_signature()}")
|
||||
print()
|
||||
|
||||
print("🎨 ASCII Art Preview:")
|
||||
print(default_profile.get_ascii_art())
|
||||
print()
|
||||
|
||||
print("🔥 Full Profile Display:")
|
||||
print(default_profile.get_full_profile())
|
||||
print()
|
||||
|
||||
# TODO: Students should customize this with their own information!
|
||||
print("🎯 YOUR TURN: Create your own profile!")
|
||||
print("Uncomment and modify the lines below:")
|
||||
print("# my_profile = DeveloperProfile(")
|
||||
print("# name='Your Name',")
|
||||
print("# affiliation='Your University/Company',")
|
||||
print("# email='your.email@example.com',")
|
||||
print("# github_username='yourgithub',")
|
||||
print("# ascii_art='''")
|
||||
print("# Your Custom ASCII Art Here!")
|
||||
print("# Maybe your initials, a logo, or something fun!")
|
||||
print("# '''")
|
||||
print("# )")
|
||||
print("# print(f'My Profile: {my_profile}')")
|
||||
print("# print(f'My Signature: {my_profile.get_signature()}')")
|
||||
print("# print(my_profile.get_full_profile())")
|
||||
|
||||
except NotImplementedError as e:
|
||||
print(f"⚠️ {e}")
|
||||
print("Implement the DeveloperProfile class above first!")
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
### 🎨 Personalization Challenge
|
||||
|
||||
**For Students**: Make TinyTorch truly yours by:
|
||||
|
||||
1. **Update your profile** in the cell above with your real information
|
||||
2. **Create custom ASCII art** - your initials, a simple logo, or something that represents you
|
||||
3. **Customize the flame file** - edit `tinytorch_flame.txt` to create your own default art
|
||||
4. **Add your signature** to code you write throughout the course
|
||||
5. **Show off your full profile** with the `get_full_profile()` method
|
||||
|
||||
This isn't just about customization - it's about taking ownership of your learning journey in ML systems!
|
||||
|
||||
**ASCII Art Customization Options:**
|
||||
|
||||
**Option 1: Custom ASCII Art Parameter**
|
||||
```python
|
||||
my_profile = DeveloperProfile(
|
||||
name="Your Name",
|
||||
ascii_art='''
|
||||
Your Custom ASCII Art Here!
|
||||
Maybe your initials, a logo, or something fun!
|
||||
'''
|
||||
)
|
||||
```
|
||||
|
||||
**Option 2: Edit the Default Flame File**
|
||||
- Edit `tinytorch_flame.txt` in this directory
|
||||
- Replace with your own ASCII art design
|
||||
- All students using defaults will see your custom art!
|
||||
|
||||
**ASCII Art Ideas:**
|
||||
- Your initials in block letters
|
||||
- A simple logo or symbol that represents you
|
||||
- Your university mascot in ASCII
|
||||
- A coding-themed design
|
||||
- Something that motivates you!
|
||||
|
||||
**Example custom ASCII art:**
|
||||
```
|
||||
A L I C E
|
||||
/\\ | | | | /\\ |
|
||||
/ \\| | | |/ \\|
|
||||
/ \\ | | / \\
|
||||
/ \\|_|/ \\
|
||||
```
|
||||
|
||||
**Pro Tip**: The `tinytorch_flame.txt` file contains the beautiful default flame art. You can:
|
||||
- Edit it directly for a personalized default
|
||||
- Create your own `.txt` file and modify the code to load it
|
||||
- Use online ASCII art generators for inspiration
|
||||
|
||||
**Example personalized hello:**
|
||||
```python
|
||||
def my_hello_tinytorch():
|
||||
profile = DeveloperProfile(name="Your Name", github_username="yourgithub")
|
||||
return f"🔥 Welcome to TinyTorch! I'm {profile.name} and I'm ready to build ML systems from scratch! Let's go! 🔥"
|
||||
```
|
||||
"""
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
## Step 4: Try the Export Process
|
||||
|
||||
Now let's export our code! In your terminal, run:
|
||||
|
||||
```bash
|
||||
python bin/tito.py sync --module setup
|
||||
```
|
||||
|
||||
This will export the code marked with `#| export` to `tinytorch/core/utils.py`.
|
||||
|
||||
**What happens during export:**
|
||||
1. nbdev scans this notebook for `#| export` cells
|
||||
2. Extracts the Python code
|
||||
3. Writes it to `tinytorch/core/utils.py` (because of `#| default_exp core.utils`)
|
||||
4. Handles imports and dependencies automatically
|
||||
|
||||
**🔍 Verification**: After export, check `tinytorch/core/utils.py` - you'll see your functions there with auto-generated headers pointing back to this notebook!
|
||||
|
||||
**Note**: The export process will use the instructor solutions (from `#|hide` cells) so the package will have working implementations even if you haven't completed the exercises yet.
|
||||
"""
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
## Step 5: Run Tests
|
||||
|
||||
After exporting, run the tests:
|
||||
|
||||
```bash
|
||||
python bin/tito.py test --module setup
|
||||
```
|
||||
|
||||
This will run all tests for the setup module and verify your implementation works correctly.
|
||||
|
||||
## Step 6: Check Your Progress
|
||||
|
||||
See your overall progress:
|
||||
|
||||
```bash
|
||||
python bin/tito.py info
|
||||
```
|
||||
|
||||
This shows which modules are complete and which are pending.
|
||||
"""
|
||||
|
||||
# %% [markdown]
|
||||
"""
|
||||
## 🎉 Congratulations!
|
||||
|
||||
You've learned the TinyTorch development workflow:
|
||||
|
||||
1. ✅ Write code in notebooks with `#| export`
|
||||
2. ✅ Export with `tito sync --module setup`
|
||||
3. ✅ Test with `tito test --module setup`
|
||||
4. ✅ Check progress with `tito info`
|
||||
|
||||
**This is the rhythm you'll use for every module in TinyTorch.**
|
||||
|
||||
### Next Steps
|
||||
|
||||
Ready for the real work? Head to **Module 1: Tensor** where you'll build the core data structures that power everything else in TinyTorch.
|
||||
|
||||
**Development Tips:**
|
||||
- Always test your code in the notebook first
|
||||
- Export frequently to catch issues early
|
||||
- Read error messages carefully - they're designed to help
|
||||
- When stuck, check if your code exports cleanly first
|
||||
|
||||
Happy building! 🔥
|
||||
"""
|
||||
if __name__ == "__main__":
|
||||
hello_tinytorch()
|
||||
|
||||
@@ -1,333 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tests for TinyTorch Setup module.
|
||||
|
||||
Tests the basic setup functionality including hello function,
|
||||
arithmetic operations, and system information class.
|
||||
Simple tests for the setup module.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Add parent directory to path for module imports
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
||||
# Add the parent directory to the path so we can import setup_dev
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
# Import from the module's development file
|
||||
from setup_dev import hello_tinytorch, add_numbers, SystemInfo, DeveloperProfile
|
||||
from setup_dev import hello_tinytorch
|
||||
|
||||
|
||||
def approx_equal(a, b, tolerance=1e-9):
|
||||
"""Simple approximation check without pytest."""
|
||||
return abs(a - b) < tolerance
|
||||
|
||||
|
||||
class TestSetupFunctions:
|
||||
"""Test setup module functions."""
|
||||
|
||||
def test_hello_tinytorch(self):
|
||||
"""Test hello_tinytorch function."""
|
||||
result = hello_tinytorch()
|
||||
assert isinstance(result, str)
|
||||
assert "TinyTorch" in result
|
||||
assert "🔥" in result # Should have fire emoji
|
||||
assert len(result) > 10 # Should be a meaningful message
|
||||
|
||||
def test_add_numbers(self):
|
||||
"""Test add_numbers function."""
|
||||
# Test positive numbers
|
||||
assert add_numbers(2, 3) == 5
|
||||
assert add_numbers(10, 15) == 25
|
||||
|
||||
# Test with zero
|
||||
assert add_numbers(0, 5) == 5
|
||||
assert add_numbers(7, 0) == 7
|
||||
assert add_numbers(0, 0) == 0
|
||||
|
||||
# Test negative numbers
|
||||
assert add_numbers(-5, 3) == -2
|
||||
assert add_numbers(-10, -15) == -25
|
||||
assert add_numbers(10, -5) == 5
|
||||
|
||||
# Test floats
|
||||
assert approx_equal(add_numbers(2.5, 3.7), 6.2)
|
||||
assert approx_equal(add_numbers(1.1, 2.2), 3.3)
|
||||
|
||||
|
||||
class TestSystemInfo:
|
||||
"""Test SystemInfo class."""
|
||||
|
||||
def test_system_info_creation(self):
|
||||
"""Test SystemInfo class instantiation."""
|
||||
info = SystemInfo()
|
||||
assert hasattr(info, 'python_version')
|
||||
assert hasattr(info, 'platform')
|
||||
assert hasattr(info, 'machine')
|
||||
|
||||
def test_system_info_properties(self):
|
||||
"""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 platform is a string
|
||||
assert isinstance(info.platform, str)
|
||||
assert len(info.platform) > 0
|
||||
|
||||
# Check machine is a string
|
||||
assert isinstance(info.machine, str)
|
||||
assert len(info.machine) > 0
|
||||
|
||||
def test_system_info_str(self):
|
||||
"""Test SystemInfo string representation."""
|
||||
info = SystemInfo()
|
||||
str_repr = str(info)
|
||||
|
||||
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.platform in str_repr
|
||||
assert info.machine in str_repr
|
||||
|
||||
def test_is_compatible(self):
|
||||
"""Test SystemInfo compatibility check."""
|
||||
info = SystemInfo()
|
||||
compatible = info.is_compatible()
|
||||
|
||||
# Should return a boolean
|
||||
assert isinstance(compatible, bool)
|
||||
|
||||
# Since we're running this test, Python should be >= 3.8
|
||||
# (This is a reasonable assumption for TinyTorch)
|
||||
assert compatible is True
|
||||
|
||||
def test_compatibility_logic(self):
|
||||
"""Test the compatibility logic more thoroughly."""
|
||||
info = SystemInfo()
|
||||
|
||||
# Current Python version should be compatible
|
||||
current_version = info.python_version
|
||||
assert current_version >= (3, 8)
|
||||
|
||||
# The is_compatible method should return True for current version
|
||||
assert info.is_compatible() is True
|
||||
|
||||
|
||||
class TestDeveloperProfile:
|
||||
"""Test DeveloperProfile class."""
|
||||
|
||||
def test_developer_profile_creation_defaults(self):
|
||||
"""Test DeveloperProfile with default values."""
|
||||
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
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
def test_developer_profile_str(self):
|
||||
"""Test DeveloperProfile string representation."""
|
||||
profile = DeveloperProfile()
|
||||
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
|
||||
|
||||
def test_developer_profile_signature(self):
|
||||
"""Test DeveloperProfile signature method."""
|
||||
profile = DeveloperProfile()
|
||||
signature = profile.get_signature()
|
||||
|
||||
assert isinstance(signature, str)
|
||||
assert "Built by" in signature
|
||||
assert "Vijay Janapa Reddi" in signature
|
||||
assert "@profvjreddi" in signature
|
||||
|
||||
def test_developer_profile_custom_signature(self):
|
||||
"""Test DeveloperProfile signature with custom values."""
|
||||
profile = DeveloperProfile(
|
||||
name="Jane Doe",
|
||||
github_username="janedoe"
|
||||
)
|
||||
signature = profile.get_signature()
|
||||
|
||||
assert "Built by Jane Doe (@janedoe)" == 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()
|
||||
|
||||
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 from file
|
||||
|
||||
# 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
|
||||
|
||||
def test_developer_profile_partial_customization(self):
|
||||
"""Test DeveloperProfile with partial customization."""
|
||||
profile = DeveloperProfile(
|
||||
name="Custom Name",
|
||||
github_username="customuser"
|
||||
)
|
||||
|
||||
# Custom values should be set
|
||||
assert profile.name == "Custom Name"
|
||||
assert profile.github_username == "customuser"
|
||||
|
||||
# Defaults should remain
|
||||
assert profile.affiliation == "Harvard University"
|
||||
assert profile.email == "vj@eecs.harvard.edu"
|
||||
|
||||
# Should still have default ASCII art from file
|
||||
assert "Tiny🔥Torch" in profile.get_ascii_art()
|
||||
assert "Build ML Systems from Scratch!" in profile.get_ascii_art()
|
||||
|
||||
|
||||
class TestModuleIntegration:
|
||||
"""Test integration between different parts of the setup module."""
|
||||
|
||||
def test_all_functions_work_together(self):
|
||||
"""Test that all setup functions work without conflicts."""
|
||||
# Test functions
|
||||
hello_msg = hello_tinytorch()
|
||||
sum_result = add_numbers(5, 10)
|
||||
|
||||
# Test class
|
||||
info = SystemInfo()
|
||||
info_str = str(info)
|
||||
is_compat = info.is_compatible()
|
||||
|
||||
# All should work without errors
|
||||
assert isinstance(hello_msg, str)
|
||||
assert sum_result == 15
|
||||
assert isinstance(info_str, str)
|
||||
assert isinstance(is_compat, bool)
|
||||
|
||||
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(SystemInfo)
|
||||
|
||||
|
||||
def run_setup_tests():
|
||||
"""
|
||||
Run all setup tests without pytest.
|
||||
"""
|
||||
print("🧪 Running Setup Module Tests...")
|
||||
print()
|
||||
|
||||
# Test functions
|
||||
test_functions = TestSetupFunctions()
|
||||
tests = [
|
||||
("test_hello_tinytorch", test_functions.test_hello_tinytorch),
|
||||
("test_add_numbers", test_functions.test_add_numbers),
|
||||
]
|
||||
|
||||
# Test SystemInfo class
|
||||
test_system_info = TestSystemInfo()
|
||||
tests.extend([
|
||||
("test_system_info_creation", test_system_info.test_system_info_creation),
|
||||
("test_system_info_properties", test_system_info.test_system_info_properties),
|
||||
("test_system_info_str", test_system_info.test_system_info_str),
|
||||
("test_is_compatible", test_system_info.test_is_compatible),
|
||||
("test_compatibility_logic", test_system_info.test_compatibility_logic),
|
||||
])
|
||||
|
||||
# Test DeveloperProfile class
|
||||
test_developer_profile = TestDeveloperProfile()
|
||||
tests.extend([
|
||||
("test_developer_profile_creation_defaults", test_developer_profile.test_developer_profile_creation_defaults),
|
||||
("test_developer_profile_creation_custom", test_developer_profile.test_developer_profile_creation_custom),
|
||||
("test_developer_profile_str", test_developer_profile.test_developer_profile_str),
|
||||
("test_developer_profile_signature", test_developer_profile.test_developer_profile_signature),
|
||||
("test_developer_profile_custom_signature", test_developer_profile.test_developer_profile_custom_signature),
|
||||
("test_developer_profile_ascii_art", test_developer_profile.test_developer_profile_ascii_art),
|
||||
("test_developer_profile_full_profile", test_developer_profile.test_developer_profile_full_profile),
|
||||
("test_developer_profile_partial_customization", test_developer_profile.test_developer_profile_partial_customization),
|
||||
])
|
||||
|
||||
# Test integration
|
||||
test_integration = TestModuleIntegration()
|
||||
tests.extend([
|
||||
("test_all_functions_work_together", test_integration.test_all_functions_work_together),
|
||||
("test_no_import_errors", test_integration.test_no_import_errors),
|
||||
])
|
||||
|
||||
# Run all tests
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
for test_name, test_func in tests:
|
||||
try:
|
||||
test_func()
|
||||
print(f"✅ {test_name}: PASSED")
|
||||
passed += 1
|
||||
except Exception as e:
|
||||
print(f"❌ {test_name}: FAILED - {e}")
|
||||
failed += 1
|
||||
|
||||
print()
|
||||
print(f"🎉 Test Results: {passed} passed, {failed} failed")
|
||||
|
||||
if failed == 0:
|
||||
print("🎉 All Setup Module Tests PASSED!")
|
||||
def test_hello_tinytorch():
|
||||
"""Test that hello_tinytorch runs without error."""
|
||||
try:
|
||||
hello_tinytorch()
|
||||
print("✅ hello_tinytorch() executed successfully")
|
||||
return True
|
||||
else:
|
||||
print(f"❌ {failed} tests failed")
|
||||
except Exception as e:
|
||||
print(f"❌ hello_tinytorch() failed: {e}")
|
||||
return False
|
||||
|
||||
def test_ascii_art_file_exists():
|
||||
"""Test that the ASCII art file exists."""
|
||||
art_file = Path(__file__).parent.parent / "tinytorch_flame.txt"
|
||||
if art_file.exists():
|
||||
print("✅ ASCII art file exists")
|
||||
return True
|
||||
else:
|
||||
print("❌ ASCII art file not found")
|
||||
return False
|
||||
|
||||
def run_tests():
|
||||
"""Run all tests."""
|
||||
print("Running setup module tests...")
|
||||
print("=" * 50)
|
||||
|
||||
tests = [
|
||||
test_hello_tinytorch,
|
||||
test_ascii_art_file_exists,
|
||||
]
|
||||
|
||||
passed = 0
|
||||
total = len(tests)
|
||||
|
||||
for test in tests:
|
||||
if test():
|
||||
passed += 1
|
||||
print()
|
||||
|
||||
print("=" * 50)
|
||||
print(f"Tests passed: {passed}/{total}")
|
||||
|
||||
if passed == total:
|
||||
print("🎉 All tests passed!")
|
||||
return True
|
||||
else:
|
||||
print("❌ Some tests failed")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run tests if script is executed directly
|
||||
success = run_setup_tests()
|
||||
success = run_tests()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user