AINS-M6001 — Notebook 1: First Marketing World
Course: Personal Attention & Influence Systems (Mag.AI-Marketing)
Theme: Minimal executable model: attention, credibility, clarity → signal reach.
PTAH-style layers: entities, rules, discrete ticks. Plain Python (dataclasses, numpy, matplotlib); no external PTAH runtime required.
Setup¶
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Callable, List, Protocol
import matplotlib.pyplot as plt
import numpy as np
plt.style.use("dark_background")
plt.rcParams["figure.figsize"] = (10, 5)
plt.rcParams["axes.grid"] = True
plt.rcParams["grid.alpha"] = 0.25
Marketer entity¶
Fields are intentionally small; extend in later notebooks (blocks, message vectors, shocks).
@dataclass
class Marketer:
attention_hours_day: float = 4.0
credibility: float = 0.5 # 0..1
message_clarity: float = 0.6 # 0..1 how tight the niche/message is
name: str = "you"
marketer = Marketer()
marketer
PTAH-like API: World, Rule, Simulation¶
Same pattern as AIN-B6001 Business notebooks: rules update state each tick.
class Entity(Protocol):
name: str
@dataclass
class Rule:
name: str
apply: Callable[[dict[str, Any]], None]
@dataclass
class World:
name: str
entities: dict[str, Any]
rules: List[Rule] = field(default_factory=list)
def register_rule(self, rule: Rule) -> None:
self.rules.append(rule)
@dataclass
class Simulation:
world: World
state: dict[str, Any]
day: int = 0
def step(self) -> None:
self.day += 1
self.state["day"] = self.day
for rule in self.world.rules:
rule.apply(self.state)
def run(self, n_days: int) -> None:
for _ in range(n_days):
self.step()
Reach rule (toy)¶
signal_reach increases with attention, credibility, clarity; diminishing returns via square-root.
[ \text{reach}_t = 100 \cdot \sqrt{a_t \cdot c_t \cdot m_t} ]
DAYS = 30
def reach(attention: float, credibility: float, clarity: float) -> float:
x = max(attention, 0.0) * max(min(credibility, 1.0), 0.0) * max(min(clarity, 1.0), 0.0)
return 100.0 * np.sqrt(x)
history: list[list[float]] = []
def daily_update(st: dict[str, Any]) -> None:
a = float(st["attention_hours_day"])
cr = float(st["credibility"])
cl = float(st["message_clarity"])
r = reach(a, cr, cl)
st["daily_reach"] = r
st["cumulative_reach"] = float(st.get("cumulative_reach", 0.0)) + r
history.append([int(st["day"]), r, float(st["cumulative_reach"])])
w = World(
name="personal_marketing_world",
entities={"marketer": marketer},
rules=[Rule(name="daily_reach", apply=daily_update)],
)
st0: dict[str, Any] = {
"day": 0,
"attention_hours_day": marketer.attention_hours_day,
"credibility": marketer.credibility,
"message_clarity": marketer.message_clarity,
"cumulative_reach": 0.0,
}
sim = Simulation(world=w, state=st0, day=0)
sim.run(DAYS)
hist = np.array(history)
hist[:5], hist[-3:]
fig, ax = plt.subplots()
ax.plot(hist[:, 0], hist[:, 1], label="daily reach")
ax.set_xlabel("day")
ax.set_ylabel("reach (arb.)")
ax.legend()
plt.show()