Extracting variables from expression in Lua - string

I have expressions in lua which contains standard metatable operations .__add,.__sub,.__mul, (+,-,*)
For example a+b*xyz-cdeI am trying to extract all free variables in table. For this expression, the table will contain {a,b,xyz,cde}. Right now I am trying it with string operations, like splitting, substituting etc. This seems to work but I feel it as ugly way. It gets little complicated as there may nesting and brackets involved in expressions. For example, the expression (a+b)-c*xyz*(a+(b+c)) should return table {a,b,c,xyz}. Can there be a simple way to extract free variables in expressions? I am even looking for simple way with string library.

If you want to do string processing, it's easy:
local V={}
local s="((a+b)-c*xyz*(a+(b+c)))"
for k in s:gmatch("%a+") do
V[k]=k
end
for k in pairs(V) do print(k) end
For fun, you can let Lua do the hard work:
local V={}
do
local _ENV=setmetatable({},{__index=function (t,k) V[k]=k return 0 end})
local _=((a+b)-c*xyz*(a+(b+c)))
end
for k in pairs(V) do print(k) end
This code evaluates the expression in an empty environment where every variable has the value zero, saving the names of the variables in the expression in a table.

Related

How to change a string into a variable

I want to write out some data into a file. I saved the filename as a variable. I wan to use % mode to substitude the variable to the text, but it gives an error:
IndentationError: unindent does not match any outer indentation level
writeafile = open('N:\myfile\%s.txt' , "a") % (variable)
Assuming we are talking about Python here, you should move variable next to the
'N:\\myfile\\%s.txt' string for correct syntax, like so:
writeafile = open("N:\\myfile\\%s.txt" % variable, "a")
However, using this style of formatting is not recommended by Pydocs:
The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals, the str.format() interface, or template strings may help avoid these errors. Each of these alternatives provides their own trade-offs and benefits of simplicity, flexibility, and/or extensibility.
Source
So, I'd suggest using f-strings, which have been available in Python since 3.6. The double \\ is intentional here, otherwise Python will treat it as an escape character and you'll get undesired results.
writeafile = open(f"N:\\myfile\\{variable}.txt", "a")
Alternatively, you could also use str.format():
writeafile = open("N:\\myfile\\{name}.txt".format(name=variable), "a")

String formatting in python 3 without print function

Trying to understand how "%s%s" %(a,a) is working in below code I have only seen it inside print function thus far.Could anyone please explain how it is working inside int()?
a=input()
b=int("%s%s" %(a,a))
this "%s" format has been borrowed from C printf format, but is much more interesting because it doesn't belong to print statement. Note that it involves just one argument passed to print (or to any function BTW):
print("%s%s" % (a,a))
and not (like C) a variable number of arguments passed to some functions that accept & understand them:
printf("%s%s,a,a);
It's a standalone way of creating a string from a string template & its arguments (which for instance solves the tedious issue of: "I want a logger with formatting capabilities" which can be achieved with great effort in C or C++, using variable arguments + vsprintf or C++11 variadic recursive templates).
Note that this format style is now considered legacy. Now you'd better use format, where the placeholders are wrapped in {}.
One of the direct advantages here is that since the argument is repeated you just have to do:
int("{0}{0}".format(a))
(it references twice the sole argument in position 0)
Both legacy and format syntaxes are detailed with examples on https://pyformat.info/
or since python 3.6 you can use fstrings:
>>> a = 12
>>> int(f"{a}{a}")
1212
% is in a way just syntactic sugar for a function that accepts a string and a *args (a format and the parameters for formatting) and returns a string which is the format string with the embedded parameters. So, you can use it any place that a string is acceptable.
BTW, % is a bit obsolete, and "{}{}".format(a,a) is the more 'modern' approach here, and is more obviously a string method that returns another string.

How to store part of a string in a variable on Lua

I have a phrase, where only some words will change, and I need to store those words on a variable.
Example:
phrase = "I cannot connect to server XPTO\TEST for the last five hours"
The only part that will change is XPTO\TEST and I need to store it on a variable so that I can use it later.
Any ideas, or is it possible?
Seems like you need some form of placeholders, if that is a case, then you can use string.format or string.gsub.
local t = {name="lua", version="5.3"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.3.tar.gz"
With PHP for example you can achieve what you want without any extra work done, because there is a feature called string interpolation (wiki).
But at the same time Lua doesn't have one, that's why you can't do that without extra string post-processing.

need guidance with basic function creation in MATLAB

I have to write a MATLAB function with the following description:
function counts = letterStatistics(filename, allowedChar, N)
This function is supposed to open a text file specified by filename and read its entire contents. The contents will be parsed such that any character that isn’t in allowedChar is removed. Finally it will return a count of all N-symbol combinations in the parsed text. This function should be stored in a file name “letterStatistics.m” and I made a list of some commands and things of how the function should be organized according to my professors' lecture notes:
Begin the function by setting the default value of N to 1 in case:
a. The user specifies a 0 or negative value of N.
b. The user doesn’t pass the argument N into the function, i.e., counts = letterStatistics(filename, allowedChar)
Using the fopen function, open the file filename for reading in text mode.
Using the function fscanf, read in all the contents of the opened file into a string variable.
I know there exists a MATLAB function to turn all letters in a string to lower case. Since my analysis will disregard case, I have to use this function on the string of text.
Parse this string variable as follows (use logical indexing or regular expressions – do not use for loops):
a. We want to remove all newline characters without this occurring:
e.g.
In my younger and more vulnerable years my father gave me some advice that I've been turning over in my mind ever since.
In my younger and more vulnerableyears my father gave me some advicethat I’ve been turning over in my mindever since.
Replace all newline characters (special character \n) with a single space: ' '.
b. We will treat hyphenated words as two separate words, hence do the same for hyphens '-'.
c. Remove any character that is not in allowedChar. Hint: use regexprep with an empty string '' as an argument for replace.
d. Any sequence of two or more blank spaces should be replaced by a single blank space.
Use the provided permsRep function, to create a matrix of all possible N-symbol combinations of the symbols in allowedChar.
Using the strfind function, count all the N-symbol combinations in the parsed text into an array counts. Do not loop through each character in your parsed text as you would in a C program.
Close the opened file using fclose.
HERE IS MY QUESTION: so as you can see i have made this list of what the function is, what it should do, and using which commands (fclose etc.). the trouble is that I'm aware that closing the file involves use of 'fclose' but other than that I'm not sure how to execute #8. Same goes for the whole function creation. I have a vague idea of how to create a function using what commands but I'm unable to produce the actual code.. how should I begin? Any guidance/hints would seriously be appreciated because I'm having programmers' block and am unable to start!
I think that you are new to matlab, so the documentation may be complicated. The root of the problem is the basic understanding of file I/O (input/output) I guess. So the thing is that when you open the file using fopen, matlab returns a pointer to that file, which is generally called a file ID. When you call fclose you want matlab to understand that you want to close that file. So what you have to do is to use fclose with the correct file ID.
fid = open('test.txt');
fprintf(fid,'This is a test.\n');
fclose(fid);
fid = 0; % Optional, this will make it clear that the file is not open,
% but it is not necessary since matlab will send a not open message anyway
Regarding the function creation the syntax is something like this:
function out = myFcn(x,y)
z = x*y;
fprintf('z=%.0f\n',z); % Print value of z in the command window
out = z>0;
This is a function that checks if two numbers are positive and returns true they are. If not it returns false. This may not be the best way to do this test, but it works as example I guess.
Please comment if this is not what you want to know.

Renaming a structure in MATLAB using an existing string

I have a structure in MATLAB called dat. I want to rename dat as an existing string.
Existing_str='NewName'
$(Existing_str)=dat
This fails as I don't think MATLAB lets me use the dollar sign in this way. The code below creates a copy of dat literally called Existing_str and destroys the Existing_str in the process.
Existing_str=dat
While the code below generates a collosal empty structure which clearly is not a copy!
eval(Existing_str)=dat
In the task I am actually trying to perform I don't know the name of the existing_str in advance so that is not a solution.
You were almost there with your `eval'. What you want is:
eval([Existing_str '=dat;']);
This works because you're composing a string inside your square brackets. If you just looked at the resulting string, it would look like NewName=dat; The eval command simply tells Matlab to evaluate the string as if you typed it into the command line.
You can use dynamic field naming (Bas's suggestion), and avoid eval:
For example, if you have just loaded a structure dat from a file 'somefile.ext' with some custom parsing function:
filename = 'somefile.ext'; % presume you actually have a list of files from dir or ls
dat = yourfunction(filename);
[~, name, ~] = fileparts(filename);
alldat.(name)=dat;
This is equivalent to:
alldat.somefile = dat;
Except that we've just automatically taken the name from the filename (in this case just by stripping off the path/extension, but you could do other things depending on the pattern of the filename).
The bonus of this is that you can then, say, with a structure that has fields alldat.file1, alldata.file2, alldat.file3, all of which have a subfield, say, size do things like this:
names = fieldnames(alldat)
for n = 1:length(names)
alldat.(names{n}).mean = mean(alldata.(names{n}).size);
end
Every sub-structure now has a field, mean, which contains the mean of the data. If you had a bunch of different named structures you would need to eval everything you wanted to do to them collectively, and the code becomes difficult to read and maintain.
The other option is a cell array. Here's an easy trick:
dat = % whatever you do to make this structure
alldat{end+1} = dat;
This just appends the new dat onto the end of an existing cell array. {end+1} ensures it doesn't overwrite existing data.

Resources