Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Machine à état

+5 votes

Ayant le besoin d'interprété un flux binaire, je souhaiterai le faire à l'aide d'une machine à état.

Quel bibliothèque vous semblerait la plus appropriée?

Pour donner une idée de la machine à état

edit : Correction du schéma. Xavier Combelle avait raison, elle était bourré d'incohérence.

demandé 18-Aou-2015 par Andarus (172 points)
edité 1-Sep-2015 par Andarus

J'ai jamais compris pourquoi il n'y avait pas une façon standardisé dans la lib standard pour faire des machines à état. Du coup il y a des tonnes de lib sans une qui sort du lot. Peut être parce que c'est assez facile de faire un truc adapté à ton problème...

Merci pour avoir posé cette question qui me taraude aussi depuis longtemps, notamment pour le développement de parsers (de fichier de configuration, de paquets etc.)
C'est vrai qu'il y l'air d'avoir beaucoup de libs mais qu'aucune ne surpasse le reste. J'attends beaucoup des réponses proposée ! :)

Par contre si je ne dis pas de bêtise, si tu gères une machine à état "binaire", tu as en fait un AST (abstract syntax tree) avec des noeuds et des feuilles (mais certes avec des probas pour les transitions): tu ne pourrais pas te baser sur ça ? https://docs.python.org/2/library/ast.html

Sinon, je sais que je suis hors-sujet mais j'ai récemment vu la référence à ce tool, qui fait apparemment le café : http://www.fizzim.com/
Si tu as un retour je suis preneur !

Cordialement.

J'ai quelques doutes: comment un bit (soit 0b0 soit 0b1) peut il valoir 0xB5 ou 0x62 qui sont des valeurs hexadécimales contenant 8 bits ?

3 Réponses

+4 votes
 
Meilleure réponse

Une state machine de la taille de ton schéma peut être exprimée assez facilement en Python sans avoir besoin d'une lib :

class StopStateMachine(StopIteration):
    pass

def state1(data):
    print(data)
    return state2, data

def state2(data):
    if not data:
        raise StopStateMachine()
    a, *data = data
    print(a)
    return state1, data

try:
    data = "Hello !"
    next_state = state1
    while True:
        next_state, data = next_state(data)
except StopStateMachine:
    print('Goodbye')

Mais il se trouve qu'il y a une state machine dans la stdlib en Python 3: l'event loop d'async io. Tu peux lui passer n'importe quel callback. Si tu appelle yield sur une coroutine, le switch est fait sur cette coroutine.

répondu 23-Aou-2015 par Sam (5,000 points)
sélectionné 10-Sep-2015 par Andarus

je serais curieux de voir une implementation en utilisant asyncio. L'objet d'un futur article ?

Faire un dossier "prog parallèle + prog concurrente en python" est dans les bacs, mais j'ai rien sur cet aspect particulier. Après, pourquoi pas, si jamais j'ai un use case qui se présente...

+1 vote

Aucune idée, étant donné que les specs (interpréter un flux binaire) sont très larges.

En s'intéressant à la doc, on voit facilement les différentes solutions.

Une bonne alternative semble être FSME, qui utilise une interface graphique pour générer du code ; si ce n'est pas déjà fait, l'automate doit être dessiné, et c'est exactement ce que permet FSME.

Tulip quant à lui semble très (trop dans ton cas ?) complet.

Enfin, FSA semble proposer une API plus simple, malgré une doc un peu rude.

S'il s'agit d'un projet d'apprentissage, considère la possibilité de tout coder toi-même, à l'aide du design pattern State ; rien ne t'empêche de remplacer par une autre solution une fois cette implémentation d’entrainement réalisée.

répondu 18-Aou-2015 par lucas (2,340 points)
0 votes

Solution que j'ai utilisé:

Pour la machine à état :
https://github.com/tyarkoni/transitions
Cette librairie apporte pas mal de "magie", mais je l'ai trouvé assez simple à utilisé la doc(le readme de github) couvre bien toute les possibilité.

Une fois le flux binaire traité j'ai utilisé construct qui permet de parser des structures binaire complexe dont le format est connue:
http://construct.readthedocs.org/en/latest/

Ce n'est surement pas la meilleur solution mais çà a marcher dans mon cas.

répondu 1-Sep-2015 par Andarus (172 points)
...