In omnet++, would an indexing in the omnetpp.ini file like this be ok:
*.Member[0].numTcpApps = 2
*.Member[1..numberOfMembers].numTcpApps = 1
the parameter numberOfMembers has been specified in the .ned file as a usual integer variable. It is initialized to some value, e.g. 10.
What happens, if my numberOfMembers variable is set to only 1. In this case I should only have one Member (Member[0]). What happens to the second entry of the .ini file then?
One cannot use the value of a NED parameter in omnetpp.ini. However, you may achieve your goal using wildcard patterns in omnetpp.ini.
Let's assume that a network is defined in .ned as:
network ExampleNetwork
{
parameters:
int numberOfMembers;
submodules:
Member[numberOfMembers] : SomeMemberType;
// ...
}
Then in omnetpp.ini one can control the network. For example, to set numTcpApps = 2 for Member[0] only, and numTcpApps = 1 for all other submodules one should write:
*.numberOfMembers = 10
*.Member[0].numTcpApps = 2
*.Member[*].numTcpApps = 1 # i.e. Member[1], Member[2], ..., Member[9]
Take care of the order of entries in omnetpp.ini, because:
The order of entries is very important with wildcards. When a key matches several wildcard patterns, the first matching occurrence is used.
As a consequence, the following order of entries:
*.numberOfMembers = 10
*.Member[*].numTcpApps = 1 # i.e. Member[0], Member[1], Member[2], ..., Member[9]
*.Member[0].numTcpApps = 2
will set numTcpApps = 1 for all submodules. The last line is not taken into account because Member[0] has been already set by the entry Member[*].
Related
I have a SOAP node, that retrieve information from a URL in a tree structure.
Then i have a compute node to define each environment variable to each namespace variable of the SOAP retrieve.
And finally, i have a mapping node, to move the content to my message assembly structure in XML.
The error its giving me it's this (IN THE COMPUTE NODE):
I have a structure like this:
ListDocs
Description
DocType
ListTypes
Attribute
Lenght
Description
Nature
Required
ListDocs
Description
DocType
ListTypes
Attribute
Lenght
Description
Nature
Required
ListDocs
Description
DocType
ListTypes
Attribute
Lenght
Description
Nature
Required
The problem is that, when i do the definition of the variables, I do it like the code below, in the COMPUTE NODE:
WHILE I < InputRoot.SOAP.Body.ns:obterTiposDocProcessosResponse.ns:return.ns75:processo.ns75:listaTiposDocumentos
DO
SET Environment.Variables.XMLMessage.return.process.listDocs.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:description;
SET Environment.Variables.XMLMessage.return.process.listDocs.tipoDocumento = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:DocType;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.attribute = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:listTypes.ns75:atribbute;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.lenght = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:listTypes.ns75:lenght;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:listTypes.ns75:description;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.nature = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:listTypes.ns75:nature;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.required = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs.ns75:listTypes.ns75:required;
SET I = I+1;
END WHILE;
BUT, in my XML final structure, it only prints the values of my first listDocs, and i want to print all of my listDocs structures.
NOTE: WITH THE WHILE LIKE THIS, IT DOESN'T EVEN WORK. I HAVE TO REMOVE THE WHILE TO PRINT THE FIRST listDocs like i said Above.
Any help?
I NEED HELP TO LOOP THE STRUCTURES, WITH A WHILE OR SOMETHING.
You should try to use the following synthax :
DECLARE I INTEGER 1;
DECLARE J INTEGER;
J = CARDINALITY(InputRoot.SOAP.Body.ns:obterTiposDocProcessosResponse.ns:return.ns75:processo.ns75:listaTiposDocumentos[])
WHILE I <= J DO
SET Environment.Variables.XMLMessage.return.process.listDocs.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:description;
....
END WHILE;
You only missed the CARDINALITY function to get the number of elements, and also the [] to define the table, and then using this [I] while accessing the elements
Note : in my sample above, the environment will be overridden at each iteration of the loop, so only the last record will be printed. You can use the [I] in the output as well if you want to construct a table in output, or you can use the following code to push each message to the output terminal (this means you have one message in input, and 3 message coming out of the output terminal)
PROPAGATE TO TERMINAL 'Out';
So for example, based on your code, if you want to generate 3 messages based on your input containing multiple element :
DECLARE I INTEGER 1;
DECLARE J INTEGER;
J = CARDINALITY(InputRoot.SOAP.Body.ns:obterTiposDocProcessosResponse.ns:return.ns75:processo.ns75:listaTiposDocumentos[])
WHILE I <= J DO
SET Environment.Variables.XMLMessage.return.process.listDocs.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:description;
SET Environment.Variables.XMLMessage.return.process.listDocs.tipoDocumento = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:DocType;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.attribute = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:atribbute;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.lenght = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:lenght;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:description;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.nature = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:nature;
SET Environment.Variables.XMLMessage.return.process.listDocs.listTypes.required = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:required;
PROPAGATE TO TERMINAL 'Out';
END WHILE;
RETURN FALSE;
For your global information, the RETURN TRUE is the instruction "pushing" the message built in the ESQL code to the output terminal. If you use PROPAGATE instruction (same effect), you should RETURN FALSE to avoid sending an empty message after looping on your records. Another way to do it is to propagate on another terminal (i.e : 'out1'), and keep the return true. In this case, you would have all you records coming out from the out1 terminal, and a message going out of the output temrinal (due to the return true) once all the messages have been propagated (this might be useful in many situations)
So the key to understanding IIB and ESQL is that you are looking at in memory Trees built from nodes.
Each Node has pointers/REFERENCEs to PARENT, NEXTSIBLING, PREVSIBLING, FIRSTCHILD and LASTCHILD Nodes.
Nodes also have FIELDNAME, FIELDNAMESPACE, FIELDTYPE and FIELDVALUE attributes.
And last but not least that you are building Output Trees by navigating Input Trees. The Environment Tree, which you are using, is a special long lasting Tree that you can both read from and write to.
So in your code InputRoot.SOAP.Body.ns75:processo.ns75:listDocs can be thought of as shorthand for instructions to navigate to the ns75:listDocs Node. The dots '.' tell ESQL interpreter the name of the child Node of the current Node. If you were telling someone how to navigate the Nodes it would go something like this.
Start at InputRoot. InputRoot is a special Node that is automatically available to you in your ESQL Modules code.
Navigate to the first child Node of InputRoot that has the name SOAP
Navigate to the first child Node of SOAP that has the name Body
Navigate to the first child Node of Body that has the name listDocs and is in the ns75 namespace.
In the absence of a subscript ESQL assumes you want the first Node that matches the specified name ns75:listDocs and ns75:listDocs[1] both refer to the same Node.
This explains what was happening in your code. You were always navigating to the same listDocs[1] node in the InputRoot and Environment Trees.
#Jerem's code improves on what you were doing by at least navigating across the listDocs nodes in the Input tree.
For each iteration of the loop the subscript [I] gets incremented and thus it chooses a different listDocs Node. The listDocs Nodes are siblings and thus the code will access the first, second and third instance of the listDocs Nodes.
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[1] <-- Iteration I=1
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[2] <-- Iteration I=2
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[3] <-- Iteration I=3
To correct #Jerem's answer you'd need to use subscripts on the lefthand side of the statement as well. Picking the description field as an example you'd need to change your code as follows.
SET Environment.Variables.XMLMessage.return.process.listDocs[I].listTypes.description = InputRoot.SOAP.Body.ns75:processo.ns75:listDocs[I].ns75:listTypes.ns75:description;
Using subscripts is regarded as a performance no no. Imagine you had 10,000 listDocs this would result in each and every iteration of the loop walking down the tree over the InputRoot, SOAP, Body, ns75:processo Nodes and then across the listDocs sibling nodes until it found the ns75:listDocs[I] Node.
This means by the time we get round to processing ns75:listDocs[10000] it will have had to repetetively walked over all the other listDocs Nodes time and time again, In fact we can calculate it would have walked over (4 x 10,000) + ((10,000 x (10,000 + 1)) / 2) = 50,045,000 Nodes
So it's REFERENCE's to the rescue and also the answer to your question. Try a loop like this.
DECLARE ns75 NAMESPACE 'http://something.or.other.from.your.wsdl';
DECLARE InListDocsRef REFERENCE TO
InputRoot.SOAP.Body.ns75:processo.ns75:listDocs;
WHILE LASTMOVE(InListDocsRef) DO
DECLARE EnvListDocsRef REFERENCE TO Environment;
CREATE LASTCHILD OF Environment.Variables.XMLMessage.return.process AS EnvListDocsRef NAME 'listDocs';
SET EnvListDocsRef.description = InListDocsRef.ns75:description;
SET EnvListDocsRef.tipoDocumento = InListDocsRef.ns75:DocType;
SET EnvListDocsRef.listTypes.attribute = InListDocsRef.ns75:listTypes.ns75:atribbute;
SET EnvListDocsRef.listTypes.lenght = InListDocsRef.ns75:listTypes.ns75:lenght;
SET EnvListDocsRef.listTypes.description = InListDocsRef.ns75:listTypes.ns75:description;
SET EnvListDocsRef.listTypes.nature = InListDocsRef.ns75:listTypes.ns75:nature;
SET EnvListDocsRef.listTypes.required = InListDocsRef.ns75:listTypes.ns75:required;
MOVE InListDocsRef NEXTSIBLING REPEAT NAME;
END WHILE;
The code above only walks over 4 + 10,000 Nodes i.e. 10 thousand Nodes vs 50 million Nodes.
A couple of other useful things to know about setting references are:
To point to the last element you can use a subscript of [<]. So to point to the last ListItem in the aggregate MyList you would code Environment.MyList.ListItem[<]
You can use an asterisk * to set a reference to an element in the tree that you don't know the name of e.g. Environment.MyAggregate.* points to the first child of MyAggregate regardless of it's name.
You can also use asterisks * to choose an element irregardless of it's namespace InListDocsRef.*:listTypes.*:description
For anonymous namespaced elements use *:* but be very careful * and *:* are not the same thing the first means no namespace any element and the second means any namespace any element.
To process lists in reverse combine the [<] subscript with the PREVIOUSSIBLING option of MOVE.
So a chunk of code for reversing a list might go something like:
DECLARE MyReverseListItemWalkingRef REFERENCE TO Environment.MyList.ListItem[<];
WHILE LASTMOVE(MyReverseListItemWalkingRef) DO
CREATE LASTCHILD OF OuputRoot.ReversedList.Item NAME 'Description' VALUE MyReverseListItemWalkingRef.Desc;
MOVE MyReverseListItemWalkingRef PREVIOUSSIBLING REPEAT NAME;
END WHILE;
Learn how to use REFERENCES they are extremely powerful and one of your simplest options when it comes to performance.
I want to intersect multiple sets (2 or more). The number of sets to be intersected are passed as ARGV from command line. As number of sets are being passed from command-line. So the number of arguments in redis.call() function are uncertain.
How can I do so using redis.call() function in Lua script.
However, I have written a script which has algo like:
Accepting the number of sets to be intersected in the KEYS[1].
Intersecting the first two sets by using setIntersected = redis.call(ARGV[1], ARGV[2]).
Running a loop and using setIntersected = redis.call("sinter", tostring(setIntersected), set[i])
Then finally I should get the intersected set.
The code for the above algorithm is :
local noOfArgs = KEYS[1] -- storing the number of arguments that will get passed from cli
--[[
run a loop noOfArgs time and initialize table elements, since we don't know the number of sets to be intersected so we will use Table (arrays)
--]]
local setsTable = {}
for i = 1, noOfArgs, 1 do
setsTable[i] = tostring(ARGV[i])
end
-- now find intersection
local intersectedVal = redis.call("sinter", setsTable[1], setsTable[2]) -- finding first intersection because atleast we will have two sets
local new_updated_set = ""
for i = 3, noOfArgs, 1 do
new_updated_set = tostring(intersectedVal)
intersectedVal = redis.call("sinter", new_updated_set, setsTable[i])
end
return intersectedVal
This script works fine when I pass two sets using command-line.
EG:
redic-cli --eval scriptfile.lua 2 , points:Above20 points:Above30
output:-
1) "playerid:1"
2) "playerid:2"
3) "playerid:7"
Where points:Above20 and points:Above30 are sets. This time it doesn't go through the for loop which starts from i = 3.
But when I pass 3 sets then I always get the output as:
(empty list or set)
So there is some problem with the loop I have written to find intersection of sets.
Where am I going wrong? Is there any optimized way using which I can find the intersection of multiple sets directly?
What you're probably looking for is the elusive unpack() Lua command, which is equivalent to what is known as the "Splat" operator in other languages.
In your code, use the following:
local intersectedVal = redis.call("sinter", unpack(setsTable))
That said, SINTER is variadic and can accept multiple keys as arguments. Unless your script does something in addition to just intesects, you'd be better use that instead.
I have been looking at some Lua code recently and multiple times the author assigns a local variable, altering the local variable seemingly with the expected outcome of also altering the assigning variable as he does not do anything with the local variable after. Is this the case or do these changes not affect the original values.
Gene Construct
local gene = {}
gene.into = 0
gene.out = 0
gene.weight = 0.0
gene.enabled = true
gene.innovation = 0`
Code
function nodeMutate(genome)
if #genome.genes == 0 then
return
end
genome.maxneuron = genome.maxneuron + 1
local gene = genome.genes[math.random(1,#genome.genes)]
if not gene.enabled then
return
end
gene.enabled = false
local gene1 = copyGene(gene)
gene1.out = genome.maxneuron
gene1.weight = 1.0
gene1.innovation = newInnovation()
gene1.enabled = true
table.insert(genome.genes, gene1)
local gene2 = copyGene(gene)
gene2.into = genome.maxneuron
gene2.innovation = newInnovation()
gene2.enabled = true
table.insert(genome.genes, gene2)
end
Changes to gene may affect genome.genes[math.random(1,#genome.genes)] because gene is a reference. From the Lua Manual - Values and Types:
Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain these values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy.
This means that when you assign a variable to an object you copy the reference to that object, not the object itself.
For example:
local a = {1,2,3}
local b = a
b[1] = 'a'
The table a now contains {'a',2,3} because b is a reference to a.
From my reading of the code I'd think the following:
local gene1 = copyGene(gene) -- local copy, distinct from original 'gene'
-- (modifications of 'gene1')
table.insert(genome.genes, gene1) -- add modified copy to 'genome.genes'
So I'd guess that copyGene produces a copy of gene, meaning that gene isn't modified (only gene1, gene2). References to these are held in local variables and these references indeed go out of scope at the end of the block. But the modified copy is added to the list (/ array / sequence, whatever you want to call it) genome.genes which does produce an externally visible effect (because that variable – genome – comes in from outside).
My higher-level impression of the code is that genome.genes is a list of genes that may or may not be enabled. Each run through this function randomly picks one of these genes and if it is enabled, (1) disables it and (2) adds two modified enabled copies to the genome.genes (which may then be the base for new copies in later runs).
I'm having some trouble with Lua. The thing is: there are some Lua codes I know what they do but I didn't understood them, so if the professors ask me to explain them, I wouldn't be able to do it.
Can you help me with this?
I know this code separates the integer part from the decimal part of a number, but I didn't understand the "(%d*)(%.?.*)$" part.
int, dec = string.match(tostring(value), "(%d*)(%.?.*)$")
This code insert on a table all the data from a text file, which is written following this model entry {name = "John", age = 20, sex = "Male"). What I didn't understand is how do I know what parameters the function load needs? And the last parameter entry = entry, I don't know if I got exactly its meaning: I think it gets the text_from_file as a piece of Lua code and everything that is after entry is sent to the function entry, which inserts it on a table, is it right?
function entry(entrydata)
table.insert(data, entrydata)
end
thunk = load(text_from_file, nil, nil, {entry = entry})
thunk()
That's it. Please, if it's possible, help me understand these 2 pieces of Lua code, I need to present the whole program working and if a professor ask me about the code, I want to be sure about everything.
For the first question, you need to learn a little about lua patterns and string.match.
The pattern (%d*)(%.?.*)$ is comprised of two smaller ones. %d* and %.?.*. The $ at the end merely indicates that the matching is to be done till the end of string tostring(value). The %d* will match 0 or more numerical values and store the result (if found, otherwise nil) t the variable int.
%.? matches a literal . character. The ? means that the . may or may not be present. The .* matches everything and stores them into dec variable.
Similarly, for the second code segment, please go through the load() reference. You have the following text in your file:
entry {name = "John", age = 20, sex = "Male")
It is equivalent to executing a function named entry with the parameter (notice that I used parameter and not parameters) a table, as follows:
entry( {name = "John", age = 20, sex = "Male") )
The last parameter to load defines the environment for the loaded string. By passing {entry = entry}, you're defining an environment in which you have a function named entry. To understand it better, look at the changes in the following segment:
function myOwnFunctionName(entrydata)
table.insert(data, entrydata)
end
thunk = load(text_from_file, nil, nil, {entry = myOwnFunctionName})
Now, the custom environment passed to load will have a variable named entry which is actually the function myOwnFunctionName.
I am generating a unique and random alphanumeric string segment to represent certain links that will be generated by the users. For doing that I was approaching with "uuid" number to ensure it's uniqueness and randomness, but, as per my requirements the string shouldn't be more than 5 characters long. So I dropped that idea.
Then I decided to generate such a string using random function of ruby and current time stamp.
The code for my random string goes like this:-
temp=DateTime.now
temp=temp + rand(DateTime.now.to_i)
temp= hash.abs.to_s(36)
What I did is that I stored the current DateTime in a temp variable and then I generated a random number passing the current datetime as parameter. Then in the second line actually added current datetime and random number together to make a unique and random string.
Soon I found,while I was testing my application in two different machines and send the request at the same time, it generated the same string(Though it's rare) once after more than 100 trials.
Now I'm thinking that I should add one more parameter like mac address or client ip address before passing to_s(36) on temp variable. But can't figure out how to do it and even then whether it will be unique or nor...
Thanks....
SecureRandom in ruby uses process id (if available) and current time. You can use the urlsafe_base64(n= 16) class method to generate the sequence you need. According to your requirements I think this is your best bet.
Edit: After a bit of testing, I still think that this approach will generate non-unique keys. The way I solved this problem for barcode generation was:
barcode= barcode_sql_id_hash("#{sql_id}#{keyword}")
Here, your keyword can be time + pid.
If you are certain that you will never need more than a given M amount of unique values, and you don't need more than rudimentary protection against guessing the next generated id, you can use a Linear Congruentual Generator to generate your identificators. All you have to do is remember the last id generated, and use that to generate a new one using the following formula:
newid = (A * oldid + B) mod M
If 2³² distinct id values are enough to suit your needs, try:
def generate_id
if #lcg
#lcg = (1664525 * #lcg + 1013904223) % (2**32)
else
#lcg = rand(2**32) # Random seed
end
end
Now just pick a suitable set of characters to represent the id in as little as 6 character. Uppercase and lowercase letters should do the trick, since (26+26)^6 > 2^32:
ENCODE_CHARS = [*?a..?z, *?A..?Z]
def encode(n)
6.times.map { |i|
n, mod = n.divmod(ENCODE_CHARS.size)
ENCODE_CHARS[mod]
}.join
end
Example:
> 10.times { n = generate_id ; puts "%10d = %s" % [n, encode(n)] }
2574974483 = dyhjOg
3636751446 = QxyuDj
368621501 = bBGvYa
1689949688 = yuTgxe
1457610999 = NqzsRd
3936504298 = MPpusk
133820481 = PQLpsa
2956135596 = yvXpOh
3269402651 = VFUhFi
724653758 = knLfVb
Due to the nature of the LCG, the generated id will not repeat until all 2³² values have been used exactly once each.
There is no way you can generate a unique UUID with only five chars, with chars and numbers you have a basic space of around 56 chars, so there is a max of 56^5 combinations , aprox 551 million (Around 2^29).
If with this scheme you were about to generate 10.000 UUIDs (A very low number of UUIDs) you would have a probability of 1/5.000 of generating a collision.
When using crypto, the standard definition of a big enough space to avert collisions is around 2^80.
To put this into perspective, your algorithm would be better off if it generated just a random integer (a 32 bit uint is 2^32, 8 times the size you are proposing) which is clearly a bad idea.