A set is an unordered collection of unique elements — duplicates are automatically removed.
unique_numbers = {1, 2, 3, 3, 2}
print(unique_numbers) # Output: {1, 2, 3}🔍 Why Use Sets?
To remove duplicates from data.
To perform mathematical set operations like union, intersection, difference.
Sets are faster for membership checks (
in).
📌 Common Set Operations
set1 = {1, 2, 3}
set2 = {3, 4, 5}
print(set1.union(set2)) # {1, 2, 3, 4, 5}
print(set1.intersection(set2)) # {3}
print(set1.difference(set2)) # {1, 2}
print(set2.difference(set1)) # {4, 5}🚫 No Indexing in Sets
s = {10, 20, 30}
# print(s[0]) ❌ Error: 'set' object is not subscriptableUse loops if you want to access items:
for num in s:
print(num)🔄 Adding & Removing Items
s = {1, 2}
s.add(3) # Add single item
s.remove(2) # Remove item (raises error if not found)
s.discard(5) # Remove safely (no error if not found)💡 Real-life Analogy
A set is like a guest list for a party —
even if someone tries to enter twice, they’re only counted once.
<div class="infographic-pyset">
<style>
.infographic-pyset {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
--error: #c0392b;
--error-soft: #fbe9e7;
--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: 820px;
margin: 0 auto;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-pyset[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
--error: #e57373;
--error-soft: #3a2222;
}
.infographic-pyset *, .infographic-pyset *::before, .infographic-pyset *::after { box-sizing: border-box; }
.infographic-pyset .ps-wrap { padding: 0 clamp(1rem, 4vw, 2rem) 1.5rem; }
.infographic-pyset h1 {
font-family: var(--display-font); font-weight: 600;
font-size: clamp(1.55rem, 5vw, 2.1rem); text-align: center; margin: 1.5rem 0 0.25rem; letter-spacing: -0.01em;
}
.infographic-pyset .ps-sub { text-align: center; color: var(--ink-soft); font-size: 0.88rem; margin: 0 0 1.4rem; }
.infographic-pyset .ps-tabs { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.infographic-pyset .ps-tab-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.8rem; font-weight: 700;
background: none; border: none; border-bottom: 2.5px solid transparent; color: var(--ink-soft);
padding: 0.55rem 0.8rem; cursor: pointer; margin-bottom: -1px;
}
.infographic-pyset .ps-tab-btn.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.infographic-pyset .ps-panel.is-hidden-tab { display: none; }
/* cloud (unordered) box visualization */
.infographic-pyset .cloud-row { display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.6rem; min-height: 50px; align-items: center; }
.infographic-pyset .chip {
padding: 0.4rem 0.7rem; font-family: var(--mono-font); font-size: 0.82rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); border-radius: 999px; color: var(--ink);
transition: background 0.2s, border-color 0.2s, transform 0.15s; animation: ps-pop-in 0.25s ease;
}
@keyframes ps-pop-in { from { opacity: 0; transform: scale(0.7); } to { opacity: 1; transform: scale(1); } }
.infographic-pyset .chip.is-highlight { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); transform: translateY(-2px); }
.infographic-pyset .chip.is-shake, .infographic-pyset .mini-chip.is-shake { animation: ps-shake 0.4s; border-color: var(--error); background: var(--error-soft); }
@keyframes ps-shake {
0%, 100% { transform: translateX(0); } 20% { transform: translateX(-4px); } 40% { transform: translateX(4px); }
60% { transform: translateX(-3px); } 80% { transform: translateX(3px); }
}
.infographic-pyset .len-badge {
display: block; text-align: center; font-family: var(--mono-font); font-size: 0.75rem; color: var(--accent);
font-weight: 700; margin-bottom: 1.1rem;
}
.infographic-pyset .ps-note { text-align: center; font-size: 0.78rem; color: var(--ink-soft); margin: -0.5rem 0 1.1rem; }
/* method cards */
.infographic-pyset .method-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; margin-bottom: 1.1rem; }
@media (max-width: 560px) { .infographic-pyset .method-grid { grid-template-columns: 1fr; } }
.infographic-pyset .method-card { background: var(--paper-alt); border: 1px solid var(--line); border-radius: 6px; padding: 0.6rem 0.7rem; }
.infographic-pyset .method-name { font-family: var(--mono-font); font-size: 0.8rem; font-weight: 700; color: var(--ink); margin-bottom: 0.4rem; }
.infographic-pyset .method-row { display: flex; gap: 0.35rem; align-items: center; flex-wrap: wrap; }
.infographic-pyset .method-row input {
font-family: var(--mono-font); font-size: 0.78rem; padding: 0.28rem 0.4rem;
border: 1px solid var(--line); border-radius: 4px; background: var(--paper); color: var(--ink); width: 84px;
}
.infographic-pyset .method-row input:focus { outline: none; border-color: var(--accent); }
.infographic-pyset .run-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700;
background: var(--accent); color: #fff; border: none; border-radius: 4px;
padding: 0.3rem 0.6rem; cursor: pointer;
}
.infographic-pyset .run-btn.danger { background: var(--error); }
.infographic-pyset .reset-row { display: flex; justify-content: center; margin-bottom: 1rem; }
.infographic-pyset .reset-btn {
font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--ink-soft);
background: none; border: 1px solid var(--line); padding: 0.35rem 0.7rem; cursor: pointer; border-radius: 4px;
}
/* terminal log — always dark */
.infographic-pyset .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-pyset .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-pyset .device-bar .dot { width: 9px; height: 9px; border-radius: 50%; background: #5a5a5a; }
.infographic-pyset .device-bar .dot:nth-child(1) { background: #ff5f56; }
.infographic-pyset .device-body {
padding: 0.8rem 0.9rem; font-family: var(--mono-font); font-size: 0.78rem; color: var(--ed-text);
min-height: 50px; max-height: 170px; overflow-y: auto;
}
.infographic-pyset .log-line { display: flex; gap: 0.5rem; line-height: 1.6; opacity: 0; animation: ps-fadein 0.25s ease forwards; flex-wrap: wrap; }
@keyframes ps-fadein { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: translateY(0); } }
.infographic-pyset .log-line .p { color: var(--ed-ok); font-weight: 700; }
.infographic-pyset .log-line .arrow { color: var(--ed-soft); }
.infographic-pyset .log-line .res { color: #fff; }
.infographic-pyset .log-line.err .res { color: var(--ed-err); }
.infographic-pyset .log-empty { color: var(--ed-soft); }
/* set operations (venn board) */
.infographic-pyset .venn-inputs { display: flex; justify-content: center; gap: 0.8rem; flex-wrap: wrap; margin-bottom: 1rem; }
.infographic-pyset .venn-input-slot { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.infographic-pyset .venn-input-slot span { font-family: var(--mono-font); font-size: 0.72rem; color: var(--ink-soft); font-weight: 700; }
.infographic-pyset .venn-input {
font-family: var(--mono-font); font-size: 0.82rem; text-align: center;
padding: 0.4rem 0.6rem; border: 1.5px solid var(--line); background: var(--paper-alt); color: var(--ink);
border-radius: 5px; width: 230px;
}
.infographic-pyset .venn-input:focus { outline: none; border-color: var(--accent); }
.infographic-pyset .op-row { display: flex; justify-content: center; gap: 0.4rem; margin-bottom: 1.2rem; flex-wrap: wrap; }
.infographic-pyset .op-btn {
font: inherit; font-family: var(--mono-font); font-size: 0.82rem; font-weight: 700;
background: var(--paper-alt); border: 1.5px solid var(--line); color: var(--ink-soft);
padding: 0.5rem 0.8rem; cursor: pointer; border-radius: 5px;
}
.infographic-pyset .op-btn.is-selected { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.infographic-pyset .op-banner {
text-align: center; font-family: var(--display-font); font-size: 1.15rem; font-weight: 600; color: var(--accent);
margin-bottom: 0.8rem;
}
.infographic-pyset .venn-board { display: flex; align-items: stretch; justify-content: center; gap: 0.35rem; margin-bottom: 1rem; }
.infographic-pyset .venn-region {
flex: 1; min-width: 0; background: var(--paper-alt); border: 1.5px solid var(--line);
padding: 0.7rem 0.5rem; display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
transition: background 0.25s, border-color 0.25s; min-height: 100px;
}
.infographic-pyset .venn-region:first-child { border-radius: 16px 4px 4px 16px; }
.infographic-pyset .venn-region:last-child { border-radius: 4px 16px 16px 4px; }
.infographic-pyset .venn-region-label { font-family: var(--mono-font); font-size: 0.68rem; color: var(--ink-soft); font-weight: 700; text-align: center; }
.infographic-pyset .venn-region.is-active { background: var(--accent-soft); border-color: var(--accent); }
.infographic-pyset .venn-region.is-active .venn-region-label { color: var(--accent); }
.infographic-pyset .venn-chip {
font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700; padding: 0.2rem 0.5rem;
border-radius: 999px; background: var(--paper); border: 1px solid var(--line); color: var(--ink);
}
.infographic-pyset .venn-region.is-active .venn-chip { border-color: var(--accent); color: var(--accent); background: var(--paper); }
.infographic-pyset .venn-result {
text-align: center; font-family: var(--mono-font); font-size: 0.95rem; font-weight: 700; color: var(--accent);
margin-bottom: 0.3rem;
}
/* unordered comparison */
.infographic-pyset .compare-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1.1rem; }
@media (max-width: 560px) { .infographic-pyset .compare-grid { grid-template-columns: 1fr; } }
.infographic-pyset .compare-card { background: var(--paper-alt); border: 1px solid var(--line); border-radius: 8px; padding: 0.9rem; text-align: center; }
.infographic-pyset .compare-title { font-family: var(--mono-font); font-size: 0.78rem; font-weight: 700; color: var(--ink); margin-bottom: 0.6rem; }
.infographic-pyset .list-box-row { display: flex; justify-content: center; gap: 0.4rem; flex-wrap: wrap; margin-bottom: 0.4rem; }
.infographic-pyset .list-box-col { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; }
.infographic-pyset .list-idx { font-family: var(--mono-font); font-size: 0.62rem; color: var(--ink-soft); }
.infographic-pyset .mini-box {
padding: 0.35rem 0.55rem; font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700;
background: var(--paper); border: 1.5px solid var(--line); border-radius: 5px; color: var(--ink);
}
.infographic-pyset .mini-chip {
padding: 0.35rem 0.6rem; font-family: var(--mono-font); font-size: 0.75rem; font-weight: 700;
background: var(--paper); border: 1.5px solid var(--line); border-radius: 999px; color: var(--ink);
}
@media (prefers-reduced-motion: reduce) {
.infographic-pyset *, .infographic-pyset *::before, .infographic-pyset *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ps-wrap">
<h1>Python Sets</h1>
<p class="ps-sub">No duplicates. No order. Built for comparing groups.</p>
<div class="ps-tabs">
<button class="ps-tab-btn is-active" data-tab="methods">Uniqueness & Methods</button>
<button class="ps-tab-btn" data-tab="ops">Set Operations</button>
<button class="ps-tab-btn" data-tab="unordered">Unordered</button>
</div>
<!-- METHODS TAB -->
<div class="ps-panel" id="tabMethods">
<div class="cloud-row" id="methodsCloud"></div>
<span class="len-badge" id="methodsLenBadge">len(fruits) = 3</span>
<p class="ps-note">fruits = {"apple", "banana", "cherry"} — try adding "apple" again below.</p>
<div class="method-grid">
<div class="method-card">
<div class="method-name">.add(x)</div>
<div class="method-row">
<input id="addInput" type="text" value="apple" />
<button class="run-btn" data-method="add">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.remove(x)</div>
<div class="method-row">
<input id="removeInput" type="text" value="banana" />
<button class="run-btn danger" data-method="remove">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.discard(x)</div>
<div class="method-row">
<input id="discardInput" type="text" value="mango" />
<button class="run-btn" data-method="discard">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">x in fruits</div>
<div class="method-row">
<input id="inInput" type="text" value="cherry" />
<button class="run-btn" data-method="in">Run</button>
</div>
</div>
<div class="method-card">
<div class="method-name">.pop()</div>
<div class="method-row"><button class="run-btn" data-method="pop">Run</button></div>
</div>
<div class="method-card">
<div class="method-name">len(fruits)</div>
<div class="method-row"><button class="run-btn" data-method="len">Run</button></div>
</div>
</div>
<div class="reset-row"><button class="reset-btn" id="methodsReset">↺ Reset set</button></div>
<div class="device">
<div class="device-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span> History</div>
<div class="device-body" id="methodsLog"><div class="log-empty">Run a method to see it here…</div></div>
</div>
</div>
<!-- SET OPERATIONS TAB -->
<div class="ps-panel is-hidden-tab" id="tabOps">
<div class="venn-inputs">
<div class="venn-input-slot">
<span>A</span>
<input class="venn-input" id="setAInput" type="text" value="apple, banana, cherry" />
</div>
<div class="venn-input-slot">
<span>B</span>
<input class="venn-input" id="setBInput" type="text" value="banana, cherry, mango" />
</div>
</div>
<div class="op-row">
<button class="op-btn is-selected" data-op="union">A | B</button>
<button class="op-btn" data-op="inter">A & B</button>
<button class="op-btn" data-op="diff">A - B</button>
<button class="op-btn" data-op="symdiff">A ^ B</button>
</div>
<div class="op-banner" id="opBanner">Union — A | B</div>
<div class="venn-board">
<div class="venn-region" id="regionAOnly">
<div class="venn-region-label">A only</div>
<div class="cloud-row" id="chipsAOnly"></div>
</div>
<div class="venn-region" id="regionBoth">
<div class="venn-region-label">both</div>
<div class="cloud-row" id="chipsBoth"></div>
</div>
<div class="venn-region" id="regionBOnly">
<div class="venn-region-label">B only</div>
<div class="cloud-row" id="chipsBOnly"></div>
</div>
</div>
<div class="venn-result" id="vennResult">A | B = {...}</div>
<p class="ps-note" id="vennCaption">Union combines everything from both sets, no duplicates.</p>
</div>
<!-- UNORDERED TAB -->
<div class="ps-panel is-hidden-tab" id="tabUnordered">
<div class="compare-grid">
<div class="compare-card">
<div class="compare-title">list — ordered, indexed</div>
<div class="list-box-row" id="compareListRow"></div>
</div>
<div class="compare-card">
<div class="compare-title">set — no order, no index</div>
<div class="cloud-row" id="compareSetRow"></div>
</div>
</div>
<div class="reset-row">
<button class="run-btn danger" id="tryIndexBtn">Try: colors_set[0]</button>
</div>
<div class="device">
<div class="device-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span> Result</div>
<div class="device-body" id="indexLog"><div class="log-empty">Tap the button above…</div></div>
</div>
<p class="ps-note">Iterating with <span style="font-family:var(--mono-font)">for x in colors_set</span> still works fine — there's just no guaranteed position.</p>
</div>
</div>
<script>
(function () {
var root = document.currentScript.closest('.infographic-pyset')
|| document.querySelector('.infographic-pyset');
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');
/* ---------------- tabs ---------------- */
var tabBtns = root.querySelectorAll('.ps-tab-btn');
var panels = {
methods: root.querySelector('#tabMethods'),
ops: root.querySelector('#tabOps'),
unordered: root.querySelector('#tabUnordered')
};
tabBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
tabBtns.forEach(function (b) { b.classList.toggle('is-active', b === btn); });
var target = btn.dataset.tab;
Object.keys(panels).forEach(function (key) {
panels[key].classList.toggle('is-hidden-tab', key !== target);
});
});
});
function pySetRepr(arr) {
if (arr.length === 0) return 'set()';
return '{' + arr.map(function (v) { return '"' + v + '"'; }).join(', ') + '}';
}
function logLine(logEl, code, result, isErr) {
var line = document.createElement('div');
line.className = 'log-line' + (isErr ? ' err' : '');
line.innerHTML = '<span class="p">>>></span><span>' + code + '</span>' +
(result !== undefined ? '<span class="arrow">→</span><span class="res">' + result + '</span>' : '');
logEl.appendChild(line);
logEl.scrollTop = logEl.scrollHeight;
}
/* ---------------- METHODS TAB ---------------- */
var INITIAL_SET = ['apple', 'banana', 'cherry'];
var fruits = INITIAL_SET.slice();
var methodsCloud = root.querySelector('#methodsCloud');
var methodsLenBadge = root.querySelector('#methodsLenBadge');
var methodsLog = root.querySelector('#methodsLog');
var methodsFirstLog = true;
function renderMethods() {
methodsCloud.innerHTML = '';
fruits.forEach(function (v) {
var chip = document.createElement('span');
chip.className = 'chip';
chip.textContent = v;
chip.dataset.val = v;
methodsCloud.appendChild(chip);
});
methodsLenBadge.textContent = 'len(fruits) = ' + fruits.length;
}
function flashChip(val) {
var chip = methodsCloud.querySelector('[data-val="' + CSS.escape(val) + '"]');
if (chip) {
chip.classList.remove('is-highlight');
void chip.offsetWidth;
chip.classList.add('is-highlight');
setTimeout(function () { chip.classList.remove('is-highlight'); }, 500);
}
}
root.querySelectorAll('#tabMethods .run-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
var method = btn.dataset.method;
if (methodsFirstLog) { methodsLog.innerHTML = ''; methodsFirstLog = false; }
if (method === 'add') {
var v = root.querySelector('#addInput').value.trim();
if (!v) return;
if (fruits.indexOf(v) !== -1) {
logLine(methodsLog, 'fruits.add("' + v + '")', 'already in the set — no change (no duplicates!)');
flashChip(v);
} else {
fruits.push(v);
logLine(methodsLog, 'fruits.add("' + v + '")', pySetRepr(fruits));
renderMethods();
}
} else if (method === 'remove') {
var v2 = root.querySelector('#removeInput').value.trim();
var pos = fruits.indexOf(v2);
if (pos === -1) {
logLine(methodsLog, 'fruits.remove("' + v2 + '")', "KeyError: '" + v2 + "'", true);
} else {
fruits.splice(pos, 1);
logLine(methodsLog, 'fruits.remove("' + v2 + '")', pySetRepr(fruits));
renderMethods();
}
} else if (method === 'discard') {
var v3 = root.querySelector('#discardInput').value.trim();
var pos2 = fruits.indexOf(v3);
if (pos2 === -1) {
logLine(methodsLog, 'fruits.discard("' + v3 + '")', 'not present — discard does nothing, no error');
} else {
fruits.splice(pos2, 1);
logLine(methodsLog, 'fruits.discard("' + v3 + '")', pySetRepr(fruits));
renderMethods();
}
} else if (method === 'in') {
var v4 = root.querySelector('#inInput').value.trim();
var found = fruits.indexOf(v4) !== -1;
logLine(methodsLog, '"' + v4 + '" in fruits', found ? 'True' : 'False');
if (found) flashChip(v4);
} else if (method === 'pop') {
if (fruits.length === 0) {
logLine(methodsLog, 'fruits.pop()', "KeyError: 'pop from an empty set'", true);
} else {
var popped = fruits.shift();
logLine(methodsLog, 'fruits.pop()', "'" + popped + "' (set now " + pySetRepr(fruits) + ')');
renderMethods();
}
} else if (method === 'len') {
logLine(methodsLog, 'len(fruits)', fruits.length);
}
});
});
root.querySelector('#methodsReset').addEventListener('click', function () {
fruits = INITIAL_SET.slice();
methodsFirstLog = true;
methodsLog.innerHTML = '<div class="log-empty">Run a method to see it here…</div>';
renderMethods();
});
/* ---------------- SET OPERATIONS TAB ---------------- */
var setAInput = root.querySelector('#setAInput');
var setBInput = root.querySelector('#setBInput');
var opBtns = root.querySelectorAll('.op-btn');
var chipsAOnly = root.querySelector('#chipsAOnly');
var chipsBoth = root.querySelector('#chipsBoth');
var chipsBOnly = root.querySelector('#chipsBOnly');
var regionAOnly = root.querySelector('#regionAOnly');
var regionBoth = root.querySelector('#regionBoth');
var regionBOnly = root.querySelector('#regionBOnly');
var vennResult = root.querySelector('#vennResult');
var opBanner = root.querySelector('#opBanner');
var vennCaption = root.querySelector('#vennCaption');
var currentOp = 'union';
var opCaptions = {
union: 'Union combines everything from both sets, no duplicates.',
inter: 'Intersection keeps only what appears in both sets.',
diff: 'Difference keeps what\'s in A, removing anything also in B.',
symdiff: 'Symmetric difference keeps what\'s in exactly one set, not both.'
};
var opNames = { union: 'Union', inter: 'Intersection', diff: 'Difference', symdiff: 'Symmetric Difference' };
var opSymbols = { union: '|', inter: '&', diff: '-', symdiff: '^' };
function parseSet(raw) {
var seen = [];
raw.split(',').forEach(function (s) {
var t = s.trim();
if (t && seen.indexOf(t) === -1) seen.push(t);
});
return seen;
}
function fillChips(container, arr) {
container.innerHTML = '';
arr.forEach(function (v) {
var chip = document.createElement('span');
chip.className = 'venn-chip';
chip.textContent = v;
container.appendChild(chip);
});
}
function renderVenn() {
var A = parseSet(setAInput.value);
var B = parseSet(setBInput.value);
var aOnly = A.filter(function (x) { return B.indexOf(x) === -1; });
var both = A.filter(function (x) { return B.indexOf(x) !== -1; });
var bOnly = B.filter(function (x) { return A.indexOf(x) === -1; });
fillChips(chipsAOnly, aOnly);
fillChips(chipsBoth, both);
fillChips(chipsBOnly, bOnly);
regionAOnly.classList.remove('is-active');
regionBoth.classList.remove('is-active');
regionBOnly.classList.remove('is-active');
var result;
if (currentOp === 'union') {
regionAOnly.classList.add('is-active'); regionBoth.classList.add('is-active'); regionBOnly.classList.add('is-active');
result = aOnly.concat(both).concat(bOnly);
} else if (currentOp === 'inter') {
regionBoth.classList.add('is-active');
result = both;
} else if (currentOp === 'diff') {
regionAOnly.classList.add('is-active');
result = aOnly;
} else {
regionAOnly.classList.add('is-active'); regionBOnly.classList.add('is-active');
result = aOnly.concat(bOnly);
}
vennResult.textContent = 'A ' + opSymbols[currentOp] + ' B = ' + pySetRepr(result);
vennCaption.textContent = opCaptions[currentOp];
opBanner.textContent = opNames[currentOp] + ' — A ' + opSymbols[currentOp] + ' B';
}
opBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
opBtns.forEach(function (b) { b.classList.toggle('is-selected', b === btn); });
currentOp = btn.dataset.op;
renderVenn();
});
});
setAInput.addEventListener('input', renderVenn);
setBInput.addEventListener('input', renderVenn);
/* ---------------- UNORDERED TAB ---------------- */
var compareItems = ['red', 'green', 'blue'];
var compareListRow = root.querySelector('#compareListRow');
var compareSetRow = root.querySelector('#compareSetRow');
var tryIndexBtn = root.querySelector('#tryIndexBtn');
var indexLog = root.querySelector('#indexLog');
var indexFirstLog = true;
function renderCompare() {
compareListRow.innerHTML = '';
compareItems.forEach(function (v, i) {
var col = document.createElement('div');
col.className = 'list-box-col';
var idxLbl = document.createElement('span');
idxLbl.className = 'list-idx';
idxLbl.textContent = i;
var box = document.createElement('div');
box.className = 'mini-box';
box.textContent = v;
col.appendChild(idxLbl);
col.appendChild(box);
compareListRow.appendChild(col);
});
compareSetRow.innerHTML = '';
compareItems.forEach(function (v) {
var chip = document.createElement('span');
chip.className = 'mini-chip';
chip.textContent = v;
compareSetRow.appendChild(chip);
});
}
tryIndexBtn.addEventListener('click', function () {
if (indexFirstLog) { indexLog.innerHTML = ''; indexFirstLog = false; }
logLine(indexLog, 'colors_set[0]', "TypeError: 'set' object is not subscriptable", true);
var firstChip = compareSetRow.querySelector('.mini-chip');
if (firstChip) {
firstChip.classList.remove('is-shake');
void firstChip.offsetWidth;
firstChip.classList.add('is-shake');
setTimeout(function () { firstChip.classList.remove('is-shake'); }, 450);
}
});
renderMethods();
renderVenn();
renderCompare();
})();
</script>
</div>