Python keyboard listener - python

I have used this code and it runs fine. However, there is something weird about it, it's like it's not Python!
The e variable in print_event is used in a way I haven't seen before. It's a regular function that prints whatever is passed to it, but the problem is how it's used, even the event variable that's supposed to be passed as an argument to the parameter e
If you don't pay attention, it seems like the append function returns added values to print_event, instead of appending them, like what the append does in Python.The whole function gets appended to the list of handlers once and then it keeps running until the program terminates,like it's a while True loop.
The code basically starts a keyboard listener and keeps recording key pressed keys, but what happens to the keys is the quesion. The for loop in low level listener doesn't make sense, why iterate through the handlers if it's supposed to record the keys, not read them. Besides, why pass the event? Handlers is a list, not a function, i'm only aware of the assignement operator for initializing variables
Also, if handlers is initialize empty, how does it assign values to items and through them if their memory space isn't allocated and doesn't exist?
I don't seeing any buffer function being called, so how's it working? Python shouldn't look like that
What i'm trying to do is to access the handlers list in real time and process the events
An explanation would be appreciated. Thanks in advance

Are you asking about Function Variables?
If yes, you can pass around functions like any other variable, and call them later by a different name.
EG:
def hi(string):
print(string)
fns = [hi, hi]
for fn in fns:
fn('hello')
If that remains puzzling, perhaps you could step through it with a debugger to make the idea seem more concrete.

Related

How to put functions into a dictionary so that they can be iterated over? [duplicate]

This question already has answers here:
Using a dictionary to select function to execute
(11 answers)
Closed 3 years ago.
I'm trying to make a dictionary which contains functions as the values. The idea is that the difficulty variable will change throughout the program, and this will affect which function we call from the dictionary.
For the sake of this, I'm not going to show the program, I've made a simple mock up that demonstrates the issue I'm having.
Whenever I run the code, without even entering a key, it runs the functions. Why is this?
def printhello():
print("hello")
def printgoaway():
print("go away")
x={1:printhello(),2:printgoaway()}
At this point I wasn't expecting anything to have happened as I haven't called any keys yet. It runs the functions anyway and prints the values.
If I then call them by doing x[1] or x[2], nothing happens.
Can someone explain to me how I would use functions in a dictionary, and stop them from automatically calling them when I make the dictionary
When you put () after the function name, that tells Python to call the function immediately.
You should change your code to do this:
x={1:printhello,2:printgoaway}
So that your dictionary contains references to the functions, instead of the result of calling them up front.
Then you can call them later like this:
x[0]()
Note the brackets here, and lack of brackets in the previous line.
The problem is that you are placing parentheses after the function names in the dictionary:
x={1:printhello(),2:printgoaway()}
This executes the functions and puts the returned values into the dictionary. Try removing the parentheses:
x={1:printhello ,2:printgoaway}
This puts the functions themselves in the dictionaries.
As an example, here is a section of one of my programs:
OPERATIONS = {'+': sum, '*': rdmath.prod}
def evaluate_subtree(node_list, ndx: int) -> int:
"""Evaluate the subtree inside node_list with the root at ndx.
Use recursion and postorder in depth first search."""
this_payload, these_children = node_list[ndx]
if not these_children: # if a leaf node
return int(this_payload)
return OPERATIONS[this_payload](evaluate_subtree(node_list, child)
for child in these_children)
Note that I put the sum function and rdmath.prod (which calculates the product of the members of an iterable) into the dictionary OPERATIONS. The last line of my snippet uses the dictionary to choose one of the two functions then executes the function on a generator comprehension, and the resulting value is returned. (So the values in the generator comprehension are either added or multiplied.)
Try something like that and see if it works for you.
printhello() runs printhello
use x={1:printhello, 2:printgoaway}to store your functions and x[1]() to call it

Using a method to create multiple, new instances of a generator

I've been learning about generators in Python recently and have a question. I've used iterators before when learning Java, so I know how they basically work.
So I understand what's going on here in this question: Python for loop and iterator behavior
Essentially, once the for loop traverses through the iterator, it stops there, so doing another for loop would continue the iterator at the end of it (and result in nothing being printed out). That is clear to me
I'm also aware of the tee method from itertools, which lets me "duplicate" a generator. I found this to be helpful when I want to check if a generator is empty before doing anything to it (as I can check whether the duplicate in list form is empty).
In a code I'm writing, I need to create many of the same generators at different instances throughout the code, so my line of thought was: why don't I write a method that makes a generator? So every time I need a new one, I can call that method. Maybe my misunderstanding has to do with this "generator creation" process but that seemed right to me.
Here is the code I'm using. When I first call the method and duplicate it using tee, everything works fine, but then once I call it again after looping through it, the method returns an empty generator. Does this "using a method" workaround not work?
node_list=[]
generate_hash_2, temp= tee(generate_nodes(...))
for node in list(temp):
node_list.append(...)
print("Generate_hash_2:{}".format(node_list))
for node in generate_hash_2:
if node.hash_value==x:
print x
node_list2=[]
generate_hash_3, temp2= tee(generate_nodes(...)) #exact same parameters as before
for node in list(temp2):
node_list2.append(...)
print("Generate_hash_3:{}".format(node_list2))
`
def generate_nodes(nodes, type):
for node in nodes:
if isinstanceof(node.type,type):
yield node
Please ignore the poor variable name choices but the temp2 prints out fine, but temp3 prints out an empty list, despite the methods taking identical parameters :( Note that the inside of the for loop doesn't modify any of the items or anything. Any help or explanation would be great!
For a sample XML file, I have this:
<top></top>
For a sample output, I'm getting:
Generate_hash_2:["XPath:/*[name()='top'][1], Node Type:UnknownNode, Tag:top, Text:"]
Generate_hash_3:[]
If you are interested in helping me understand this further, I've been writing these methods to get an understanding of the files in here: https://github.com/mmoosstt/XmlXdiff/tree/master/lib/diffx , specifically the differ.py file
The code in that file constantly calls the _gen_dx_nodes() method (with the same parameters), which is a method that creates a generator. But the code's generator never "ends" and forces the writer to do something to reset it. So I'm confused why this happens to me (because I've been running into my problem when calling that method from different methods in succession). I've also been using the same test cases so I'm pretty lost here on how to fix this. Any help would be great!

What happens to a Python input value if it's not assigned to a variable?

Was just wondering this. So sometimes programmers will insert an input() into a block of code without assigning its value to anything for the purpose of making the program wait for an input before continuing. Usually when it runs, you're expected to just hit enter without typing anything to move forward, but what if you do type something? What happens to that string if its not assigned to any variable? Is there any way to read its value after the fact?
TL;DR: If you don't immediately assign the return value of input(), it's lost.
I can't imagine how or why you would want to retrieve it afterwards.
If you have any callable (as all callables have return values, default is None), call it and do not save its return value, there's no way to get that again. You have one chance to capture the return value, and if you miss it, it's gone.
The return value gets created inside the callable of course, the code that makes it gets run and some memory will be allocated to hold the value. Inside the callable, there's a variable name referencing the value (except if you're directly returning something, like return "unicorns".upper(). In that case there's of course no name).
But after the callable returns, what happens? The return value is still there and can be assigned to a variable name in the calling context. All names that referenced the value inside the callable are gone though. Now if you don't assign the value to a name in your call statement, there are no more names referencing it.
What does that mean? It's gets on the garbage collector's hit list and will be nuked from your memory on its next garbage collection cycle. Of course the GC implementation may be different for different Python interpreters, but the standard CPython implementation uses reference counting.
So to sum it up: if you don't assign the return value a name in your call statement, it's gone for your program and it will be destroyed and the memory it claims will be freed up any time afterwards, as soon as the GC handles it in background.
Now of course a callable might do other stuff with the value before it finally returns it and exits. There are a few possible ways how it could preserve a value:
Write it to an existing, global variable
Write it through any output method, e.g. store it in a file
If it's an instance method of an object, it can also write it to the object's instance variables.
But what for? Unless there would be any benefit from storing the last return value(s), why should it be implemented to hog memory unnecessarily?
There are a few cases where caching the return values makes sense, i.e. for functions with determinable return values (means same input always results in same output) that are often called with the same arguments and take long to calculate.
But for the input function? It's probably the least determinable function existing, even if you call random.random() you can be more sure of the result than when you ask for user input. Caching makes absolutely no sense here.
The value is discarded. You can't get it back. It's the same as if you just had a line like 2 + 2 or random.rand() by itself; the result is gone.

Alternatives to storing variables globally

I am starting out with Python now, working on the Learn Python The Hard Way, on exercise 36. I want to create a good game, and learn some more techniques before moving on with the next exercise. I haven't approached the subject of Classes and Object yet, yet I want to see if I can do something that would be a bit more complex than a standard first 'choose-your-own-adventure' game.
I want to collect four different keys in 'Ganon's Lair', and then use those four keys to open a door in the 'main-hall'. I already have quite some of it worked out (not elegantly), but I still need to figure out how to store keys without them getting erased. An unelegant way is to assign them as global variables, such as I do here.
def grass_room():
global key1
grass_instructions = """As you enter the lair of the grass room, you see
a spider hanging on the ceiling, with his
big eye focused on you. You could grab your 1.slingshot,
or perhaps 2.make a run for the green-coloured key under his
tail?"""
print grass_instructions
gohma_boss = raw_input("> ")
if gohma_boss == "1":
print "You shoot him in the eye, he falls down and dies. You grab the key, and return."
key1 = True
main_hall("not_empty")
else:
print die("You die.")
main_hall("not_empty")
Any suggestions for different ways to 'save' this key across functions, besides making them global?
If you want some variable or variables to be shared between functions, there are a few ways to do it:*
Pass each variable's value into every function as an argument, and return it from every function as part of a return tuple.
Wrap all of the values up in some structure, like a dict that you can look each thing up in by name, so you only have one value to pass and return.
Make the values attributes of an object, and turn the functions into methods of that object's type.
Use a closure, which I won't bother to explain because I'm sure you haven't learned about closures yet.
Use globals.
The Pythonic way to do this is definitely #3, but you haven't learned about classes yet. In that case, I'd just use #5, as you're already doing.
And when you learn about classes, coming back and modifying this script to use a class instead will be a great exercise.
* In fact, under the covers, options 3-5 are all pretty much syntactic sugar for option 2… but don't worry about that.
You could make your key datatype a list or a dict and pass the key list/dict into each key-changing function. Since lists and dicts are mutable, changes made to the key list/dict in one function will be seen in the calling scope and in any subsequent functions that key is passed to.

function in python

In a function, I need to perform some logic that requires me to call a function inside a function. What I did with this, like:
def dfs(problem):
stack.push(bache)
search(root)
while stack.isEmpty() != 0:
def search(vertex):
closed.add(vertex)
for index in sars:
stack.push(index)
return stack
In the function, dfs, I am using search(root), is this is the correct way to do it?
I am getting an error: local variable 'search' referenced before assignment
There are many mysterious bug-looking aspects in your code. The wrong order of definition (assuming you do need the search function to be a nested one) and the syntax error from the empty while loop have already been observed, but there are more...:
def dfs(problem):
stack.push(bache)
search(root)
what's bache, what's stack, what's root? If they're all global variables, then you're overusing globals -- and apparently nowhere ever using the argument problem (?!).
while stack.isEmpty() != 0:
what's this weird-looking method isEmpty? IOW, what type is stack (clearly not a Python list, and that's weird enough, since they do make excellent LIFO stacks;-)...? And what's ever going to make it empty...?
def search(vertex):
closed.add(vertex)
...don't tell me: closed is yet another global? Presumably a set? (I remember from a few of your Qs back that you absolutely wanted to have a closed dict, not set, even though I suggested that as a possibility...
for index in sars:
...and what's sars?!
stack.push(index)
return stack
what a weird "loop" -- one that executes exactly once, altering a global variable, and then immediately returns that global variable (?) without doing any of the other steps through the loop. Even if this is exactly what you mean (push the first item of sars, period) I don't recommend hiding it in a pseudo-loop -- it seriously looks like a mystery bug just waiting to happen;-).
You need to de-indent your search function. The way you have it set up right now you are defining your search function as a part of the completion of your dfs call. Also, encapsulation in a class would help.
Thats the wrong order. Try this:
def dfs(problem):
def search(vertex):
closed.add(vertex)
for index in sars:
stack.push(index)
return stack
stack.push(bache)
search(root)
while stack.isEmpty() != 0:
Either define search before you call it, or define it outside of dfs.
you have to define the function before using it
root doesn't seem to be available in your scope - make sure it's reachable
You don't have body to your for your while loop. That is probably causing problems parsing the code. I would also suggest putting the local function definition before it is used, so it is easier to follow.

Categories

Resources