Re: Launching Helium: A Selenium wrapper that makes web automation 50% easier

2013-12-16 Thread Michael Herrmann
On Monday, December 16, 2013 12:40:56 PM UTC+1, larry@gmail.com wrote:
...
> Is this open source?

No. We quit our daytime jobs to work on this project and need the income to 
sustain our development...
-- 
https://mail.python.org/mailman/listinfo/python-list


Launching Helium: A Selenium wrapper that makes web automation 50% easier

2013-12-16 Thread Michael Herrmann
Hi everyone,

I'm working for a startup called BugFree Software and would like to announce 
that today we're launching our second product!

Helium is a library that wraps around Selenium to simplify web automation. It 
does away with many of the technicalities involved with web scripting. For 
example: Here is a Selenium script. Can you guess what it does?

>>> ff = Firefox()
...
>>> text_area = ff.find_element_by_id("u_0_1q")
>>> text_area.send_keys("Hello World!")
>>> button = ff.find_element_by_class_name("_42g-")
>>> button.click()

Here is the same script rewritten using Helium:

>>> start_firefox()
...
>>> write("Hello World!", into="Update Status")
>>> click("Post")

Can you now guess what it does? That's right; It updates your Facebook status.

In an extended comparison that we were invited to write for the December issue 
of Professional Tester (professionaltester.com), we found that an example 
script automating Gmail took 66% fewer lines of code and 75% less effort using 
Helium than with Selenium alone.

You can find more information and download Helium from http://heliumhq.com. Any 
feedback would be highly appreciated.

Hoping to hear your thoughts and comments,
Michael Herrmann
heliumhq.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Packaging a proprietary Python library for multiple OSs

2013-12-05 Thread Michael Herrmann
On Thursday, December 5, 2013 4:26:40 PM UTC+1, Kevin Walzer wrote:
> On 12/5/13, 5:14 AM, Michael Herrmann wrote:
> If your library and their dependencies are simply .pyc files, then I 
> don't see why a zip collated via py2exe wouldn't work on other 
> platforms. Obviously this point is moot if your library includes true 
> compiled (C-based) extensions.

As I said, I need to make my *build* platform-independent.

Thanks,
Michael
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Packaging a proprietary Python library for multiple OSs

2013-12-05 Thread Michael Herrmann
On Thursday, December 5, 2013 3:09:32 PM UTC+1, Roy Smith wrote:
> >  1. Is it considered a bad idea in the Python community to ship one large 
> > Zip file with all dependencies?
> Yes.

I see. Unfortunately, the library's users may be non-technical and might not 
even have experience with Python. The easier the installation process, 
therefore, the better.

> > How do *you* prefer to obtain and install Python libraries?
> "pip install"

Thanks for this input.

> >  2. Is it possible to distribute the library in a form that allows for an 
> >  offline installation without administrator privileges using other tools, 
> >  such as setuptools?
> 
> You can use "pip --find-links" to point pip at a local repository of 
> packages.  That solves the offline part.  And the "without admin privs" 
> part is solved by setting up a virtualenv.

Both "pip --find-links" and "virtualenv" sound technically feasible but may be 
too difficult for my users (especially virtualenv).

> > A hard requirement is that I can only ship binary distributions of my 
> > library, as this is a proprietary product. I looked at Distutils and 
> > Setuptools, where the recommended approach seems to be to simply ship all 
> > sources.
> Keep in mind that shipping just the pyc files offers very weak 
> protection against people examining your code.  Google for "python 
> decompile" and you'll find a number of projects.  I'm looking at the 
> docs for uncompyle now, which says:
> > 'uncompyle' converts Python byte-code back into equivalent Python
> > source. It accepts byte-code from Python version 2.7 only.

Very interesting point. Thank you very much for pointing out uncompyle. I had 
always known that it was easy to decompile .pyc files, but hadn't imagined it 
to be that easy. I just tried uncompyle with some of our proprietary .pyc 
files. It took 5 minutes to set up and the results are near-perfect. Scary... 
:-S We might have to look into tools such as 
http://www.bitboost.com/#Python_obfuscator to obfuscate our code.

Thanks for the valuable insights!
Michael
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Packaging a proprietary Python library for multiple OSs

2013-12-05 Thread Michael Herrmann
On Thursday, December 5, 2013 11:56:16 AM UTC+1, rusi wrote:
> Wheel is the upcoming standard I think.
> http://www.python.org/dev/peps/pep-0427/

I hadn't known of Wheel - thanks for pointing it out!

-- 
https://mail.python.org/mailman/listinfo/python-list


Packaging a proprietary Python library for multiple OSs

2013-12-05 Thread Michael Herrmann
Hi everyone,

I am developing a proprietary Python library. The library is currently 
Windows-only, and I want to also make it available for other platforms (Linux & 
Mac). I'm writing because I wanted to ask for your expert opinion on how to 
best do this.

The library is currently shipped in the form of a Zip file. This archive 
contains the compiled Python code for the implementation of my library, plus 
all dependencies. By placing the Zip file on his PYTHONPATH, the customer can 
use the library from his Python scripts.

Shipping a Zip file with all dependencies included has the following advantages:

 * No internet access or administrator privileges are required to install the 
library.
 * The customer does not have to worry about installing / managing dependencies 
of my library.

It also has the disadvantage that the customer is not (easily) able to use his 
own versions of my library's dependencies.

Even though I am not generating an EXE, I am using py2exe to obtain the 
distributable Zip file for my library. This "hack" is very convenient, as 
py2exe allows me to simply say which packages I require and does the work of 
performing a dependency analysis of the required libraries for me. py2exe 
automatically generates the Zip file with my (compiled) library code, and all 
dependencies.

Unfortunately, py2exe is only available for Windows. I need to also be able to 
build it on Linux & Mac, hence change the build process to not use py2exe.

My questions are:

 1. Is it considered a bad idea in the Python community to ship one large Zip 
file with all dependencies? From what I have seen, it seems to be an unusual 
approach, at the least. How do *you* prefer to obtain and install Python 
libraries?
 2. Is it possible to distribute the library in a form that allows for an 
offline installation without administrator privileges using other tools, such 
as setuptools?

My insight into the state of the art in Python regarding these matters is 
limited, so I would appreciate advice from someone with more experience in the 
subject.

A hard requirement is that I can only ship binary distributions of my library, 
as this is a proprietary product. I looked at Distutils and Setuptools, where 
the recommended approach seems to be to simply ship all sources.

Many thanks!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-04-04 Thread Michael Herrmann
Hi everyone,

we just released the new version of our GUI automation tool with the improved 
API: http://www.getautoma.com/blog/Automa-1-5-1-window-switching. Thank you 
again for your help.

Best regards,
Michael

On Monday, March 25, 2013 8:29:23 PM UTC+1, Michael Herrmann wrote:
> Hello everyone, 
> 
> 
> 
> my name is Michael, I'm the lead developer of a Python GUI automation library 
> for Windows called Automa: http://www.getautoma.com. We want to add some 
> features to our library but are unsure how to best expose them via our API. 
> It would be extremely helpful for us if you could let us know which API 
> design feels "right" to you.
> 
> 
> 
> Our API already offers very simple commands for automating the GUI of a 
> Windows computer. For example:
> 
> 
> 
>   from automa.api import *
> 
>   start("Notepad")
> 
>   write("Hello World!")
> 
>   press(CTRL + 's')
> 
>   write("test.txt", into="File name")
> 
>   click("Save")
> 
>   click("Close")
> 
> 
> 
> When you execute this script, Automa starts Notepad and simulates key 
> strokes, mouse movements and clicks to perform the required commands. At the 
> moment, each action is performed in the currently active window. 
> 
> 
> 
> We do not (yet) have a functionality that allows you to explicitly switch to 
> a specific window. Such a functionality would for instance make it possible 
> to open two Notepad windows using the start(...) command, and copy text 
> between them.
> 
> 
> 
> One API design would be to have our start(...) function return a "Window" 
> (say) object, whose methods allow you to do the same operations as the global 
> functions write(...), press(...), click(...) etc., but in the respective 
> window. In this design, the example of operating two Notepad windows could be 
> written as
> 
> 
> 
>   notepad_1 = start("Notepad")
> 
>   notepad_2 = start("Notepad")
> 
>   notepad_1.write("Hello World!")
> 
>   notepad_1.press(CTRL + 'a', CTRL + 'c')
> 
>   notepad_2.press(CTRL + 'v')
> 
> 
> 
> The problem with this design is that it effectively duplicates our API: We 
> want to keep our "global" functions because they are so easy to read. If we 
> add methods to a new "Window" class that do more or less the same, we feel 
> that we are violating Python's principle that "There should be one - and 
> preferably only one - obvious way to do it."
> 
> 
> 
> An alternative design would be to make the window switching an explicit 
> action. One way of doing this would be to add a new global function, say 
> "switch_to" or "activate", that takes a single parameter that identifies the 
> window to be switched to. We could still have start(...) return a Window 
> object, that could then be passed to our function:
> 
> 
> 
>   notepad_1 = start("Notepad")
> 
>   notepad_2 = start("Notepad")
> 
>   switch_to(notepad_1)
> 
>   write("Hello World!")
> 
>   press(CTRL + 'a', CTRL + 'c')
> 
>   switch_to(notepad_2)
> 
>   press(CTRL + 'v')
> 
> 
> 
> Maybe our Window objects could also be used as context managers:
> 
> 
> 
>   notepad_1 = start("Notepad")
> 
>   notepad_2 = start("Notepad")
> 
>   with notepad_1:
> 
>   write("Hello World!")
> 
>   press(CTRL + 'a', CTRL + 'c')
> 
>   with notepad_2:
> 
>   press(CTRL + 'v')
> 
> 
> 
> As a final idea, switching could also be done as a method of the Window class:
> 
> 
> 
>   notepad_1 = start("Notepad")
> 
>   notepad_2 = start("Notepad")
> 
>   notepad_1.activate()
> 
>   write("Hello World!")
> 
>   press(CTRL + 'a', CTRL + 'c')
> 
>   notepad_2.activate()
> 
>   press(CTRL + 'v')
> 
> 
> 
> It would be extremely helpful for us if you could let me know which way of 
> using the API you would prefer. If you opt for an explicit version, how would 
> you call the respective method? "activate" / "switch_to" / "focus" or 
> something else?
> 
> 
> 
> Thank you so much!
> 
> 
> 
> Best wishes,
> 
> Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-28 Thread Michael Herrmann
On Thursday, March 28, 2013 1:42:35 AM UTC+1, Steven D'Aprano wrote:
> On Wed, 27 Mar 2013 02:34:09 -0700, Michael Herrmann wrote:
> 
> > On Tuesday, March 26, 2013 11:37:23 PM UTC+1, Steven D'Aprano wrote:
> >> 
> >> Global *variables* are bad, not global functions. You have one global
> >> variable, "the current window". So long as your API makes it obvious
> >> when the current window changes, implicitly operating on the current
> >> window is no more dangerous than Python's implicit operations on the
> >> current namespace (e.g. "x = 2" binds 2 to x in the current namespace).
> 
> > I'm generally wary of everything global, but you're right as long as no
> > (global) state is involved.
> 
> That comment surprises me. Your preferred API:
> 
> switch_to(notepad)
> write("Hello World!")
> press(CTRL + 'a', CTRL + 'c')
> 
> uses implied global state (the current window). Even if you avoid the use 
> of an actual global for (say) an instance attribute, it's still 
> semantically a global. Surely you realise that?

I do :-) You made the statement that global variables are bad, not global 
functions. I didn't want to agree completely with this comment, because if a 
global function refers to a global variable, I would consider it "bad" too. You 
correctly point out that our global functions would be exactly of that "bad" 
kind. Of course, it doesn't make sense to be too dogmatic about "bad", which is 
why I am considering the global functions as an option, for advantages they 
have despite being "bad".

> Not trying to be argumentative, I'm just surprised at your comment.

No offense taken :) I guess I just wasn't expressing myself clearly.

> > ...
> > After everybody's input, I think Design #2 or Design #4 would be the
> > best fit for us:
> > 
> > Design #2:
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > switch_to(notepad_1)
> > write("Hello World!")
> > press(CTRL + 'a', CTRL + 'c')
> > switch_to(notepad_2)
> > press(CTRL + 'v')
> 
> This is nice syntax for trivial cases and beginners whose needs are not 
> demanding, but annoying for experts who have more complicated 
> requirements. If this is the only API, experts who need to simultaneously 
> operate in two windows will be forced to write unproductive boilerplate 
> code that does nothing but jump from window to window.
> 
> 
> Well what do you know, even in the simple case above, you have 
> unproductive code that does nothing but jump from window to window :-)
> 
> I'm not against this API, I'm just against it as the *only* API.
> 
> > Design #4:
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > notepad_1.activate()
> > write("Hello World!")
> > press(CTRL + 'a', CTRL + 'c')
> > notepad_2.activate()
> > press(CTRL + 'v')
> 
> This is actually no different from #2 above, except that it uses method 
> call syntax while #2 uses function call syntax. So it has the same 
> limitations as above: it's simple for simple uses, but annoying for 
> complex use.
> 
> Neither API supports advanced users with complicated needs. A hybrid 
> approach, where you have function call syntax that operates on the 
> implicit current window, plus method call syntax that operates on any 
> window, strikes me as the best of both worlds. With a little forethought 
> in your implementation, you don't have to duplicate code. E.g. something 
> like this:
> 
> class WindowOps:
> def __init__(self, theWindow=None):
> self.theWindow = None
> 
> def press(self, c):
> win = self.getWindow()
> send_keypress_to(win)
> 
> def getWindow(self):
> if self.theWindow is None:
> return gTheTopWindow
> return self.theWindow
> 
> _implicit = WindowOps(None)
> press = _implicit.press
> # etc.
> del _implicit
> 
> This gives you the best of both worlds, for free: a simple API using an 
> implicit top window for simple cases, and a slightly more complex API 
> with an explicit window for advanced users.

I understand completely where you are coming from, however if we offer two ways 
of doing the same thing, people will start mixing the styles and things will 
get messy. A user commented above that this approach - offering gl

Re: Help me pick an API design (OO vs functional)

2013-03-28 Thread Michael Herrmann
On Wednesday, March 27, 2013 5:45:49 PM UTC+1, Ethan Furman wrote:
> On 03/27/2013 02:34 AM, Michael Herrmann wrote:
> > Design #2:
> >  notepad_1 = start("Notepad")
> >  notepad_2 = start("Notepad")
> >  switch_to(notepad_1)
> >  write("Hello World!")
> >  press(CTRL + 'a', CTRL + 'c')
> >  switch_to(notepad_2)
> >  press(CTRL + 'v')
> ...
> 
> Go with #2.  Not everything has to be a method.  len(), for example, is not a 
> method, even though it calls one.

That's a good point. I actually think #2 is the one we'll use.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-28 Thread Michael Herrmann
On Wednesday, March 27, 2013 2:56:55 PM UTC+1, Mitya Sirenef wrote:
> ...
> 
> I think alt-tab has to be special in any case. Regular alt-tab would act
> like the GOTO statement. As a programmer looking at a script you have no
> idea where you just alt-tabbed to without possibly looking through
> dozens of lines of previous code.
> 
> Keypresses that start a new window also seem pretty special to me.
> They're inherently special. After all, the essential function of a
> windowing system is when a new window is created, which means subsequent
> operations have an entirely different meaning, in a text editor 
> key will delete a character, in a file manager  key will delete a
> file!
> 
> But, as I mentioned, if you can get away with treating simple dialogs
> implicitly (and I don't see why you can't, at this point), that'd be the
> preferred way for me.

Ok. Thank you for your inputs!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-27 Thread Michael Herrmann
On Wednesday, March 27, 2013 12:44:49 PM UTC+1, Chris Angelico wrote:
> ...
> Not seeking to advocate this particular option, but it would be
> possible to make a single wrapper for all your functions to handle the
> focus= parameter:
> 
> def focusable(func):
>   @functools.wraps(func)
>   def wrapper(*args,focus=None):
>   if focus: focus.activate()
>   return func(*args)
>   return wrapper
> 
> Then you just decorate all your functions with that:
> 
> def write(string):
> # do something with the active window

Hi, sure, I wouldn't have copy-pasted the code and of course there are 
techniques to avoid code duplication. It's not so much what I'm worried about. 
What I'm worried about is that the concept of window-switching gets "smeared" 
over several other not-really related concepts such as clicking and typing. I 
feel it violates orthogonality: http://www.artima.com/intv/dry3.html is the 
best freely available resource I could find but I think it's best explained in 
The Pragmatic Programmer 
http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X.

Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-27 Thread Michael Herrmann
On Tuesday, March 26, 2013 11:37:23 PM UTC+1, Steven D'Aprano wrote:
> 
> Global *variables* are bad, not global functions. You have one global 
> variable, "the current window". So long as your API makes it obvious when 
> the current window changes, implicitly operating on the current window is 
> no more dangerous than Python's implicit operations on the current 
> namespace (e.g. "x = 2" binds 2 to x in the current namespace).

I'm generally wary of everything global, but you're right as long as no 
(global) state is involved. 

> I recommend you look at the random.py API. You have a Random class, that 
> allows the user to generate as many independent random number generators 
> as needed. And the module also initialises a private instance, and 
> exposes the methods of that instance as top-level functions, to cover the 
> 90% simple case where your application only cares about a single RNG.

I looked it up - I think this is a very good approach; to provide easy access 
to the functionality used in 90% of cases but still give users the flexibility 
to cover the edge cases.

After everybody's input, I think Design #2 or Design #4 would be the best fit 
for us:

Design #2: 
notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
switch_to(notepad_1) 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
switch_to(notepad_2) 
press(CTRL + 'v') 

Design #4: 
notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
notepad_1.activate() 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
notepad_2.activate() 
press(CTRL + 'v') 

Normally, I'd go for Design #4, as it results in one less global, is better for 
autocompletion etc. The thing with our library is that it tries to make its 
scripts as similar as possible to giving instructions to someone looking over 
their shoulder at a screen. And in this situation you would just say

   activate(notepad)

rather than

   notepad.activate().

So the problem lies in a difference between Python's and English grammar. For 
beauty, I should go with #2. For pragmatism, I should go with #4. It hurts, but 
I'm leaning towards #4. I have to think about it a little.

Thank you so much to everybody for your inputs so far!
Best,
Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-27 Thread Michael Herrmann
On Tuesday, March 26, 2013 11:01:08 PM UTC+1, Mitya Sirenef wrote:
> On 03/26/2013 10:59 AM, Michael Herrmann wrote:
>  > ...
>  > Forcing the library user to always use the "with ..." seems like 
> overkill though. I think the gained precision does not justify this 
> burden on the library user. Hm
> 
> I don't see why that's a big deal, I've used AHK extensively and in my
> experience you don't switch windows all that often. I think it's best to
> optimize to have easy to type and read commands while you're working in
> the same window.
> 
> I think you could argue that dialogs that belong to the main window
> should be handled implicitly, though. I think for other windows it'd
> definitely be good to use context managers, but for quick/simple dialogs
> it's too much hassle, although for large, complex dialogs that have
> inner tabs and require a lot of work, it again starts to make sense.
> 
> At the very least, for small dialogs it's sipmpler to do:
> 
> with press(CTRL + 's'):
>  write("test.txt", into="File name")
>  click("Save")

I think what the context manager approach really has going for itself is the 
syntactic structure it gives to scripts, that makes it easy to see what is 
going on in which window. Semantically, however, I think the fit of this 
approach has some rough edges: The fact that there needs to be some special 
treatment for ALT + TAB, that actions such as `press` "sometimes" return values 
that are needed to continue the script and so on. It really has its appeal, but 
I think it's a bit too special and intricate to be used by a broad audience.

> Calamities are of two kinds: misfortunes to ourselves, and good fortune 
> to others.

;-)

Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-27 Thread Michael Herrmann
On Tuesday, March 26, 2013 5:41:42 PM UTC+1, Dave Angel wrote:
> On 03/26/2013 10:40 AM, Michael Herrmann wrote:
> 
> > On Tuesday, March 26, 2013 3:13:30 PM UTC+1, Neil Cerutti wrote:
> >>
> >> Have you considered adding a keyword argument to each of your
> >> global functions, which is normally None, but allows a user to
> >> provide a prefered focus window?
> 
> >> enter_text("test.txt", focus=save_dialog)
> >> press_button(Savebutton, focus=save_dialog)
> 
> > It's an interesting new idea but I somehow feel it makes the existing 
> > functions too complicated. Also, having to add it to all existing, and 
> > future functions sounds a bit too cumbersome to me.
> 
> Perhaps Neil didn't make it clear enough.  I figure he meant a keyword 
> argument with an explicit default value of None.  (or if you followed my 
> earlier discussion, default value of focused)
> 
> That way your user can keep using the functions for when there's no 
> ambiguity, but add a focus= parameter only when needed.
> 
> To go back to my sample wrapper functions, they'd look something like 
> (untested):
> 
> def write(*args, focus=focused):
>  focus.write(*args)

I understood what you meant - I'm not so worried about the invocations, as of 
course the parameter can be omitted if there's a default value/behaviour. What 
I am worried about is the complexity this approach adds to several functions. 
Yes, you could argue that one keyword argument really isn't that much, but then 
you have to maintain and document it for all functions that have the new 
keyword parameter. In other words, a single functionality that is not needed 
90% of the time increases the complexity of several, not really related 
functions. I am very grateful for your suggestions! But I don't think adding 
this keyword parameter is the way to go for us.

Thanks,
Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-27 Thread Michael Herrmann
On Tuesday, March 26, 2013 4:16:57 PM UTC+1, Chris Angelico wrote:
> On Wed, Mar 27, 2013 at 1:59 AM, Michael Herrmann
> 
>  wrote:
> > save_dialogue = press(CTRL + 's')
> 
> Does every single API need to then consider the possibility of focus
> changing? How does the press() function know that this will (or might
> - if the file's already been named, Ctrl-S won't open a dlg) change
> focus? How does the caller know?

While I can see where it is coming from, I am also not a big fan of this idea. 

Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 2:41:38 PM UTC+1, Mitya Sirenef wrote:
> ... 
> At the __exit__, further commands are no longer routed to that window;
> if it was a nested context, window is switched to the outer context,
> WHEN there are commands in it (i.e. on the first command). This seems
> pretty intuitive to me:
> 
> with notepad1:
>  ^S
>  with notepad2:
>  ^S
>  write('something')
> 

> ...
>  > What I am most afraid of: that the window that's currently the 
>  > context "disappears":
> 
>  > notepad = start("Notepad")
>  > with notepad:
>  > press(ALT + TAB)
>  > write("Am I in Notepad now?")
> 
> 
> Alt-tab needs to be handled by a wrapper function that gives you the
> object of the window you've switched to:
> 
> otherwin = alt_tab()
> with otherwin:
>  ...
> 
> If window is changed within 'with' block, the rest of block should be
> ignored. Perhaps there could also be a way to switch this behaviour off,
> for the entire script or for current block only.
> 
> 
>  > What do you think of designs #3 and #4?
>  > ...
> 
> These are ok, too, but I feel it's much easier to send commands to a
> wrong window vs. context managers. The same command in a different
> window can have vastly different and dangerous effect. In other python
> code that's generally not common at all, and would be bad style:
> 
> lst = lst1
> lst.append('x')
> del lst[3]
> lst.insert(0, 'a')
> lst = lst2
> del lst[2]
> lst.append('y')
> lst = lst3
> lst.insert(0, 'x')
> lst += [1,2]
> 
> I think current window should also be acquired explicitly:
> 
> with get_current_window():
>  type("some kind of snippet")
> 
> For usage when a command should apply to all types of windows.

I was skeptical of your suggestion at first but trying it out on an example 
script made me see its appeal:

notepad_main = start("Notepad")
with notepad_main:
write("Hello World!")
save_dialogue = press(CTRL + 's')
with save_dialogue:
write("test.txt", into="File name")
click("Save")
click("Close")

Forcing the library user to always use the "with ..." seems like overkill 
though. I think the gained precision does not justify this burden on the 
library user. Hm
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 3:13:30 PM UTC+1, Neil Cerutti wrote:
> On 2013-03-25, Mitya Sirenef wrote:
> 
> > I think I would prefer context managers. I don't think it's a
> > big problem for win users because this behaviour would be one
> > of the first things documented in the start guide and would be
> > all over example scripts, so a new user missing or forgetting
> > it is not a realistic scenario.
> 
> 
> If window focus switching is really a rarity, and only done
> briefly then I agree that a context manager makes a nice and neat
> solution.
> 
> 
> But it's too powerful a generalisation for such a small corner
> case.
> 
> Have you considered adding a keyword argument to each of your
> global functions, which is normally None, but allows a user to
> provide a prefered focus window?
> 
> enter_text("test.txt", focus=save_dialog)
> 
> press_button(Savebutton, focus=save_dialog)

It's an interesting new idea but I somehow feel it makes the existing functions 
too complicated. Also, having to add it to all existing, and future functions 
sounds a bit too cumbersome to me. 

> (Those are just guesses at your API functions; sorry.)

No worries! Thank you for your suggestion!

Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 1:42:26 PM UTC+1, Dave Angel wrote:
> ...
> 
> Also, it seems that in this thread, we are using "window" both to refer 
> to a particular application instance (like Notepad1 and Notepad2), and 
> to refer to windows within a single application.
> 
> 
> 
> Anyway, if you're only automating a few specific apps, you're not likely 
> to run into the problems that methods were intended to address.  After 
> all, Notepad's bugs haven't seemed to change for a couple of decades, so 
> why should they fix anything now?
> 
> Having a selected window be an implied object for those global functions 
> yields at least the same problems as any writable global. 
> Multithreading, unexpected side effects from certain functions, 
> callbacks, etc.
> 
> As long as you know the program is going to be simple, pile on the 
> globals.  But as soon as it advances, each of them is a trap to fall into.

You're right with everything you say. globals are bad and it may happen that 
this will bite me. I'm just not sure whether we should sacrifice the simpler 
syntax useful in say 80% of cases for something I'm not yet sure will ever 
become a real problem. 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 1:59:58 PM UTC+1, Steven D'Aprano wrote:
> On Tue, 26 Mar 2013 05:04:43 -0700, Michael Herrmann wrote:
> ...
> Am I the only one who appreciates the simplicity of
> 
> > start("Notepad")
> > write("Hello World!")
> > press(CTRL + 's')
> > write("test.txt", into="File name")
> > click("Save")
> > press(ALT + F4)
> 
> > over
> 
> > notepad = start("Notepad")
> > notepad.write("Hello World!")
> > notepad.press(CTRL + 's')
> > notepad.write("test.txt", into="File name")
> > notepad.click("Save")
> > notepad.press(ALT + F4)?
> 
> You are not the only one.
> 
> I suggest that you have a set of functions that work on "the current 
> window", whatever that is. Preferably there should always be a current 
> window, but if not, ensure that you give a clear error message.

This is exactly the way it is currently. I am glad you also see it that way.

> Then you have syntax for operating on any named(?) window. So a user can 
> implicitly operate on the current window:
> 
> select(notepad)
> write("goodbye cruel world")
> save()

One idea would be to use the Window(...) constructor to select windows:

notepad = Window('Untitled - Notepad')
select(notepad)
save()

One advantage of using a global method to switch to a window is that this would 
allow you to directly switch to a Window without having to call Window(...):

switch_to('Untitled - Notepad')

I'm still not fully convinced of a global method though, for the reasons 
several people here have already mentioned.

> or explicitly on any window they like:
> 
> excel.quit()

This example makes it look likely that there will have to be other operations 
that can be performed on windows (/running applications as Dave pointed out). 
So, a 'quit()' method that closes a window in addition to the already mentioned 
focus/select/activate method. This in turn makes the global function less 
attractive as once we start going down that route, global functions will 
proliferate.

> I suggest you dig up an old book on "Hypercard", for Apple Macs in the 
> 1980s and 90s. Back in the day, Macs could only run a single application 
> at a time, and Hypercard was limited to a single window at a time (called 
> a "stack"). But that stack (think: window) could have multiple 
> "cards" (think: window tabs), one of which was always current. 
> Hypercard's built-in programming language Hypertalk let you do things 
> like this:
> 
> go to stack "Notepad"
> type "goodbye cruel world" in field "main" of card 7
> click button "Save"
> click button "Quit" of card "Main" of stack "Excel"
> 
> (more or less... it's been a few years since I've had a classic Mac 
> capable of running Hypercard.)

Very interesting. I had never heard of HyperCard. I read up on it a little and 
it sounds very similar to the model we are internally building of open 
applications (stacks) and their windows (cards). Also funny that HyperCard was 
one of Ward Cunningham's inspirations for coming up with the Wiki idea: 
http://c2.com/cgi/wiki?WikiWikiHyperCard

Thanks for this!

Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 1:16:56 PM UTC+1, Jean-Michel Pichavant wrote:
> - Original Message -
> > > > notepad_1 = start("Notepad")
> > > > notepad_2 = start("Notepad")
> > > > notepad_1.write("Hello World!")
> > > > notepad_1.press(CTRL + 'a', CTRL + 'c')
> > > > notepad_2.press(CTRL + 'v')
> > > > 
> 
>  ^
>  |
>   here, this is an above example :D
> 
> > > > The problem with this design is that it effectively duplicates
> > > > our
> > > > API: We want to keep our "global" functions because they are so
> > > > easy
> > > > to read.
> > > 
> > > So is the example above. This is the best solution in my opinion.
> > 

Ah, so you meant "is also easy to read" ;) I agree but the example with global 
functions is even easier to read. I guess I am being pretty anal about these 
issues, but I see every unnecessary syntax we can save as a win.

> [snip]
> > Doesn't the IPython do auto-completion for "global" functions?
> 
> Yes it does, but as Chris pointed out, your global/module namespace will be 
> "polluted" by a lot of names.
> By using completion on an object, you get the method it has access to, which 
> is very useful to narrow down what you can do with it.

I see. I know you prefer design #1 but that would at least place design #4 over 
#3, right?

Thanks.
Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 12:57:21 PM UTC+1, Chris Angelico wrote:
> On Tue, Mar 26, 2013 at 10:52 PM, Michael Herrmann
> > Doesn't the IPython do auto-completion for "global" functions?
> 
> Even if it does, it'll be polluted with every other global. Methods
> don't have that problem. On the flip side, since presumably this is
> (will be) a module, anyone who wants autocomplete of its top-level
> functions can simply "import module" instead of "from module import
> *", which will do the same namespacing.

True! I don't think "polluting" the global namespace is that much of an issue.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 12:43:18 PM UTC+1, Chris Angelico wrote:
> On Tue, Mar 26, 2013 at 8:38 PM, Michael Herrmann
> 
> > What do you think of designs #3 and #4?
> 
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > switch_to(notepad_1)
> > write("Hello World!")
> > press(CTRL + 'a', CTRL + 'c')
> > switch_to(notepad_2)
> > press(CTRL + 'v')
> >
> 
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > notepad_1.activate()
> > write("Hello World!")
> > press(CTRL + 'a', CTRL + 'c')
> > notepad_2.activate()
> > press(CTRL + 'v')
> 
> Ehh, I referred to these as options 2 and 4. Got lost in the indexing
> somewhere. These are the same two I meant, though - these are the
> options I think are the most plausible.
> 
> (Hindsight being 20/20, it'd have been awesome if the original
> snippets had had identifiers next to them. Oh well, no matter.)

True, and the indexing mistake was my fault... Here goes:

Design #1:
notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
notepad_1.write("Hello World!") 
notepad_1.press(CTRL + 'a', CTRL + 'c') 
notepad_2.press(CTRL + 'v')

Design #2:
notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
switch_to(notepad_1) 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
switch_to(notepad_2) 
press(CTRL + 'v')

Design #3:
notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
with notepad_1: 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
with notepad_2: 
press(CTRL + 'v')

Design #4:
notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
notepad_1.activate() 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
notepad_2.activate() 
press(CTRL + 'v')

Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 12:38:35 PM UTC+1, Chris Angelico wrote:
> ...
> Fundamental point: As I understand the API, it doesn't *actually* tie
> to a window. You don't locate the Notepad window and send it keys -
> you switch focus to Notepad and then send keys to the whole system. Is
> this correct? I'm basing my understanding on this paragraph from your
> original post:
> 
> > We do not (yet) have a functionality that allows you to explicitly switch 
> > to a
> > specific window. Such a functionality would for instance make it possible to
> > open two Notepad windows using the start(...) command, and copy text
> > between them.
> 
> If so, then all of the method-based options are effectively lying,
> because they imply a binding that's not there. The actual sequence of
> actions includes imperatives of "switch to some other window", so I
> think that's what the API should reflect. Otherwise, there's risk that
> something will get horribly horribly confused between the programmer's
> brain and the end result (which could happen on either side of your
> code).

As I just wrote in my reply to Dave, internally we know very well which window 
an action is to be performed in. This window is the window that'd be in the 
foreground after the previous action, if nothing interferes with the system 
while the script is being executed. A common exception is when you enter 
commands in the interactive interpreter: say you write

>>> start("Notepad")

The Notepad window opens, but for you to enter the next command, you have to 
switch back to the interpreter window. If you do that, and enter

>>> write("Hello World")

then we remember that you were previously working with the Notepad window and 
activate this window before performing the key strokes to type "Hello World".

> But if you can unambiguously identify a running instance of something
> and switch to it, then a method on the object that start() returns
> would be absolutely correct. So I'd be looking at either your second
> or fourth options from the original post.

Those are also my favorites at the moment :)

Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 11:26:30 AM UTC+1, Dave Angel wrote:
> ...
> Seems to me that the official interface should all be methods.  However, 
> you could have a new object which always represents the "focus" window. 
>   Then the USER could define trivial functions:
> 
> def write(*args):
>  focused.write(*args)

It's an interesting idea. But why not give this write(...) to them in the first 
place? Am I the only one who appreciates the simplicity of

start("Notepad") 
write("Hello World!") 
press(CTRL + 's') 
write("test.txt", into="File name") 
click("Save") 
press(ALT + F4) 

over 

notepad = start("Notepad") 
notepad.write("Hello World!") 
notepad.press(CTRL + 's') 
notepad.write("test.txt", into="File name") 
notepad.click("Save") 
notepad.press(ALT + F4)?

> Somewhere in this thread you mention that save() creates a new window, 
> so a method-oriented approach would require that the user get that 
> window object, and call its methods rather than the original window's. 
> I say that's a very good thing, since the things you send may very well 
> have very different meanings to the save dialog than they do in the 
> original one.

save() is not a function, but I assume you mean the action that opens the 
"Save" dialogue (I think that'd be `press(CTRL + 's')`). You are right that 
it's nice for it to be explicit. However, in 95% of cases, the window you want 
the next action to be performed in is the window that is currently active. I 
appreciate the explicitness, but to force it on the user for only 5% of cases 
seems a bit much. 

> Another concern I'd have is what happens if the user changes focus with 
> his mouse?  Does that change the meaning you had for focus() in the 
> above exchange?  Do you want your press() method to apply to a different 
> window when the user changes to that window?

No. Internally, we remember which window is the currently active window. If you 
just run a script without user-intervention, this will be the respective 
foreground window. If some other window is in the foreground - which most 
typically happens when the user is interactively entering commands one after 
the other, so the foreground window is the console window, we do switch to the 
window that's supposed to be the active one. It may sound like black magic, but 
it works very well in practice, and really is not too ambiguous. When you read 
a script like

start("Notepad")
write("Hello World")
press(CTRL + 's')
write("test.txt", into="File name")
click("Save")
click("Close")

I hold that you intuitively know what's going on, without even thinking about 
window switching.

Best,
Michael
www.getautoma.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 11:07:45 AM UTC+1, Jean-Michel Pichavant wrote:
> - Original Message -
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > notepad_1.write("Hello World!")
> > notepad_1.press(CTRL + 'a', CTRL + 'c')
> > notepad_2.press(CTRL + 'v')
> > 
> > The problem with this design is that it effectively duplicates our
> > API: We want to keep our "global" functions because they are so easy
> > to read. 
> 
> So is the example above. This is the best solution in my opinion. 

Thanks for your reply. What do you mean by "So is the example above" though? 

> I think you're having the same issue that some other APIs, let's say 
> matplotlib for example. They try to accommodate scientists (matlab) and 
> programmers(python) by having a double API style.
> 
> One looks like
> 
> legend()
> title()
> plot()
> save()
> 
> the other looks like
> 
> fig = figure()
> fig.add_legend()
> fig.title()
> fig.plot()
> fig.save()
> 
> The problem is, when searching for example on the net, you'll end up with a 
> mix of both, it can become a nightmare.

Interesting point. I'll google a little about matplotlib.

> I definitely prefer the later, for the reasons that have already been given 
> to you in this thread and by the fact that with the correct (I)python shell, 
> you can create your window object and get auto-completion on its methods just 
> by hitting , very helpful when introspecting objects. Can be achieved of 
> course in any python shell with function like dir() ; my point being that OOO 
> design keeps things in their place, see the zen of python "Namespaces are one 
> honking great idea -- let's do more of those!"

Doesn't the IPython do auto-completion for "global" functions? 

Thanks,
Michael (www.getautoma.com)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 12:40:45 AM UTC+1, Mitya Sirenef wrote:
> ...
> 
> I think I would prefer context managers. I don't think it's a big 
> problem for
> win users because this behaviour would be one of the first things documented
> in the start guide and would be all over example scripts, so a new user 
> missing
> or forgetting it is not a realistic scenario.
> 
> The advantages are that it's explicit, blocks are indented and it's 
> impossible to
> miss which window is the action applied to, and at the same time actions are
> short and easy to type and read.

Thank you for your reply. What do you think of Chris Angelico's points?
He wrote:
> What happens at the __exit__ of the context manager? What happens if 
> context managers are nested? I'd be inclined to the simpler option of 
> an explicit switch (since focus doesn't really "stack" and it'd feel 
> weird for focus to *sometimes* switch away when you're done working 
> with one window), though the context manager syntax does have its 
> advantages too. 

What I am most afraid of: that the window that's currently the context 
"disappears":
notepad = start("Notepad")
with notepad:
press(ALT + TAB)
write("Am I in Notepad now?")

What do you think of designs #3 and #4?

notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
switch_to(notepad_1) 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
switch_to(notepad_2) 
press(CTRL + 'v') 

notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
notepad_1.activate() 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
notepad_2.activate() 
press(CTRL + 'v')

I somehow prefer "activate" over "focus" as in my feeling, you'd normally say 
that you focus *on* something, so it should be called "focus_on" or 
"give_focus[_to]". Can you say, in everyday English, that you "focus a window"? 
I'm not a native speaker so maybe my feeling is misguided.

Thanks,
Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Tuesday, March 26, 2013 12:11:34 AM UTC+1, Ethan Furman wrote:
> On 03/25/2013 12:29 PM, Michael Herrmann wrote:
> ...
> >
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > notepad_1.write("Hello World!")
> > notepad_1.press(CTRL + 'a', CTRL + 'c')
> > notepad_2.press(CTRL + 'v')
> 
> This is the way to go.  Just move your global functions into the Window 
> object (or whatever you call it), break 
> backwards compatibility (major version number change, perhaps?), and call it 
> good.
> 
> It makes much more sense to call methods of several different objects (which 
> is explicit -- you always know which object 
> is being used) than having a magic function that changes the object in the 
> background (plus you now have to search 
> backwards for the last magic invocation to know -- and what if a called 
> function changes it?).

Your points are valid and I cannot really say anything against them. The 
problem with moving all global functions into the Window object is that this 
adds a lot of syntactic baggage that isn't needed in 90% of the cases. We 
really prefer the simplicity of

start("Notepad")
write("Hello World!")
press(CTRL + 's')
write("test.txt", into="File name")
click("Save")
press(ALT + F4)

over

notepad = start("Notepad")
notepad.write("Hello World!")
notepad.press(CTRL + 's')
notepad.write("test.txt", into="File name")
notepad.click("Save")
notepad.press(ALT + F4).

Also, there's a problem here: The "Save" dialogue that opens in the above 
script is technically a different window so in theory you would have to 
introduce a new object to distinguish between the original window that lets you 
edit your text document from the "Save" window. This is very tedious and 
error-prone. You are right, though, that we have to do some logic in the 
background to remember the last window.

In light of this, could you live with something along the lines of design #4?

notepad_1 = start("Notepad") 
notepad_2 = start("Notepad") 
notepad_1.focus() 
write("Hello World!") 
press(CTRL + 'a', CTRL + 'c') 
notepad_2.focus() 
press(CTRL + 'v') 

Thanks,
Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-26 Thread Michael Herrmann
On Monday, March 25, 2013 10:08:53 PM UTC+1, Chris Angelico wrote:
> ...
> > I kind of like the context manager solution because the indentation makes 
> > it very obvious what happens in which window. You are right about our 
> > target group though. Also, the "with" is not as explicit as it probably 
> > should be.
> 
> What happens at the __exit__ of the context manager? What happens if
> context managers are nested? I'd be inclined to the simpler option of
> an explicit switch (since focus doesn't really "stack" and it'd feel
> weird for focus to *sometimes* switch away when you're done working
> with one window), though the context manager syntax does have its
> advantages too.

You are right, an __exit__ for a window doesn't really make sense and neither 
does stacking. There's also the problem that the focus window may change - for 
instance when closing it. What happens if you're still inside the "with ..." 
then? At first glance, I think the context manager solution looks nice 
syntactically, but maybe it isn't the way to go here.

> ...
> 
> > We'd of course love to support other platforms but don't currently have the 
> > resources to do this. We actually just wrote a blog entry about this and 
> > some related questions: http://www.getautoma.com/blog/automa-faq If we have 
> > something wrong, do let us know in the comments over there!
> 
> 
> Make the API clean enough and someone else might well write a Linux
> equivalent. Then it'll be as simple as a try/import/except/import at
> the top and multiple platforms will work.

Yes, that's a good point. A clean API is very important to us (hence my posting 
here).

Thanks for your answer!
Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Help me pick an API design (OO vs functional)

2013-03-25 Thread Michael Herrmann
Hi Kwpolska,

thanks for your reply (as last time I posted here!). 

On Monday, March 25, 2013 8:42:25 PM UTC+1, Kwpolska wrote:
> ...
> 
> > notepad_1 = start("Notepad")
> > notepad_2 = start("Notepad")
> > with notepad_1:
> > write("Hello World!")
> > press(CTRL + 'a', CTRL + 'c')
> > with notepad_2:
> > press(CTRL + 'v')
> 
> That’s ugly, and don’t forget that your users aren’t Pythonistas most
> of the time.

I kind of like the context manager solution because the indentation makes it 
very obvious what happens in which window. You are right about our target group 
though. Also, the "with" is not as explicit as it probably should be. 

> ...
> PS. do you plan a version for non-Windows OSes?  Also, €99 is too expensive.

We'd of course love to support other platforms but don't currently have the 
resources to do this. We actually just wrote a blog entry about this and some 
related questions: http://www.getautoma.com/blog/automa-faq If we have 
something wrong, do let us know in the comments over there!

It's very hard work building such an automation tool and also we have to live 
off something. Unfortunately, we can't make the price any lower.

P.S.: First-time bottom-posting!
-- 
http://mail.python.org/mailman/listinfo/python-list


Help me pick an API design (OO vs functional)

2013-03-25 Thread Michael Herrmann
Hello everyone, 

my name is Michael, I'm the lead developer of a Python GUI automation library 
for Windows called Automa: http://www.getautoma.com. We want to add some 
features to our library but are unsure how to best expose them via our API. It 
would be extremely helpful for us if you could let us know which API design 
feels "right" to you.

Our API already offers very simple commands for automating the GUI of a Windows 
computer. For example:

from automa.api import *
start("Notepad")
write("Hello World!")
press(CTRL + 's')
write("test.txt", into="File name")
click("Save")
click("Close")

When you execute this script, Automa starts Notepad and simulates key strokes, 
mouse movements and clicks to perform the required commands. At the moment, 
each action is performed in the currently active window. 

We do not (yet) have a functionality that allows you to explicitly switch to a 
specific window. Such a functionality would for instance make it possible to 
open two Notepad windows using the start(...) command, and copy text between 
them.

One API design would be to have our start(...) function return a "Window" (say) 
object, whose methods allow you to do the same operations as the global 
functions write(...), press(...), click(...) etc., but in the respective 
window. In this design, the example of operating two Notepad windows could be 
written as

notepad_1 = start("Notepad")
notepad_2 = start("Notepad")
notepad_1.write("Hello World!")
notepad_1.press(CTRL + 'a', CTRL + 'c')
notepad_2.press(CTRL + 'v')

The problem with this design is that it effectively duplicates our API: We want 
to keep our "global" functions because they are so easy to read. If we add 
methods to a new "Window" class that do more or less the same, we feel that we 
are violating Python's principle that "There should be one - and preferably 
only one - obvious way to do it."

An alternative design would be to make the window switching an explicit action. 
One way of doing this would be to add a new global function, say "switch_to" or 
"activate", that takes a single parameter that identifies the window to be 
switched to. We could still have start(...) return a Window object, that could 
then be passed to our function:

notepad_1 = start("Notepad")
notepad_2 = start("Notepad")
switch_to(notepad_1)
write("Hello World!")
press(CTRL + 'a', CTRL + 'c')
switch_to(notepad_2)
press(CTRL + 'v')

Maybe our Window objects could also be used as context managers:

notepad_1 = start("Notepad")
notepad_2 = start("Notepad")
with notepad_1:
write("Hello World!")
press(CTRL + 'a', CTRL + 'c')
with notepad_2:
press(CTRL + 'v')

As a final idea, switching could also be done as a method of the Window class:

notepad_1 = start("Notepad")
notepad_2 = start("Notepad")
notepad_1.activate()
write("Hello World!")
press(CTRL + 'a', CTRL + 'c')
notepad_2.activate()
press(CTRL + 'v')

It would be extremely helpful for us if you could let me know which way of 
using the API you would prefer. If you opt for an explicit version, how would 
you call the respective method? "activate" / "switch_to" / "focus" or something 
else?

Thank you so much!

Best wishes,
Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is it bad style to override the built-in function `type`?

2012-12-03 Thread Michael Herrmann
Hi Rusi, 

> Im entering this thread late (was off mail for a week), so pardon me
> if someone has already said this -- but have you looked at the
> difference between internal and external dsls:
> http://martinfowler.com/bliki/DomainSpecificLanguage.html (and links
> therein) ?
> Roughly speaking if what you are making is an external dsl, then its
> not really python (it may be python-inspired but thats not really
> germane) and so reusing python lexemes/structures etc in ways not
> exactly consistent with python usage should be no issue
> 
> If its an internal DSL, you are headed for causing/suffering grief.
> 
> I looked at your site [yes it looked almost interesting -- if only it
> ran on linux :-( ] and I cant really decide whether to classify it as
> external or internal

We want to capitalize on all of Python's advantages (tool/IDE support, 
available libraries etc) and are thus strictly offering an internal DSL (see 
http://www.getautoma.com/features/python_integration). As you pointed out, 
that's why it's important to stay consistent with Python's conventions. 

I agree it'd be nice to have Automa run on Linux, but unfortunately that's 
still a long time away...

Best,
Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is it bad style to override the built-in function `type`?

2012-11-29 Thread Michael Herrmann
Hey everyone,

this is my final mail. With all your help we have decided on names for our 
function. It was a surprisingly difficult process but your inputs helped 
tremendously. I have described our experiences (very good ones here, but 
somewhat mixed ones with StackOverflow) in a blog entry: 
http://www.getautoma.com/blog/New-version-of-Automa-with-improved-API

I will now stop spamming this list. Thank you so much again! If you're 
interested in how we're getting on in the future, do follow us on Twitter 
@BugFreeSoftware or on our blog http://www.getautoma.com/blog!

Thanks again, 
Michael
Co-founder and lead developer
@BugFreeSoftware
http://www.getautoma.com

On Friday, November 23, 2012 5:12:39 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> do you think it's bad style to override the built-in function `type`? I'm 
> co-developing a GUI automation library called Automa 
> (http://www.getautoma.com) and 'type' would be a very fitting name for a 
> function that generates artificial key strokes. 
> 
> 
> 
> This post is motivated by an already lengthy discussion on this mailing list 
> (http://bit.ly/10aOy4H), where we tried to find alternative names for `type`. 
> Many were found, but none are quite as fitting as 'type'. 
> 
> 
> 
> For the sake of avoiding a discussion that is already being lead elsewhere 
> please confine this thread to what you generally think about overriding 
> `type`, and post suggestions for alternative names or solutions in the other 
> thread.
> 
> 
> 
> Thank you very much!
> 
> Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-29 Thread Michael Herrmann
Hey everyone,

this is my final mail. With all your help we have decided on names for our 
function. It was a surprisingly difficult process but your inputs helped 
tremendously. I have described our experiences (very good ones here, but 
somewhat mixed ones with StackOverflow) in a blog entry: 
http://www.getautoma.com/blog/New-version-of-Automa-with-improved-API

I will now stop spamming this list. Thank you so much again! If you're 
interested in how we're getting on in the future, do follow us on Twitter 
@BugFreeSoftware or on our blog http://www.getautoma.com/blog!

Thanks again, 
Michael
Co-founder and lead developer
@BugFreeSoftware
http://www.getautoma.com

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-25 Thread Michael Herrmann
On Sunday, November 25, 2012 4:56:49 AM UTC+1, Steven D'Aprano wrote:
> Michael, please trim your replies. There is no need to quote nearly 200 
> lines of previous emails that you don't make direct reference to in your 
> response. We prefer inline quoting here (where you interleave quoted text 
> with the direct response to that quote), but if you must top-post or 
> bottom-post, please trim.

Sorry - I'm using the Web interface for Google Groups and it hides the quoted 
previous emails from me. I will take care in the future. 

> Also, please stop sending two copies of every post: you can send an email 
> to [email hidden], or you can post a news message to the 
> newsgroup comp.lang.python, but don't do both. You're just flooding both 
> places with two copies  of everything you say.

Same - the Google groups web interface sometimes did that by default. I'll 
double check the recipients in the future. I'm sorry!

Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-25 Thread Michael Herrmann
On Sunday, November 25, 2012 12:23:13 AM UTC+1, Dennis Lee Bieber wrote:
> ...
>   Pardon? In ASCII (and encodings that share the first 128 positions),
> 
> a TAB is x09.
> 
> 
> 
> >>> def show(c):
> 
> ... print "%r is 0x%2.2X" % (c, ord(c))
> 
> ...
> 
> >>> show(raw_input()[0])
> 
> i
> 
> 'i' is 0x69
> 
> >>> show(raw_input()[0])
> 
> 
> 
> '\t' is 0x09
> 
> >>>
> 
> 
> 
>   My "input" for the second was 
> 
> 
> 
>   Typically, keyboard/console interfaces generate
> 
>  - 0x60 when the control key is held down.
> 
> Lowercase "i" is 0x69; minuse 0x60 give 0x09, which is the TAB
> 
> character.
> 
> 
> 
>   A GUI interface, however, may capture the combination for some other
> 
> usage.

Thanks! I did not know that.

Michael
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Is it bad style to override the built-in function `type`?

2012-11-24 Thread Michael Herrmann
Hi,

how about "write" instead of "type"? Just came to me in a flash of inspiration. 
I know it's also pretty general but at least it's not a built-in!

Thanks!
Michael

On Friday, November 23, 2012 11:30:18 PM UTC+1, Cameron Simpson wrote:
> On 23Nov2012 10:41, Michael Herrmann <> wrote:
> 
> [...]
> 
> | I know it's a common beginner's mistake to incautiously override
> 
> | built-in functions. However, we put in a lot of research and have come to
> 
> | the conclusion that, if Python had not already defined it, `type` would
> 
> | be the best name. We are now trying to evaluate how bad the disadvantages
> 
> | you mention are in comparison to the advantage to having a name that is
> 
> | more intuitive to use in the problem domain.
> 
> | 
> 
> | Can you somehow relate to my explanations, or are your experiences
> 
> | with overwriting built-in variables so bad that you would advise to
> 
> | never ever do it?
> 
> 
> 
> My own experience says that it is a thing best avoiding without a truly
> 
> amazing reason not to.
> 
> 
> 
> I urge you not to: type(foo) is a very basic Python idiom and you're
> 
> breaking it. One day it _will_ bite you or your users. You will
> 
> understand, but I would give goods odds that some of your users will not
> 
> the day they go to examine the type of an object for perfectly normal
> 
> pythonic reasons.
> 
> 
> 
> Example: I have a module that stores "objects" and they have as a
> 
> primary key a "name" and a "type" - not Python types, just strings.
> 
> Accordingly I have a similar situation to yours: the desire to use the
> 
> word "type". Fortunately for me, as an attribute in (usually small) code
> 
> chunks I can usually go:
> 
> 
> 
>   t = foo.type
> 
>   ... work with t here ...
> 
> 
> 
> Where I must pass one as a parameter I use the common convention of
> 
> naming the parameter "type_" at the receiving end.
> 
> 
> 
> For the calling end, as in your case, you want to use:
> 
> 
> 
>   type(blah)
> 
> 
> 
> Is it at all possible to make all uses of your "type" function method
> 
> calls? Eg:
> 
> 
> 
>   something.type("text to type")
> 
> 
> 
> It avoids the overloading while keeping your desired name.
> 
> -- 
> 
> Cameron Simpson 
> 
> 
> 
> Wouldn't it be great if all emergency stopping situations occurred on your
> 
> favourite bit of road..you'd probably know about it before it happened
> 
> and would be able to take other evasive action.
> 
> - Neville Brabet

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-24 Thread Michael Herrmann
Hey, 

how about 'write' instead of 'enter'?

write("Hello World!")
write("Brick Lane", into="Street")

This avoids the ambiguity of whether 'enter' ends by pressing ENTER or not.

Thanks,
Michael

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-24 Thread Michael Herrmann
Thanks for your reply Dennis,

the commands sounding like they should be commands to a user is the whole point 
of the exercise: In doing so, we hope to make the API accessible also to users 
from a less technical background. You are perfectly right that system events 
are being generated and passed around, however that is not what these users 
care about. Frankly, also I coming from a very technical background don't care 
which events are generated and how, as long as it works. 

I agree that "key_down"/"key_up" has a nice symmetry to it. Maybe a solution 
could also be to use a context manager:
with key_down(SHIFT):
# some action...

Cheers

On Friday, November 23, 2012 11:11:34 PM UTC+1, Dennis Lee Bieber wrote:
> On Thu, 22 Nov 2012 10:00:54 -0800 (PST), Michael Herrmann
> 
>  declaimed the following in
> 
> gmane.comp.python.general:
> 
> 
> 
> > These names aren't perfect. As Emile rightly pointed out, several tools 
> > distinguish between 'press' and 'release' and a user might wonder how to 
> > release a key that was pressed using 'press'. That's an ambiguity that is 
> > certainly there, however we hope that once the user has at least seen
> 
> > press(ENTER)
> 
> > it is clear what is meant. Distinguishing between pressing and releasing 
> > could we think easily be done with, say
> 
> > hold_down(SHIFT)
> 
> > ...
> 
> > release(SHIFT)
> 
> > Another ambiguity of 'press' that I pointed out in my original mail is that 
> > it could also be understood as "pressing a button". The current idea is to 
> > raise a ValueError if the user supplies a string that is longer than one 
> > character:
> 
> > >>> press("OK")
> 
> > ValueError: 'press' generates keystrokes and can only press single 
> > letters at a time. Did you maybe mean click("OK") or press('O', 'K')?
> 
> > 
> 
> 
> 
>   "press", "hold_down", "release" just sound so much like they should
> 
> be commands to a /user/ not to a means of programmatically controlling
> 
> an interface. A "user" presses a button -- but a program is just
> 
> injecting the "event" of a button press into the input processing stream
> 
> (it's been decades, but I still think in Amiga terms -- where all input
> 
> events routed through one input handler and chained to the programs
> 
> wanting to work with raw events... This meant that, but injecting the
> 
> event codes before the input handler, a program could make another
> 
> program [including the OS] think one had ejected/inserted floppies,
> 
> mouse movements, keystrokes)
> 
> 
> 
>   "hold_down" and "release" would seem more memorable, and symmetric,
> 
> if named "key_down" and "key_up"; and if "press" is limited to single
> 
> codes -- "key" [or "keystroke"]
> 
> 
> 
>   The closest M$ .Net method is called SendKeys() and works with
> 
> strings.
> 
> http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.uitesting.keyboard.sendkeys%28v=vs.100%29.aspx
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> > What do you think of this solution? I hope anybody read this far. I 
> > probably shouldn't have written that much but wanted to do justice to your 
> > inputs.
> 
> > 
> 
> > Thanks!
> 
> > 
> 
> > Michael
> 
> > 
> 
> > On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> 
> > > Hi, 
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> > > having difficulty picking a name for the function that simulates key 
> > > strokes. I currently have it as 'type' but that clashes with the built-in 
> > > function. Example uses of 'type': 
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > type(ENTER)
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > type("Hello World!")
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > type(CTRL + 'a')
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > What, in your view, would be the most intuitive alternative name?
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > Here are my thoughts so far: I could call it 'press' but then our GUI 
> > > automation tool also allows you to click things and then "press" might be 
> > > mistaken for "pressing a button". A less ambiguous alternative is 
> > > "type_keys" but that is rather long and doesn't read as well, for 
> > > instance in type_keys(ENTER).
> 
> > > 
> 
> > > 
> 
> > > 
> 
> > > Thank you very much!
> 
> -- 
> 
>   Wulfraed Dennis Lee Bieber AF6VN
> 
> HTTP://wlfraed.home.netcom.com/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-24 Thread Michael Herrmann
Hi Steven,

press('s') is allowed. So is press('S') - it presses shift for you and is thus 
equivalent to press(SHIFT + 's'). You can write press('f', 's'). You cannot 
write press('fs') because that's what enter(...) is for. If you try - or, as I 
would deem more likely, happen do to it by mistake - you get the following 
warning:
>>> press('fs')
ValueError: 'press' generates single keystrokes and is not intended to 
be used for typing in long plain-text strings. Did you maybe mean one of the 
following?
 * enter("fs")
 * click("fs")
 * press('f', 's')
I'm not aware of CTRL + i having a connection with TAB. You cannot use it to 
get a tab. We haven't decided on what to do when you press('\t'). If you want 
three tabs, you can write
press(TAB, TAB, TAB)
If you want a tab, a letter and a newline, you can do
enter("""\tA 
\tB 
\tC 
""")
The reasoning is that you are entering plain text, that is a string that you 
would like to appear in the window you are typing into in the same way as you 
are supplying it to `enter`.

If you want to type "Hello World!" without entering it, you call
enter("Hello World!")
Yes, I did write "call *enter* to do X *without entering*". You are hinting at 
a valid ambiguity with `enter` that Chris already pointed out. I don't think 
it's worse than the ambiguity of
>>> type("Hello World!")


We would need a new function for holding down keys to release them later. You 
are again pointing out an imho valid ambiguity. However, you were just happily 
using `press` with the understanding that it presses and releases keys, so I 
hope this one isn't too bad.

As I said, I opened a new thread solely for overriding `type` in the context of 
a GUI automation library: 
https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.python/GjZ2hAS1Wyk.
 So far, 4/4 people there advised against it. If only Python hadn't defined 
`type`...

Michael

On Friday, November 23, 2012 11:30:04 PM UTC+1, Steven D'Aprano wrote:
> On Fri, 23 Nov 2012 05:42:22 -0800, Michael Herrmann wrote:
> 
> 
> 
> > Dear all,
> 
> > 
> 
> > the emails are getting kind of long so to ask you briefly: What do you
> 
> > think of splitting `type` into two functions `press` and `enter`?
> 
> 
> 
> This invites confusion as to the rules of when you can call `press` and 
> 
> when you can call `enter`. Especially since you haven't explained the 
> 
> rules, just given a bunch of non-exhaustive examples and invited people 
> 
> to extrapolate what the rules are.
> 
> 
> 
> (By the way, they aren't use-cases, they're examples.)
> 
> 
> 
> 
> 
> > Their use cases are:
> 
> > press(CTRL + 'a')
> 
> > press(ENTER)
> 
> > press(ALT + 'f', 's')
> 
> > enter("Hello World!")
> 
> > enter("test.txt", into="File name")
> 
> 
> 
> 
> 
> Is `press('s')` allowed?
> 
> 
> 
> What about `press('S')`, or do I have to write `press(SHIFT + 's')`?
> 
> 
> 
> If I can write `press(ALT + 'f', 's')`, can I write `press('f', 's')`? If 
> 
> not, why not?
> 
> 
> 
> Can I write `press('fs')` as a simpler version of `press('f', 's')`? If 
> 
> not, why not?
> 
> 
> 
> Can I write `press(CTRL + 'i')` to get a tab? How about `press('\t')`?
> 
> 
> 
> If I want three tabs, can I write `press('\t\t\t')`, or do I have to write
> 
> 
> 
> press(CTRL + 'i')
> 
> press(CTRL + 'i')
> 
> press(CTRL + 'i')
> 
> 
> 
> If I want a tab, a letter, and a newline, repeated three times, can I do 
> 
> this?
> 
> 
> 
> press("""\tA
> 
> \tB
> 
> \tC
> 
> """)
> 
> 
> 
> Or do I have to do this?
> 
> 
> 
> press(CTRL + 'i')
> 
> enter('A')
> 
> press(CTRL + 'i')
> 
> enter('B')
> 
> press(CTRL + 'i')
> 
> enter('C')
> 
> 
> 
> Speaking of enter, how do I type "Hello World!" without entering it? If I 
> 
> want to type "Hello World!" without ENTER, do I have to do this?
> 
> 
> 
> press('H')
> 
> press('e')
> 
> press('l')
> 
> press('l')
> 
> ... you get the picture
> 
> 
> 
> 
> 
> With a function named "press", I would expect to be able to say:
> 
> 
> 
> press('a')
> 
> time.sleep(5)
> 
> release('a')
> 
> 
> 
> How do I do something like that?
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-23 Thread Michael Herrmann
Hi,

I see your concern with having two functions that have to be separately 
remembered... I personally would also be fine with type(), however some people 
are violently against it. I opened a new thread 
(https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.python/GjZ2hAS1Wyk)
 to ask just how many people would have a problem with this. I know I'm really 
spamming this list and apologize. I promise it'll be over soon.

Michael

On Friday, November 23, 2012 5:43:08 PM UTC+1, Kwpolska wrote:
> On Fri, Nov 23, 2012 at 2:42 PM, Michael Herrmann
> 
> <...> wrote:
> 
> > Dear all,
> 
> >
> 
> > the emails are getting kind of long so to ask you briefly: What do you 
> > think of splitting `type` into two functions `press` and `enter`? Their use 
> > cases are:
> 
> > press(CTRL + 'a')
> 
> > press(ENTER)
> 
> > press(ALT + 'f', 's')
> 
> > enter("Hello World!")
> 
> > enter("test.txt", into="File name")
> 
> >
> 
> > Thanks,
> 
> > Michael
> 
> 
> 
> First of, please don’t top-post.  Second of, the type—enter split a
> 
> bad idea.  It would require me to think whether I should use one or
> 
> the other.  type() is perfectly fine, because Automa is never going to
> 
> be used as from automa import *.  And if it is, it’s in your shell for
> 
> non-Pythonistas.
> 
> 
> 
> And also, my general thoughts: type() is just fine.  Unless you want
> 
> to call it 
> simulate_pressing_keys_on_the_keyboard_without_getting_a_mechanical_arm_out_of_the_screen_and_pressing_the_keys_with_it(),
> 
> but then you will need to create
> 
> simulate_using_the_mouse_without_getting_a_mechanical_arm_out_of_the_screen_and_moving_the_mouse_or_pressing_its_buttons_with_it(),
> 
> too.
> 
> 
> 
> --
> 
> Kwpolska <http://kwpolska.tk>
> 
> stop html mail  | always bottom-post
> 
> www.asciiribbon.org | www.netmeister.org/news/learn2quote.html
> 
> GPG KEY: 5EAAEA16
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-23 Thread Michael Herrmann
Hi again,

Steven's points and the "feeling" for `type` are very good and maybe the 
problems I mentioned can be ramified. I therefore opened a new thread to find 
out what the general public thinks about overwriting built-in functions such as 
`type` here: 
https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.python/GjZ2hAS1Wyk

Thanks,
Michael

On Friday, November 23, 2012 10:08:06 AM UTC+1, Michael Herrmann wrote:
> Hi Steven,
> 
> 
> 
> On Friday, November 23, 2012 6:41:35 AM UTC+1, Steven D'Aprano wrote:
> 
> > On Thu, 22 Nov 2012 10:00:54 -0800, Michael Herrmann wrote:
> 
> > 
> 
> > 
> 
> > 
> 
> > > We took the fact that naming our one function 'type' was so difficult to
> 
> > 
> 
> > > name as an indicator that it may be trying to do too many things:
> 
> > 
> 
> > 
> 
> > 
> 
> > I don't think it is difficult to name at all.
> 
> > 
> 
> > 
> 
> > 
> 
> > > On the one hand, it allows you to enter plain text as in `type("Hello
> 
> > 
> 
> > > World!")`; 
> 
> > 
> 
> > 
> 
> > 
> 
> > That would be called "typing".
> 
> 
> 
> I agree that "typing" might be more common in this context. However, you also 
> understand me when I say "enter".
> 
> 
> 
> > 
> 
> > 
> 
> > 
> 
> > > on the other hand, it lets you press single keys, 
> 
> > 
> 
> > 
> 
> > 
> 
> > That would be called "typing".
> 
> 
> 
> Here, I disagree. You "press" enter and you "press" ALT+TAB. You might be 
> able to say "type ENTER" but that is much less common. Google agrees: 
> http://bit.ly/10o8yAQ vs. http://bit.ly/WmVwyU.
> 
> 
> 
> > 
> 
> > 
> 
> > 
> 
> > > possibly in combination with control keys as for instance in 
> 
> > 
> 
> > > `type(CTRL + 'a')`. 
> 
> > 
> 
> > 
> 
> > 
> 
> > That would be called "prestidigitation".
> 
> > 
> 
> > 
> 
> > 
> 
> > Nah, just kidding. That would also be called "typing".
> 
> 
> 
> Here too Google favours "press ctrl+a" over "type ctrl+a".
> 
> 
> 
> > 
> 
> > 
> 
> > 
> 
> > 
> 
> > 
> 
> > 
> 
> > 
> 
> > > We believe it won't normally be necessary to combine the two.
> 
> > 
> 
> > 
> 
> > 
> 
> > I can't imagine why you say that. You even go ahead and give a perfectly 
> 
> > 
> 
> > fine example of combining a control character with plain text.
> 
> > 
> 
> > 
> 
> > 
> 
> > I don't know what operating system you are using, but under Linux, people 
> 
> > 
> 
> > often use strings of regular characters mixed in with control- or alt-
> 
> > 
> 
> > characters. E.g. I in the shell, I might type Alt-B Shift-' END Shift-' 
> 
> > 
> 
> > to jump backwards one word (Alt-B), insert a double quote mark (Shift-'), 
> 
> > 
> 
> > jump to the end of the line I am editing (END), and insert another double 
> 
> > 
> 
> > quote mark.
> 
> 
> 
> Unfortunately, I didn't explain what I mean by "plain text". Your example 
> could be implemented with the "press" from our proposal, as follows:
> 
>   press(ALT + 'B', '"', END, '"')
> 
> What I meant when I said that "press" could not be used to enter plain text 
> was that it would not be possible to enter a sequence of multiple normal 
> letters enclosed in single quotes, as in
> 
>   press("Hello World")
> 
> If in your example you had wanted to add more than just a single character to 
> the beginning or end of the line, this means you would have to write
> 
>   press(ALT + 'B')
> 
>   enter("beginning of line")
> 
>   press(END)
> 
>   enter("end of line")
> 
> I agree that the following would read better here:
> 
>   press(ALT + 'B')
> 
>   type("beginning of line")
> 
>   press(END)
> 
>   type("end of line")
> 
> However like Google above, I would disagree with
> 
>   type(ALT + 'B')
> 
>   type("beginning of line")
> 
>   type(END)
> 
>   type("end of line&

Re: 10 sec poll - please reply!

2012-11-23 Thread Michael Herrmann
Dear all, 

the emails are getting kind of long so to ask you briefly: What do you think of 
splitting `type` into two functions `press` and `enter`? Their use cases are:
press(CTRL + 'a') 
press(ENTER) 
press(ALT + 'f', 's') 
enter("Hello World!") 
enter("test.txt", into="File name") 

Thanks, 
Michael

On Thursday, November 22, 2012 7:00:55 PM UTC+1, Michael Herrmann wrote:
> Dear all,
> 
> 
> 
> thank you for your replies. After experimenting with your suggestions, we 
> have arrived at a solution that we believe fits well with our existing API. 
> However, before we implement this solution, we would like to ask you one last 
> time to sign off on our proposal or raise any serious problems you see with 
> it.
> 
> 
> 
> We took the fact that naming our one function 'type' was so difficult to name 
> as an indicator that it may be trying to do too many things: On the one hand, 
> it allows you to enter plain text as in `type("Hello World!")`; on the other 
> hand, it lets you press single keys, possibly in combination with control 
> keys as for instance in `type(CTRL + 'a')`. We believe it won't normally be 
> necessary to combine the two. For instance, while you could see what
> 
>   type(CTRL + 'a' + "Hello World!")
> 
> does, we think you would be more likely to use the two separate calls
> 
>   type(CTRL + 'a')
> 
>   type("Hello World!")
> 
> 
> 
> One of the main goals of our automation product is that using it should feel 
> like giving instructions to a human being looking over their shoulder at a 
> screen. For this reason, it's very useful for us if the function names in our 
> API are short, if possible without underscores, and close to the vocabulary 
> you would use in an everyday conversation. We hope that by offering an API 
> with this property, we can not only make it easier to use for experienced 
> programmers such as yourself, but also be approachable for people from a less 
> technical background.
> 
> 
> 
> In our gut feeling, the words apart from `type` that would most normally be 
> used in an everyday conversation to express the three examples I have given 
> in my first mail are:
> 
>   press(CTRL + 'a')
> 
>   enter("Hello World")
> 
>   press(ENTER)
> 
> 
> 
> We really quite like the word `type`, and a few people here seem to favour it 
> too. In particular, Steven: We're glad you accidentally clicked on our mail. 
> Thank you for your inputs and the great quote by Phil Karlton. We think you 
> were right in everything you said. However, some people seem to be *really* 
> put off when you override a built-in function. Even though of course you can 
> avoid the overriding by saying
> 
>   from automa.api import type *as* ...,
> 
> (as Tim pointed out) we'd like to avoid irritating those people. For this 
> reason, we would rather not use `type`.
> 
> 
> 
> Many people here voted for send_keys(...). We agree with Dave and Neil that 
> `type` may have too many uses already. As Chris and MRAB pointed out, 
> 'send_keys' is used in many other automation tools. This makes it intuitive 
> for people with knowledge of such tools. However, as I said above (and should 
> have probably said earlier), we are also trying to reach users from a less 
> technical background. Since these people would not normally use 'send_keys' 
> in an everyday conversion, we are afraid that it would not be an intuitive 
> name for them. A similar argument applies to some extent to our 'type_keys', 
> to our 'generate_keystrokes', Ramit's 'simulate_keypress', 
> 'simulate_key(s)_down', 'send_kb_press', 'fake_typing' and 'send_char(s)' and 
> Tim's 'feedkeys'. We thank you for your suggestions. Hopefully you can also 
> agree with our choice!
> 
> 
> 
> Some suggestions were very nice, short and pretty unambiguous, such as 
> Dennis' `emit` and particularly Alan's `strike`. However, they're 
> unfortunately also rather rarely used and we'd be afraid that it'd be hard to 
> remember them. Thank you though!
> 
> 
> 
> A final point that Evan made and that also we find very important is to have 
> verbs in our function names. 
> 
> 
> 
> Our proposed solution is to split what we previously called `type` into two 
> functions, 'press' and 'enter' (proposed by xDog Walker). 'press' could be 
> used to press single keys or comb

Re: 10 sec poll - please reply!

2012-11-22 Thread Michael Herrmann
Hi,

thanks for your prompt reply; I agree that there is also this ambiguity. This 
would go away if we were to use `type` but as I said we don't dare to do that. 
That's the problem with short names - they're always ambiguous at least to some 
extent. 

The only alleviation I can offer for the valid concern you are raising is that 
the user will notice upon the very first use that Enter is not pressed after 
the text has been typed in, and then (if necessary) add a `press(ENTER)` 
afterwards.

It's a pity that `type` is taken... It's very tempting to just use it. But then 
again you might have people trying to `type(ALT + TAB)`, which in our current 
proposal can only be input using `press`...

What do the others think about this?

Cheers

On Thursday, November 22, 2012 8:08:39 PM UTC+1, Chris Angelico wrote:
> On Fri, Nov 23, 2012 at 5:00 AM, Michael Herrmann
> 
> <...> wrote:
> 
> > In our gut feeling, the words apart from `type` that would most normally be 
> > used in an everyday conversation to express the three examples I have given 
> > in my first mail are:
> 
> > press(CTRL + 'a')
> 
> > enter("Hello World")
> 
> > press(ENTER)
> 
> 
> 
> Looks fairly good, except for one possible problem: The verb "enter"
> 
> often means "type this, and then press the Enter key". (For instance,
> 
> "open up a terminal/shell and enter this command".) Is that likely to
> 
> be a point of confusion?
> 
> 
> 
> It's plenty plausible either way. I like the multiple-keystrokes version:
> 
> > press(ALT + 'f', 's')
> 
> and the split API does make good sense.
> 
> 
> 
> ChrisA

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-22 Thread Michael Herrmann
names aren't perfect. As Emile rightly pointed out, several tools 
distinguish between 'press' and 'release' and a user might wonder how to 
release a key that was pressed using 'press'. That's an ambiguity that is 
certainly there, however we hope that once the user has at least seen
press(ENTER)
it is clear what is meant. Distinguishing between pressing and releasing could 
we think easily be done with, say
hold_down(SHIFT)
...
release(SHIFT)
Another ambiguity of 'press' that I pointed out in my original mail is that it 
could also be understood as "pressing a button". The current idea is to raise a 
ValueError if the user supplies a string that is longer than one character:
>>> press("OK")
ValueError: 'press' generates keystrokes and can only press single 
letters at a time. Did you maybe mean click("OK") or press('O', 'K')?

What do you think of this solution? I hope anybody read this far. I probably 
shouldn't have written that much but wanted to do justice to your inputs.

Thanks!

Michael

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-21 Thread Michael Herrmann
Dear all,

thanks so much for your replies. Based on your inputs, we have started to 
experiment with changes to our API. I hope to be able to present the results to 
you tomorrow.

Thanks again,
Michael

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-20 Thread Michael Herrmann
Thanks again for your further replies. So far, it's 4 votes for 'send_keys' and 
1 vote for 'type'. 

Regarding 'send_keys': To me personally it makes sense to send keys _to_ 
something. However, in our API, send_keys would not be called on an object or 
with a parameter indicating the target. It would just be

send_keys(ENTER)
send_keys("Hello World!")
send_keys(CTRL + 'a')

Does that change your preference for 'send_keys'?

Thanks a lot!!!

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-20 Thread Michael Herrmann
P.S.: The website is back online; our hosting provider was having technical 
problems...

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: 10 sec poll - please reply!

2012-11-20 Thread Michael Herrmann
Hi,

thank you for your replies. So far two people said 'send_keys' and one person 
said 'type'. 

Steven, thanks for your reply. Sorry if the message title disturbed you. My 
personal feelings aren't too strongly against 'type' either, but then I'm 
afraid it might bother more experienced Python programmers who are used to a 
very different meaning of 'type'. Do you think that could be a problem?

Thanks again to all who have replied,
Michael

On Tuesday, November 20, 2012 1:18:38 PM UTC+1, Michael Herrmann wrote:
> Hi, 
> 
> 
> 
> I'm developing a GUI Automation library (http://www.getautoma.com) and am 
> having difficulty picking a name for the function that simulates key strokes. 
> I currently have it as 'type' but that clashes with the built-in function. 
> Example uses of 'type': 
> 
> 
> 
> type(ENTER)
> 
> 
> 
> type("Hello World!")
> 
> 
> 
> type(CTRL + 'a')
> 
> 
> 
> What, in your view, would be the most intuitive alternative name?
> 
> 
> 
> Here are my thoughts so far: I could call it 'press' but then our GUI 
> automation tool also allows you to click things and then "press" might be 
> mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
> but that is rather long and doesn't read as well, for instance in 
> type_keys(ENTER).
> 
> 
> 
> Thank you very much!

-- 
http://mail.python.org/mailman/listinfo/python-list


10 sec poll - please reply!

2012-11-20 Thread Michael Herrmann
Hi, 

I'm developing a GUI Automation library (http://www.getautoma.com) and am 
having difficulty picking a name for the function that simulates key strokes. I 
currently have it as 'type' but that clashes with the built-in function. 
Example uses of 'type': 

type(ENTER)

type("Hello World!")

type(CTRL + 'a')

What, in your view, would be the most intuitive alternative name?

Here are my thoughts so far: I could call it 'press' but then our GUI 
automation tool also allows you to click things and then "press" might be 
mistaken for "pressing a button". A less ambiguous alternative is "type_keys" 
but that is rather long and doesn't read as well, for instance in 
type_keys(ENTER).

Thank you very much!
-- 
http://mail.python.org/mailman/listinfo/python-list