I would like to know if it's possible to use the content of a variable list of strings to create a new variable.
As an example:
str={"cow","monkey"}
these strings are extracted from a file. Now I would like to refer to these strings as if it was a variable. So the variable cow could be set to {4,2,3} or anything else. Any reference as str[[1]] gives the string "cow" of course.
Any clues or is this a bad idea anyway?
Of course I could add info in the list I already have such as:
str={{"cow",{4,2,3}},{"monkey",{}}
but then I still won't be able to directly address cow as a variable.
The simplest would be to just manually use symbols cow and monkey rather than strings:
In[309]:=
cow = 1;
monkey = 2;
{cow, monkey}
Out[311]= {1, 2}
But this is probably not what you asked. If you want to automatically convert strings to variables, then
what you have to do (if I understood the question correctly) is to first convert your strings to symbols, since symbols can be assigned values and used as variables:
Remove[cow,monkey];
str = {"cow", "monkey"};
str1 = ToExpression /# str
{cow, monkey}
(I assume that symbols cow and monkey have not been used/defined). After that, you can use the answer for this question to assign to the variables based on their positions in str1. However, the usefulness of this approach is also questionable.
What I think makes the most sense is to create so called indexed variables, such as
myIndexedVar["cow"] = 1;
myIndexedVar["monkey"] = 2;
where myIndexedVar is essentially a hash-table of key-value pairs, with keys being your strings and values being whatever you want to assign to them. The process can be automated if needed.
EDIT
To illustrate assignments to such variables, here is a function which automates that:
assignVariables[varNames_List, values_List, hashName_Symbol ] /;
Length[varNames] == Length[values] :=
MapThread[(hashName[#1] = #2) &, {varNames, values}];
Here is how you can use it:
In[316]:= assignVariables[str,{{4,2,3},{}},myIndexedVar]
Out[316]= {{4,2,3},{}}
In[317]:= myIndexedVar["cow"]
Out[317]= {4,2,3}
In[318]:= myIndexedVar["monkey"]
Out[318]= {}
But again, this really is a hash-table, so your question makes most sense to me when reformulated as: "I want to make a hash-table with string keys. What's the easiest way to do that in Mathematica, add key-value pairs and access them". The answer seems to be - indexed variables, as illustrated above. You may also find it useful to read on DownValues, since these provide the mechanism for indexed variables.
Leonid's last method is probably the best, but I am fond of replacement rules, therefore I offer:
str={"cow","monkey"};
rules = {"cow" -> {4,2,3}, "monkey" -> {}};
str[[1]] /. rules
Out = {4, 2, 3}
See Rule, and ReplaceAll for more.
ToExpression will convert a string to an expression. Symbol["x"] creates the symbol x as the name suggests.
However, I wonder how you plan to use them. If you don't know a priori what's in the file with names how are you going to use them? If str={"cow","monkey"} and I create a list of symbols with strSym=ToExpression/#str then the only way I could continue in my code is to index this second array. I cannot simply say cow=5 in my code because I don't know at the time of writing the code that there will be a variable named cow.
In[1]:= str = {"cow", "monkey"};
strSym = ToExpression /# str
Out[2]= {cow, monkey}
In[3]:= strSym[[1]] // Evaluate = 5
Out[3]= 5
In[4]:= ?cow
Global`cow
cow=5
As you can see, indexing also requires an additional Evaluate, because Set (=) has HoldFirst as Attribute. So I can't set cow by indexing unless I have the index evaluated otherwise I overwrite the definition of strSym[[1]] .
Related
This question might have already been answered but I haven't found it yet.
Let's say I have a std::map<string,string> which contains string pairs of <replace_all_this, to_this>.
I checked Boost's format library, which is close but not perfect:
std::map<string,string> m;
m['$search1'] = 'replace1';
m['$search2'] = 'replace2';
format fmter1("let's try to %1% and %2%.");
fmter % 36; fmter % 77;
for(auto r : m) {
fmter % r.second;
}
// would print "let's try to replace1 and replace2
This would work, but I lose control of what.
Actually I'd like to have this as result:
format fmter1("let's try to $search2 and $search1 even if their order is different in the map.");
...
//print: "let's try to replace2 and replace1 even if their order is different in the map".
Please note: map can contain more items, and items can occur multiple times in the formatter.
What is the way to go for this in 2020, I'd like it to be effective and fast, so I'd avoid iterating over the map multiple times.
There may be new libraries but there is no new algorithm to do that faster than what we have so far.
Assuming your format implies a $<name> for your variables, you can search for the first '$', read the <name> search for that in the map, then do the replace. This allows you to either skip the replacement or process it too (i.e. make it recursive where a variable can reference another).
I don't think that doing it the other way around would be any faster: i.e. go through the map and search for the names in the string means you'd be parsing the strings many times and if you have many variables, it will be a huge waste if most are not likely part of your string. Also if you want to prevent some level of recursivity, it's very complicated.
Where you can eventually optimize is in calculating the size of the resulting string and allocate that buffer once instead of using += which is not unlikely going to be slower.
I have such an implementation in my snaplogger. The variable has to be between brackets and it can include multiple parameters to further tweak the data. There is documentation here about what is supported by that function and as written, you can easily extend the class to add more features. It's probably not a one to one match to what you're looking for, but it shows you that there is not 20 ways of implementing that function.
set var1 A
set var2 {A}
Is it possible to check if variable is list in TCL? For var1 and var2 llength gives 1. I am thinking that these 2 variables are considered same. They are both lists with 1 element. Am I right?
Those two things are considered to be entirely identical, and will produce identical bytecode (except for any byte offsets used for indicating where the content of constants are location, which is not information normally exposed to scripts at all so you can ignore it, plus the obvious differences due to variable names). Semantically, braces are a quoting mechanism and not an indicator of a list (or a script, or …)
You need to write your code to not assume that it can look things up by inspecting the type of a value. The type of 123 could be many different things, such as an integer, a list (of length 1), a unicode string or a command name. Tcl's semantics are based on you not asking what the type of a value is, but rather just using commands and having them coerce the values to the right type as required. Tcl's different to many other languages in this regard.
Because of this different approach, it's not easy to answer questions about this in general: the answers get too long with all the different possible cases to be considered in general yet most of it will be irrelevant to what you're really seeking to do. Ask about something specific though, and we'll be able to tell you much more easily.
You can try string is list $var1 but that will accept both of these forms - it will only return false on something that can't syntactically be interpreted as a list, eg. because there is an unmatched bracket like "aa { bb".
I want to learn how to add spaces in variable names.
I know that a lot languages prevent me from doing this, but I believe that there is a trick to do this because I saw someone did it in MQL5
A MetaTrader Terminal allows to show a UI-Dialogue Panel for MMI-assisted setting values for input and extern variables declared in { Expert Advisor | Technical Indicator | Script } code, during a code-execution launch.
( Ref. a picture below ): .
If you really want to be evil you can sometimes use the left-to-right mark, U+200E which looks like a regular space but is generally not considered whitespace. Different languages and/or specific platforms may behave differently.
This trick seems to work in C# and apparently you can do similar things in ruby.
I tried this using g++ and luckily for everyone's sanity it is not allowed:
foo.cc:5:10: error: non-ASCII characters are not allowed outside of literals and identifiers
int a<U+200E> b = 3;
Please don't do this outside of pranks and April fool's day jokes.
In C++ you can't put spaces in variable names but you can get what you want using a std::map.
For example:
#include <map>
#include <string>
int main()
{
std::map<std::string, std::string> vars;
vars["Time Frame"] = "15 minutes";
vars["Indicator Period"] = "16";
// ... etc
}
The std::map is an associative container that maps one std::string onto another.
Depending on how you intend to use the map you may also want to consider using an std::unordered_map which should have higher performance but will not keep the keys sorted and may have a higher memory usage.
As much as I know, there isn't any option to add spaces to variables name.
The trouble with using spaces in names (whether filenames, variable names or something else) is that you need to have some other mechanism for determining what is part of this name and what is part of the next section of code. Your sample looks like a form, so that has it's own formatting and structure.
SQL does allow you to "quote" variable names with either [name with space] or with backticks `name with space`.
Most other languages do not allow spaces in variable names, because any whitedspace is considered a separator for different lexical unit [different name/word/variable]. There is no way you can change this, as it would alter the meaning of "normal code". Most languages do allow/use _ as a "space in names" character.
Of course, if you have "variables" that are your own construct, read from for example a database or file, you can use your own syntax, and use for example std::map<std::string, sometype> or std::unordered_map<std::string, sometype> to connect the string from your data to the corresponding value.
Spaces (white space) are used in C++ to isolate keywords and variable names, thus they cannot exist in a variable name or the compiler will treat the text as multiple identifiers.
Example - valid: static const unsigned int my_variable = 6U;
If there is a space between my and variable how does the compiler know which is the variable name? If there are two variables here, it doesn't make sense.
Also, as you can see, there may be more than one keyword in a statement.
I find a solution .In Mql5 , when you add a comment next to the variable name , it will appear instead of the variable name .
See this image : http://prntscr.com/79vaae
I'm looking for some C++ library that would help to optimize memory usage by storing similar (not exact) strings in memory only once. It is not FlyWeight or string interning which is capable to store exact objects/strings only once. The library should be able to analyze and understand that, for example, two particular strings of different length have identical first 100 characters, this substring should be stored only once.
Example 1:
std::string str1 = "http://www.contoso.com/some/path/app.aspx?ch=test1"<br/>
std::string str2 = "http://www.contoso.com/some/path/app.aspx?ch=test2"<br/>
in this case it is obvious that the only difference in these two strings is the last character, so it would be a great saving in memory if we hold only one copy of "http://www.contoso.com/some/path/app.aspx?ch=test" and then two additional strings "1" and "2"
Example 2:
std::string str1 = "http://www.contoso.com/some/path/app.aspx?ch1=test1"<br/>
std::string str2 = "http://www.contoso.com/some/path/app.aspx?ch2=test2"<br/>
this is more complicated case when there are multiple identical substrings : one copy of "http://www.contoso.com/some/path/app.aspx?ch", then two strings "1" and "2", one copy of "=test" and since we already have strings "1" and "2" stored we don't need any additional strings.
So, is there such a library? Is there something that can help to develop such a library relatively fast? strings are immutable, so there is no need to worry about updating indexes or locks for threadsafety
If strings have common prefix the solution may be - using radix tree (also known as trie) (http://en.wikipedia.org/wiki/Radix_tree) for string representation. So you can only store pointer to tree leaf. And get whole string by growing up to tree root.
hello world
hello winter
hell
[2]
/
h-e-l-l-o-' '-w-o-r-l-d-[0]
\
i-n-t-e-r-[1]
Here is one more solution: http://en.wikipedia.org/wiki/Rope_(data_structure)
libstdc++ implementation: https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a00223.html
SGI documentation: http://www.sgi.com/tech/stl/Rope.html
But I think you need to construct your strings for rope to work properly. Maybe found longest common prefix and suffix for every new string with previous string and then express new string as concatenation of previous string prefix, then uniq part and then previous string suffix.
For example 1, what I can come up with is Radix Tree, a space-optimized version from Trie. I did a simple google and found quite a few implementations in C++.
For example 2, I am also curious about the answer!
First of all, note that std::string is not immutable and you have to make sure that none of these strings are accidentally modified.
This depends on the pattern of the strings. I suggest using hash tables (std::unordered_map in C++11). The exact details depend on how you are going to access these strings.
The two strings you have provided differ only after the "?ch" part. If you expect that many strings will have long common prefixes where these prefixes are almost of the same size. You can do the following:
Let's say the size of a prefix is 43 chars. Let s be a string. Then, we can consider s[0-42] a key into the hash table and the rest of the string as a value.
For example, given "http://www.contoso.com/some/path/app.aspx?ch=test1" the key would be "http://www.contoso.com/some/path/app.aspx?" and "ch=test1" would be the value. if the key already exists in the hash table you can just add the value to the collection of values associated with key. Otherwise, add the key/value pair.
This is just an example, what the key is and what the value is depend on how you are going to access these strings.
Also if all string have "=test" in them, then you don't have to store this with every value. You can just store it once and then insert it when retrieving a string. So given the value "ch1=test1", what will be stored is just "ch11". This depends on the pattern of the strings.
Consider the following Emacs Lisp code, which defines a customizable variable that can either be a literal string or a regular expression:
(defcustom myvar "" "String or regexp"
:type '(choice (string :tag "String")
(regexp :tag "Regexp")))
This works just fine in the Custom interface (customize-variable 'myvar), but it then becomes impossible to tell whether the variable was set to a string or a regular expression. Even the Custom interface thinks it's a string no matter what. If you set the variable to a regexp using Custom and then close and reopen the Custom buffer for the variable, it will once again say it's a string.
So, is there any way to disambiguate this, to ensure that when the variable is set to a regexp through Custom, my code can determine that it's meant to be a regexp and not a simple string?
Ideally, I would like some sort of mechanism to have the string be stored internally as (cons 'string VALUE), where VALUE is the string that the user types in, and similarly have the regexp stored internally as (cons 'regexp VALUE).
Edit
From my searching, I've found the :value-to-internal and :value-to-external properties that you can supply to define-widget, but I can't figure out how to use them in a way that doesn't cause an error when I try to customize the resulting variable.
Rephrasing my answer from help-gnu-emacs --
Do what you suggested: use a cons instead of a string.
You need some way to programmatically distinguish arbitrary text from text used as a regexp. You know that intention at customize time: the user chooses one or the other.
You need to make sure that the user choice results in different (distinguishable) values. A cons recording (a) the text and (b) the type/choice/use is a good way to do that.