"""
================================================================================
File: 03_virtual_envs.py
Topic: Virtual Environments in Python
================================================================================

This file explains virtual environments in Python. Virtual environments are
isolated Python environments that allow you to manage dependencies separately
for each project, avoiding conflicts between different projects.

Key Concepts:
- What are virtual environments
- Creating and activating venvs
- Managing dependencies with pip
- requirements.txt
- Best practices

Note: This is a reference/tutorial file - the commands are shown as examples.

================================================================================
"""

# =============================================================================
# 1. WHAT ARE VIRTUAL ENVIRONMENTS?
# =============================================================================

print("=== What Are Virtual Environments? ===")

print("""
A virtual environment is an ISOLATED Python environment that:

  ✓ Has its own Python interpreter
  ✓ Has its own site-packages directory
  ✓ Doesn't affect global Python installation
  ✓ Allows different projects to have different dependencies

Why use virtual environments?
  - Project A needs Django 3.2
  - Project B needs Django 4.1
  - Without venvs, you'd have conflicts!

With virtual environments, each project has its own Django version.
""")

# =============================================================================
# 2. CREATING A VIRTUAL ENVIRONMENT
# =============================================================================

print("\n=== Creating a Virtual Environment ===")

print("""
Using the built-in 'venv' module (Python 3.3+):

  # Navigate to your project directory
  cd my_project

  # Create a virtual environment named 'venv'
  python -m venv venv

  # Or name it something else
  python -m venv .venv        # Hidden folder (common convention)
  python -m venv env          # Another common name
  python -m venv my_env       # Custom name

This creates a folder with:
  venv/
    ├── Include/       # C header files
    ├── Lib/           # Python packages
    │   └── site-packages/
    ├── Scripts/       # Activation scripts (Windows)
    │   ├── activate
    │   ├── activate.bat
    │   └── python.exe
    └── pyvenv.cfg     # Configuration file
""")

# =============================================================================
# 3. ACTIVATING AND DEACTIVATING
# =============================================================================

print("\n=== Activating and Deactivating ===")

print("""
ACTIVATION (must do before using the venv):

  Windows (Command Prompt):
    venv\\Scripts\\activate.bat

  Windows (PowerShell):
    venv\\Scripts\\Activate.ps1
    
    If you get execution policy error:
    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

  macOS/Linux:
    source venv/bin/activate

When activated, your prompt changes:
  (venv) C:\\my_project>
  (venv) user@computer:~/my_project$

DEACTIVATION:
  deactivate

After deactivation, prompt returns to normal.
""")

# =============================================================================
# 4. INSTALLING PACKAGES
# =============================================================================

print("\n=== Installing Packages ===")

print("""
After activating your venv, use pip to install packages:

  # Install a package
  pip install requests

  # Install specific version
  pip install requests==2.28.0

  # Install minimum version
  pip install 'requests>=2.25.0'

  # Install multiple packages
  pip install requests numpy pandas

  # Install from requirements.txt
  pip install -r requirements.txt

  # Upgrade a package
  pip install --upgrade requests

  # Uninstall a package
  pip uninstall requests

  # List installed packages
  pip list

  # Show package info
  pip show requests
""")

# =============================================================================
# 5. REQUIREMENTS FILE
# =============================================================================

print("\n=== Requirements File ===")

print("""
The requirements.txt file lists all project dependencies:

CREATING requirements.txt:
  # Generate from current environment
  pip freeze > requirements.txt

EXAMPLE requirements.txt:
  # requirements.txt
  requests==2.28.1
  numpy>=1.21.0
  pandas~=1.5.0
  python-dotenv

VERSION SPECIFIERS:
  package==1.0.0    # Exact version
  package>=1.0.0    # Minimum version
  package<=1.0.0    # Maximum version
  package~=1.0.0    # Compatible version (>=1.0.0, <2.0.0)
  package!=1.0.0    # Exclude version
  package>=1.0,<2.0 # Version range

INSTALLING FROM requirements.txt:
  pip install -r requirements.txt

BEST PRACTICE: Create different files for different environments:
  requirements.txt          # Production dependencies
  requirements-dev.txt      # Development dependencies
  requirements-test.txt     # Testing dependencies
""")

# =============================================================================
# 6. VIRTUAL ENVIRONMENT ALTERNATIVES
# =============================================================================

print("\n=== Alternative Tools ===")

print("""
1. venv (built-in)
   - Simple, included with Python
   - Good for basic needs
   
   python -m venv venv

2. virtualenv
   - More features than venv
   - Faster environment creation
   
   pip install virtualenv
   virtualenv venv

3. pipenv
   - Combines venv + pip
   - Uses Pipfile instead of requirements.txt
   - Automatic locking of dependencies
   
   pip install pipenv
   pipenv install requests
   pipenv shell

4. poetry
   - Modern dependency management
   - Better dependency resolution
   - Build and publish packages
   
   pip install poetry
   poetry new my_project
   poetry add requests

5. conda
   - Package manager + environment manager
   - Great for data science (NumPy, SciPy pre-compiled)
   
   conda create -n myenv python=3.10
   conda activate myenv
   conda install numpy
""")

# =============================================================================
# 7. PROJECT STRUCTURE WITH VENV
# =============================================================================

print("\n=== Project Structure ===")

print("""
Recommended project structure:

my_project/
├── venv/               # Virtual environment (don't commit!)
├── src/
│   └── my_package/
│       ├── __init__.py
│       └── main.py
├── tests/
│   ├── __init__.py
│   └── test_main.py
├── .gitignore          # Include 'venv/' here!
├── requirements.txt
├── requirements-dev.txt
├── setup.py or pyproject.toml
└── README.md

.gitignore should include:
  venv/
  .venv/
  env/
  __pycache__/
  *.pyc
  .pytest_cache/
""")

# =============================================================================
# 8. COMMON COMMANDS REFERENCE
# =============================================================================

print("\n=== Quick Reference ===")

print("""
╔══════════════════════════════════════════════════════════════════╗
║                    VIRTUAL ENVIRONMENT COMMANDS                   ║
╠══════════════════════════════════════════════════════════════════╣
║ CREATE                                                            ║
║   python -m venv venv                                            ║
║                                                                   ║
║ ACTIVATE                                                          ║
║   Windows:  venv\\Scripts\\activate                                ║
║   Mac/Linux: source venv/bin/activate                            ║
║                                                                   ║
║ DEACTIVATE                                                        ║
║   deactivate                                                      ║
║                                                                   ║
║ INSTALL PACKAGES                                                  ║
║   pip install package_name                                       ║
║   pip install -r requirements.txt                                ║
║                                                                   ║
║ EXPORT DEPENDENCIES                                               ║
║   pip freeze > requirements.txt                                  ║
║                                                                   ║
║ CHECK PYTHON LOCATION                                             ║
║   Windows: where python                                          ║
║   Mac/Linux: which python                                        ║
║                                                                   ║
║ DELETE VENV (just remove the folder)                             ║
║   Windows: rmdir /s /q venv                                      ║
║   Mac/Linux: rm -rf venv                                         ║
╚══════════════════════════════════════════════════════════════════╝
""")

# =============================================================================
# 9. BEST PRACTICES
# =============================================================================

print("\n=== Best Practices ===")

print("""
1. ALWAYS use virtual environments
   - Even for small projects
   - Prevents "works on my machine" problems

2. Don't commit venv to version control
   - Add 'venv/' to .gitignore
   - Share requirements.txt instead

3. Use meaningful venv names
   - venv, .venv, or env are common
   - Use .venv to hide the folder

4. Pin your versions in production
   - Use pip freeze > requirements.txt
   - Review and clean up before committing

5. Separate dev and production dependencies
   - requirements.txt for production
   - requirements-dev.txt for testing, linting, etc.

6. Document how to set up the environment
   - Include setup instructions in README.md

7. Use pip-tools for better dependency management
   - pip install pip-tools
   - Create requirements.in with direct dependencies
   - pip-compile requirements.in creates pinned file
""")

# =============================================================================
# 10. TROUBLESHOOTING
# =============================================================================

print("\n=== Troubleshooting ===")

print("""
COMMON ISSUES AND SOLUTIONS:

1. "python not recognized" after activation
   Solution: Use full path or reinstall Python with PATH option

2. PowerShell "execution policy" error
   Solution: 
   Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

3. "pip install" uses global pip
   Solution: Make sure venv is activated first
   Check: python -c "import sys; print(sys.prefix)"

4. Can't delete venv folder (files in use)
   Solution: 
   - Deactivate first
   - Close any terminals/IDEs using it
   - Restart computer if needed

5. requirements.txt has too many packages
   Solution: Use pipreqs to generate minimal requirements
   pip install pipreqs
   pipreqs /path/to/project

6. Package conflicts
   Solution: Create fresh venv and install carefully
   Or use pip-compile for dependency resolution
""")

# =============================================================================
# 11. IDE INTEGRATION
# =============================================================================

print("\n=== IDE Integration ===")

print("""
VS CODE:
  1. Open project folder
  2. Select Python Interpreter (Ctrl+Shift+P)
  3. Choose "Python: Select Interpreter"
  4. Select the venv Python (./venv/Scripts/python.exe)
  5. New terminals auto-activate venv

PYCHARM:
  1. File > Settings > Project > Python Interpreter
  2. Click gear icon > Add
  3. Select "Existing environment" or create new
  4. Point to venv/Scripts/python.exe

JUPYTER NOTEBOOK:
  1. Activate venv
  2. Install: pip install ipykernel
  3. Register: python -m ipykernel install --user --name=myenv
  4. Select kernel in Jupyter
""")

# =============================================================================
# 12. EXAMPLE WORKFLOW
# =============================================================================

print("\n=== Example Workflow ===")

print("""
STARTING A NEW PROJECT:

  # 1. Create project folder
  mkdir my_awesome_project
  cd my_awesome_project

  # 2. Create virtual environment
  python -m venv venv

  # 3. Activate it
  venv\\Scripts\\activate      # Windows
  source venv/bin/activate   # Mac/Linux

  # 4. Upgrade pip (good practice)
  python -m pip install --upgrade pip

  # 5. Install packages
  pip install requests numpy pandas

  # 6. Create requirements.txt
  pip freeze > requirements.txt

  # 7. Create .gitignore
  echo "venv/" > .gitignore
  echo "__pycache__/" >> .gitignore

  # 8. Start coding!
  code .

JOINING AN EXISTING PROJECT:

  # 1. Clone the repository
  git clone https://github.com/user/project.git
  cd project

  # 2. Create virtual environment
  python -m venv venv

  # 3. Activate it
  venv\\Scripts\\activate      # Windows

  # 4. Install dependencies
  pip install -r requirements.txt

  # 5. Start working!
""")

print("\n" + "=" * 60)
print("Virtual environments are essential for Python development!")
print("Always use them to keep your projects isolated and reproducible.")
print("=" * 60)
