π Extended OOP Example with All Concepts
<div class="infographic-pyoop">
<style>
.infographic-pyoop {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--c-abs: #c0392b; --c-abs-soft: #fbe9e7;
--c-enc: #b45309; --c-enc-soft: #fdf0dc;
--c-inh: #1f9d55; --c-inh-soft: #e3f5ec;
--c-poly: #9333ea; --c-poly-soft: #f3e8fd;
--mono-font: 'IBM Plex Mono', 'SFMono-Regular', Menlo, monospace;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', system-ui, sans-serif;
box-sizing: border-box;
max-width: 760px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-pyoop[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--c-abs: #e57373; --c-abs-soft: #3a2222;
--c-enc: #e0a458; --c-enc-soft: #3a2c14;
--c-inh: #6fdc8c; --c-inh-soft: #16342a;
--c-poly: #c58af2; --c-poly-soft: #2e2140;
}
.infographic-pyoop *, .infographic-pyoop *::before, .infographic-pyoop *::after { box-sizing: border-box; }
.infographic-pyoop .oop-wrap { padding: 0 clamp(1rem, 4vw, 2rem) 1.5rem; }
.infographic-pyoop h1 {
font-family: var(--display-font); font-weight: 600;
font-size: clamp(1.45rem, 5vw, 1.95rem); text-align: center; margin: 1.5rem 0 0.25rem; letter-spacing: -0.01em;
}
.infographic-pyoop .oop-sub { text-align: center; color: var(--ink-soft); font-size: 0.85rem; margin: 0 0 1.3rem; }
.infographic-pyoop .pillar-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 0.9rem; flex-wrap: wrap; }
.infographic-pyoop .pillar-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.74rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); color: var(--ink-soft);
padding: 0.38rem 0.6rem; cursor: pointer; border-radius: 999px;
}
.infographic-pyoop .pillar-btn.abs-b.is-selected { border-color: var(--c-abs); color: var(--c-abs); background: var(--c-abs-soft); }
.infographic-pyoop .pillar-btn.enc-b.is-selected { border-color: var(--c-enc); color: var(--c-enc); background: var(--c-enc-soft); }
.infographic-pyoop .pillar-btn.inh-b.is-selected { border-color: var(--c-inh); color: var(--c-inh); background: var(--c-inh-soft); }
.infographic-pyoop .pillar-btn.poly-b.is-selected { border-color: var(--c-poly); color: var(--c-poly); background: var(--c-poly-soft); }
.infographic-pyoop .code-block {
font-family: var(--mono-font); font-size: 0.72rem; line-height: 1.65; white-space: pre;
background: var(--paper-alt); border: 1px solid var(--line); border-radius: 8px;
padding: 0.8rem 0.9rem; margin-bottom: 0.6rem; overflow-x: auto;
}
.infographic-pyoop .code-block .kw { color: var(--accent); font-weight: 700; }
.infographic-pyoop .code-block .cm { color: var(--ink-soft); }
.infographic-pyoop .code-block .mark { border-radius: 4px; padding: 0 0.1rem; }
.infographic-pyoop .code-block .mark.abs.is-on { background: var(--c-abs-soft); box-shadow: 0 0 0 1.5px var(--c-abs); }
.infographic-pyoop .code-block .mark.enc.is-on { background: var(--c-enc-soft); box-shadow: 0 0 0 1.5px var(--c-enc); }
.infographic-pyoop .code-block .mark.inh.is-on { background: var(--c-inh-soft); box-shadow: 0 0 0 1.5px var(--c-inh); }
.infographic-pyoop .code-block .mark.poly.is-on { background: var(--c-poly-soft); box-shadow: 0 0 0 1.5px var(--c-poly); }
.infographic-pyoop .pillar-caption { text-align: center; font-size: 0.82rem; color: var(--ink-soft); margin-bottom: 1.3rem; min-height: 1.3em; }
.infographic-pyoop .pillar-caption strong { color: var(--ink); }
.infographic-pyoop .section-title {
text-align: center; font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700;
text-transform: uppercase; letter-spacing: 0.03em; color: var(--ink-soft); margin-bottom: 0.8rem;
}
.infographic-pyoop .setup-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 0.8rem; flex-wrap: wrap; }
.infographic-pyoop .cls-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.8rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); color: var(--ink-soft);
padding: 0.4rem 0.7rem; cursor: pointer; border-radius: 6px;
}
.infographic-pyoop .cls-btn.is-selected { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.infographic-pyoop .setup-row input {
font-family: var(--mono-font); font-size: 0.82rem; padding: 0.4rem 0.6rem;
border: 1.5px solid var(--line); border-radius: 5px; background: var(--paper-alt); color: var(--ink); width: 100px;
text-align: center;
}
.infographic-pyoop .setup-row input:focus { outline: none; border-color: var(--accent); }
.infographic-pyoop .create-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.82rem; font-weight: 700;
background: var(--accent); color: #fff; border: none; border-radius: 999px;
padding: 0.45rem 0.9rem; cursor: pointer;
}
.infographic-pyoop .account-card {
border: 2px solid var(--accent); background: var(--accent-soft); border-radius: 10px;
padding: 0.8rem 0.95rem; margin-bottom: 1rem;
}
.infographic-pyoop .account-title { font-family: var(--mono-font); font-size: 0.82rem; font-weight: 700; color: var(--accent); text-align: center; margin-bottom: 0.6rem; }
.infographic-pyoop .account-info { display: flex; justify-content: center; gap: 1rem; font-family: var(--mono-font); font-size: 0.8rem; margin-bottom: 0.7rem; flex-wrap: wrap; }
.infographic-pyoop .account-info b { color: var(--ink); }
.infographic-pyoop .action-row { display: flex; justify-content: center; gap: 0.4rem; flex-wrap: wrap; }
.infographic-pyoop .action-row input { width: 80px; }
.infographic-pyoop .action-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.74rem; font-weight: 700;
background: var(--paper); color: var(--accent); border: 1.5px solid var(--accent); border-radius: 6px;
padding: 0.32rem 0.55rem; cursor: pointer;
}
.infographic-pyoop .device {
--ed-bg: #1e1e1e; --ed-bar: #2d2d2d; --ed-text: #d4d4d4; --ed-soft: #8a8a8a; --ed-ok: #6fdc8c; --ed-err: #ff6b6b;
background: var(--ed-bg); border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
}
.infographic-pyoop .device-bar {
display: flex; align-items: center; gap: 0.4rem;
background: var(--ed-bar); padding: 0.5rem 0.7rem; border-bottom: 1px solid #3a3a3a;
font-size: 0.72rem; color: var(--ed-soft); font-weight: 600;
}
.infographic-pyoop .device-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #5a5a5a; }
.infographic-pyoop .device-bar .dot:nth-child(1) { background: #ff5f56; }
.infographic-pyoop .device-body { padding: 0.75rem 0.9rem; font-family: var(--mono-font); font-size: 0.78rem; color: var(--ed-text); min-height: 60px; max-height: 190px; overflow-y: auto; }
.infographic-pyoop .log-line { line-height: 1.7; opacity: 0; animation: oop-fadein 0.25s ease forwards; }
@keyframes oop-fadein { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.infographic-pyoop .log-line.err { color: var(--ed-err); font-weight: 700; }
.infographic-pyoop .log-line.out { color: #fff; font-weight: 600; }
.infographic-pyoop .log-empty { color: var(--ed-soft); }
@media (prefers-reduced-motion: reduce) {
.infographic-pyoop *, .infographic-pyoop *::before, .infographic-pyoop *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="oop-wrap">
<div class="pillar-row">
<button class="pillar-btn abs-b" data-pillar="abs">π§ Abstraction</button>
<button class="pillar-btn enc-b" data-pillar="enc">π Encapsulation</button>
<button class="pillar-btn inh-b" data-pillar="inh">𧬠Inheritance</button>
<button class="pillar-btn poly-b" data-pillar="poly">π Polymorphism</button>
</div>
<div class="code-block" id="codeBlock"><span class="kw">from</span> abc <span class="kw">import</span> ABC, abstractmethod
<span class="kw">class</span> <span class="mark abs" data-p="abs">Account(ABC)</span>:
<span class="kw">def</span> __init__(self, holder, balance=0):
self.holder = holder
self.<span class="mark enc" data-p="enc">__balance</span> = balance
<span class="kw">def</span> deposit(self, amount):
self.<span class="mark enc" data-p="enc">__balance</span> += amount
<span class="kw">def</span> withdraw(self, amount):
<span class="kw">if</span> amount <= self.<span class="mark enc" data-p="enc">__balance</span>:
self.<span class="mark enc" data-p="enc">__balance</span> -= amount
<span class="kw">else</span>:
print("Insufficient funds")
<span class="kw">def</span> get_balance(self):
<span class="kw">return</span> self.<span class="mark enc" data-p="enc">__balance</span>
<span class="mark abs" data-p="abs">@abstractmethod</span>
<span class="kw">def</span> <span class="mark abs" data-p="abs">account_type(self)</span>:
pass
<span class="kw">class</span> <span class="mark inh" data-p="inh">SavingsAccount(Account)</span>:
<span class="kw">def</span> <span class="mark poly" data-p="poly">account_type(self)</span>:
<span class="kw">return</span> "Savings Account"
<span class="kw">class</span> <span class="mark inh" data-p="inh">CurrentAccount(Account)</span>:
<span class="kw">def</span> <span class="mark poly" data-p="poly">account_type(self)</span>:
<span class="kw">return</span> "Current Account"</div>
<p class="pillar-caption" id="pillarCaption">Tap a pillar above to see exactly where it lives in the code.</p>
<div class="section-title">Try it</div>
<div class="setup-row">
<button class="cls-btn is-selected" data-cls="SavingsAccount">SavingsAccount</button>
<button class="cls-btn" data-cls="CurrentAccount">CurrentAccount</button>
<input id="holderInput" type="text" value="Ravi" placeholder="holder" />
<button class="create-btn" id="createBtn">Create</button>
</div>
<div id="accountArea"></div>
<div class="device">
<div class="device-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span> Terminal</div>
<div class="device-body" id="oopLog"><div class="log-empty">Create an account, then deposit, withdraw, and check it.</div></div>
</div>
</div>
<script>
(function () {
var root = document.currentScript.closest('.infographic-pyoop')
|| document.querySelector('.infographic-pyoop');
var bodyAttr = document.body.getAttribute('data-darkmode');
var dark;
if (bodyAttr === 'true') { dark = true; }
else if (bodyAttr === 'false') { dark = false; }
else {
var match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) root.setAttribute('data-theme', 'dark');
/* ---------------- pillar highlight ---------------- */
var pillarBtns = root.querySelectorAll('.pillar-btn');
var marks = root.querySelectorAll('.mark');
var pillarCaption = root.querySelector('#pillarCaption');
var pillarCaptions = {
abs: 'Account promises account_type() will exist, without saying how. It can\'t even be built on its own.',
enc: '__balance is name-mangled β every read or write has to go through Account\'s own methods.',
inh: 'Both subclasses get __init__, deposit, withdraw, and get_balance for free from Account.',
poly: 'Same call, account_type() β SavingsAccount and CurrentAccount each answer differently.'
};
var currentPillar = null;
pillarBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
var p = btn.dataset.pillar;
var wasOn = currentPillar === p;
pillarBtns.forEach(function (b) { b.classList.remove('is-selected'); });
marks.forEach(function (m) { m.classList.remove('is-on'); });
if (wasOn) {
currentPillar = null;
pillarCaption.textContent = 'Tap a pillar above to see exactly where it lives in the code.';
} else {
currentPillar = p;
btn.classList.add('is-selected');
root.querySelectorAll('.mark[data-p="' + p + '"]').forEach(function (m) { m.classList.add('is-on'); });
pillarCaption.innerHTML = pillarCaptions[p];
}
});
});
/* ---------------- account simulator ---------------- */
var clsBtns = root.querySelectorAll('.cls-btn');
var holderInput = root.querySelector('#holderInput');
var createBtn = root.querySelector('#createBtn');
var accountArea = root.querySelector('#accountArea');
var oopLog = root.querySelector('#oopLog');
var firstLog = true;
var currentCls = 'SavingsAccount';
var accountTypeLabel = { SavingsAccount: 'Savings Account', CurrentAccount: 'Current Account' };
clsBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
clsBtns.forEach(function (b) { b.classList.toggle('is-selected', b === btn); });
currentCls = btn.dataset.cls;
});
});
function logLine(text, cls) {
if (firstLog) { oopLog.innerHTML = ''; firstLog = false; }
var line = document.createElement('div');
line.className = 'log-line' + (cls ? ' ' + cls : '');
line.textContent = text;
oopLog.appendChild(line);
oopLog.scrollTop = oopLog.scrollHeight;
}
createBtn.addEventListener('click', function () {
var holder = (holderInput.value || '').trim() || 'Ravi';
var cls = currentCls;
var varName = cls === 'SavingsAccount' ? 's' : 'c';
var balance = 0;
logLine(varName + ' = ' + cls + '("' + holder + '")');
var card = document.createElement('div');
card.className = 'account-card';
card.innerHTML =
'<div class="account-title">' + varName + ' = ' + cls + '("' + holder + '")</div>' +
'<div class="account-info"><span>holder: <b>' + holder + '</b></span><span>balance: βΉ<b class="balVal">0</b></span></div>' +
'<div class="action-row">' +
'<input type="text" class="amtInput" value="1000" />' +
'<button class="action-btn depositBtn">deposit(amount)</button>' +
'<button class="action-btn withdrawBtn">withdraw(amount)</button>' +
'<button class="action-btn printBtn">print summary</button>' +
'</div>';
accountArea.innerHTML = '';
accountArea.appendChild(card);
var balVal = card.querySelector('.balVal');
var amtInput = card.querySelector('.amtInput');
card.querySelector('.depositBtn').addEventListener('click', function () {
var amt = parseFloat(amtInput.value) || 0;
balance += amt;
balVal.textContent = balance;
logLine(varName + '.deposit(' + amt + ')');
});
card.querySelector('.withdrawBtn').addEventListener('click', function () {
var amt = parseFloat(amtInput.value) || 0;
logLine(varName + '.withdraw(' + amt + ')');
if (amt <= balance) {
balance -= amt;
balVal.textContent = balance;
} else {
logLine('Insufficient funds', 'err');
}
});
card.querySelector('.printBtn').addEventListener('click', function () {
logLine('print(f"{' + varName + '.holder} has a {' + varName + '.account_type()} with balance: \u20b9{' + varName + '.get_balance()}")');
logLine(holder + ' has a ' + accountTypeLabel[cls] + ' with balance: \u20b9' + balance, 'out');
});
});
})();
</script>
</div>β What It Shows:
Concept | Where It Appears |
|---|---|
Encapsulation |
|
Constructor |
|
Abstraction |
|
Inheritance |
|
Polymorphism |
|
Methods |
|