Модуль:CategoryStatistics
Материал из Поле цифровой дидактики
Для документации этого модуля может быть создана страница Модуль:CategoryStatistics/doc
local p = {}
local function getContent(titleText)
local titleObj = mw.title.new(titleText)
if not titleObj then
return nil
end
return titleObj:getContent()
end
local function countWords(text)
local n = 0
for _ in mw.ustring.gmatch(text, '%S+') do
n = n + 1
end
return n
end
local function getTitlesFromCategory(category, limit)
if not mw.smw then
return nil, 'Ошибка: mw.smw недоступен'
end
local results = mw.smw.ask({
string.format('[[Category:%s]]', category),
'?#-=title',
'limit=' .. tostring(limit or 50)
})
if not results or #results == 0 then
return nil, 'Нет страниц в категории: ' .. category
end
local titles = {}
for _, item in ipairs(results) do
if type(item) == 'table' then
local title = item.title or item[1]
if title and title ~= '' then
table.insert(titles, title)
end
elseif type(item) == 'string' and item ~= '' then
table.insert(titles, item)
end
end
return titles, nil
end
local function summarize(data)
local n = #data
if n == 0 then
return nil
end
local sum = 0
local minv = data[1]
local maxv = data[1]
for _, v in ipairs(data) do
sum = sum + v
if v < minv then minv = v end
if v > maxv then maxv = v end
end
local mean = sum / n
table.sort(data)
local median
if n % 2 == 0 then
median = (data[n / 2] + data[n / 2 + 1]) / 2
else
median = data[math.ceil(n / 2)]
end
local variance = 0
if n > 1 then
for _, v in ipairs(data) do
variance = variance + (v - mean) ^ 2
end
variance = variance / (n - 1)
else
variance = 0
end
local stddev = math.sqrt(variance)
return {
count = n,
sum = sum,
mean = mean,
median = median,
variance = variance,
stddev = stddev,
min = minv,
max = maxv
}
end
function p.words(frame)
local category = frame.args.category or frame.args[1] or 'Book'
local limit = tonumber(frame.args.limit) or 50
local titles, err = getTitlesFromCategory(category, limit)
if not titles then
return err
end
local values = {}
for _, title in ipairs(titles) do
local text = getContent(title)
if text then
table.insert(values, countWords(text))
end
end
if #values == 0 then
return 'Нет доступных страниц для анализа'
end
local s = summarize(values)
local out = '{| class="wikitable"\n'
out = out .. '! Показатель !! Значение\n'
out = out .. '|-\n| Категория || ' .. category .. '\n'
out = out .. '|-\n| Страниц в расчёте || ' .. s.count .. '\n'
out = out .. '|-\n| Среднее число слов || ' .. string.format('%.2f', s.mean) .. '\n'
out = out .. '|-\n| Медиана || ' .. string.format('%.2f', s.median) .. '\n'
out = out .. '|-\n| Дисперсия || ' .. string.format('%.2f', s.variance) .. '\n'
out = out .. '|-\n| Стандартное отклонение || ' .. string.format('%.2f', s.stddev) .. '\n'
out = out .. '|-\n| Минимум || ' .. string.format('%.2f', s.min) .. '\n'
out = out .. '|-\n| Максимум || ' .. string.format('%.2f', s.max) .. '\n'
out = out .. '|}\n'
return out
end
return p
