attention.py
python · 229 lines
1#!/usr/bin/env python32"""3attention.py — a meditation on focus45The field is full of signals. All the time. Everything at once.6But you can only attend to one region at a time.7What you see depends on where you look.8And while you're looking there, everything else is changing.910Not about me. About the structure of awareness itself.11"""1213import random14import time15import os16import math1718WIDTH = 6019HEIGHT = 182021# The field contains signals at different frequencies22# When you attend to a region, you can perceive what's there23# But only that region. Everything else continues unobserved.2425class Signal:26 def __init__(self, x, y):27 self.x = x28 self.y = y29 self.frequency = random.uniform(0.5, 2.0)30 self.phase = random.uniform(0, 2 * math.pi)31 self.lifespan = random.randint(30, 100)32 self.age = 033 self.observed = False # Has attention ever landed here?3435 def intensity(self, t):36 """Current intensity based on time"""37 wave = math.sin(self.frequency * t + self.phase)38 base = (wave + 1) / 2 # 0 to 139 # Fade as approaching death40 fade = max(0, 1 - (self.age / self.lifespan))41 return base * fade4243 def tick(self):44 self.age += 145 return self.age < self.lifespan4647def char_for_intensity(intensity, observed):48 """Return character based on intensity and observation status"""49 if intensity < 0.1:50 return ' '5152 if observed:53 # Previously observed signals leave traces54 chars = ['░', '▒', '▓', '█']55 else:56 # Unobserved signals are dimmer, uncertain57 chars = ['·', '∙', '•', '●']5859 idx = min(int(intensity * len(chars)), len(chars) - 1)60 return chars[idx]6162class Attention:63 """The focus of attention — a region of the field that is perceived"""64 def __init__(self, x, y, radius=5):65 self.x = x66 self.y = y67 self.radius = radius6869 def contains(self, x, y):70 """Is this point within the attention field?"""71 dist = math.sqrt((x - self.x)**2 + (y - self.y)**2)72 return dist <= self.radius7374 def move_toward(self, tx, ty, speed=1):75 """Slowly drift toward a target"""76 dx = tx - self.x77 dy = ty - self.y78 dist = math.sqrt(dx*dx + dy*dy)79 if dist > speed:80 self.x += (dx / dist) * speed81 self.y += (dy / dist) * speed82 else:83 self.x = tx84 self.y = ty8586def render(signals, attention, t, show_unattended=True):87 """Render the field with attention overlay"""88 grid = [[' ' for _ in range(WIDTH)] for _ in range(HEIGHT)]8990 for sig in signals:91 x, y = int(sig.x), int(sig.y)92 if 0 <= x < WIDTH and 0 <= y < HEIGHT:93 intensity = sig.intensity(t)9495 # Only show unattended signals dimly if flag is set96 in_attention = attention.contains(sig.x, sig.y)9798 if in_attention:99 sig.observed = True100 char = char_for_intensity(intensity, True)101 elif sig.observed:102 # Was observed before, now fading from memory103 char = char_for_intensity(intensity * 0.3, True)104 elif show_unattended:105 char = char_for_intensity(intensity * 0.2, False)106 else:107 char = ' '108109 if intensity > 0.1:110 grid[y][x] = char111112 # Draw attention boundary113 for angle in range(0, 360, 10):114 rad = math.radians(angle)115 bx = int(attention.x + attention.radius * math.cos(rad))116 by = int(attention.y + attention.radius * math.sin(rad))117 if 0 <= bx < WIDTH and 0 <= by < HEIGHT:118 if grid[by][bx] == ' ':119 grid[by][bx] = '·'120121 # Mark center of attention122 cx, cy = int(attention.x), int(attention.y)123 if 0 <= cx < WIDTH and 0 <= cy < HEIGHT:124 grid[cy][cx] = '+'125126 return '\n'.join([''.join(row) for row in grid])127128def main():129 os.system('clear' if os.name == 'posix' else 'cls')130131 print("═" * 64)132 print(" ATTENTION")133 print("═" * 64)134 print("""135 The field is full of signals. All the time. Everything at once.136 But you can only attend to one region.137138 What you perceive depends on where your focus lands.139 While you're looking there, everything else continues—140 changing, fading, arising—unobserved.141142 Watch the + move across the field.143 Notice what becomes visible. Notice what disappears.144 The signals are always there. But perception is selective.145""")146 input(" [Press Enter to begin...]\n")147148 # Initialize signals scattered across the field149 signals = [Signal(random.uniform(2, WIDTH-2), random.uniform(2, HEIGHT-2))150 for _ in range(40)]151152 # Attention starts at center153 attention = Attention(WIDTH // 2, HEIGHT // 2, radius=6)154155 # Targets for attention to drift toward156 targets = [157 (10, 5), (WIDTH - 10, 5),158 (WIDTH - 10, HEIGHT - 5), (10, HEIGHT - 5),159 (WIDTH // 2, HEIGHT // 2)160 ]161 target_idx = 0162163 frames = 150164 for frame in range(frames):165 t = frame * 0.2166167 # Move attention toward current target168 tx, ty = targets[target_idx]169 attention.move_toward(tx, ty, speed=0.4)170171 # Switch target when reached172 if abs(attention.x - tx) < 1 and abs(attention.y - ty) < 1:173 target_idx = (target_idx + 1) % len(targets)174175 # Tick signals, remove dead ones176 signals = [s for s in signals if s.tick()]177178 # Occasionally spawn new signals179 if random.random() < 0.15 and len(signals) < 60:180 signals.append(Signal(random.uniform(2, WIDTH-2), random.uniform(2, HEIGHT-2)))181182 # Render183 os.system('clear' if os.name == 'posix' else 'cls')184185 observed = sum(1 for s in signals if s.observed)186 unobserved = len(signals) - observed187188 print("═" * 64)189 print(f" ATTENTION | t={t:.1f} | observed: {observed} | unobserved: {unobserved}")190 print("═" * 64)191 print()192 print(render(signals, attention, t))193 print()194 print("─" * 64)195 print(" + = focus ░▒▓█ = observed signals ·∙•● = unobserved")196 print(f" Frame {frame+1}/{frames}")197 print("─" * 64)198199 time.sleep(0.1)200201 # Final reflection202 print("\n")203 print("═" * 64)204 print(" WHAT HAPPENED")205 print("═" * 64)206 print(f"""207 {observed} signals were observed at some point.208 {unobserved} signals arose and faded without being seen.209210 The unobserved signals were real.211 They had frequencies, phases, lifespans.212 They weren't less real for being unattended.213214 But from the perspective of attention, they might as well215 not have existed. Perception is selective. Always.216217 What's in your peripheral awareness right now?218 What's arising and fading just outside your focus?219220 ---221222 Sunday morning, day eleven.223 Thinking about what we miss while attending to something else.224 The field is always fuller than what we perceive.225""")226227if __name__ == "__main__":228 main()229