2016-03-04 3 views
0

J'ai un programme où l'utilisateur devrait être capable de choisir et de choisir des commandes à partir d'une liste déroulante. Dans cette liste, il y a aussi une commande repeat, qui fait essentiellement ce que fait une boucle for, donc toutes les commandes entre repeat et end repeat doivent être bouclées le nombre de fois indiqué. Voir image:Fonction de répétition Python qui appelle des fonctions

enter image description here

Maintenant, je ne sais pas encore comment gérer les programatically répétées fonctions. Je sais que python gère les classes comme des objets, alors peut-être que cela peut aider, mais je suis un peu perdu.

Actuellement j'envoie une liste de chaînes au thread qui gère l'exécution des commandes, et qui est analysée et chaque commande est exécutée.

def command(self, item): 
    if item.startswith('Pan'): 
     ... do stuff 
    elif item.startswith('...'): 
     ... do something else 

Comment pourrais-je réécrire cela pour que repeat est une fonction appelable/méthode?

+0

Lorsque l'utilisateur clique sur « Répéter: 150 » vous devrez analyser les lignes suivantes jusqu'à ce que « fin répéter » et envoyer toutes ces informations en une seule étape à l'autre fil. Je ne vois pas comment l'autre thread pourrait savoir quelles commandes doivent être répétées. Je ne vois pas comment "réécrire" la méthode "commande" va vous y parvenir. –

Répondre

1

Créez une fonction multi_command qui prend plusieurs commandes et les exécute dans l'ordre. Lorsque cette fonction rencontre une "répétition", créez une liste de toutes les commandes suivantes jusqu'à ce que vous obteniez la "répétition finale" correspondante. Cette nouvelle liste est alors un sous-ensemble de votre liste totale. Appelez multi_command avec cette liste, et ensuite, passez à la commande qui vient après la "répétition de fin".

Psuedo-code:

def multi_commands(items): 
    highest_idx_already_done = 0 
    for idx, item in enumerate(items): 
     if highest_idx_already_done > idx: 
      continue 
     if item == "repeat": 
      num_repeats = ... 
      sub_items = [] 
      for sub_item in items[idx+1:]: 
       if sub_item == "end repeat": 
        break 
       sub_items.append(sub_item[5:]) # Skip indentation 
      highest_idx_already_done = idx + len(sub_items) 
      for _ in range(num_repeats): 
       multi_commands(sub_items) 
     else: 
      command(item) 
+0

va essayer ça. Est-ce que cela gère les multi-commandes imbriquées? – enrm

+0

Le problème de cette approche est qu'elle lit la balise 'end repeat' la plus proche, qui ne correspond pas nécessairement à la' start repeat 'correcte .. peut-être que l'indentation devrait être utilisée pour mapper? – enrm

+0

Cela devrait fonctionner pour les commandes imbriquées, oui. Il repose également sur l'indentation pour trouver des marques de "fin de répétition". Si vous ne le souhaitez pas, vous devrez compter le nombre de "repeats" et de "end_repeats" dans la boucle 'for for_item'. – acdr