#Help me understand how Lua's 'High Scores' exercise works

20 messages · Page 1 of 1 (latest)

modest dirge
#

Hello, I can't quite grasp how I'm supposed to take the inputs and return the output this exercises asks for, could you help me please?

outer egret
#

If you run the tests, that typically highlights what specifics are needed. It will complain if a needed function is missing or if it returns the wrong type of data.

#

Did you run the tests? Are there useful test failure messages? Do those suggest what needs changing?

modest dirge
#

Hello, I've written a few lines of code and I still don't understand what 'self' means or how the outputs are returned but it just works. Still, I'm having this issue where I don't quite get how to create a table that is equal to the one given in input, and how to pass that into a bubble sort function; in particular, this:

local function bubble_sort(table)
    for i = 1, #table-1 do
        if table[i] > table[i+1] then
            tmp = table[i+1]
            table[i+1] = table[i]
            table[i] = tmp
        end
    end

    return table
end
    
local function personal_best(self) return bubble_sort(self) end

gives me:

(table: 0x560a258bbc40) {
  [latest] = function: 0x560a25872be0
  [personal_best] = function: 0x560a25872b90
  [personal_top_three] = function: 0x560a2587bd60
  [scores] = function: 0x560a258b4010
  [values] = {
    [1] = 40
    [2] = 100
    [3] = 70 } }

instead of 100.

#
local function scores(self) return self.values end

local function latest(self) return self.values[#self.values] end

local function bubble_sort(table)
    for i = 1, #table-1 do
        if table[i] > table[i+1] then
            tmp = table[i+1]
            table[i+1] = table[i]
            table[i] = tmp
        end
    end

    return table
end
    
local function personal_best(self) return bubble_sort(self)[#self.values] end
    
local function personal_top_three(self)
end

return function(values)
    return {
        values = values,
        scores = scores,
        latest = latest,
        personal_best = personal_best,
        personal_top_three = personal_top_three
      }
end

This is all I've written, and I also don't get the "return function(values)" part

#

By the way, I've added '[#self.values]' to return the last item from the sorted table, which is the highest score, and I just get nil, of course

outer egret
#

I think self is the class that has those methods. You're passing the class and not the scores to bubble sort I think?

sick flame
#

In lua, the "colon" notation is just "syntactic sugar" for passing the function's receiver as the first parameter.

#

In other words, these are equivalent: ```lua
obj:personal_top_three()
obj.personal_top_three(obj)
-- ^ ................. ^^^

#

By convention, self is the parameter name

#

If you look at the test file, you will see: ```lua
local HighScores = require 'high-scores'

describe('high-scores', function()
it('table of scores', function()
local values = { 30, 50, 20, 70 }
local scores = HighScores(values)
local expected = { 30, 50, 20, 70 }
assert.are.same(expected, scores:scores())
end)
...

#

The return value of require is used as a function. So, your code must return a function.

#

The function your code returns must create a table containing the functions named "scores", "latest", etc.

modest dirge
#

After thinking about it for a while I decided to re-do everything from scratch, and I've come up with this:

return function(scores)
    local latest = scores[#scores]
    local sorted = {}
    for i = 1, #scores do
        sorted[i] = scores[i]
    end
    
    while true do
        swaps = 0
        for i = 1, #sorted-1 do
            if sorted[i] > sorted[i+1] then
                tmp = sorted[i+1]
                sorted[i+1] = sorted[i]
                sorted[i] = tmp
                swaps = swaps+1
            end
        end
        if swaps == 0 then break end
    end

    local personal_best = sorted[#scores]
    local personal_top_three = {}

    for i = 0, 2 do
        personal_top_three[i+1] = sorted[#sorted-i]
    end

    return {
        scores = function() return scores end,
        latest = function() return latest end,
        personal_best = function() return personal_best end,
        personal_top_three = function() return personal_top_three end
    }
end

It works like a charm, but I've still got some perplexities about the last return statement, mainly with how the function calls itself to return a variable which is not defined in it (I'm talking about scores).
Thanks for all your helping.

sick flame
#

This is called a "closure". Lua is implemented so that functions remember the context in which they were defined. This context contains all the local variables and the scores parameter. What you have here is one form of Lua object-oriented programming: the outer function (the class) creates a table (the object) containing functions (methods) and the context of the outer function hold the object's private instance variables.

modest dirge
#

I get it know, thank you kindly.

lucid sparrow
#

hello! i am also having trouble with this exercise. i don't understand how my answers are supposed to be structured. the code i have written so far is ```lua
return function(scores)
function scores(values)
return values
end

function latest(values)
return values[#values]
end

return {scores, latest}
end

however i get the error `./high-scores_spec.lua:8: attempt to call a nil value (method 'scores')` whenever i run it.
sick flame
lucid sparrow
#

thank you! i ended up defining each function separately and them returning them all with

return {
    scores = scores,
    latest = latest,
    personal_best = personal_best,
    personal_top_three = personal_top_three
  }

at the end.

#

not sure if there are cleaner ways of doing it, but this works