跳转到内容
打开/关闭菜单
  • 451 条目
  • 802 文件
  • 22 用户
  • 9003 编辑
Blockland Wiki
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

模块:OPDI:修订间差异

来自Blockland Wiki
创建页面,内容为“local p = {} local function num(v) if v == nil then return nil end v = mw.text.trim(tostring(v)) if v == '' then return nil end return tonumber(v) end local function clamp(x, lo, hi) if x < lo then return lo end if x > hi then return hi end return x end local function index_linear(value, minv, maxv) return clamp((value - minv) / (maxv - minv), 0, 1) end local function income_index(gdp_pc) return clamp((math.log(gdp_pc) - math.log(100)) / (math.log(…”
 
无编辑摘要
 
第1行: 第1行:
local p = {}
local p = {}


-- 字符串转数字,并清理可能存在的空格或前后缀
local function num(v)
local function num(v)
if v == nil then return nil end
if v == nil then return nil end
v = mw.text.trim(tostring(v))
v = mw.text.trim(tostring(v))
-- 过滤掉可能附带的单位或逗号(如 "1145 元" 或 "5,700,000")
v = string.gsub(v, '[%s,,%%元岁]', '')
if v == '' then return nil end
if v == '' then return nil end
return tonumber(v)
return tonumber(v)
第18行: 第21行:
end
end


-- 收入指数优化:调低历史背景下的绝对下限,避免低收入国家指数雪崩
local function income_index(gdp_pc)
local function income_index(gdp_pc)
return clamp((math.log(gdp_pc) - math.log(100)) / (math.log(75000) - math.log(100)), 0, 1)
local min_gdp = 50  -- 设定历史发展中绝对贫困的底线
local max_gdp = 75000
if gdp_pc <= min_gdp then return 0 end
return clamp((math.log(gdp_pc) - math.log(min_gdp)) / (math.log(max_gdp) - math.log(min_gdp)), 0, 1)
end
end


-- 第三产业指数优化:将下限放宽到 0%,避免工业/农业大国一票否决
local function tertiary_index(share)
local function tertiary_index(share)
return index_linear(share, 20, 80)
return index_linear(share, 0, 80)
end
end


local function demographic_factor(birth, death)
local function demographic_factor(birth, death)
-- 死亡率和自然增长率只作为轻惩罚项,避免“出生率越低越先进”的单向误判。
-- 死亡率和自然增长率轻度惩罚项,避免单向误判
local death_penalty = clamp((death - 12) / 28, 0, 0.12)
local death_penalty = clamp((death - 12) / 28, 0, 0.12)
local growth = birth - death
local growth = birth - death
第34行: 第42行:
end
end


local function calc(args)
local function calc(frame)
local male = num(args.male or args['男性预期寿命'])
-- 同时获取当前 invoke 的参数和外层父模板的参数
local female = num(args.female or args['女性预期寿命'])
local args = frame.args
local literacy = num(args.literacy or args['识字率'])
local parentArgs = frame:getParent().args
local gdp_pc = num(args.gdp_pc or args['人均GDP'])
local tertiary = num(args.tertiary or args['第三产业占比'])
local function getArg(key)
local birth = num(args.birth or args['出生率'])
return args[key] or parentArgs[key]
local death = num(args.death or args['死亡率'])
end


local male = num(getArg('male') or getArg('男性预期寿命'))
local female = num(getArg('female') or getArg('女性预期寿命'))
local literacy = num(getArg('literacy') or getArg('识字率'))
local gdp_pc = num(getArg('gdp_pc') or getArg('人均GDP'))
local tertiary = num(getArg('tertiary') or getArg('第三产业占比'))
local birth = num(getArg('birth') or getArg('出生率'))
local death = num(getArg('death') or getArg('死亡率'))
-- 核心数据缺一不可校验
if not (male and female and literacy and gdp_pc and tertiary and birth and death) then
if not (male and female and literacy and gdp_pc and tertiary and birth and death) then
return nil
return nil
第57行: 第74行:
local demo = demographic_factor(birth, death)
local demo = demographic_factor(birth, death)


-- 加权几何平均:健康、教育、收入为主体;产业结构为轻权重;人口项为修正系数。
-- 几何平均保护:给各项指数一个极小的底线(0.01),防止单项落后导致总分直接归零
health = math.max(health, 0.01)
education = math.max(education, 0.01)
income = math.max(income, 0.01)
structure = math.max(structure, 0.01)
 
-- 加权几何平均计算
local score = (health ^ 0.35) * (education ^ 0.25) * (income ^ 0.30) * (structure ^ 0.10) * demo
local score = (health ^ 0.35) * (education ^ 0.25) * (income ^ 0.30) * (structure ^ 0.10) * demo
return clamp(score, 0, 1)
return clamp(score, 0, 1)
第81行: 第104行:


function p.score(frame)
function p.score(frame)
local score = calc(frame.args)
local score = calc(frame)
if not score then return '' end
if not score then return '' end
return string.format('%.3f', score)
return string.format('%.3f', score)
第87行: 第110行:


function p.grade(frame)
function p.grade(frame)
local score = calc(frame.args)
local score = calc(frame)
if not score then return '' end
if not score then return '' end
return grade(score)
return grade(score)
第93行: 第116行:


function p.display(frame)
function p.display(frame)
local score = calc(frame.args)
local score = calc(frame)
if not score then return '{{Stay}} 无数据' end
if not score then return '{{Stay}} 无数据' end
return string.format('%.3f(%s)', score, grade(score))
return string.format('%.3f(%s)', score, grade(score))

2026年5月16日 (六) 22:27的最新版本

此模块的文档可以在模块:OPDI/doc创建

local p = {}

-- 字符串转数字,并清理可能存在的空格或前后缀
local function num(v)
	if v == nil then return nil end
	v = mw.text.trim(tostring(v))
	-- 过滤掉可能附带的单位或逗号(如 "1145 元" 或 "5,700,000")
	v = string.gsub(v, '[%s,,%%元岁]', '')
	if v == '' then return nil end
	return tonumber(v)
end

local function clamp(x, lo, hi)
	if x < lo then return lo end
	if x > hi then return hi end
	return x
end

local function index_linear(value, minv, maxv)
	return clamp((value - minv) / (maxv - minv), 0, 1)
end

-- 收入指数优化:调低历史背景下的绝对下限,避免低收入国家指数雪崩
local function income_index(gdp_pc)
	local min_gdp = 50   -- 设定历史发展中绝对贫困的底线
	local max_gdp = 75000
	if gdp_pc <= min_gdp then return 0 end
	return clamp((math.log(gdp_pc) - math.log(min_gdp)) / (math.log(max_gdp) - math.log(min_gdp)), 0, 1)
end

-- 第三产业指数优化:将下限放宽到 0%,避免工业/农业大国一票否决
local function tertiary_index(share)
	return index_linear(share, 0, 80)
end

local function demographic_factor(birth, death)
	-- 死亡率和自然增长率轻度惩罚项,避免单向误判
	local death_penalty = clamp((death - 12) / 28, 0, 0.12)
	local growth = birth - death
	local growth_penalty = clamp((math.abs(growth - 0.8) - 2.5) / 35, 0, 0.08)
	return 1 - death_penalty - growth_penalty
end

local function calc(frame)
	-- 同时获取当前 invoke 的参数和外层父模板的参数
	local args = frame.args
	local parentArgs = frame:getParent().args
	
	local function getArg(key)
		return args[key] or parentArgs[key]
	end

	local male = num(getArg('male') or getArg('男性预期寿命'))
	local female = num(getArg('female') or getArg('女性预期寿命'))
	local literacy = num(getArg('literacy') or getArg('识字率'))
	local gdp_pc = num(getArg('gdp_pc') or getArg('人均GDP'))
	local tertiary = num(getArg('tertiary') or getArg('第三产业占比'))
	local birth = num(getArg('birth') or getArg('出生率'))
	local death = num(getArg('death') or getArg('死亡率'))

	-- 核心数据缺一不可校验
	if not (male and female and literacy and gdp_pc and tertiary and birth and death) then
		return nil
	end
	if gdp_pc <= 0 then
		return nil
	end

	local life = (male + female) / 2
	local health = index_linear(life, 20, 85)
	local education = clamp(literacy / 100, 0, 1)
	local income = income_index(gdp_pc)
	local structure = tertiary_index(tertiary)
	local demo = demographic_factor(birth, death)

	-- 几何平均保护:给各项指数一个极小的底线(0.01),防止单项落后导致总分直接归零
	health = math.max(health, 0.01)
	education = math.max(education, 0.01)
	income = math.max(income, 0.01)
	structure = math.max(structure, 0.01)

	-- 加权几何平均计算
	local score = (health ^ 0.35) * (education ^ 0.25) * (income ^ 0.30) * (structure ^ 0.10) * demo
	return clamp(score, 0, 1)
end

local function grade(score)
	if score >= 0.93 then return 'A+' end
	if score >= 0.88 then return 'A' end
	if score >= 0.84 then return 'A-' end
	if score >= 0.80 then return 'B+' end
	if score >= 0.76 then return 'B' end
	if score >= 0.72 then return 'B-' end
	if score >= 0.68 then return 'C+' end
	if score >= 0.64 then return 'C' end
	if score >= 0.60 then return 'C-' end
	if score >= 0.55 then return 'D+' end
	if score >= 0.50 then return 'D' end
	if score >= 0.45 then return 'D-' end
	if score >= 0.38 then return 'E+' end
	if score >= 0.30 then return 'E' end
	return 'E-'
end

function p.score(frame)
	local score = calc(frame)
	if not score then return '' end
	return string.format('%.3f', score)
end

function p.grade(frame)
	local score = calc(frame)
	if not score then return '' end
	return grade(score)
end

function p.display(frame)
	local score = calc(frame)
	if not score then return '{{Stay}} 无数据' end
	return string.format('%.3f(%s)', score, grade(score))
end

return p