Inner loops for column 2 in imacros - loops

I am having a problem in form filling. I have two column, both have data, I made a loop for that, but I want a inner loop for column 2, like first it select the row 2 from column 1 and then select data from column 2 until the column 2 over.
For example, I have 10 entries in column one and 20 entries in column 2
outer loop column 1
inner loop column 2
inner loop ends if data in column 2 not found
again repeat
Here is the code:
VERSION BUILD=10022823
TAB T=1
SET !DATASOURCE F:\tgif.csv
SET !LOOP 2
SET !DATASOURCE_LINE {{!LOOP}}
URL GOTO={{!COL1}}
SIZE X=1392 Y=863
WAIT SECONDS=2.797
DS CMD=CLICK X=589 Y=396 CONTENT=
WAIT SECONDS=2
DS CMD=KEY CONTENT={{!COL2}}
WAIT SECONDS=5
TAG POS=1 TYPE=BUTTON:SUBMIT FORM=ACTION:/ajax/updatestatus.php?av=100009092062416 ATTR=TXT:Post
WAIT SECONDS=5

For more complicated iMacro scripts (e.g. with looping and so forth), you can use the iMacro Firefox add-on to run Javascript scripts. Also, in general, for better control it's almost always better to use TAG that targets more specific element attributes (e.g. class, id, etc) instead of by position.
What you want to do sounds like it can be done through a nested loop. If firstField and secondField are arrays, then you could do something like:
for (var i=0, alength = firstField.length; i < alength; i++){
//select first column
for (var j=0, blength = secondField.length; j < blength; j++){
//select cell in second column, with the same first column #
}
}
To play iMacro code through javascript, you can use iimPlay:
iimPlay("CODE: " + m) //for mac, for windows, you can take out the "CODE: " part, if I remember correctly. Or it might be the other way around!
I'm revamping it, so the inclusion part isn't working yet (and some features haven't been added completely)...but I'm working on a javascript library to work with iMacros. You can see it here:
https://github.com/anonmily/iMacroLibrary
If you want, you can use segments of the code or just as help with how to use Javascript with iMacros. To use it, right now, you can just copy what's inside the iMacroLibrary.js document, then add on your own code afterwards. You can minify everything in the library after the "Define unsafewindow" section so that is' a single line, saving space. Then, you can use CSS selectors to select elements on the page and interact with them. You can also import and export CSV data too.
var Year = $M('.yearinput');
var Make = #M('.makeinput');
//or
var Year = $M('select',1); //the first dropdown (select) element
var Make = $M('select',2); //the second dropdown (select) element
Year.click();
Year.extract('TXT')
Make.extract('TXTALL'); //the same as Make.extractAll()
To export or import CSV data:
exportcsv = function(csvarray, filename);
importcsv = function(file_name, line_num, fields_num);
The older version of the library (before I started tweaking with it again...!) Is commit#: 8b6045ecf9559fa7c9e13492d69af067c86a61b5
It's a bit messy towards the end since that's where I put some code for testing, but you can see how it can be implemented that way. Just for reference!
P.S. For automation though, I've been playing around with the Python library Splinter, and it's actually easier to use than iMacros in some ways. The code is easier to write too! I've started to convert some of my old iMacros to Python because of that; there's definitely more power and flexibility. iMacros is great for simple tasks that can be easily/quickly recorded, in my opinion. For web scraping, Beautiful Soup is quite useful too. Also, I've heard about Selenium for web automation as well, though I've not tried it as of yet. Just throwing out some other options out there, just in case. I sure wish I'd known of them earlier!

Related

How to iterate over elements in selenium

Actually i want to read emails one by one in junk folder of "outlook:live" and mark emails "Not spam".
emails = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH,"//div[#class = 'xoCOIP8PzdTVy0T6q_uG6']")))
This xpath matches 400 instances. I want to make a loop to select one email at a time like select first email, click on the div and perform action and then 2nd email and so on. I'm trying this
emails = WebDriverWait(driver,
5).until(EC.element_to_be_clickable((By.XPATH,"//div[#class =
'xoCOIP8PzdTVy0T6q_uG6']")))
for count in range(0,len(emails)):
(emails)[count+1].click()
Please help me know where im doing wrong. Thanks in advance
It appears that the function you're using to return the clickable elements is only returning a single element, so you'll have to use a different function, make a change in your logic, etc.
For instance, you could use Selenium's find_elements_by_xpath("//div[#class = 'xoCOIP8PzdTVy0T6q_uG6']") which will return a list of WebElement object(s) if the element(s) are found, or an empty list if the element(s) is not found. This will, of course, not take into consideration the possibility of the elements not being completely loaded on the page. In my experience, just slapping a time.sleep(10) after you open the page is "'good enough".
I recommend making sure your elements can be discovered and interacted with first to make sure this isn't all in vain, if you haven't already.
Another option is to add another function, something like a elements_to_be_clickable() function, to the Expected Conditions source code.
From the Expected Condition documentation, I've done some research and it looks like the element_to_be_clickable() function only returns a single element. Moreover, from the source code, said function mainly makes use of the visibility_of_element_located() function. I believe you could follow similar logic to the element_to_be_clickable() function, but instead use the visibility_of_all_elements_located() function, in order to return multiple WebElements (since visibiilty_of_all_elements_located() returns a list of WebElements).

What's an efficient way to find the last web element on a web page using RSelenium?

I'm using RSelenium to automatically scroll down a social media website and save posts. I want to find the last instance of a web element (specifically, the post dates), but it's taking unacceptably long using my current method (using findElements() to return all post dates then extracting the last one - see code below) if I've scrolled a long way down the page.
Can anyone recommend a fast way to find the last web element (specifically, the post date) on a web page? For example, is there a way you can use findElement() (which searches for the first match) such that it starts from the bottom of the page rather than the top? Any suggestions welcome.
Here's a trivial example of my code, but it takes an unacceptably long time if I've scrolled a long way down the page.
# Load webpage of interest
library(RSelenium)
library(rvest)
rD = rsDriver(browser = "firefox")
remDr = rD[["client"]]
url = paste0("https://stocktwits.com/symbol/NZDCHF")
remDr$navigate(url)
# Scroll down page three times, loading new content each time.
for (i in 1:3) { #Only scrolling 3 times for illustration
remDr$executeScript("window.scrollTo(0,document.body.scrollHeight);")
Sys.sleep(2) #delay by 3sec to give chance to load
}
# Get date of last post. WORKS BUT TAKES FOREVER IF I'VE SCROLLED MANY TIMES
e = remDr$findElements("css", ".message-date")
last_date = e[[length(e)]]$getElementText()
I found a messy workaround to solve the above. Specifically, I used the below to get the last message (which included the date), then wrote a regular expression to extract the last date.
last_child = remDriver$findElement(using = "css selector",
value = ".messageli:last-child")
last_child = unlist(last_child$getElementText())

Issue reading .txt file in Matlab. I want to get an array from this file without the unnecessary info it contains

I'm having trouble reading a .txt file to get some data. I want to be able to change some of the values this data contains.
At first, I used this:
A=importdata('myfile.txt');
And got this cell array:
Now what I want is this:
1) Get rid of the headers (the information from cell 1 to 22). That could be easily done by simple indexing (creating a sub-array using just the info from cell 23 to the end of the file).
2) I want to separate the information into different cells, using these identifiers. But I don't know how to separate them into different cells of the array.
'# item bepoch ecode label onset diff dura b_flags a_flags enable bin'
3) Do the same in step 2 to fill those columns with the data in the rest of the cells.
I'm trying to use this approach, but I'm not getting the expected results.
If someone can help me, I'd be glad.
Have you tried dragging the file into the variable workspace window and using the data import wizard? It has some nice features that normally take care of what you are trying to do automatically. Unfortunately, it seems that your text file may have unconventional spacing, but Matlab may be able to handle it if you set the delimeter to ' ' or suchlike.

Paging with reverse cursors in appengine

I am trying to get forward and backwards pagination working for a query I have on my app.
I have started with the example at: https://developers.google.com/appengine/docs/python/ndb/queries#cursors
I would expect that example to do a typical forward/back pagination to create cursors that you can pass to your template in order to be used in a subsequent request for the page after/before the current one. But what it is doing is getting cursors for the same page, one from the beginning and the other from the end (if I have understood correctly).
What I want is a cursor to the beginning of the following page, and a cursor to the beginning of the previous page, to use in my UI.
I have managed to almost get that with the following code, based on the mentioned example:
curs = Cursor(urlsafe=self.request.get('cur'))
q = MyModel.query(MyModel.usett == usett_key)
q_forward = q.order(-MyModel.sugerida)
q_reverse = q.order(MyModel.sugerida)
ofus, next_curs, more = q_forward.fetch_page(num_items_page,
start_cursor=curs)
rev_cursor = curs.reversed()
ofus1, prev_curs, more1 = q_reverse.fetch_page(num_items_page,
start_cursor=rev_cursor)
context = {}
if more and next_curs:
context['next_curs'] = next_curs.urlsafe()
if more1 and prev_curs:
context['prev_curs'] = prev_curs.reversed().urlsafe()
The problem, and the point of this question, is that I use more and more1 to see if there is a next page. And that is not working in the backwards sense. For the first page, more1 is True, in the second page more1 is False, and subsequent pages give True.
I would need something that gives False for the first page and True for every other page. It seems like this more return value is the thing to use, but maybe I have a bad Query setup, or any other thing wrong.
Thanks everyone!
Edit: Since I didn't find a simple solution for this, I switched to using ndbpager.
There's no such thing.
You know thats theres (at least) one page before the current page if you started the query with a cursor (the first page usualy dosnt have a cursor).
A common trick to access the previous page is inverting the sort-order.
If you have a list, sorted by creationdate desc, you could take the creationdate of the first element of your current page, query for elements with creationdate < this creationdate using inverted sort order. This will return the oldest elements which are newer then the given creationdate. Flip the list of retrived elements (to bring them into the correct order again) and there you have the elements of the page before, without using a cursor.
Note: this requires the values of your sortorder beeing distinct.
In some cases, its also possible to use a prebuild index allowing random-access to different pages, see https://bitbucket.org/viur/server/src/98de79b91778bb9b16e520acb28e257b21091790/indexes.py for more.
I have a workaround and not the best solution. it is baiscally redirecting back to the previous page.
Previous
I think PagedQuery has the capability but still waiting for someone to post a more comprehensive tutorial about it.

SSRS Dynamic String Expression

I am creating a report where I need to indent a row in a table based on a value from my result set for that row. For example if the value is 0 don't indent at all. If the value is 1 indent by 5 spaces. If 2 indent by a factor 10 spaces, etc.
The way I originally tried to do this is to use something like this:
= Space(Fields!depth.Value * 5) + Fields!name.Value
This works fine when rendered in visual studio but displaying it in the browser window when rendered through reporting services causes those spaces to be removed. I got around this problem before with this tip: http://mssqltips.com/tip.asp?tip=1286.
Any suggestions on how to dynamically control this indentation? I want to be able to do this dynamically with out hard coding numerous IF statements as im trying to make this report flexible enough that I can get any number back for this value.
You could try setting the left padding on the cell in question to an expression like this:
=CStr(2 * Fields!depth.Value) + "pt"
You might have to play with the multiplier since it's points rather than spaces.

Resources