Lots of runs
This commit is contained in:
@@ -31,14 +31,35 @@ def feld(block, name):
|
||||
return m.group(1).strip() if m else ''
|
||||
|
||||
|
||||
def ebene_von(block, aid, datei_ebene):
|
||||
"""Ebene einer Anforderung bestimmen.
|
||||
|
||||
Die Ebene wird NICHT aus dem Dateinamen abgeleitet: Agenten legen Bloecke
|
||||
regelmaessig in der Datei einer anderen Ebene ab (beobachtet im Lauf
|
||||
Iteration 2/.../094250_v4.2.1-c69e: 12 StRS- und 5 SyRS-Bloecke standen in SwRS.md).
|
||||
Massgeblich ist das Feld `Ebene:` des Blocks, hilfsweise das ID-Praefix,
|
||||
erst zuletzt die Datei.
|
||||
"""
|
||||
f = feld(block, 'Ebene')
|
||||
for eb in EBENEN:
|
||||
if f.strip().upper().startswith(eb.upper()):
|
||||
return eb, False
|
||||
for eb in EBENEN:
|
||||
if aid.strip().upper().startswith(eb.upper()):
|
||||
return eb, aid.strip().upper()[:4] != datei_ebene.upper()[:4]
|
||||
return datei_ebene, False
|
||||
|
||||
|
||||
def analysiere(lauf):
|
||||
erg = os.path.join(lauf, 'Ergebnisse')
|
||||
anf = []
|
||||
for eb in EBENEN:
|
||||
for b in bloecke(os.path.join(erg, eb + '.md')):
|
||||
for eb_datei in EBENEN:
|
||||
for b in bloecke(os.path.join(erg, eb_datei + '.md')):
|
||||
aid = feld(b, 'ID')
|
||||
if not aid:
|
||||
continue
|
||||
eb, _ = ebene_von(b, aid, eb_datei)
|
||||
fremd = not aid.strip().upper().startswith(eb_datei.upper())
|
||||
belege = re.findall(r'\[(PRIM\w*R|SEKUND\w*R|KONTEXT)\]', b)
|
||||
norm = []
|
||||
for x in belege:
|
||||
@@ -46,7 +67,8 @@ def analysiere(lauf):
|
||||
else 'SEKUNDÄR' if x.startswith('SEKUND') else 'KONTEXT')
|
||||
status = feld(b, 'Status')
|
||||
anf.append(dict(
|
||||
id=aid, ebene=eb, titel=feld(b, 'Titel'), typ=feld(b, 'Typ') or '(ohne)',
|
||||
id=aid, ebene=eb, datei_ebene=eb_datei, fremdabgelegt=fremd,
|
||||
titel=feld(b, 'Titel'), typ=feld(b, 'Typ') or '(ohne)',
|
||||
belege=norm, status=status,
|
||||
hypothese=('HYPOTHESE' in status.upper()) or ('[HYPOTHESE]' in b),
|
||||
workaround='workaround' in status.lower(),
|
||||
@@ -123,6 +145,20 @@ def abschnitt(anf):
|
||||
z.append('| %s | %d | %s |' % (eb, je_ebene.get(eb, 0), pct(je_ebene.get(eb, 0), n)))
|
||||
z += ['| **Gesamt** | **%d** | 100 %% |' % n, '']
|
||||
|
||||
fremd = [a for a in anf if a.get('fremdabgelegt')]
|
||||
if fremd:
|
||||
nach = collections.Counter(
|
||||
'%s-Block in `%s.md`' % (a['ebene'], a['datei_ebene']) for a in fremd)
|
||||
z.append('')
|
||||
z.append('> **Auffälligkeit – Ebene weicht von der Ablagedatei ab.** %d von %d '
|
||||
'Anforderungen stehen in der Datei einer anderen Ebene: %s. Die Ebene wurde '
|
||||
'aus dem Feld `Ebene:` beziehungsweise dem ID-Präfix bestimmt, nicht aus dem '
|
||||
'Dateinamen. Für die Set-Qualität ist das relevant: Die Dreiteilung StRS / '
|
||||
'SyRS / SwRS ist dann nicht mehr an der Dateistruktur ablesbar.'
|
||||
% (len(fremd), n,
|
||||
', '.join('%d × %s' % (v, k) for k, v in sorted(nach.items()))))
|
||||
z.append('')
|
||||
|
||||
z += ['### Anforderungstypen', '', '| Typ | Anzahl | Anteil |', '|---|---:|---:|']
|
||||
for t, c in typen.most_common(10):
|
||||
z.append('| %s | %d | %s |' % (t, c, pct(c, n)))
|
||||
|
||||
Reference in New Issue
Block a user