Firetron's Median

stable
By Firetron in Miscellaneous Published March 2021 👁 1,314 views 💬 1 comments

Description

Finds the middle value of a table of values. If there is an even number of elements, takes the average of the 2 middle values. Custom Command Dependencies: None Test Code:
if not Load('done', false) then

  local table = Grab(ClosePrices(), 0, 9)

  Log(' ')
  Log(table)
  Log('Unsorted Table:')
  Log(' ')

  Log(ArraySort(table))
  Log('Sorted Table:')
  Log(' ')

  local median = CC_Median(table)

  Log(median)
  Log('Median Value:')
  Log(' ')

  Save('done', true)

end
HaasScript
--  ============================================================================
--    Firetron's Median
--
--    Finds the middle value of a table of values. If there is an even number of
--    elements, takes the average of the 2 middle values.
--
--    Custom Command Dependencies:
--    None
--
--    Discord: @FiretronP75
--  ============================================================================

--  ========================================================
--    Variables
--  ========================================================

--  ------------------------------------
--    Definition
--  ------------------------------------

local dDefault
local dDescription
local dName
local dOutput
local dRequired
local dSuggestions
local dType

--  ------------------------------------
--    Function
--  ------------------------------------

local GetMedian

--  ------------------------------------
--    Parameter
--  ------------------------------------

local pIsSorted
local pTable

--  ========================================================
--    Command Definition
--  ========================================================

dName        = 'Median'
dDescription = 'Finds the middle value of a table of values. If there is an even number of elements, takes the average of the 2 middle values.'
DefineCommand(dName, dDescription)

--  ========================================================
--    Parameter Definition
--  ========================================================

dType        = ListDynamicType
dName        = 'table'
dDescription = 'Table of values to find the median value of.'
dRequired    = true
dDefault     = {3, 1, 2}
dSuggestions = 'Prices'
pTable = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

dType        = BooleanType
dName        = 'isSorted'
dDescription = 'Set to true if the table is already sorted.'
dRequired    = false
dDefault     = false
dSuggestions = ''
pIsSorted = DefineParameter(dType, dName, dDescription, dRequired, dDefault, dSuggestions)

--  ========================================================
--    Functions
--  ========================================================

GetMedian = function ()

  local length = #pTable

  if length == 0 then return 0 end
  if length == 1 then return pTable[1] end

  local list = pIsSorted
           and pTable
            or ArraySort(pTable)

  if length % 2 == 1 then

    local middleIndex = (length / 2) + 0.5

    return ArrayGet(list, Round(middleIndex, 0))

  end

  local middleIndex1 = length / 2
  local middleIndex2 = middleIndex1 + 1

  local middleValue1 = ArrayGet(list, middleIndex1)
  local middleValue2 = ArrayGet(list, middleIndex2)

  return (middleValue1 + middleValue2) / 2

end

--  ========================================================
--    Output Definitions
--  ========================================================

dType        = NumberType
dOutput      = GetMedian()
dDescription = 'The median value of the table values.'
dSuggestions = ''
DefineOutput(dType, dOutput, dDescription, dSuggestions)

1 Comment

Sign in to leave a comment.

F
Firetron about 5 years ago

Now works for ListNumber input as well as Table input.
Now has an isSorted param, which you can set to true if you already sorted your list, so the command won't sort it again, redundantly.