# 164. Custom String Interpolation

**Snippet 1: Custom Formatting for a Class**

```python
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __format__(self, format_spec):
        if format_spec == 'short':
            return f"{self.name[0]}. ({self.age})"
        return f"{self.name}, Age: {self.age}"

# Create a Person instance
person = Person("Alice", 30)

# Custom format: short version
print(f"{person:short}")

# Default format
print(f"{person}")
```

***

**Snippet 2: Custom Currency Formatting**

```python
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __format__(self, format_spec):
        if format_spec == 'currency':
            return f"${self.price:,.2f}"
        return f"{self.name}: {self.price}"

# Create a Product instance
product = Product("Laptop", 1500.50)

# Custom format: currency
print(f"{product:currency}")

# Default format
print(f"{product}")
```

***

**Snippet 3: Custom Date Formatting**

```python
import datetime

class Event:
    def __init__(self, title, date):
        self.title = title
        self.date = date

    def __format__(self, format_spec):
        if format_spec == 'long':
            return f"{self.title} on {self.date.strftime('%A, %B %d, %Y')}"
        return f"{self.title} at {self.date.strftime('%b %d, %Y')}"

# Create an Event instance
event = Event("Conference", datetime.date(2025, 6, 15))

# Custom format: long date
print(f"{event:long}")

# Default format
print(f"{event}")
```

***

**Snippet 4: Custom Percentage Formatting**

```python
class Score:
    def __init__(self, value):
        self.value = value

    def __format__(self, format_spec):
        if format_spec == 'percent':
            return f"{self.value * 100:.1f}%"
        return f"Score: {self.value}"

# Create a Score instance
score = Score(0.875)

# Custom format: percentage
print(f"{score:percent}")

# Default format
print(f"{score}")
```

***

**Snippet 5: Custom String Formatting for a Rectangle Class**

```python
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def __format__(self, format_spec):
        if format_spec == 'area':
            return f"Area: {self.width * self.height} square units"
        return f"Rectangle ({self.width} x {self.height})"

# Create a Rectangle instance
rectangle = Rectangle(10, 20)

# Custom format: area
print(f"{rectangle:area}")

# Default format
print(f"{rectangle}")
```

***

**Snippet 6: Custom Time Duration Formatting**

```python
class Duration:
    def __init__(self, hours, minutes):
        self.hours = hours
        self.minutes = minutes

    def __format__(self, format_spec):
        if format_spec == 'short':
            return f"{self.hours}h {self.minutes}m"
        return f"{self.hours} hours and {self.minutes} minutes"

# Create a Duration instance
duration = Duration(3, 45)

# Custom format: short
print(f"{duration:short}")

# Default format
print(f"{duration}")
```

***

**Snippet 7: Custom IP Address Formatting**

```python
class IPAddress:
    def __init__(self, ip):
        self.ip = ip

    def __format__(self, format_spec):
        if format_spec == 'dotted':
            return f"{self.ip}"
        return f"IP Address: {self.ip}"

# Create an IPAddress instance
ip = IPAddress("192.168.0.1")

# Custom format: dotted
print(f"{ip:dotted}")

# Default format
print(f"{ip}")
```

***

**Snippet 8: Custom Formatting for a Student Class**

```python
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

    def __format__(self, format_spec):
        if format_spec == 'grade':
            return f"{self.name} received a grade of {self.grade}"
        return f"Student: {self.name}"

# Create a Student instance
student = Student("John", "A")

# Custom format: grade
print(f"{student:grade}")

# Default format
print(f"{student}")
```

***

**Snippet 9: Custom List Formatting**

```python
class ItemList:
    def __init__(self, items):
        self.items = items

    def __format__(self, format_spec):
        if format_spec == 'count':
            return f"{len(self.items)} items"
        return f"Items: {', '.join(self.items)}"

# Create an ItemList instance
item_list = ItemList(["apple", "banana", "cherry"])

# Custom format: count
print(f"{item_list:count}")

# Default format
print(f"{item_list}")
```

***

**Snippet 10: Custom Hexadecimal Formatting**

```python
class HexNumber:
    def __init__(self, number):
        self.number = number

    def __format__(self, format_spec):
        if format_spec == 'hex':
            return hex(self.number)
        return f"Number: {self.number}"

# Create a HexNumber instance
hex_number = HexNumber(255)

# Custom format: hexadecimal
print(f"{hex_number:hex}")

# Default format
print(f"{hex_number}")
```

***
