Let's put it via an intuitive example.
I don't want others to modify my source code, so I put a statement in my code:
if( hash_value_of(this_file) != "A_PRE-DEFINED_HASH_VALUE" )
output("Aha! You modified my file!")
So in this case, the pre-defined hash value will affect the actual hash value of the source file at the output stage. It's like a strange loop so that I have to find a way to calculate a hash value beforehand that exactly matches the output.
It is of note that actually I don't care if this method can protect my source file at all. It is just an example. What of concern is how to calculate such a hash value beforehand.
Is there any algorithm matches the need? I am not expecting to get answers like "why do you even think about it?", "what's the usage?". It's only an algorithm discussion. Thanks for any contribution!
Related
I use Array.wrap(x) all the time in order to ensure that Array methods actually exist on an object before calling them.
What is the best way to similarly ensure a Hash?
Example:
def ensure_hash(x)
# TODO: this is what I'm looking for
end
values = [nil,1,[],{},'',:a,1.0]
values.all?{|x| ensure_hash(x).respond_to?(:keys) } # true
The best I've been able to come up with so far is:
Hash::try_convert(x) || {}
However, I would prefer something more elegant.
tl; dr: In an app with proper error handling, there is no "easy, care-free" way to handle something that may or may not be hashy.
From a conceptual standpoint, the answer is no. There is no similar solution as Array.wrap(x) for hashes.
An array is a collection of values. Single values can be stored outside of arrays (e.g. x = 42) , so it's a straight-forward task to wrap a value in an array (a = [42]).
A hash is a collection of key-value pairs. In ruby, single key-value pairs can't exist outside of a hash. The only way to express a key-value pair is with a hash: h = { v: 42 }
Of course, there are a thousand ways to express a key-value pair as a single value. You could use an array [k, v] or a delimited string `"k:v" or some more obscure method.
But at that point, you're no longer wrapping, you're parsing. Parsing relies on properly formatted data and has multiple points of failure. No matter how you look at it, if you find yourself in a situation where you may or may not have a hash, that means you need to write a proper chunk of code for data validation and parsing (or refactor your upstream code so that you can always expect a hash).
I have this parameter as an array. The array is big, 100 cells. It is a parameter that can be initiated in omnet.ini file. The cells with even numbers should get value A and odd numbers should get value B. How can I do this in an automated manner?
Is there a way besides having all odd and even indices initiated one by one manually?
Wildcards can be useful but I do not know how to use them to separate odd and even indices.
Thanks.
You can access the actual module index with the index operator. Combining this with the conditional operator ?: you can easily define the value:
**.myModule[*].myParameter = index % 2 == 0 ? "A" : "B"
I'm not aware of any feature like this. There are a number of work-arounds you could use:
Provide two parameters and select the correct one in code
Use the volatile keyword (probably not appropriate here)
Put the entire thing in your .ini file
I'd personally implement the first approach, that way you can use the wildcard to pass both parameters ([*].myNode.parameterEven and [*].myNode.parameterUneven) and then set the correct values in your array in a for loop.
However, you could also use the volatile keyword in your NED file, see the manual for more details. However, this approach mostly works well if you have different parameters depending on which node you are assigning it to. For this case I think the first approach is better.
The last alternative is just putting the entire thing in your .ini file, which may be useful if you want to parameterize the array later.
I have issue with technically deep question about loops in ruby.
I have algorithm that is executed sequentially for array of Boolean values and operate on one data structures.
def function(boolean, data_structure)
The key point is that the order of execution is most important thing because expression
function(true, data_structure);function(true, data_structure); function(false, data_structure)
will leave other result in data structure than expression
function(true, data_structure);function(false, data_structure); function(true, data_structure)
I spent some time trying with each loop, but I didn't get any problems as other result in data structure due execution similar expression as follow
[true, true, false ....].each do |value| function(value, data_structure) end
My question: in default ruby configuration is my each loop is the same like followed for loop?
for i in 0..array.size do function(array[i], data_structure) end
Because each loop makes the code much clearer and easier to modify and I was thinking about leave each expression rather than using for loop.
(Of course in my case I have a lot more code rather than calling only function()..)
Yes, it's identical. It will loop through the elements of the array, in order.
I'm learning ruby and have a few questions about some code I wrote for a newbie challenge. Purpose of challenge is to find country with largest population from an xml document.
I've included my code below. Questions I have are:
Is there a way to avoid having to initialize the #max_pop variable (#max_pop=0)?
Is there shorthand for combining the entire conditional block into 1 line?
Do I have to use instance vars #max_pop, #max_pop_country? Got error without them.
Which is more efficient:
Loop through each country and check if pop > max_pop (approach in code below)
Create pop hash (pop[:country]) and then find country with highest pop
Is there hash method to return key value pair for largest element in hash (to do 4.1)?
Source Code:
#max_pop=0
doc.elements.each("cia/country") do |country|
if country.attributes["population"].to_i > #max_pop
#max_pop=country.attributes["population"].to_i
#max_pop_country=country.attributes["name"]
end
end
puts "country with largest pop is #{#max_pop_country} with pop of #{#max_pop}
I am not familiar with rexml, but you ought to be able to simplify everything to something like this:
max_pop_elem = doc.elements.enum_for(:each, "cia/country").max_by { |c| c.attributes["population"].to_i }
max_pop_country = max_pop_elem.attributes["name"]
max_pop = max_pop_elem.attributes["population"].to_i
Yes, see above.
Yes, see above.
No. You should use local variables instead of instance variables when possible.
Don't worry about efficiency of CPU time until you have a slow program. Then use ruby-prof. Until then, just worry about the efficiency of coding time (do things the easy way).
Yes, just do key, value = hash.max_by{|k,v| v}.
In general, if you are going to be iterating over things you should learn about Ruby's Enumerable module. I made a reference sheet for it here.
I'm writing an algorithm that detects clones in source code. E.g. if there is a block like:
for(int i = o; i <5; i++){
doSomething(abc);
}
...and if this block is repeated somewhere else in the source code it will be detected as a clone. The method I am using at the moment is to create hashes for lines/blocks and compare them with hashes of other lines/blocks in the same source to see if there are any matches.
Now, if the same block as above was to be repeated somewhere with only the argument of doSomething different, it would not be detected as a clone even though it would appear very much like a clone to you and me. My algorithm detects exact matches but doesn't detect matching blocks where only the argument is different.
Could anyone suggest any ways of getting around this issue? Thanks!
Here's a super-simple way, which might go too far in erasing information (i.e., might produce too many false positives): replace every identifier that isn't a keyword with some fixed name. So you'd get
for (int DUMMY = DUMMY; DUMMY<5; DUMMY++) {
DUMMY(DUMMY);
}
(assuming you really meant o rather than 0 in the initialization part of the for-loop).
If you get a huge number of false positives with this, you could then post-process them by, for instance, looking to see what fraction of the DUMMYs actually correspond to the same identifier in both halves of the match, or at least to identifiers that are consistent between the two.
To do much better you'll probably need to parse the code to some extent. That would be a lot more work.
Well if you're going todo something else then you're going to have to parse to code at least a bit. For example you could detect methods and then ignore the method arguments in your hash. Anyway I think it's always true that you need your program to understand the code better than 'just text blocks', and that might get awefuly complicated.