Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Réagir à la frappe d'une touche clavier pour un script en mode console

11 réponses
Avatar
Francois Lafont
Bonjour à tous,

J'ai un petit programme en mode *console* qui simule une expérience
aléatoire un grand nombre de fois. Le programme fonctionne, mais il peut
mettre un peu de temps (10 minutes) à se terminer car il répète par
exemple 100 000 fois une même simulation. En gros, code, c'est ça :

for k in range(10000):
simule_experience()
affiche_petit_bilan()

J'aimerais que le programme réagisse quand j'appuie sur la barre espace.
Je m'explique.

Je lance le programme, il boucle, il boucle... je n'ai pas de prompt sur
la console pendant ce temps bien sûr. Si jamais j'appuie sur SPACE (et
seulement si je fais cela), dès que le programme arrive en début de
boucle, au lieu de simuler une nouvelle expérience, le programme se
stoppe et m'affiche un truc du genre «Pour l'instant 56 257 expériences
simulées, tapez ENTER pour que le programme reprenne son travail... ».
Dans ce cas, si j'appuie sur ENTER (et seulement si je fais cela), le
programme reprend ses boucles. Et ainsi de suite...

Merci d'avance pour votre aide.


--
François Lafont

1 réponse

1 2
Avatar
Pierre Maurette
Alain Ketterlin, le 11/7/2010 a écrit :
Francois Lafont writes:

Merci beaucoup Pierre pour votre code, qui, pour l'avoir testé, fait
exactement ce que j'ai demandé. Il ne me reste plus qu'à l'étudier (en
l'état je suis loin de le maîtriser).



Le code de Pierre fait effectivement ce qu'il faut faire. J'ai juste une
remarque sur l'utilisation à mon avis superflue de eval(). Il vaut
peut-être mieux utiliser :

if os.name == 'posix':
[...]
fonction = lambda : sys.stdin.read(1)
# ou simplement def fonction(): return sys.stdin.read(1)
else:
[...]
fonction = msvcrt.getch

et plus bas utiliser fonction comme un "callable" normal

c = fonction()

Pour la partie termios, bonne lecture du man :-)



Je suis entièrement de votre avis. Ce qui s'est passé, c'est que dans
l'excitation du moment j'avais d'abord pensé à l'approche fonctionnelle
et été perturbé par le fait qu'une fonction prenait 0 paramètres et
l'autre 1 (constant). D'où l'eval sans enthousiasme. Ce qui est très
con puisque j'utilise massivement les lambda de cette façon dans des
dictionnaires d'actions.
Alors j'ai repris le code dans l'idée d'en archiver une version
nettoyée, entre autre de l'eval. On peut également conditionner tout le
/def kbThreah(): etc./.
Et j'ai regardé le code de la branche posix, que j'avais lamentablement
pompé sur la toile. Ça ne m'a pas trop plu, quand j'ai constaté qu'on
bouclait sans fin sur une exception. Je ne connais rien de la gestion
des priorités des threads Python, je me suis dit qu'enfiler un sleep()
à ce niveau devrait améliorer les choses

while c != ' ':
try:
c = sys.stdin.read(1)
except IOError:
time.sleep(0.1)

et puis je suis parti sur d'autres recherches sur des entrées clavier
bloquantes peu gourmandes, mais je n'ai rien trouvé d'enthousiasmant.


--
Pierre Maurette
1 2