Files
atm-curs-dl/gen/workshop_5_copilul_interior.py
Claude Agent b758349b54 MODUL 5: 10 reparatii pe cele doua workshop-uri, dupa verificare
Gasite de un verificator care nu scrisese documentele, aplicate de un corector
separat de amandoi.

Tiparul dominant, patru din zece: inferenta autorului pusa in coloana „rostit
de curs" a diagramei rani_masti. Cuvantul „stop" nu apare deloc in
transcrierea workshop-ului 5 (singura ocurenta e „Recording stopped"), dar
„muti stopul" statea in negru, ca si cum l-ar fi spus cursul. Mutate in
albastru, ca derivatii.

Cea mai utila: emendarea „o sa va [im]bolnaviti" era gresita. Transcrierea
spune „o sa va vindecati in timp de chestia asta", iar asta e sensul corect
- „a se vindeca DE ceva" = o sa va treaca. Workshop 1 o confirma: „o sa va
plictisiti si nu o sa mai vreti sa faceti day trading". Citatul e pus la loc
neatins.

Restul: titlu de carte inventat, „un minut" care nu e in sursa, ordinea
grupelor data ca a cursului, o enumerare de trei acolo unde sursa numara doua,
si o sageata de diagrama care cadea pe „comportament" desi eticheta spunea
„gand" (acum legata prin assert de caseta tinta).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ThN7ixZrowca8aTGrK1MUJ
2026-10-02 02:14:42 +00:00

269 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Cele trei scheme din summaries/06_MODUL_5/06_workshop_5_copilul_interior.md.
Workshop de psihologie: nu există preț, deci nu există candele. Schemele sunt
doar structuri (lanțul de decizie, maparea rană -> mască -> greșeală de
execuție, axa de vârstă a etapelor). Se generează de aici ca să existe un
singur loc unde se schimbă o etichetă și ca să treacă prin assert-urile de
lățime — nu se editează SVG-ul din .md.
Rulează: .venv/bin/python gen/workshop_5_copilul_interior.py
"""
import re
from pathlib import Path
MD = Path("/workspace/atm-curs-dl/summaries/06_MODUL_5/06_workshop_5_copilul_interior.md")
GRAY, RED, GREEN, BLUE, ORANGE = "#777", "#c00", "#188a3e", "#1a5fb4", "#b06000"
INK, MUTED, LINE, FILL = "#333", "#666", "#9bb0c7", "#f7f9fb"
CHAR_W = 5.7 # px/caracter la 12px sans-serif, calibrat ca în audit_diagrams.py
svgs = {}
def fits(txt: str, box_w: float, fs: float = 12.0) -> str:
"""Text care intră în lățimea dată la font-size-ul dat, altfel assert."""
w = len(txt) * CHAR_W * fs / 12.0
assert w <= box_w, f"text de {w:.0f}px în {box_w:.0f}px: {txt!r}"
return txt
# --------------------------------------------------------------- 1. lanțul de decizie
FILTRE = ["filtrele VAKOG — vizual, auditiv, kinestezic",
"valorile și credințele (unele limitative)",
"experiențele, cu rănile emoționale din ele"]
LANT2 = [("gând", '„iar m-a trădat piața"'),
("emoție", "furie"),
("comportament", "intri în revanșă"),
("rezultat", "a doua pierdere")]
BOX2_X = [14 + 172 * k for k in range(len(LANT2))]
BOX2_W = 152
# caseta în care intră săgeata care coboară din „reprezentare mentală"
ARROW_TARGET = 0
X_ARR = BOX2_X[ARROW_TARGET] + BOX2_W / 2
def lant_rana() -> str:
p = ['<svg viewBox="0 0 700 330" xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="14" y="22" fill="{INK}" style="font-weight:bold">Formula de'
' funcționare reluată la începutul workshopului — rana stă în a doua'
' casetă</text>']
# stimul extern
p += [f'<rect x="14" y="40" width="150" height="56" fill="{FILL}"'
f' stroke="{LINE}" stroke-width="1"/>',
f'<text x="24" y="60" fill="{INK}" style="font-weight:bold">'
f'{fits("stimul extern", 130)}</text>',
f'<text x="24" y="78" fill="{MUTED}" font-size="10">'
f'{fits("tot ce e în afara pielii", 130, 10)}</text>',
f'<text x="24" y="90" fill="{MUTED}" font-size="10">'
f'{fits("ex: piața îți ia stopul", 130, 10)}</text>']
p += [f'<line x1="166" y1="68" x2="196" y2="68" stroke="{LINE}" stroke-width="1.5"/>',
f'<path d="M 190 64 L 198 68 L 190 72 Z" fill="{LINE}"/>']
# reprezentare mentală, cu filtrele
p += [f'<rect x="200" y="40" width="330" height="96" fill="{BLUE}"'
f' fill-opacity="0.07" stroke="{BLUE}" stroke-width="1.5"/>',
f'<text x="210" y="60" fill="{BLUE}" style="font-weight:bold">'
f'{fits("reprezentare mentală — lentila prin care vezi", 310)}</text>']
for k, t in enumerate(FILTRE):
y = 78 + 18 * k
p += [f'<circle cx="216" cy="{y - 4}" r="3" fill="{BLUE}"/>',
f'<text x="226" y="{y}" fill="{INK}" font-size="11">'
f'{fits(t, 296, 11)}</text>']
p += [f'<text x="546" y="64" fill="{RED}" font-size="11">'
f'{fits("rana nu schimbă", 140, 11)}</text>',
f'<text x="546" y="80" fill="{RED}" font-size="11">'
f'{fits("evenimentul —", 140, 11)}</text>',
f'<text x="546" y="96" fill="{RED}" font-size="11">'
f'{fits("schimbă lentila", 140, 11)}</text>',
f'<line x1="534" y1="88" x2="542" y2="88" stroke="{RED}" stroke-width="1.5"/>']
# coborârea pe rândul doi
p += [f'<path d="M 210 138 L 210 152 L {X_ARR} 152 L {X_ARR} 162"'
f' fill="none" stroke="{LINE}" stroke-width="1.5"/>',
f'<path d="M {X_ARR - 4} 156 L {X_ARR} 164 L {X_ARR + 4} 156 Z" fill="{LINE}"/>']
for k, (nume, ex) in enumerate(LANT2):
x = BOX2_X[k]
p += [f'<rect x="{x}" y="170" width="{BOX2_W}" height="54" fill="{FILL}"'
f' stroke="{LINE}" stroke-width="1"/>',
f'<text x="{x + 10}" y="190" fill="{INK}" style="font-weight:bold">'
f'{fits(nume, BOX2_W - 20)}</text>',
f'<text x="{x + 10}" y="212" fill={chr(34)}{ORANGE}{chr(34)}'
f' font-size="11">{fits(ex, 132, 11)}</text>']
if k < len(LANT2) - 1:
p += [f'<line x1="{x + BOX2_W + 2}" y1="197" x2="{x + 170}" y2="197"'
f' stroke="{LINE}" stroke-width="1.5"/>',
f'<path d="M {x + 164} 193 L {x + 172} 197 L {x + 164} 201 Z"'
f' fill="{LINE}"/>']
p += [f'<rect x="14" y="240" width="672" height="74" fill="{RED}"'
f' fill-opacity="0.06" stroke="{RED}" stroke-width="1"/>',
f'<text x="24" y="260" fill="{RED}" style="font-weight:bold">'
f'{fits("De ce te interesează la execuție", 652)}</text>',
f'<text x="24" y="280" fill="{INK}" font-size="11">'
f'{fits("Doi traderi cu același stop luat, pe același grafic, scriu două reprezentări diferite — deci două", 652, 11)}</text>',
f'<text x="24" y="296" fill="{INK}" font-size="11">'
f'{fits("comportamente diferite. Regula scrisă dinainte acționează în caseta a doua, nu în ultima.", 652, 11)}</text>',
'</svg>']
return "\n ".join(p)
# ------------------------------------------------- 2. rană -> mască -> greșeală
# col. 4 = ce e rostit în transcriere (negru); col. 5 = derivația mea pe execuție
# (albastru). Oricare poate fi "" — la abandon cursul nu spune nimic pe cont.
RANI = [("respingere", "fugarul", "de obicei tatăl",
"închizi tranzacția mai devreme; fugi de reguli", ""),
("abandon", "dependentul", "de obicei mama",
"", "nu intri până nu confirmă altcineva setup-ul"),
("umilire", "masochistul", "de obicei mama",
"te autosabotezi", "suporți pierderea mai mult decât trebuie"),
("trădare", "dominatorul", "părintele de sex opus",
"nu ai încredere în nicio strategie; o serie proastă = trădare",
"de aici schimbatul strategiei după o serie proastă"),
("nedreptate", "rigidul", "părintele mai autoritar",
"vrei să ai dreptate; overtrading „ca să meriți”",
"de aici mutatul stopului ca să nu greșești")]
ROW_H = 40
def rani_masti() -> str:
h = 76 + ROW_H * len(RANI) + 58
p = [f'<svg viewBox="0 0 700 {h}" xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="14" y="22" fill="{INK}" style="font-weight:bold">Cele cinci'
' răni: masca fiecăreia și greșeala de execuție pe care o produce</text>',
f'<text x="20" y="46" fill="#44576e" font-size="10">RANA</text>',
f'<text x="118" y="46" fill="#44576e" font-size="10">MASCA</text>',
f'<text x="212" y="46" fill="#44576e" font-size="10">PĂRINTE ASOCIAT</text>',
f'<text x="344" y="46" fill="#44576e" font-size="10">CE FACE PE CONT</text>',
f'<line x1="14" y1="52" x2="686" y2="52" stroke="{LINE}" stroke-width="1"/>']
for k, (rana, masca, par, negru, albastru) in enumerate(RANI):
y = 74 + ROW_H * k
p += [f'<text x="20" y="{y}" fill="{INK}" font-size="11"'
f' style="font-weight:bold">{fits(rana, 92, 11)}</text>',
f'<text x="118" y="{y}" fill="{ORANGE}" font-size="11">'
f'{fits(masca, 88, 11)}</text>',
f'<text x="212" y="{y}" fill="{MUTED}" font-size="10">'
f'{fits(par, 126, 10)}</text>']
randuri = [(t, c) for t, c in ((negru, INK), (albastru, BLUE)) if t]
for j, (txt, col) in enumerate(randuri):
p.append(f'<text x="344" y="{y + 14 * j}" fill="{col}"'
f' font-size="11">{fits(txt, 340, 11)}</text>')
if k < len(RANI) - 1:
p.append(f'<line x1="14" y1="{y + 21}" x2="686" y2="{y + 21}"'
f' stroke="{LINE}" stroke-width="0.5" stroke-opacity="0.6"/>')
yb = 76 + ROW_H * len(RANI) + 18
p += [f'<text x="14" y="{yb}" fill="{INK}" font-size="11">'
f'{fits("În coloana a patra, rândul negru e rostit în transcriere; rândul albastru de sub el e derivația mea pe execuție.", 672, 11)}</text>',
f'<text x="14" y="{yb + 16}" fill="{MUTED}" font-size="11">'
f'{fits("La abandon cursul vorbește doar de relații și dependențe, nu de cont. Poți fi în mai multe răni, cu una dominantă.", 672, 11)}</text>',
'</svg>']
return "\n ".join(p)
# ----------------------------------------------------- 3. etapele copiilor interiori
# (start_ani, stop_ani, nume, linia 1, linia 2)
ETAPE = [(0.0, 1.5, "sinele infantil",
"nevoi de bază: hrană, somn, atingere, siguranță.",
"Fără amintiri — cursul le pune în „memoria celulară”."),
(1.5, 3.0, "sinele copilului mic",
"autonomie și testarea limitelor.",
"Mediu restrictiv aici duce în rușine, vinovăție, îndoială."),
(3.0, 6.0, "copilul interior tânăr",
"imaginație, creativitate, stimă de sine.",
"Aici se formează, spune cursul, umilirea și respingerea."),
(6.0, 12.0, "copilul interior școlar",
"identitate și valoare de sine, prin grup.",
"Critica produce aici „nu sunt suficient de bun”."),
(12.0, 15.0, "adolescentul interior",
"rebeliune, căutare de identitate, apartenență.",
"De aici vine, spune cursul, încălcarea regulilor."),
(16.0, 22.0, "tânărul adult interior",
"asumarea responsabilității, primele decizii mari.",
"De aici vine indecizia, inclusiv în trading.")]
AX0, AXW, YEARS, ROW = 20.0, 250.0, 22.0, 54
def eti(a: float, b: float) -> str:
"""Eticheta de vârstă: luni sub doi ani, altfel ani, cu virgulă zecimală."""
if b <= 1.6:
return f"{int(a * 12)}–{int(b * 12)} luni"
lo = "18 luni" if a == 1.5 else f"{a:g}".replace(".", ",")
return f"{lo}–{b:g} ani".replace(".", ",")
def _x(an: float) -> float:
return AX0 + AXW * an / YEARS
def etape_copii() -> str:
h = 74 + ROW * len(ETAPE) + 44
p = [f'<svg viewBox="0 0 700 {h}" xmlns="http://www.w3.org/2000/svg"'
' style="width:100%;height:auto;font:12px sans-serif">',
f'<text x="14" y="22" fill="{INK}" style="font-weight:bold">Nu un copil'
' interior, ci șase — barele sunt la scară pe axa de vârstă</text>']
# axa de vârstă, sus
p += [f'<line x1="{AX0}" y1="52" x2="{_x(YEARS)}" y2="52" stroke="{LINE}"'
' stroke-width="1"/>']
for an in (0, 3, 6, 12, 22):
p += [f'<line x1="{_x(an)}" y1="48" x2="{_x(an)}" y2="56"'
f' stroke="{LINE}" stroke-width="1"/>',
f'<text x="{_x(an) - 4}" y="45" fill="{MUTED}" font-size="10">{an}</text>']
p.append(f'<text x="{_x(YEARS) + 8}" y="56" fill="{MUTED}" font-size="10">ani</text>')
y_last = 74 + ROW * (len(ETAPE) - 1) + 18
p += [f'<line x1="{_x(3)}" y1="58" x2="{_x(3)}" y2="{y_last}" stroke="{RED}"'
' stroke-width="1" stroke-dasharray="4 3"/>']
for k, (a, b, nume, l1, l2) in enumerate(ETAPE):
y = 74 + ROW * k
col = RED if b <= 3 else INK
p += [f'<rect x="{_x(a)}" y="{y}" width="{_x(b) - _x(a)}" height="18"'
f' fill="{col}" fill-opacity="0.16" stroke="{col}" stroke-width="1"/>',
f'<text x="298" y="{y + 12}" fill="{col}" font-size="11"'
f' style="font-weight:bold">{fits(f"{nume} · {eti(a, b)}", 388, 11)}</text>',
f'<text x="298" y="{y + 28}" fill="{INK}" font-size="11">'
f'{fits(l1, 388, 11)}</text>',
f'<text x="298" y="{y + 43}" fill="{MUTED}" font-size="10">'
f'{fits(l2, 388, 10)}</text>']
yb = 74 + ROW * len(ETAPE) + 16
p += [f'<text x="14" y="{yb}" fill="{RED}" font-size="11">'
f'{fits("Linia punctată de la 3 ani: sub ea nu ai amintiri (neocortexul nu e dezvoltat), deci informația vine", 672, 11)}</text>',
f'<text x="14" y="{yb + 16}" fill="{RED}" font-size="11">'
f'{fits("de la părinți sau din corp, nu din memorie. Între 15 și 16 ani cursul nu numește o etapă separată.", 672, 11)}</text>',
'</svg>']
return "\n ".join(p)
svgs["lant_rana"] = lant_rana()
svgs["rani_masti"] = rani_masti()
svgs["etape_copii"] = etape_copii()
# ---------------------------------------------------------------------- assert-uri
# 1. nicio bară nu iese din axă și barele sunt în ordine crescătoare de vârstă
assert all(0 <= a < b <= YEARS for a, b, *_ in ETAPE), "interval de vârstă invalid"
assert [a for a, *_ in ETAPE] == sorted(a for a, *_ in ETAPE), "etape neordonate"
# 2. eticheta „sub 3 ani nu ai amintiri" trebuie să acopere exact primele două etape
sub3 = [e for e in ETAPE if e[1] <= 3.0]
assert len(sub3) == 2, f"linia de 3 ani nu mai taie 2 etape, ci {len(sub3)}"
# 3. textul spune „șase" copii interiori
assert len(ETAPE) == 6, "titlul spune șase etape"
# 4. textul spune „cinci răni", fiecare cu exact o mască
assert len(RANI) == 5 and len({r[1] for r in RANI}) == 5, "5 răni, 5 măști distincte"
# 5. fiecare rană spune ceva pe cont, din curs sau de la mine; „muți stopul" nu
# poate sta în negru (cuvântul „stop" nu apare în transcrierea workshopului)
assert all(r[3] or r[4] for r in RANI), "o rană fără nimic pe coloana de cont"
assert not any("stop" in r[3] for r in RANI), "«stop» nu e rostit în transcriere"
# 5b. săgeata care coboară din reprezentarea mentală cade pe caseta „gând"
_i = [n for n, _ in LANT2].index("gând")
assert _i == ARROW_TARGET and BOX2_X[_i] < X_ARR < BOX2_X[_i] + BOX2_W, \
f"săgeata la x={X_ARR} nu cade pe caseta „gând” ({BOX2_X[_i]}…{BOX2_X[_i] + BOX2_W})"
# 6. niciun SVG nu are linie goală (python-markdown ar rupe blocul)
for name, svg in svgs.items():
assert "\n\n" not in svg, f"linie goală în {name}"
assert svg.count("<svg") == 1 and svg.rstrip().endswith("</svg>"), name
if MD.exists():
md = MD.read_text(encoding="utf-8")
for name, svg in svgs.items():
pat = re.compile(rf"<!--SVG:{name}-->.*?<!--/SVG-->", re.S)
assert pat.search(md), f"marcatorul {name} lipsește din .md"
md = pat.sub(lambda _m: f"<!--SVG:{name}-->\n{svg}\n<!--/SVG-->", md)
MD.write_text(md, encoding="utf-8")
print("scris", MD)
else:
print("nu există încă", MD)