10 sec poll - please reply!

M

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
 
M

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
 
S

Steven D'Aprano

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".
on the other hand, it lets you press single keys,

That would be called "typing".
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".


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.

It is a needless restriction to assume that every control character must
only be part of a single key press event. I even remember a Mac
application back in the early 1990s or late 1980s that used combinations
like Ctrl-A Y to perform commands. (Actually, such older Macs didn't have
a Control key, they used Command instead, but the principle is the same.)

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.

In a word processor, I might say

"Type Ctrl-A Ctrl-X to cut all the text from the document."

rather than

"Press Ctrl-A. Now press Ctrl-X."

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`.

You need to ask yourself, who is your primary audience for your software?

Is it ... ?

a) non-technical people who aren't very familiar with Python, and might
not even know that there is a built-in function also called "type", or
care if they do know;

b) Python programmers who have embraced the concept of namespaces and
have no fear about x.foo clashing with y.foo;

c) Python programmers with a superstitious dread of using any name which
is not global unique, just in case somebody accidentally shadows one
function "foo" with another function "foo".

I think it is downright silly to avoid using the descriptive and simple
name "type" out of some superstition against re-using names which have
been used elsewhere, even in the builtins.

If it were possible to be confused by the two types, e.g. if they took
the same arguments but did radically different things, then I would
accept that it was too dangerous/confusing to re-use the name. Reasonable
fears about shadowing and confusion are, well, reasonable. But nobody is
going to confuse your use of type as a command:

type(some_string)

with the built-in use as a function

if type(something) is list:
MyClass = type(x, y, z)


I don't think there is any point in having two functions that do exactly
the same thing. Expect your users to develop all sorts of superstitions
like "you can only use press() with a single key at a time", and get
confused as to when you are supposed to use enter() and when press() (for
whatever names you eventually choose).
 
M

Michael Herrmann

Hi Steven,

I don't think it is difficult to name at all.







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".
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.
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".
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 textwas 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")
or even
type(ALT + 'B' + "beginning of line" + END + "end of line")

It is a needless restriction to assume that every control character must

only be part of a single key press event. I even remember a Mac

application back in the early 1990s or late 1980s that used combinations

like Ctrl-A Y to perform commands. (Actually, such older Macs didn't have

a Control key, they used Command instead, but the principle is the same.)










In a word processor, I might say



"Type Ctrl-A Ctrl-X to cut all the text from the document."



rather than



"Press Ctrl-A. Now press Ctrl-X."

With the current proposal, it'd be
press(CTRL + 'A', CTRL + 'X')
Forgetting about `type` vs `press` for a moment, chaining the key combinations like this is OK, isn't it?
You need to ask yourself, who is your primary audience for your software?



Is it ... ?



a) non-technical people who aren't very familiar with Python, and might

not even know that there is a built-in function also called "type", or

care if they do know;



b) Python programmers who have embraced the concept of namespaces and

have no fear about x.foo clashing with y.foo;



c) Python programmers with a superstitious dread of using any name which

is not global unique, just in case somebody accidentally shadows one

function "foo" with another function "foo".

I agree that this is an important question to ask. however we unfortunatelycannot answer it yet. We think our software should be usable by people from all three groups, but which group will use it the most we don't know yet.
I think it is downright silly to avoid using the descriptive and simple

name "type" out of some superstition against re-using names which have

been used elsewhere, even in the builtins.



If it were possible to be confused by the two types, e.g. if they took

the same arguments but did radically different things, then I would

accept that it was too dangerous/confusing to re-use the name. Reasonable

fears about shadowing and confusion are, well, reasonable. But nobody is

going to confuse your use of type as a command:



type(some_string)



with the built-in use as a function



if type(something) is list:

MyClass = type(x, y, z)

Actually, when I first read your example, I was confused. I guess it's because the two different meanings of `type` were so close together I still hadthe first in mind when encountering the second. Nevertheless, it did confuse me.

That's actually a key point: You are not confused or irritated by giving `type` a new meaning, and you have very valid reasons why. However, several people we asked in other places were surprised or irritated. You have very good points, but we won't get a chance to explain them to these other users when they first see our API. As the API designers, we have to try to find asolution that's acceptable for most people, and will therefore not be perfect for everyone.
I don't think there is any point in having two functions that do exactly

the same thing. Expect your users to develop all sorts of superstitions

like "you can only use press() with a single key at a time", and get

confused as to when you are supposed to use enter() and when press() (for

whatever names you eventually choose).

I agree that it's not good to have two functions do exactly the same thing.However, it also has to be pointed out that it's not good for one functionto do too many things. An example like
type(ALT + 'B' + "beginning of line" + END + "end of line")
imho tries to do too much in one go. With things like this, that you could not forbid with having only one function `type` that does everything, you would soon run into problems like "does it now press ALT all the time, or just for the first 'B'? Then your syntax/API pretty quickly explodes and you end up having to add some form of bracketing, escape sequences etc etc. That's something the splitting should hopefully avoid.

Again, it's a long(ish) mail, and that's because it's very interesting to bounce our ideas off of you. Thank you for giving us a chance to do this!

Michael
 
M

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
 
K

Kwpolska

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—entersplit 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.
 
D

Dennis Lee Bieber

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/lib...ls.uitesting.keyboard.sendkeys(v=vs.100).aspx
 
S

Steven D'Aprano

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?
 
M

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: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 asyou 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 hintingat a valid ambiguity with `enter` that Chris already pointed out. I don't think it's worse than the ambiguity of<type 'str'>

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
 
M

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 Thu, 22 Nov 2012 10:00:54 -0800 (PST), Michael Herrmann

<Michael Herrmann> declaimed the following in

gmane.comp.python.general:


These names aren't perfect. As Emile rightly pointed out, several toolsdistinguish 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

it is clear what is meant. Distinguishing between pressing and releasing could we think easily be done with, say



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/lib...ls.uitesting.keyboard.sendkeys(v=vs.100).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.

--

Wulfraed Dennis Lee Bieber AF6VN

HTTP://wlfraed.home.netcom.com/
 
M

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 Thu, 22 Nov 2012 10:00:54 -0800 (PST), Michael Herrmann

<Michael Herrmann> declaimed the following in

gmane.comp.python.general:


These names aren't perfect. As Emile rightly pointed out, several toolsdistinguish 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

it is clear what is meant. Distinguishing between pressing and releasing could we think easily be done with, say



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/lib...ls.uitesting.keyboard.sendkeys(v=vs.100).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.

--

Wulfraed Dennis Lee Bieber AF6VN

HTTP://wlfraed.home.netcom.com/
 
M

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
 
D

Dennis Lee Bieber

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

Pardon? In ASCII (and encodings that share the first 128 positions),
a TAB is x09.
.... print "%r is 0x%2.2X" % (c, ord(c))
....
i
'i' is 0x69

'\t' is 0x09
My "input" for the second was <ctrl-i>

Typically, keyboard/console interfaces generate
<ord-lowercase-letter> - 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.
 
S

Steven D'Aprano

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.

Also, please stop sending two copies of every post: you can send an email
to (e-mail address removed), 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.
 
M

Michael Herrmann

...
Pardon? In ASCII (and encodings that share the first 128 positions),

a TAB is x09.



... 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 <ctrl-i>



Typically, keyboard/console interfaces generate

<ord-lowercase-letter> - 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
 
M

Michael Herrmann

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top