A question I have seen posed often, but have not yet found a solution that fits my problem. I would therefore appreciate some help to improve both my code and my understanding of Python.
I'm working on a large chunk of code that features Grammatical Evolution and runs in several nested (unavoidable at the moment) classes.
The base class (Genetic) handles the population, each member of the population is an instance of Individual class and is evaluated using the Algorithm class. To avoid over-complicating - a code that runs in several layers (with Spice simulated added to the mix) and runs for... quite a long time - hours at some times.
This is the reason why I started to search for a solution that would allow me to stop the execution in a way that would not mess everything up. If I use the usual ctrl+c option it simply destroys everything and forces me to restart the kernel and loose all the data.
What I'm thinking about is adding a sort of a monitor to the code that would allow me to enter a keypress sequence and then say "Ok, I see you want to finish, I'll simply complete the current evaluation loop and exit".
In my belief I cannot use a keyboard interrupt since this would immediately exit the code execution. More likely I would need a flag that would change if the key is detected....
Any help would be appreciated.
So to summarize my pseudoIdea would be like this:
for each generation:
if exit.flag != true:
for each individual:
evaluate individual
else:
write result
finish and exit
when key detected set exit.flag to true
Thank you!
Found a solution using pynput
from genetic.mainCore import Genetic
from grammar.basicDict import params
from algorithm.core import Algorithm
from pynput import keyboard
def on_activate_h():
print('<ctrl>+<alt>+h pressed')
global gen
gen.forcEnd = True
listener = keyboard.GlobalHotKeys({'<ctrl>+<alt>+h': on_activate_h})
listener.start()
algi = Algorithm()
gen = Genetic(algi)
gen.initGrammar(params)
gen.initPopulation()
gen.run()
listener.stop()
I modified the gen.run() method to include a forcEnd check. If it is set to True we skip the evaluation of next generation and exit. Tested this and it works, even when using an external simulator!