how do i call for a vaiable using user_input - lua

the file im working on is a feckin mess so im going to use this instead
a = 1
b = 2
c = 3
user_input =
I want to be able to write b in the terminal and get back 2
ive tried all the different io functions and I don't want to use print
… sorry if this is stupid simple im a new programmer (learning)
also please don't out right tell me how to solve this problem just get me on the right track please

If you are asking how to output something based on the user input you could instead make a table like
values = {
['a'] = 1,
['b'] = 2,
['c'] = 3,
--continued for as many as you want
}
and then simply print the value at the index they input
if values[user_input] then --Make sure the index is valid before trying to print it
print(values[user_input])
end

I think what you are saying is:
if (user_input=="b"){
print(b)
}

Since you use globals a, b and c, you can refer to them as _G[var]:
var = io.read()
print _G[var]
Also, you can use getfenv()/setfenv() in Lua 5.1 and _ENV in Lua 5.2+ to avoid polluting the global scope (see http://lua-users.org/wiki/EnvironmentsTutorial).

#! /usr/bin/env lua
local table = {}
table .a = 1
table .b = 2
table .c = 3
local function test_inclusion()
io .write( 'key: ' )
key = io .read()
if table[ key ] then
value = table[ key ]
io .write( 'value: ' ..value ..'\n' )
end
end
test_inclusion()

Related

Lua/pico8: Converting str to variable without access to _G table

I'm looking to iterate over some similarly named variables. a_1,a_2,a_3=1,2,3
So that instead of using:
if a_1>0 then a_1-=1 end
if a_2>0 then a_2-=1 end
if a_3>0 then a_3-=1 end
I can do something like:
for i=1,3 do
if a_'i'>1 then a_'i'-=1 end --syntax is wrong here
end
Not sure how to go about doing this, as stated there is no access to _G library in pico8. var-=1 is just var=var-1. Given there are functions like tostr() and tonum() was wondering if there was a tovar() kind of trick to this. Basically need a way to convert the i value to a letter in my variable name and concat it to the variable name...in the conditional statement. Or some alternative method if there is one.
In Lua, when in doubt, use a table.
In this case you could put the 3 variable on a table at the start, and unpack them at the end:
local a={a_1,a_2,a_3}
for i=1,3 do
if(a[i]>1) a[i]-=1
end
a_1,a_2,a_3=unpack(a)
Not sure which Lua version does pico 8 use but for LuaJIT, you could try using loadstring and there is load for Lua5.2+ (I know, not the best solution):
for i = 1, 3 do
local x
loadstring("x = a_" .. tostring(i))()
if x > 1 then
x = x - 1
loadstring("a_" .. tostring(i) .. " = x")()
end
end

LUA: How to Create 2-dimensional array/table from string

I see several posts about making a string in to a lua table, but my problem is a little different [I think] because there is an additional dimension to the table.
I have a table of tables saved as a file [i have no issue reading the file to a string].
let's say we start from this point:
local tot = "{{1,2,3}, {4,5,6}}"
When I try the answers from other users I end up with:
local OneDtable = {"{1,2,3}, {4,5,6}"}
This is not what i want.
how can i properly create a table, that contains those tables as entries?
Desired result:
TwoDtable = {{1,2,3}, {4,5,6}}
Thanks in advance
You can use the load function to read the content of your string as Lua code.
local myArray = "{{1,2,3}, {4,5,6}}"
local convert = "myTable = " .. myArray
local convertFunction = load(convert)
convertFunction()
print(myTable[1][1])
Now, myTable has the values in a 2-dimensional array.
For a quick solution I suggest going with the load hack, but be aware that this only works if your code happens to be formatted as a Lua table already. Otherwise, you'd have to parse the string yourself.
For example, you could try using lpeg to build a recursive parser. I built something very similar a while ago:
local lpeg = require 'lpeg'
local name = lpeg.R('az')^1 / '\0'
local space = lpeg.S('\t ')^1
local function compile_tuple(...)
return string.char(select('#', ...)) .. table.concat{...}
end
local expression = lpeg.P {
'e';
e = name + lpeg.V 't';
t = '(' * ((lpeg.V 'e' * ',' * space)^0 * lpeg.V 'e') / compile_tuple * ')';
}
local compiled = expression:match '(foo, (a, b), bar)'
print(compiled:byte(1, -1))
Its purpose is to parse things in quotes like the example string (foo, (a, b), bar) and turn it into a binary string describing the structure; most of that happens in the compile_tuple function though, so it should be easy to modify it to do what you want.
What you'd have to adapt:
change name for number (and change the pattern accordingly to lpeg.R('09')^1, without the / '\0')
change the compile_tuple function to a build_table function (local function build_tanle(...) return {...} end should do the trick)
Try it out and see if something else needs to be changed; I might have missed something.
You can read the lpeg manual here if you're curious about how this stuff works.

Can i make a function to create table and name it with a parameter used when called?

I'm trying to make a function that, when I call it, I can pass it a name and it will make a table for me. I then want it to return the table so I can use it. My code does make a table but I can't seem to access it. I'm thinking Lua is having trouble naming after an argument, but I'm not sure how to fix it. Here is a sample code of what I am trying to accomplish:
Tablemaker.lua:
Tabler = {}
Tabler.init = function (n,x,y,z)
--This is where i think it is messing up
N = {}
N.a = x
N.b = y
N.c = z
--had a print function here so i know the table is made.
I am leaving it out for you guys.
--not sure if i need it but i put return here.
Return n
End
Main.lua:
Require ("Tablemaker.lua")
Tabler.init (meow,15,32,45)
--a sepaeate print function here to verify i can access my
table. When the console tries to print, it gives meow = nil.
Which i am assuming the table is not properly named meow and
is instead named n. However using print(n.a) for example gives
n = nil also.
Print(meow.a .. " " .. meow.b .. " " .. meow.c)
And thats about it. I'm trying to make a vector class (not sure why one isn't in Lua), but even without vectors I want to be able to pass names into functions. What should i do?
You can make function create named table in global, but why would you ever need that? Just return it and assign it to whatever you like be it global or local or whatever. Globals are bad anyway.
Tabler = {}
Tabler.init = function (x,y,z)
N = {}
N.a = x
N.b = y
N.c = z
Return N
End
Require ("Tablemaker.lua")
local meow = Tabler.init(15,32,45)
Print(meow.a .. " " .. meow.b .. " " .. meow.c)

Find all upper/lower/mixed combinations of a string

I need this for a game server using Lua..
I would like to be able to save all combinations of a name
into a string that can then be used with:
if exists (string)
example:
ABC_-123
aBC_-123
AbC_-123
ABc_-123
abC_-123
etc
in the game only numbers, letters and _ - . can be used as names.
(A_B-C, A-B.C, AB_8 ... etc)
I understand the logic I just don't know how to code it:D
0-Lower
1-Upper
then
000
001
etc
You can use recursive generator. The first parameter contains left part of the string generated so far, and the second parameter is the remaining right part of the original string.
function combinations(s1, s2)
if s2:len() > 0 then
local c = s2:sub(1, 1)
local l = c:lower()
local u = c:upper()
if l == u then
combinations(s1 .. c, s2:sub(2))
else
combinations(s1 .. l, s2:sub(2))
combinations(s1 .. u, s2:sub(2))
end
else
print(s1)
end
end
So the function is called in this way.
combinations("", "ABC_-123")
You only have to store intermediate results instead of printing them.
If you are interested only in the exists function then you don't need all combinations.
local stored_string = "ABC_-123"
function exists(tested_string)
return stored_string:lower() == tested_string:lower()
end
You simply compare the stored string and the tested string in case-insensitive way.
It can be easily tested:
assert(exists("abC_-123"))
assert(not exists("abd_-123"))
How to do this?
There's native function in Lua to generate all permutations of a string, but here are a few things that may prove useful.
Substrings
Probably the simplest solution, but also the least flexible. Rather than combinations, you can check if a substring exists within a given string.
if str:find(substr) then
--code
end
If this solves your problem, I highly reccomend it.
Get all permutations
A more expensive, but still a working solution. This accomplishes nearly exactly what you asked.
function GetScrambles(str, tab2)
local tab = {}
for i = 1,#str do
table.insert(tab, str:sub(i, i))
end
local tab2 = tab2 or {}
local scrambles = {}
for i = 0, Count(tab)-1 do
local permutation = ""
local a = Count(tab)
for j = 1, #tab do
tab2[j] = tab[j]
end
for j = #tab, 1, -1 do
a = a / j
b = math.floor((i/a)%j) + 1
permutation = permutation .. tab2[b]
tab2[b] = tab2[j]
end
table.insert(scrambles, permutation)
end
return scrambles
end
What you asked
Basically this would be exactly what you originally asked for. It's the same as the above code, except with every substring of the string.
function GetAllSubstrings(str)
local substrings = {}
for i = 1,#str do
for ii = i,#str do
substrings[#substrings+1]=str:sub(ii)
end
end
return substrings
end
Capitals
You'd basically have to, with every permutation, make every possible combination of capitals with it.
This shouldn't be too difficult, I'm sure you can code it :)
Are you joking?
After this you should probably be wondering. Is all of this really necessary? It seems like a bit much!
The answer to this lies in what you are doing. Do you really need all the combinations of the given characters? I don't think so. You say you need it for case insensitivity in the comments... But did you know you could simply convert it into lower/upper case? It's very simple
local str = "hELlO"
print(str:lower())
print(str:upper())
This is HOW you should store names, otherwise you should leave it case sensitive.
You decide
Now YOU pick what you're going to do. Whichever direction you pick, I wish you the best of luck!

Lua multiline comments past ]]'s

I'm trying to find out a way to use a multiline comment on a batch of code, but it keeps mistaking some syntax in it as a ]] and thinking I want it to end there, which I don't!
--[[
for k,v in pairs(t) do
local d = fullToShort[k]
local col = xColours[v[1]] -- It stops here!
cecho(string.format(("<%s>%s ", col, d))
end
--]]
I thought I read somewhere it was possible to do use a different sort of combination to avoid those errors, like --[=[ or whatnot... Could someone help?
As you can see in Strings tutorial there is a special [===[ syntax for nesting square braces. You can use it in block comments too. Just note, that number of = signs must be the same in open and close sequence.
For example 5 equals will work.
--[=====[
for k,v in pairs(t) do
local d = fullToShort[k]
local col = xColours[v[1]] -- It stops here!
cecho(string.format(("<%s>%s ", col, d))
end
--]=====]
You can use the following to create multiline comments past ]]'s:
--[[
codes
]]

Resources