I'm new to Erlang and this is a question I didn't get a proper answer surfing through the internet for several days.
I want to code something as shown in following code segment (consider it as pseudo code) :
Check =false;
lists:foreach(fun(Row) ->
if somecondition ->
Check = true;
true -> ok
end
end, RowList)
At the end I need to get the value of variable Check. As in Erlang we can't re-"assign" a value to a variable, how can I get the value of Check at the end of the code block shown above ?
I think you can use this lists:any/2.
http://www.erlang.org/doc/man/lists.html#any-2
lists:any(fun(Row) -> somecondition end, RowList).
The generic way to go through a list and modify a value for each element is to use lists:foldl/3 http://www.erlang.org/doc/man/lists.html#foldl-3. For your specific example it is easier and shorter to use lists:any/2 as above.
Related
I am new to IDL and find the KEYWORD_SET difficult to grasp. I understand that it is a go no go switch. I think its the knocking on and off part that I am having difficulty with. I have written a small program to master this as such
Pro get_this_done, keyword1 = keyword1
WW=[3,6,8]
PRINT,'WW'
print,WW
y= WW*3
IF KEYWORD_Set(keyword1) Then BEGIN
print,'y'
print,y
ENDIF
Return
END
WW prints but print, y is restricted by the keyword. How do I knock off the keyword to allow y to print.
Silly little question, but if somebody can indulge me, it would be great.
After compiling the routine, type something like
get_this_done,KEYWORD1=1b
where the b after the one sets the numeric value to a BYTE type integer (also equivalent to TRUE). That should cause the y-variable to be printed to the screen.
The KEYWORD_SET function will return a TRUE for lots of different types of inputs that are basically either defined or not zero. The IF loop executes when the argument is TRUE.
Keywords are simply passed as arguments to the function:
get_this_done, KEYWORD1='whatever'
or also
get_this_done, /KEYWORD1
which will give KEYWORD1 the INT value of 1 inside the function. Inside the function KEYWORD_SET will return 1 (TRUE) when the keyword was passed any kind of value - no matter whether it makes sense or not.
Thus as a side note to the question: It often is advisable to NOT use KEYWORD_SET, but instead resort to a type query:
IF SIZE(variable, /TNAME) EQ 'UNDEFINED' THEN $
variable = 'default value'
It has the advantage that you can actually check for the correct type of the keyword and handle unexpected or even different variable types:
IF SIZE(variable, /TNAME) NE 'LONG' THEN BEGIN
IF SIZE(variable, /TNAME) EQ 'STRING' THEN $
PRINT, "We need a number here... sure that the cast to LONG works?"
variable = LONG(variable)
ENDIF
I have a function that validates a url based on input from a user. The way the function is set up, if the url doesn't validate (either because it doesn't exist or because it is a duplicate) the function simply ends.
How do I make it so that if the url isn't validated, the user goes back to the input dialogue to start the validation process over again instead of just ending the function?
exfun <- function(){
x <- toupper(readline("Do you want to do the function? Y/N......."))
if (x == "Y"){
writeLines("This is where the function body would be, but it's huge so for the sake of this StackExchange question, we'll just make it a simple thing")
} else
writeLines("Well then why did you start the function? We'll try this again")
#This is where I would like the function to return to the "x<-...." line.
There are a few places where I would like to be able to "return to line X" as there are at least two validation points. I have it set up as a series of if else arguments which else into a message. How can I make it else into a message and bring the user back to the beginning/a previous validation test?
I fiddled with the repeat function, but couldn't get it to return from if else correctly.
I'm not really answering your question, but I'll give you an example that might help you (and probably someone will give a hint to improve this).
You can set a while loop and put conditions to continue the loop or to end it, simply like this:
i <- 1
while (T) {
print(i)
i <- i + 1
if (i==5) {
print("NEXT")
next
}
if (i==10) break
}
As you see, the if with next conditions do something in your code, and keep running it after the command print("NEXT"). Also, the break is inside a condition to stop your loop.
I hope it helps, because with your example is difficult to give a full answer.
Is it possible to return multiple values from a function?
I want to pass the return values into another function, and I wonder if I can avoid having to explode the array into multiple values
My problem?
I am upgrading Capybara for my project, and I realized, thanks to CSS 'contains' selector & upgrade of Capybara, that the statement below will no longer work
has_selector?(:css, "#rightCol:contains(\"#{page_name}\")")
I want to get it working with minimum effort (there are a lot of such cases), So I came up with the idea of using Nokogiri to convert the css to xpath. I wanted to write it so that the above function can become
has_selector? xpath(:css, "#rightCol:contains(\"#{page_name}\")")
But since xpath has to return an array, I need to actually write this
has_selector?(*xpath(:css, "#rightCol:contains(\"#{page_name}\")"))
Is there a way to get the former behavior?
It can be assumed that right now xpath func is like the below, for brevity.
def xpath(*a)
[1, 2]
end
You cannot let a method return multiple values. In order to do what you want, you have to change has_selector?, maybe something like this:
alias old_has_selector? :has_selector?
def has_selector? arg
case arg
when Array then old_has_selector?(*arg)
else old_has_selector?(arg)
end
end
Ruby has limited support for returning multiple values from a function. In particular a returned Array will get "destructured" when assigning to multiple variables:
def foo
[1, 2]
end
a, b = foo
a #=> 1
b #=> 2
However in your case you need the splat (*) to make it clear you're not just passing the array as the first argument.
If you want a cleaner syntax, why not just write your own wrapper:
def has_xpath?(xp)
has_selector?(*xpath(:css, xp))
end
I try to filter nodes :
user = g.v(42);
g.idx('comparisons')[[id:Neo4jTokens.QUERY_HEADER + '*']]
.filter{
if (it.out('COMPARED_VALUE1').in('VOTED').in('VOTES').next().equals(user))
{
return true;
}
return false;
}.count();
I don't really understand how pipes works, but I understand that the next() breaks something in the filter "loop".
I should get 2 results, but I get none.
Regards,
I might need to amend my answer as I could require more specifics on what you are trying to achieve (as #Michael also requested), but if you think your problem is with next(), then consider the following:
user = g.v(42);
g.idx('comparisons')[[id:Neo4jTokens.QUERY_HEADER + '*']]
.filter{it.out('COMPARED_VALUE1').in('VOTED').in('VOTES').next().equals(user)}.count();
First, note above that your filter closure can immediately reduce to that (which will yield the same error, of course). Given that filter closure you are assuming that a user vertex will come out of the pipeline when you next(). That may not be the case. As such, I would re-write the filter closure as:
user = g.v(42);
g.idx('comparisons')[[id:Neo4jTokens.QUERY_HEADER + '*']].filter{
def p = it.out('COMPARED_VALUE1').in('VOTED').in('VOTES')
p.hasNext() ? p.next().equals(user) : false
}.count();
That should likely solve your problem right there given the assumption that you only need to evaluate the first item in the pipeline p which is effectively what you were doing before. I wonder if you couldn't simply use except/retain pattern here to get your answer as it is a bit less convoluted:
user = g.v(42);
g.idx('comparisons')[[id:Neo4jTokens.QUERY_HEADER + '*']]
.out('COMPARED_VALUE1').in('VOTED').in('VOTES').retain([user])
.count();
Hopefully something here puts on you on the right track to your answer.
What do you want to achieve?
Sorry my gremlin knowledge is close to zero these days.
In cypher it would probably look like this
START user=node(42), comp=node:comparisons("id:*")
MATCH comp-[:COMPARED_VALUE1]->()<-[:VOTED*2]-(user)
RETURN count(*)
We wrote some Watir that would recursively look through a page's frames until it found the element you were asking for, and it would then return it to you. It doesn't seem like we can do this with Watir-WebDriver.
What we used to do:
So essentially we'd run something like:
findButton(:id, "Login_button")
And we'd loop through all the frames in the page, looking for this button.
def findButton(desc, b = #browser)
# look for object in main page
if b.button(desc).exist?
obj = b.button(desc)
#return and be done.
else
# look for object in frames
count = b.document.frames.length
(1..count).each do |i|
if b.frame(:index,i).button(desc).exist?
obj = b.frame(:index,i).button(desc)
break
end
end
if obj == nil
(1..count).each do |i|
obj = find(desc, b.frame(:index,i))
if obj != nil
break
end
end
end
end
if obj == nil && b == #browser
raise "Can't find button with descriptor #{desc}"
end
obj
end
We'd then use the element object returned:
findButton(:id, "login_button").click, for example.
Why it doesn't seem like we can anymore
So now we're evaluating Watir-WebDriver and the document element doesn't appear to be part of the Watir browser object anymore... but that's okay, right? So then I went and looked through the frames, collection:
browser = Watir::Browser.new :ie
{......}
browser.frames
First off, Browser.frames takes about 2-3 seconds to return any data, even when there's only one frame (Latest watir-webdriver Gem as of today's date, Ruby 193p0, and IE9). Secondly, it doesn't seem like frame object that is returned actually contains the element access I need. browser.frames[1].button(:id, "Login_Button") returns a variety of errors, depending on what I'm looking for.
It almost seems like this exposes a WebDriver limitation that Watir-WebDriver was hoping to work around, in that WebDriver just doesn't resemble a DOM structure, and elements don't always have the proper "Types" that is familiar to Watir, and in fact to the DOM itself.
Some might say it's silly to loop through frames looking for an element, but it's just one of those times where it's best if I have that capability. Our application uses anywhere from 3-5 frames at any given moment, and you can't always predict what frame or what order an element might be in.
Have I missed something? Am I not understanding a fundamental principle of Watir-WebDriver?
There doesn't seem to be a problem with the watir-webdriver API. For example:
require 'watir-webdriver'
def find_element_in_all_frames browser, &block
element = block.call browser
return element if element.exists?
browser.frames.each do |frame|
result = find_element_in_all_frames frame, &block
return result if result
end
return nil
end
Watir::always_locate = false
browser = Watir::Browser.start 'http://www.w3schools.com/html/tryit.asp?filename=tryhtml_frame_mix'
element = find_element_in_all_frames(browser) { |b| b.h3(:text => 'Frame A') }
puts element.text
browser.close
works completely fine, and returns the correct element.
When running with Watir::always_locate set to true, it takes about 5 seconds, with it set to false, about 2 seconds.
You'd use it as:
element = find_element_in_all_frames(browser) { |b| b.button(:id :> "login_button") }
element.click
I don't think this time is unreasonable as the tool is basically switching contexts multiple times to find the element.
If you really want things to work better, it's time to rewrite your app without frames.