mirror of
https://github.com/MLSysBook/TinyTorch.git
synced 2026-03-12 07:53:34 -05:00
Redesign TinyTorch CLI logo with vertical 'tiny' integration
- Create bold ASCII art logo with 'tiny' spelled vertically - Add flame banner above TORCH for visual impact - Update tagline to 'Don't import the future. Build it from tensors up.' - Simplify logo command to show philosophy and meaning - Remove unused preferences system - Clean up display logic and improve color scheme The new design features 'tiny' integrated vertically alongside TORCH, creating a unique visual identity that reinforces the framework's philosophy of building from small foundations up to powerful systems.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Logo command for TinyTorch CLI: displays beautiful ASCII art logo.
|
||||
Logo command for TinyTorch CLI: explains the symbolism and meaning behind TinyTorch.
|
||||
"""
|
||||
|
||||
from argparse import ArgumentParser, Namespace
|
||||
@@ -7,11 +7,9 @@ from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
from rich.align import Align
|
||||
from rich.columns import Columns
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from .base import BaseCommand
|
||||
from ..core.preferences import UserPreferences
|
||||
|
||||
class LogoCommand(BaseCommand):
|
||||
@property
|
||||
@@ -20,228 +18,103 @@ class LogoCommand(BaseCommand):
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return "Display the TinyTorch ASCII art logo with theme support"
|
||||
return "Learn about the TinyTorch logo and its meaning"
|
||||
|
||||
def add_arguments(self, parser: ArgumentParser) -> None:
|
||||
parser.add_argument("--animate", action="store_true", help="Show animated flame effect")
|
||||
parser.add_argument("--simple", action="store_true", help="Show simple logo without extra elements")
|
||||
parser.add_argument("--bright", action="store_true", help="Use bright/vivid theme with yellow center")
|
||||
parser.add_argument("--theme", choices=["standard", "bright"], help="Choose logo theme")
|
||||
parser.add_argument("--save-theme", action="store_true", help="Save the selected theme as default")
|
||||
parser.add_argument("--image", action="store_true",
|
||||
help="Show path to the actual logo image file")
|
||||
|
||||
def run(self, args: Namespace) -> int:
|
||||
# Determine theme
|
||||
theme = self._get_theme(args)
|
||||
|
||||
# Save theme preference if requested
|
||||
if args.save_theme:
|
||||
self._save_theme_preference(theme)
|
||||
self.console.print(f"[green]✅ Saved '{theme}' as default theme[/green]")
|
||||
|
||||
if args.animate:
|
||||
self.show_animated_logo(theme=theme)
|
||||
elif args.simple:
|
||||
self.show_simple_logo(theme=theme)
|
||||
else:
|
||||
self.show_full_logo(theme=theme)
|
||||
return 0
|
||||
|
||||
def show_full_logo(self, theme: str = "standard"):
|
||||
"""Show the complete logo with version and tagline."""
|
||||
console = self.console
|
||||
|
||||
# ASCII Art Logo (now returns a Text object)
|
||||
logo_art = self.get_logo_art(theme=theme)
|
||||
# Display the ASCII logo first
|
||||
from ..core.console import print_ascii_logo
|
||||
print_ascii_logo()
|
||||
|
||||
# Add additional tagline
|
||||
tagline = Text()
|
||||
tagline.append("\nBuild Complete Neural Networks from First Principles", style="dim cyan")
|
||||
# Create the explanation text
|
||||
explanation = Text()
|
||||
|
||||
# Combine logo and tagline
|
||||
full_content = Text()
|
||||
full_content.append(logo_art)
|
||||
full_content.append(tagline)
|
||||
# Title
|
||||
explanation.append("\n🔥 The TinyTorch Story\n\n", style="bold yellow")
|
||||
|
||||
# Display with rich styling
|
||||
border_style = "bright_blue" if theme == "standard" else "bright_yellow"
|
||||
console.print()
|
||||
# The flame and sparks
|
||||
explanation.append("The Flame 🔥\n", style="bold orange1")
|
||||
explanation.append(
|
||||
"The flame represents the spark of understanding - how learning ML systems "
|
||||
"starts with a small flame that can grow into mastery. Just as a torch "
|
||||
"lights the way in darkness, TinyTorch illuminates the path to understanding "
|
||||
"neural networks from first principles.\n\n",
|
||||
style="dim"
|
||||
)
|
||||
|
||||
# The sparks
|
||||
explanation.append("The Sparks ✨\n", style="bold orange1")
|
||||
explanation.append(
|
||||
"In our full logo, sparks fly from the flame - representing how knowledge "
|
||||
"spreads. Each concept you learn sends off sparks that ignite understanding "
|
||||
"in other areas. What starts small can catch fire and grow into something powerful.\n\n",
|
||||
style="dim"
|
||||
)
|
||||
|
||||
# The "tiny" philosophy
|
||||
explanation.append("Why 'Tiny'? \n", style="bold cyan")
|
||||
explanation.append(
|
||||
"Inspired by TinyML's philosophy: small systems are accessible and powerful. "
|
||||
"'Tiny' means we start with the fundamentals, building understanding piece by piece. "
|
||||
"By keeping things small and focused, complex concepts become approachable. "
|
||||
"Every giant neural network started with tiny building blocks - tensors, gradients, "
|
||||
"and simple operations.\n\n",
|
||||
style="dim"
|
||||
)
|
||||
|
||||
# The "Torch" connection
|
||||
explanation.append("Why 'Torch'? \n", style="bold cyan")
|
||||
explanation.append(
|
||||
"A tribute to PyTorch, the framework that revolutionized deep learning. "
|
||||
"While PyTorch is powerful, its complexity can overwhelm beginners. "
|
||||
"TinyTorch distills those same concepts into their essence, letting you "
|
||||
"build and understand every component. You're not just using a framework - "
|
||||
"you're building one.\n\n",
|
||||
style="dim"
|
||||
)
|
||||
|
||||
# The neural network in the flame
|
||||
explanation.append("The Hidden Network 🔥\n", style="bold orange1")
|
||||
explanation.append(
|
||||
"Look closely at our logo - within the flame, there's a neural network pattern. "
|
||||
"This represents the core truth: inside every ML system, no matter how complex, "
|
||||
"are simple, connected components working together. The flame contains the network, "
|
||||
"just as understanding contains mastery.\n\n",
|
||||
style="dim"
|
||||
)
|
||||
|
||||
# The philosophy
|
||||
explanation.append("The Philosophy 💡\n", style="bold green")
|
||||
explanation.append(
|
||||
"TinyTorch embodies the belief that anyone can understand ML systems by building them. "
|
||||
"Start small, understand deeply, build everything. What begins as a tiny flame of "
|
||||
"curiosity becomes the torch that lights your path to ML engineering mastery.\n\n",
|
||||
style="dim"
|
||||
)
|
||||
|
||||
# Display in a nice panel
|
||||
console.print(Panel(
|
||||
Align.center(full_content),
|
||||
border_style=border_style,
|
||||
explanation,
|
||||
title="[bold]About the TinyTorch Logo[/bold]",
|
||||
border_style="orange1",
|
||||
padding=(1, 2)
|
||||
))
|
||||
console.print()
|
||||
|
||||
# Show quick stats
|
||||
self.show_progress_stats(theme=theme)
|
||||
|
||||
def show_simple_logo(self, theme: str = "standard"):
|
||||
"""Show just the ASCII art logo."""
|
||||
console = self.console
|
||||
logo_art = self.get_logo_art(theme=theme) # Now returns a Text object
|
||||
# Show logo file path if requested
|
||||
if args.image:
|
||||
logo_path = Path(__file__).parent.parent.parent / "logo" / "logo.png"
|
||||
if logo_path.exists():
|
||||
console.print(f"\n[cyan]Logo image location:[/cyan] {logo_path}")
|
||||
console.print("[dim]Open this file to see the full logo with sparks[/dim]")
|
||||
else:
|
||||
console.print(f"\n[yellow]Logo image not found at expected location[/yellow]")
|
||||
|
||||
console.print()
|
||||
console.print(Align.center(logo_art))
|
||||
console.print()
|
||||
|
||||
def show_animated_logo(self, theme: str = "standard"):
|
||||
"""Show logo with animated flame effect."""
|
||||
console = self.console
|
||||
# Final inspiring message
|
||||
console.print("\n[bold yellow]🔥 Start small. Understand deeply. Build everything.[/bold yellow]\n")
|
||||
|
||||
# Animation frames - different for each theme
|
||||
if theme == "bright":
|
||||
flame_frames = ["✨", "⚡", "🔥", "💫", "✨"] # More energetic
|
||||
else:
|
||||
flame_frames = ["🔥", "🔶", "🔸", "✨", "🔥"] # Professional
|
||||
|
||||
border_style = "bright_blue" if theme == "standard" else "bright_yellow"
|
||||
|
||||
for i in range(10): # Show 10 frames
|
||||
console.clear()
|
||||
|
||||
# Get current flame
|
||||
flame = flame_frames[i % len(flame_frames)]
|
||||
|
||||
# Create animated logo (now returns a Text object)
|
||||
logo_art = self.get_logo_art(theme=theme, flame_char=flame)
|
||||
|
||||
tagline = Text()
|
||||
tagline.append("\nBuild Complete Neural Networks from First Principles", style="dim cyan")
|
||||
|
||||
full_content = Text()
|
||||
full_content.append(logo_art)
|
||||
full_content.append(tagline)
|
||||
|
||||
console.print()
|
||||
console.print(Panel(
|
||||
Align.center(full_content),
|
||||
border_style=border_style,
|
||||
padding=(1, 2)
|
||||
))
|
||||
|
||||
time.sleep(0.2)
|
||||
|
||||
# Show final static version
|
||||
self.show_full_logo(theme=theme)
|
||||
|
||||
def get_logo_art(self, theme: str = "standard", flame_char: str = None):
|
||||
"""Generate the ASCII art logo matching the actual TinyTorch design."""
|
||||
# Set default flame character based on theme
|
||||
if flame_char is None:
|
||||
flame_char = "✨" if theme == "bright" else "🔥"
|
||||
|
||||
# Create a Text object to properly handle Rich markup
|
||||
logo_text = Text()
|
||||
|
||||
# Theme-specific styling
|
||||
if theme == "bright":
|
||||
# Bright theme: vivid yellow center, orange "tiny" text
|
||||
top_flames = "✨🔥✨"
|
||||
else:
|
||||
# Standard theme: professional orange/red tones
|
||||
top_flames = f"{flame_char}{flame_char}"
|
||||
|
||||
# ASCII art representing the real TinyTorch logo:
|
||||
# Flame on left with neural network inside, "tiny TORCH" on right
|
||||
logo_lines = [
|
||||
f" {top_flames} ",
|
||||
" ╱──╲ ████████╗ ██████╗ ██████╗ ██████╗██╗ ██╗",
|
||||
" ╱ ⚡ ╲ ╚══██╔══╝██╔═══██╗██╔══██╗██╔════╝██║ ██║",
|
||||
" ╱ ╱ ╲ ╲ ██║ ██║ ██║██████╔╝██║ ███████║",
|
||||
" │ ●━━━● │ ██║ ██║ ██║██╔══██╗██║ ██╔══██║",
|
||||
" │ │ ⚡ │ │ ██║ ╚██████╔╝██║ ██║╚██████╗██║ ██║",
|
||||
" │ ●━┬━● │ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝",
|
||||
" ╲ ╲●╱ ╱ ",
|
||||
" ╲━━━╱ ",
|
||||
" ╲╱ "
|
||||
]
|
||||
|
||||
# Add the first line with styled "tiny"
|
||||
if theme == "bright":
|
||||
logo_text.append(logo_lines[0])
|
||||
logo_text.append("tiny", style="bold orange1")
|
||||
logo_text.append(" \n")
|
||||
else:
|
||||
logo_text.append(logo_lines[0])
|
||||
logo_text.append("tiny", style="dim")
|
||||
logo_text.append(" \n")
|
||||
|
||||
# Add the main ASCII art lines
|
||||
for line in logo_lines[1:8]:
|
||||
logo_text.append(line + "\n")
|
||||
|
||||
# Add the tagline with proper styling
|
||||
logo_text.append(logo_lines[8])
|
||||
if theme == "bright":
|
||||
logo_text.append(flame_char, style="bright_yellow")
|
||||
logo_text.append(" Learn ML Systems by Building Them", style="bold orange1")
|
||||
else:
|
||||
logo_text.append(f"{flame_char} Learn ML Systems by Building Them", style="orange1")
|
||||
logo_text.append("\n")
|
||||
|
||||
# Add the final line
|
||||
logo_text.append(logo_lines[9])
|
||||
|
||||
return logo_text
|
||||
|
||||
def show_progress_stats(self, theme: str = "standard"):
|
||||
"""Show current progress through the course."""
|
||||
console = self.console
|
||||
|
||||
# Check how many modules are completed
|
||||
# This is a simplified version - could be enhanced to check actual module status
|
||||
|
||||
# Theme-specific emoji and styling
|
||||
if theme == "bright":
|
||||
journey_emoji = "🌟"
|
||||
fire_emoji = "⚡"
|
||||
start_emoji = "💫"
|
||||
border_style = "bright_yellow"
|
||||
else:
|
||||
journey_emoji = "📊"
|
||||
fire_emoji = "🔥"
|
||||
start_emoji = "🚀"
|
||||
border_style = "bright_green"
|
||||
|
||||
stats_table = f"""
|
||||
[bold cyan]{journey_emoji} Your TinyTorch Journey[/bold cyan]
|
||||
|
||||
[bold green]Module Progress:[/bold green]
|
||||
🎯 17 Total Modules Available
|
||||
📚 Build from Tensors → Training → TinyGPT
|
||||
{fire_emoji} Learn by Implementation, Not Theory
|
||||
|
||||
[bold yellow]Quick Commands:[/bold yellow]
|
||||
[dim]tito module status[/dim] - Check module progress
|
||||
[dim]tito checkpoint timeline[/dim] - Visual progress tracker
|
||||
[dim]tito module view[/dim] - Start coding in Jupyter Lab
|
||||
[dim]tito system doctor[/dim] - Diagnose any issues
|
||||
|
||||
[bold magenta]Ready to Build ML Systems? Start with:[/bold magenta]
|
||||
[dim]tito module view 01_setup[/dim] - Configure your environment
|
||||
"""
|
||||
|
||||
console.print(Panel(
|
||||
Text.from_markup(stats_table),
|
||||
title=f"{start_emoji} Getting Started",
|
||||
border_style=border_style,
|
||||
padding=(1, 2)
|
||||
))
|
||||
|
||||
def _get_theme(self, args: Namespace) -> str:
|
||||
"""Determine the theme to use based on arguments and preferences."""
|
||||
# Check command line arguments first
|
||||
if args.bright:
|
||||
return "bright"
|
||||
if args.theme:
|
||||
return args.theme
|
||||
|
||||
# Fall back to saved preferences
|
||||
prefs = UserPreferences.load_from_file()
|
||||
return prefs.logo_theme
|
||||
|
||||
def _save_theme_preference(self, theme: str) -> None:
|
||||
"""Save the theme preference to config file."""
|
||||
prefs = UserPreferences.load_from_file()
|
||||
prefs.logo_theme = theme
|
||||
prefs.save_to_file()
|
||||
return 0
|
||||
@@ -22,57 +22,96 @@ def get_console() -> Console:
|
||||
_console = Console(stderr=False)
|
||||
return _console
|
||||
|
||||
def print_banner():
|
||||
"""Print the TinyTorch banner using Rich."""
|
||||
def print_banner(compact: bool = False):
|
||||
"""Print the TinyTorch banner using Rich with clean block text style."""
|
||||
console = get_console()
|
||||
banner_text = Text("Tiny🔥Torch: Build ML Systems from Scratch", style="bold red")
|
||||
if compact:
|
||||
print_compact_banner()
|
||||
else:
|
||||
# Create banner text that matches the clean block text theme
|
||||
banner_text = Text()
|
||||
banner_text.append("tiny", style="dim cyan")
|
||||
banner_text.append("🔥", style="red")
|
||||
banner_text.append("TORCH", style="bold orange1")
|
||||
banner_text.append(": Build ML Systems from Scratch", style="dim")
|
||||
console.print(Panel(banner_text, style="bright_blue", padding=(1, 2)))
|
||||
|
||||
def print_compact_banner():
|
||||
"""Print a compact TinyTorch banner with 'tiny' above TORCH."""
|
||||
console = get_console()
|
||||
# Create compact banner text
|
||||
banner_text = Text()
|
||||
banner_text.append("tiny", style="dim cyan")
|
||||
banner_text.append("\n🔥", style="red")
|
||||
banner_text.append("TORCH", style="bold orange1")
|
||||
banner_text.append(": Build ML Systems from Scratch", style="dim")
|
||||
console.print(Panel(banner_text, style="bright_blue", padding=(1, 2)))
|
||||
|
||||
def print_ascii_logo():
|
||||
"""Print the beautiful ASCII art TinyTorch logo matching the real design."""
|
||||
def print_ascii_logo(compact: bool = False):
|
||||
"""Print the clean, minimal ASCII art TinyTorch logo."""
|
||||
console = get_console()
|
||||
|
||||
if compact:
|
||||
print_compact_ascii_logo()
|
||||
return
|
||||
|
||||
# Create styled logo text with proper Rich formatting
|
||||
logo_text = Text()
|
||||
|
||||
# ASCII Art Logo lines
|
||||
# ============================================
|
||||
# TINYTORCH LOGO - EDIT HERE!
|
||||
# ============================================
|
||||
# To edit: Change the ASCII characters in logo_lines
|
||||
# Add/remove spaces at the beginning of each line to adjust positioning
|
||||
|
||||
logo_lines = [
|
||||
" 🔥🔥 ",
|
||||
" ╱──╲ ",
|
||||
" ╱ ● ╲ ████████╗ ██████╗ ██████╗ ██████╗██╗ ██╗",
|
||||
" ╱ ╱ ╲ ╲ ╚══██╔══╝██╔═══██╗██╔══██╗██╔════╝██║ ██║",
|
||||
" │ ●───● │ ██║ ██║ ██║██████╔╝██║ ███████║",
|
||||
" │ │ ● │ │ ██║ ██║ ██║██╔══██╗██║ ██╔══██║",
|
||||
" │ ●─┬─● │ ██║ ╚██████╔╝██║ ██║╚██████╗██║ ██║",
|
||||
" ╲ ╲●╱ ╱ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝",
|
||||
" ╲───╱ ",
|
||||
" ╲─╱ "
|
||||
# Flames above each TORCH letter
|
||||
" 🔥🔥🔥🔥",
|
||||
" ████████╗ ██████╗ ██████╗ ██████╗██╗ ██╗", # TORCH line 1
|
||||
" ╚t═██╔══╝██╔═══██╗██╔══██╗██╔════╝██║ ██║", # TORCH line 2
|
||||
" i ██║ ██║ ██║██████╔╝██║ ███████║", # TORCH line 3
|
||||
" n ██║ ██║ ██║██╔══██╗██║ ██╔══██║", # TORCH line 4
|
||||
" y ██║ ╚██████╔╝██║ ██║╚██████╗██║ ██║", # TORCH line 5
|
||||
" ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝" # TORCH line 6
|
||||
]
|
||||
|
||||
# Add the first line
|
||||
logo_text.append(logo_lines[0] + "\n")
|
||||
# ============================================
|
||||
# COLOR CONFIGURATION - EDIT COLORS HERE!
|
||||
# ============================================
|
||||
# Available colors: black, red, green, yellow, blue, magenta, cyan, white
|
||||
# Prefix with 'bright_' for brighter versions (e.g., 'bright_red')
|
||||
# Add 'bold' for bold text (e.g., 'bold red' or 'bold bright_black')
|
||||
|
||||
# Add the second line with styled "tiny"
|
||||
logo_text.append(logo_lines[1])
|
||||
logo_text.append("tiny", style="dim")
|
||||
logo_text.append(" \n")
|
||||
FLAME_COLOR = "yellow" # Color for 🔥 emoji
|
||||
TINY_COLOR = "bold yellow" # Color for "tiny" text (warmer, more visible)
|
||||
TORCH_COLOR = "bold white" # Color for "TORCH" text (better contrast)
|
||||
TAGLINE_COLOR = "orange1" # Color for tagline
|
||||
|
||||
# Add the main ASCII art lines
|
||||
for line in logo_lines[2:9]:
|
||||
logo_text.append(line + "\n")
|
||||
|
||||
# Add the tagline with proper styling
|
||||
logo_text.append(logo_lines[9])
|
||||
logo_text.append("🔥 Learn ML Systems by Building Them", style="orange1")
|
||||
# Process and apply colors to each line
|
||||
for i, line in enumerate(logo_lines):
|
||||
if i == 0: # Flame line
|
||||
logo_text.append(line, style=FLAME_COLOR)
|
||||
elif i == 4: # Line with tiny + TORCH
|
||||
# Find where "tiny" ends and TORCH begins (look for ██)
|
||||
if "██║" in line:
|
||||
torch_start = line.find("██║")
|
||||
tiny_part = line[:torch_start]
|
||||
torch_part = line[torch_start:]
|
||||
logo_text.append(tiny_part, style=TINY_COLOR)
|
||||
logo_text.append(torch_part, style=TORCH_COLOR)
|
||||
else:
|
||||
logo_text.append(line, style=TORCH_COLOR)
|
||||
else: # Pure TORCH lines
|
||||
logo_text.append(line, style=TORCH_COLOR)
|
||||
logo_text.append("\n")
|
||||
|
||||
# Add tagline
|
||||
tagline = Text()
|
||||
tagline.append("\nBuild Complete Neural Networks from First Principles", style="dim cyan")
|
||||
|
||||
logo_text.append("\n🔥 Don't import the future. Build it from tensors up.", style="orange1")
|
||||
logo_text.append("\n")
|
||||
|
||||
# Combine logo and tagline
|
||||
full_content = Text()
|
||||
full_content.append(logo_text)
|
||||
full_content.append(tagline)
|
||||
|
||||
# Display centered with rich styling
|
||||
console.print()
|
||||
@@ -83,6 +122,11 @@ def print_ascii_logo():
|
||||
))
|
||||
console.print()
|
||||
|
||||
def print_compact_ascii_logo():
|
||||
"""Print the compact ASCII art TinyTorch logo - same as main logo now."""
|
||||
# Just use the main logo since it's already compact and clean
|
||||
print_ascii_logo(compact=False)
|
||||
|
||||
def print_error(message: str, title: str = "Error"):
|
||||
"""Print an error message with consistent formatting."""
|
||||
console = get_console()
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
"""
|
||||
User preferences management for TinyTorch CLI.
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional
|
||||
from dataclasses import dataclass, asdict
|
||||
|
||||
|
||||
@dataclass
|
||||
class UserPreferences:
|
||||
"""User preferences for TinyTorch CLI."""
|
||||
|
||||
# Logo preferences
|
||||
logo_theme: str = "standard" # "standard" or "bright"
|
||||
|
||||
# Future preferences can be added here
|
||||
# animation_enabled: bool = True
|
||||
# color_scheme: str = "auto"
|
||||
|
||||
@classmethod
|
||||
def load_from_file(cls, config_file: Optional[Path] = None) -> 'UserPreferences':
|
||||
"""Load preferences from config file."""
|
||||
if config_file is None:
|
||||
config_file = cls.get_default_config_path()
|
||||
|
||||
if not config_file.exists():
|
||||
# Return defaults if no config file exists
|
||||
return cls()
|
||||
|
||||
try:
|
||||
with open(config_file, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Create instance with loaded data, using defaults for missing keys
|
||||
return cls(**{
|
||||
key: data.get(key, getattr(cls(), key))
|
||||
for key in cls.__dataclass_fields__
|
||||
})
|
||||
except (json.JSONDecodeError, FileNotFoundError, KeyError):
|
||||
# Return defaults if config file is corrupted
|
||||
return cls()
|
||||
|
||||
def save_to_file(self, config_file: Optional[Path] = None) -> None:
|
||||
"""Save preferences to config file."""
|
||||
if config_file is None:
|
||||
config_file = self.get_default_config_path()
|
||||
|
||||
# Ensure config directory exists
|
||||
config_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(config_file, 'w') as f:
|
||||
json.dump(asdict(self), f, indent=2)
|
||||
|
||||
@staticmethod
|
||||
def get_default_config_path() -> Path:
|
||||
"""Get the default config file path."""
|
||||
# Look for project root first
|
||||
current = Path.cwd()
|
||||
while current != current.parent:
|
||||
if (current / 'pyproject.toml').exists():
|
||||
return current / '.tito' / 'config.json'
|
||||
current = current.parent
|
||||
|
||||
# Fallback to current directory
|
||||
return Path.cwd() / '.tito' / 'config.json'
|
||||
@@ -95,7 +95,6 @@ Convenience Commands:
|
||||
book Build and manage Jupyter Book
|
||||
grade Simplified grading interface (wraps NBGrader)
|
||||
demo Run AI capability demos (show what your framework can do!)
|
||||
logo Display the beautiful TinyTorch ASCII art logo
|
||||
|
||||
Examples:
|
||||
tito system info Show system information
|
||||
@@ -103,7 +102,6 @@ Examples:
|
||||
tito module view 01_setup Start coding in Jupyter Lab
|
||||
tito export 01_tensor Export specific module to package
|
||||
tito checkpoint timeline Visual progress timeline
|
||||
tito logo --animate Show animated ASCII logo
|
||||
tito book build Build the Jupyter Book locally
|
||||
"""
|
||||
)
|
||||
@@ -174,8 +172,8 @@ Examples:
|
||||
if hasattr(parsed_args, 'no_color') and parsed_args.no_color:
|
||||
self.config.no_color = True
|
||||
|
||||
# Show banner for interactive commands
|
||||
if parsed_args.command and not self.config.no_color:
|
||||
# Show banner for interactive commands (except logo which has its own display)
|
||||
if parsed_args.command and not self.config.no_color and parsed_args.command != 'logo':
|
||||
print_banner()
|
||||
|
||||
# Validate environment for most commands (skip for doctor)
|
||||
@@ -206,13 +204,12 @@ Examples:
|
||||
" [bold green]export[/bold green] - Export modules to package\n"
|
||||
" [bold green]test[/bold green] - Run tests\n"
|
||||
" [bold green]book[/bold green] - Build and manage Jupyter Book\n"
|
||||
" [bold green]logo[/bold green] - Display the ASCII art logo\n\n"
|
||||
" [bold green]logo[/bold green] - Learn about TinyTorch philosophy\n"
|
||||
"[bold]Quick Start:[/bold]\n"
|
||||
" [dim]tito system info[/dim] - Show system information\n"
|
||||
" [dim]tito module status --metadata[/dim] - Module status with metadata\n"
|
||||
" [dim]tito module view 01_setup[/dim] - Start coding in Jupyter Lab\n"
|
||||
" [dim]tito checkpoint timeline[/dim] - Visual progress timeline\n"
|
||||
" [dim]tito logo --animate[/dim] - Show animated logo\n\n"
|
||||
"[bold]Get Help:[/bold]\n"
|
||||
" [dim]tito system[/dim] - Show system subcommands\n"
|
||||
" [dim]tito module[/dim] - Show module subcommands\n"
|
||||
|
||||
Reference in New Issue
Block a user