Module:Sandbox/Vergir: Difference between revisionsGive feedback
Audit script v2: normalize underscores, check target existence, group by change (with help from vergir-bot LLM) |
Audit script v3: formatted label values + classification column (with help from vergir-bot LLM) |
||
| Line 2: | Line 2: | ||
-- with attribute styling enabled (Passive/Active Main stats), compute the | -- with attribute styling enabled (Passive/Active Main stats), compute the | ||
-- label link target under the CURRENT priority (attr link > StatLinks) | -- label link target under the CURRENT priority (attr link > StatLinks) | ||
-- and the PROPOSED priority (StatLinks > attr link) and | -- and the PROPOSED priority (StatLinks > attr link), and classify the change. | ||
local p = {} | local p = {} | ||
local lang = require "Module:Lang" | local lang = require "Module:Lang" | ||
| Line 11: | Line 11: | ||
local LABEL_KEY_REMAP = { DotDuration = "DOTDuration" } | local LABEL_KEY_REMAP = { DotDuration = "DOTDuration" } | ||
local IGNORED = { BuildUpPerShot = true } | local IGNORED = { BuildUpPerShot = true } | ||
-- Keys whose StatLinks entry is worse than the current type link. | |||
-- Proposed StatLinks fix noted alongside. | |||
local STATLINKS_FIX = { | |||
SlowPercent = "Movement Slow", | |||
MaxSlowPercent = "Movement Slow", | |||
} | |||
local DEBATABLE = { | |||
GroundDashReductionPercent = true, | |||
} | |||
local function get_pair(base, s1, s2) | local function get_pair(base, s1, s2) | ||
| Line 30: | Line 40: | ||
end | end | ||
local | -- Resolve a title through one redirect hop; returns final page name | ||
local function | local resolve_cache = {} | ||
if t == nil then return | local function resolve(t) | ||
if | if t == nil then return nil end | ||
if resolve_cache[t] == nil then | |||
local title = mw.title.new(t) | local title = mw.title.new(t) | ||
if | local r = t | ||
if title and title.exists and title.isRedirect then | |||
local tgt = title.redirectTarget | |||
local | if tgt then r = tgt.prefixedText end | ||
elseif not title or not title.exists then | |||
r = t .. " (MISSING)" | |||
end | end | ||
resolve_cache[t] = r | |||
end | end | ||
return | return resolve_cache[t] | ||
end | |||
local function fmt_value(label_key, value, label) | |||
local n = tonumber(tostring(value):match("^-?%d+%.?%d*")) | |||
if not n then return label end | |||
local prefix = get_pair(label_key, "_prefix", "_Prefix") | |||
local postfix = get_pair(label_key, "_postfix", "_Postfix") | |||
if prefix == "{s:sign}" then prefix = n >= 0 and "+" or "" end | |||
local s = tostring(n) | |||
if prefix ~= "" then s = prefix .. s end | |||
if postfix ~= "" then s = s .. (postfix == "HP/s" and " " or "") .. postfix end | |||
return s .. " " .. label | |||
end | end | ||
function p.audit(frame) | function p.audit(frame) | ||
local names = {} | local names = {} | ||
for key, item in pairs(data) do | for key, item in pairs(data) do | ||
| Line 58: | Line 79: | ||
end) | end) | ||
local n_items, n_stats, n_same | local rows = {} | ||
local counts = {} | |||
local n_items, n_stats, n_same = 0, 0, 0 | |||
for _, key in ipairs(names) do | for _, key in ipairs(names) do | ||
local item = data[key] | local item = data[key] | ||
| Line 81: | Line 103: | ||
local cur = attr_link or sl | local cur = attr_link or sl | ||
local new = sl or attr_link | local new = sl or attr_link | ||
if (cur or "") == (new or "") then | |||
n_same = n_same + 1 | |||
else | else | ||
local kind | |||
if STATLINKS_FIX[label_key] then | |||
kind = "Regression → fixed via StatLinks (" .. label_key .. " = " .. STATLINKS_FIX[label_key] .. ")" | |||
elseif DEBATABLE[label_key] then | |||
kind = "Debatable" | |||
elseif resolve(cur) == resolve(new) then | |||
kind = "NOP (redirect to same page)" | |||
else | |||
kind = "Fix" | |||
end | |||
counts[kind] = (counts[kind] or 0) + 1 | |||
table.insert(rows, string.format( | table.insert(rows, string.format( | ||
"|- | "|-\n| [[%s]] || %s || [[%s]] || [[%s]] || %s", | ||
item.Name or key, fmt_value(label_key, obj.Value, label), | |||
item.Name or key, | cur or "", new or "", kind)) | ||
end | end | ||
end | end | ||
| Line 108: | Line 132: | ||
local out = {} | local out = {} | ||
table.insert(out, string.format( | table.insert(out, string.format( | ||
"Items scanned: %d. Passive/Active main stats with a label: %d. Unchanged: %d. | "Items scanned: %d. Passive/Active main stats with a label: %d. Unchanged: %d. Changed: %d.\n", | ||
n_items, n_stats, n_same, | n_items, n_stats, n_same, #rows)) | ||
local ks = {} | |||
for k in pairs(counts) do table.insert(ks, k) end | |||
table.sort(ks) | |||
local | for _, k in ipairs(ks) do table.insert(out, string.format("* %s: %d", k, counts[k])) end | ||
for k in pairs( | table.insert(out, '{| class="wikitable sortable"\n! Item !! Label !! Current target !! Proposed target !! Type') | ||
table.sort( | |||
for _, k in ipairs( | |||
table.insert(out, '{| class="wikitable sortable"\n! Item | |||
for _, r in ipairs(rows) do table.insert(out, r) end | for _, r in ipairs(rows) do table.insert(out, r) end | ||
table.insert(out, "|}") | table.insert(out, "|}") | ||