Skip to content

Instantly share code, notes, and snippets.

@tylerneylon
Created December 17, 2014 22:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tylerneylon/bda5769357f35ff17833 to your computer and use it in GitHub Desktop.
Save tylerneylon/bda5769357f35ff17833 to your computer and use it in GitHub Desktop.
Graph functions in your terminal.
#!/usr/local/bin/lua
usage_str = [[
Usage:
lgraph 'function of x'
Example:
lgraph 'x^2'
]]
Grapher = {xmin = -1, xmax = 1, ymin = -1, ymax = 1, ncols = 160, nrows = 50}
function Grapher:new ()
return setmetatable({}, {__index = self})
end
local function round(x)
return math.floor(x + 0.5)
end
-- This returns a *function* that maps [a1, b1] to [a2, b2].
local function range_mapper(a1, b1, a2, b2)
return function (x)
local perc_from_a = (x - a1) / (b1 - a1)
return a2 + (b2 - a2) * perc_from_a
end
end
-- Makes a map self.char[col][row] = <nil or character to print>.
function Grapher:setup_char_table(eqn)
local f = loadstring('local x = ...; return ' .. eqn)
-- This will be a table of tables so that self.char[col][row] is either
-- nil or the character to print at that location.
self.char = {}
local y_to_row = range_mapper(self.ymin, self.ymax, self.nrows, 1)
local col_to_x = range_mapper(1, self.ncols, self.xmin, self.xmax)
for col = 1, self.ncols do
local y = f(col_to_x(col))
local row = round(y_to_row(y))
if self.char[col] == nil then self.char[col] = {} end
self.char[col][row] = 'o'
end
end
function Grapher:graph(eqn)
self:setup_char_table(eqn)
for row = 1, self.nrows do
for col = 1, self.ncols do
io.write(self.char[col][row] or ' ')
end
io.write('\n')
end
end
AxisGrapher = Grapher:new()
function AxisGrapher:graph(eqn)
self:setup_char_table(eqn) -- This part is the same.
local zero_col = round(range_mapper(self.xmin, self.xmax, 1, self.ncols)(0))
local zero_row = round(range_mapper(self.ymin, self.ymax, self.nrows, 1)(0))
for row = 1, self.nrows do
for col = 1, self.ncols do
local c = self.char[col][row]
if not c and row == zero_row then c = '-' end
if not c and col == zero_col then c = '|' end
io.write(c or ' ')
end
io.write('\n')
end
end
if not arg[1] or (arg[1] == '-a' and not arg[2]) then
print(usage_str)
os.exit(0)
end
if arg[1] == '-a' then
g = AxisGrapher:new()
arg[1] = arg[2]
else
g = Grapher:new()
end
g:graph(arg[1])
@tylerneylon
Copy link
Author

I made this for a Lua tutorial video I'm working on. Its purpose is to illustrate how to handle simple object-oriented patterns in Lua.

Oh, you can also graph things with it. Here's an example:

$ lgraph 'math.sin(7 * x)'
            ooo                                oooo                             
          oo   oo                             o    o                            
         o       o                           o      o                           
        o                                   o        o                         o
                  o                        o          o                         
       o           o                      o                                   o 
      o                                                o                     o  
                    o                    o              o                       
     o               o                                                      o   
                                        o                o                 o    
    o                 o                o                                        
   o                                                      o               o     
                       o              o                    o                    
  o                     o                                                o      
 o                                   o                      o           o       
                         o          o                        o                  
o                         o        o                                   o        
                           o      o                           o       o         
                            o    o                             oo   oo          
                             oooo                                ooo         

I modified the ncols and nrows values so the above example will make sense when viewed on this gist page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment