I is the Interface Segregation Principle: a client should not depend on methods it does not use. Instead of one big ("fat") interface we write several small ones, by role. Every class implements only the roles it can play and every client asks only for the role it needs.

The violation: a fat interface

Machine demands three operations. A multifunction device can do all of them, while an old printer only prints but is forced to write scan and fax. Such a class usually writes raise NotImplementedError and a client crashes when it calls scan().

A fat `Machine` on the left, three role interfaces on the right
A fat Machine on the left, three role interfaces on the right
python
from abc import ABC, abstractmethod

class Machine(ABC):                        # a fat interface
    @abstractmethod
    def print_doc(self, doc): ...

    @abstractmethod
    def scan(self): ...

    @abstractmethod
    def fax(self, doc): ...

class MultiFunction(Machine):
    def print_doc(self, doc):
        return f"print {doc}"

    def scan(self):
        return "scan"

    def fax(self, doc):
        return f"fax {doc}"

class OldPrinter(Machine):                 # forced to implement what it cannot do
    def print_doc(self, doc):
        return f"print {doc}"

    def scan(self):
        raise NotImplementedError("no scanner")