-
-
Save gr33n7007h/96d48bcb7297aae105848d6405f109d2 to your computer and use it in GitHub Desktop.
Graph functions in your terminal.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment