IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

[Projet solveur SAT] Débuter avec python.


Sujet :

Python

  1. #1
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut [Projet solveur SAT] Débuter avec python.
    Bonjour à tous.

    Je suis en train de réaliser un solveur SAT en Python. J'ai choisi ce langage parce que je ne le connaissais pas et que c'était l’occasion de l'apprendre. Mais vu que c'est un nouveau langage pour moi, j'ouvre ce topic pour mes questions de débutants.

    N'hésiter pas à me conseiller d'autre façon de faire (tant sur la syntaxe que sur l'algorithmique lorsque je posterai du code) et de me dire comment faire au mieux.

    1. Alors pour commencer, je n'arrive pas à copier un itérateur. J'ai essayer tout et n'importe quoi (v = iter(a), copy.copy(v), puis new(v), copy(v) et j'en passe des meilleurs). Comment faire ? [Résolu, solution : tee()]
    2. J'ai un fichier avec une formule et pour le moment, l'intégralité de la formule est copié dans une variable que je parcours avec l'itérateur. Je dois aller en avant et parfois revenir en arrière (j'ai appris que les itérateurs ne pouvaient pas aller en sens inverse dans Python, pour autant qu'on ne l'implémente pas. D'où mon désir de "sauvegarder" l'itérateur à la question 1. De plus n'y a t'il pas d'autre moyen d'optimiser l'accès au fichier avec un itérateur sans passer par la variable temporaire contenant la formule ?
    3. Ensuite, j'ai 3 fichiers (main.py, a.py, constants.py), main.py inclu a.py et a.py inclu constants.py. Malgré tout, a.py ne peut pas utiliser les constantes déclarées dans constants.py (simplement de la forme A=1). J'ai essayé d'inclure avec import constants ou encore from constants import *. Sans succès. edit
      Solution



    Merci beaucoup pour votre aide.

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    1)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> liste = [12, 5, 9]
    >>> liste, copy_liste = iter(liste), iter(liste)
    >>> liste
    <list_iterator object at 0x02F1F6D0>
    >>> copy_liste
    <list_iterator object at 0x02F54890>
    2)

    Si on peut revenir en arrière avec les indices

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> liste = [12, 5, 9]
    >>> for i, j in enumerate(liste):
    	if i != 0:
    		print(liste[i-1])
     
     
    12
    5
    3)

    Si constants.py inclus tous les autres modules, vous n'incluez logiquement pas constants.py dans a.py par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from a import *
     
    print(var_du_module_a)

  3. #3
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Merci pour votre réponse. Je me suis très certainement mal exprimé mais je n'ai pas trouvé de solutions dans votre message.

    1) En fait je veux copier un itérateur à partir d'un itérateur.

    2) C'est des indices donc pas un itérateur à proprement parler il me semble ? Je dispose juste d'une variable "a" qui est un itérateur sur un objet (à la limite on ne sait pas lequel).

    3) constants.py n'inclus aucun fichiers. En fait, Main.py inclus a.py qui inclus constants.py. Et dans a.py, je ne peux pas accéder aux variables déclarées dans constants.py.

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    1) ça change rien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    iterator = iter(liste)
    iterator_copy = iterator
    2) Ok, là ton problème peut se résoudre à l'aide d'un itérateur bidirectionnel

    Voir doc officielle

    3)
    constants.py n'inclus aucun fichiers. En fait, Main.py inclus a.py qui inclus constants.py. Et dans a.py, je ne peux pas accéder aux variables déclarées dans constants.py.
    Bizarre

  5. #5
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    1) Malheureusement mes tests n'indiquent pas ce comportement, je pense que l'opérateur "=" fait une copie "par référence" (si c'est le terme utilisé dans le jargon Pÿthon). Preuve :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    v = "A"
    a = iter(v)
    b = a
    c = a.next()
    print b.next()
    et le résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
          print b.next()
    StopIteration
    Ce qui veut dire que l'incrémentation de l'itérateur "a" à également incrémenté "b".

    2) L'itérateur que vous me montrez dans la doc permet de parcourir la séquence en sens inverse. Ce n'est pas bidirectionnelle vu qu'on ne peut pas faire de .next(), puis l'instant d'après revenir sur nos pas. (Ou alors je n'ai pas compris l'exemple).

    3)

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    2) L'itérateur que vous me montrez dans la doc permet de parcourir la séquence en sens inverse. Ce n'est pas bidirectionnelle vu qu'on ne peut pas faire de .next(), puis l'instant d'après revenir sur nos pas. (Ou alors je n'ai pas compris l'exemple).
    euh... là faut me donner un exemple car je suis perdu, à part avec l'indexation, je ne vois pas comment tu pourrais revenir en arrière.

    Après tu as la possibilté de parcourir une liste de façon circulaire, mais je ne pense pas que se soit cela que tu souhaites.

    1) Malheureusement mes tests n'indiquent pas ce comportement, je pense que l'opérateur "=" fait une copie "par référence" (si c'est le terme utilisé dans le jargon Pÿthon). Preuve :
    Le module itertools et la méthode tee() vous permettra de créer le nombre d'itérateur que vous souhaitez si j'ai bien compris.

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    Pour la copie d'itérable (je suis en version 3 python pour le test),

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    l, m = [iter(elt) for elt in tee(['a', 'b', 'c'], 2)]
    print(next(l))
    print(next(m))

  8. #8
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Réunissons la question 1 et 2.

    Exemple simple : un parcours d'une séquence de caractère. On veut s'arrêter AVANT le prochain espace. Pour détecter cette espace on est obligé de faire iterator.next() == whitespace. Mais après le .next() nous avons été un pas trop loin. D'où la nécessité de vouloir revenir un pas en arrière.

    En utilisant les itérateurs je veux modéliser un "flux".

    EDIT : Je viens de voir votre dernier message. Effectivement "tee" marche. Merci.
    Malgré tout, je doute que ça soit la meilleure solution à mon problème, il s'agit peut-être plus d'un problème de conception alors.

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    Le plus simple aurait un exemple d'entrée sortie, mais bon...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> ch = 'abc def'
    >>> ch.split()
    ['abc', 'def']
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> ch = 'abc def'
    >>> ch = iter(ch)
    >>> while True:
    	c = next(ch)
    	if c == ' ':
    		break
    	print(c)
     
     
    a
    b
    c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> for i in 'abc def':
    	if i == ' ':
    		break
    	else: print(i)
     
     
    a
    b
    c

  10. #10
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Merci pour ces exemples intéressants. Néanmoins la condition "lorsqu'on trouve un espace" était juste un exemple et peut éventuellement être plus compliqué.

    J'ai édité mon premier message avec une simplification du problème #3 que je vous remet ici :

    Le problème est encore plus simple que cela. J'ai ces deux fichiers :

    test.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    import s
    import os
    import sys
     
    def main(args):
      print GLOBAL_B
     
    if __name__ == '__main__':
        main(sys.argv)
    s.py
    Et l'erreur suivante à l'interprétation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Traceback (most recent call last):
      File "test.py", line 10, in <module>
        main(sys.argv)
      File "test.py", line 7, in main
        print GLOBAL_B
    NameError: global name 'GLOBAL_B' is not defined

  11. #11
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    Merci pour ces exemples intéressants. Néanmoins la condition "lorsqu'on trouve un espace" était juste un exemple et peut éventuellement être plus compliqué.
    Mais s'adapte évidemment

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def main(args):
      print s.GLOBAL_B

  12. #12
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Pour la question 2, cherches-tu à faire un parseur (analyseur syntaxique)? Les expressions régulières (module re dans Python) pourraient être utile dans ce cas.

  13. #13
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    Arf j'ai pas vu, il a édité, j'ai proposé une seule solution, en l'occurence

    surtout car c'est la solution conseillé, d'importer de cette façon

    Ou alors une autre

    Mais surtout pas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from mon_module import *

  14. #14
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    @fred1599 : Pourquoi la dernière solution n'est-elle pas acceptable ? (Je suppose que c'est pour éviter les conflits de nom, dans ce cas, quand est-il du fait qu'on est sur que ce nom de constante ne ré-apparaitra pas ?).

    @dividee : Je vais commencer par le début. N'hésitez pas à commenter ou me contredire sur certains points qui vous semblerais faux.

    Le but est d'analyser une formule dans un fichier. La première étape est de construire un arbre de syntaxe. J'ai décidé que pour rendre l'application plus propre je passerais par un module "Lexer". Il se construit grâce à un itérateur représentant le flux de donnée devant être analysé et, par le biais d'une méthode, renvoie des "Token", classe encapsulant une constante entière représentant un certain caractère (par exemple "/\" (ET logique) représenté par la valeur "1"). Ceci dans le but de dissocié l'interprétation graphique/syntaxique de l'interprétation sémantique de ce symbole. Le parser reçoit donc des Tokens et construira l'arbre syntaxique grâce à eux. C'est également lui qui sera chargé de construire la structure de donnée qui sera utilisée par la suite.

    Donc une expression régulière ne conviendra pas pour ces raisons (confirmez svp.) :

    1. Trop lente par rapport à un module spécialisé (j'accuse la généricité du module "re").
    2. Ne permet pas de renvoyer une abstraction comme le "Token".
    3. Donc un module "Lexer" serait quand même nécessaire.
    4. Mais pour être utile, l'expression régulière devrait analyser l'entièreté de la formule d'abord. Donc on ne peut pas construire notre arbre de syntaxe en une seule passe.


    Merci pour vos réponses.

  15. #15
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    Pourquoi la dernière solution n'est-elle pas acceptable ?
    Réponse:

    Je suppose que c'est pour éviter les conflits de nom
    exact!

    quand est-il du fait qu'on est sur que ce nom de constante ne ré-apparaitra pas ?
    Euh... Pas dis que j'ai compris, mais si tu as le nom du module et la constante à la suite, il y a peu de chance de retrouver la même constante.

    Rien ne t'empêche de nommer tes modules d'un autre nom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import s as module_s
    print(module_s.GLOBAL_B)

  16. #16
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    A vrai dire, je trouve lourd d'importer exactement ce que j'utilise (from XX import bla,bla,bla,...) et lourd aussi de devoir préfixer chaque constantes par le nom de son module. Enfin je vais surement opter pour la première solution.

    Sinon c'est toujours intéressant de savoir qu'on peut renommer des modules merci

  17. #17
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    La 1ère solution et la dernière (renommer ton module) sont identiques.

  18. #18
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    A moins que je me trompe, lorsqu'on fait "from XX import z", on peut accéder à 'z' sans préfixe.

    J'ai également une question sur les itérateurs. A part avec la méthode "next()" il n'est pas possible d'accéder à la valeur actuellement pointée par l'itérateur ?

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    v = "abc"
    a = iter(v)
    # Je veux la lettre 'a' mais sans avancer l'itérateur sur 'b'

  19. #19
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 060
    Par défaut
    A moins que je me trompe, lorsqu'on fait "from XX import z", on peut accéder à 'z' sans préfixe.
    La première méthode était

    J'ai également une question sur les itérateurs. A part avec la méthode "next()" il n'est pas possible d'accéder à la valeur actuellement pointée par l'itérateur ?
    Si

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print('\n'.join([i for i in v]))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i, j in enumerate(v):
        print('index {0} : lettre {1}'.format(i, j))

  20. #20
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Si

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print('\n'.join([i for i in v]))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i, j in enumerate(v):
        print('index {0} : lettre {1}'.format(i, j))
    Ben non, que ce soit avec for ou enumerate, tu consommes l’itérateur*!

    N’y a pas de miracle, un itérateur par construction, ne fournit que next()… Si tu veux bosser sur les éléments n-1, n, n+1, tu peux soit les «*mettre en cache*» (garder les x derniers éléments lus), soit, si ce n’est pas assez souple, convertir l’itérateur un liste, ou mieux (si tu n’a pas besoin de le modifier), en tuple, puis d’utiliser enumerate…

    En tout cas, je ne vois pas d’autre solution –*et s’il s’agit simplement d’interprêter une fonction, convertir l’itérateur en liste ou tuple ne devrait vraiment pas être un problème*!

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. projet avec python
    Par chilo113 dans le forum Général Python
    Réponses: 1
    Dernier message: 01/12/2013, 23h27
  2. [1.x] débuter avec un projet symfony avec Xampp
    Par safa.nasich dans le forum Symfony
    Réponses: 4
    Dernier message: 28/06/2011, 20h17
  3. Projet de simulation avec python
    Par Sam-e dans le forum Programmation multimédia/Jeux
    Réponses: 2
    Dernier message: 10/03/2011, 10h47
  4. [Plugin]Lancement d'un projet JSP sous Eclipse avec Tomcat
    Par samios dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 25/08/2004, 18h03
  5. Débuter avec Java
    Par reptils dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 11/07/2004, 21h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo