Module:Interval edo approximation: Difference between revisions

Pailiaq (talk | contribs)
No edit summary
Pailiaq (talk | contribs)
No edit summary
 
(7 intermediate revisions by 3 users not shown)
Line 2: Line 2:
-- Calculates EDO approximations for just intervals
-- Calculates EDO approximations for just intervals
-- Usage: {{#invoke:EDO_Approximations|main|interval=3/2|tolerance=9|min_edo=5|max_edo=60}}
-- Usage: {{#invoke:EDO_Approximations|main|interval=3/2|tolerance=9|min_edo=5|max_edo=60}}
local u = require("Module:Utils")
local yesno = require("Module:Yesno")
local yesno = require("Module:Yesno")
local p = {}
local p = {}


-- ===== CONFIGURATION VARIABLES =====
-- ===== CONFIGURATION VARIABLES =====
local DEFAULT_TOLERANCE = 9.0  -- Relative error tolerance in percent
local DEFAULT_TOLERANCE = 13.0  -- Relative error tolerance in percent
local DEFAULT_MIN_EDO = 5      -- Minimum EDO to check
local DEFAULT_MIN_EDO = 5      -- Minimum EDO to check
local DEFAULT_MAX_EDO = 60    -- Maximum EDO to check
local DEFAULT_MAX_EDO = 60    -- Maximum EDO to check
Line 14: Line 15:
-- Python: return 1200 * math.log2(ratio)
-- Python: return 1200 * math.log2(ratio)
local function cents(ratio)
local function cents(ratio)
    -- Lua doesn't have log2, so use change of base formula
     return 1200 * u.log2(ratio)
     return 1200 * (math.log(ratio) / math.log(2))
end
 
-- Parse a ratio string like '3/2' into a number
-- Python: parts = ratio_str.strip().split('/'); return float(parts[0]) / float(parts[1])
local function parse_ratio(ratio_str)
    -- Strip whitespace (equivalent to Python's strip())
    ratio_str = ratio_str:match("^%s*(.-)%s*$")
 
    -- Split on '/' and parse numerator/denominator
    local slash_pos = ratio_str:find("/")
    if not slash_pos then
        return nil
    end
 
    local num_str = ratio_str:sub(1, slash_pos - 1)
    local denom_str = ratio_str:sub(slash_pos + 1)
 
    local num = tonumber(num_str)
    local denom = tonumber(denom_str)
 
    if not num or not denom or denom == 0 then
        return nil
    end
 
    -- Return exact division (equivalent to Python's float division)
    return num / denom
end
end


Line 117: Line 91:
     local args = frame.args
     local args = frame.args
     local interval_str = args.interval or args[1]
     local interval_str = args.interval or args[1]
local interval_name = args.interval_name -- Optional display name
local interval_name = args.interval_name   -- Optional display name
     -- Convert string parameters to numbers using config defaults
     -- Convert string parameters to numbers using config defaults
     local tolerance = tonumber(args.tolerance) or DEFAULT_TOLERANCE
     local tolerance = tonumber(args.tolerance) or DEFAULT_TOLERANCE
Line 129: Line 103:


     -- Parse interval string to numeric ratio
     -- Parse interval string to numeric ratio
     local ratio = parse_ratio(interval_str)
     local ratio = u.eval_num_arg(interval_str)
     if not ratio then
     if not ratio then
         return "Error: Invalid interval format (use format like '3/2')"
         return "Error: Invalid interval format (use format like '3/2')"
Line 143: Line 117:
     -- Build the wikitable
     -- Build the wikitable
     -- mw-collapsible: adds [hide] toggle button
     -- mw-collapsible: adds [hide] toggle button
    -- mw-collapsed: table defaults to collapsed ##removed
     -- sortable: makes columns sortable by clicking headers
     -- sortable: makes columns sortable by clicking headers
     local output = {}
     local output = {}
Line 153: Line 128:


table.insert(output, '|+ style="font-size: 105%;" | '
table.insert(output, '|+ style="font-size: 105%;" | '
     .. string.format('Edo approximations for %s (%.2f{{c}})<br /><span style="font-size: 0.75em;">\'\'&le;&nbsp;%dedo, relative error &le;&nbsp;%g%%\'\'</span>',
     .. string.format('Edo&nbsp;approximations&nbsp;for&nbsp;%s&nbsp;(%.2f{{c}})<br /><span style="font-size: 0.75em;">\'\'&le;&nbsp;%dedo,&nbsp;relative&nbsp;error&nbsp;&le;&nbsp;%g%%\'\'</span>',
         display_name, ratio_cents, max_edo, tolerance))
         display_name, ratio_cents, max_edo, tolerance))
     table.insert(output, '|-')
     table.insert(output, '|-')