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

Problème d'init de variables

20 réponses
Avatar
NicolasP
Bonjour,

Dans un programme avec interface graphique wxPython, j'ai un objet graphique de type liste virtuelle qui possède plusieurs colonnes.
Ces colonnes sont initialisées par mon code comme ceci.

self.columns = [u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité"]
index = 0
for c in self.columns :
self.InsertColumn (index, c)
index += 1

En changeant l'ordre des éléments dans self.columns, je peux changer l'ordre d'affichage des colonnes dans la liste.

Mon problème est que partout ailleurs dans le code, c'est le numéro de colonne qui est utilisé.
Par exemple, wxPython envoie un évènement à mon application pour demander le contenu de la colonne x de la ligne y.
Je fais alors :
if x == self.columns.index(u"Nom") :
...
elif x == self.columns.index(u"Mouvement") :
...
etc

Ca marche mais ça ne me plait pas. Et bonjour les bugs quand je changerais un nom de colonne un jour.
Et je ne peux pas non plus changer l'ordre des colonnes dynamiquement pendant l'exécution.

J'aimerais remplir des variables contenant le numéro de colonne automatiquement à l'init.
J'ai pensé à un truc du genre :

self.col_nom = 0
self.col_mouvement = 0
self.col_affectation = 0
self.col_montant = 0
self.col_observation = 0
self.col_date_debut = 0
self.col_date_fin = 0
self.col_periode = 0
self.columns = ((u"Nom" , self.col_nom),
(u"Mouvement" , self.col_mouvement),
(u"Affectation" , self.col_affectation),
(u"Montant" , self.col_montant),
(u"Observation" , self.col_observation),
(u"Date début" , self.col_date_debut),
(u"Date fin" , self.col_date_fin),
(u"Périodicité" , self.col_periode))
index = 0
for k,v in self.columns :
self.InsertColumn (index, k)
# Je fais quoi avec v ?
index += 1

Mais après je fais comment pour affecter une valeur aux variables self.col_xxx ?
Il n'y a pas de pointeurs en Python mais c'est bien un truc du genre qu'il me faudrait ici.

Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom" , "self.col_nom"),
(u"Mouvement" , "self.col_mouvement"),
(u"Affectation" , "self.col_affectation"),
(u"Montant" , "self.col_montant"),
(u"Observation" , "self.col_observation"),
(u"Date début" , "self.col_date_debut"),
(u"Date fin" , "self.col_date_fin"),
(u"Périodicité" , "self.col_periode"))
for k,v in self.columns :
self.InsertColumn (index, k)
exec(v+"=%d"%index)
index += 1

Quelqu'un aurait-il une belle solution à me proposer ?

Nicolas

10 réponses

1 2
Avatar
Alain Ketterlin
NicolasP writes:

[...]
self.columns = [u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité"]



[...]
En changeant l'ordre des éléments dans self.columns, je peux ch anger
l'ordre d'affichage des colonnes dans la liste.



Il me semble que wxWidgets permet de déplacer des colonnes à
l'exécution. Je ne connais pas le binding python, mais je me souviens de
GetColAt. Si c'est effectivement le cas, cela devrait te simplifier la
vie.

if x == self.columns.index(u"Nom") :
...



Hmmm, j'aurais fait ; if self.columns[x] == u"Nom", histoire d'évi ter la
recherche dans la liste...

Ca marche mais ça ne me plait pas. Et bonjour les bugs quand je
changerais un nom de colonne un jour.


[...]

Je ne peux pas t'en dire plus, mais vérifie vraiment ce que permet
wxWidgets, je serais surpris qu'il ne fasse pas le travail lui-même, et
te permette d'obtenir un numéro de colonne "absolu", càd indà ©pendant des
différents déplacements. Auquel cas ta première approche est sûrement la
plus simple.

-- Alain.
Avatar
NicolasP
Le 13/10/2010 11:56, Alain Ketterlin a écrit :
NicolasP writes:

[...]
self.columns = [u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité"]



[...]
En changeant l'ordre des éléments dans self.columns, je peux changer
l'ordre d'affichage des colonnes dans la liste.



Il me semble que wxWidgets permet de déplacer des colonnes à
l'exécution. Je ne connais pas le binding python, mais je me souviens de
GetColAt. Si c'est effectivement le cas, cela devrait te simplifier la
vie.

if x == self.columns.index(u"Nom") :
...



Hmmm, j'aurais fait ; if self.columns[x] == u"Nom", histoire d'éviter la
recherche dans la liste...



Effectivement, ça serait plus efficace.

Ca marche mais ça ne me plait pas. Et bonjour les bugs quand je
changerais un nom de colonne un jour.


[...]

Je ne peux pas t'en dire plus, mais vérifie vraiment ce que permet
wxWidgets, je serais surpris qu'il ne fasse pas le travail lui-même, et
te permette d'obtenir un numéro de colonne "absolu", càd indépendant des
différents déplacements. Auquel cas ta première approche est sûrement la
plus simple.


je n'ai pas souvenir de cette fonctionnalité.
Je vais chercher...

Merci

Nicolas


-- Alain.
Avatar
cémoi
Salut,

ta requête me parait quelque peu confuse, mais je vais essayer de faire
quelques
suggestions ...

Le 13/10/2010 10:05, NicolasP a écrit :
Bonjour,

Dans un programme avec interface graphique wxPython, j'ai un objet
graphique de type liste virtuelle qui possède plusieurs colonnes.
Ces colonnes sont initialisées par mon code comme ceci.

self.columns = [u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité"]
index = 0
for c in self.columns :
self.InsertColumn (index, c)
index += 1



Ici on peut faire plus court:

for index, c in enumerate(self.columns):
self.InsertColumn(index, c)

ou même:

[self.insertColumn(index, c) for index, c in enumerate(self.columns)]


<snip>


Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom" , "self.col_nom"),
(u"Mouvement" , "self.col_mouvement"),
(u"Affectation" , "self.col_affectation"),
(u"Montant" , "self.col_montant"),
(u"Observation" , "self.col_observation"),
(u"Date début" , "self.col_date_debut"),
(u"Date fin" , "self.col_date_fin"),
(u"Périodicité" , "self.col_periode"))
for k,v in self.columns :
self.InsertColumn (index, k)
exec(v+"=%d"%index)
index += 1



for i, (k, v) in enumerate(self.columns):
self.InsertColumn(i, k)
v = i


Un peu de relecture du didacticiel Python n'est peut-être pas superflu :)
Tu verras qu'une fois que tu sauras manipuler les listes, les tuples et les
dictionnaires avec aisance tu trouveras certainement un code plus direct
et plus élégant.

HTH,

Laurent
Avatar
bruno.desthuilliers
On 13 oct, 18:11, cémoi wrote:

for index, c in enumerate(self.columns):
        self.InsertColumn(index, c)

ou même:

[self.insertColumn(index, c) for index, c in enumerate(self.columns)]




Ce qui génère une liste pour rien et n'améliore en rien la lisibilit é.
Avatar
bruno.desthuilliers
On 13 oct, 10:05, NicolasP wrote:
(snip)

Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom"         , "self.col_nom"),
                 (u"Mouvement"   , "self.col_mouvemen t"),
                 (u"Affectation" , "self.col_affectatio n"),
                 (u"Montant"     , "self.col_montan t"),
                 (u"Observation" , "self.col_observatio n"),
                 (u"Date début"  , "self.col_date_d ebut"),
                 (u"Date fin"    , "self.col_date_f in"),
                 (u"Périodicité" , "self.col_period e"))
for k,v in self.columns :



for index, (k, v) in enumerate(self.columns):

     self.InsertColumn (index, k)
     exec(v+"=%d"%index)


Quelqu'un aurait-il une belle solution à me proposer ?



Tu peux déja supprimer les "self." et utiliser setattr:

self.columns = ((u"Nom" , "col_nom"),
(u"Mouvement" , "col_mouvement"),
(u"Affectation" , "col_affectation"),
(u"Montant" , "col_montant"),
(u"Observation" , "col_observation"),
(u"Date début" , "col_date_debut"),
(u"Date fin" , "col_date_fin"),
(u"Périodicité" , "col_periode"))
for index, (name, attr) in enumerate(self.columns):
self.InsertColumn (index, name)
setattr(self, attr, index)


Ou bien plus simplement utiliser un dict:

self.columns_index = {}
self.columns = (u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité")

for index, name in self.columns:
self.InsertColumn(index, name)
self.columns_index[index] = name

# dans le gestionnaire d'évènements
colname = self.colums_index[x]

Ceci étant, ça continue à me paraitre bancal comme truc, et comme
toutes les solutions bancales, la solution est généralement dans 1/
une meilleure compréhension de l'outil (ici wxWidgets) et 2/ la
structure de données appropriée.
Avatar
cémoi
Le 13/10/2010 19:50, a écrit :
On 13 oct, 18:11, cémoi wrote:

for index, c in enumerate(self.columns):
self.InsertColumn(index, c)

ou même:

[self.insertColumn(index, c) for index, c in enumerate(self.columns)]




Ce qui génère une liste pour rien et n'améliore en rien la lisibilité.



Oui, mauvais exemple de ma part, désolé !
Avatar
Pierre Quentel
On 13 oct, 10:05, NicolasP wrote:
Bonjour,

Dans un programme avec interface graphique wxPython, j'ai un objet graphi que de type liste virtuelle qui possède plusieurs colonnes.
Ces colonnes sont initialisées par mon code comme ceci.

self.columns = [u"Nom",
                 u"Mouvement",
                 u"Affectation",
                 u"Montant",
                 u"Observation",
                 u"Date début",
                 u"Date fin",
                 u"Périodicité"]
index = 0
for c in self.columns :
     self.InsertColumn (index, c)
     index += 1

En changeant l'ordre des éléments dans self.columns, je peux changer l'ordre d'affichage des colonnes dans la liste.

Mon problème est que partout ailleurs dans le code, c'est le numéro d e colonne qui est utilisé.
Par exemple, wxPython envoie un évènement à mon application pour de mander le contenu de la colonne x de la ligne y.
Je fais alors :
if x == self.columns.index(u"Nom") :
...
elif x == self.columns.index(u"Mouvement") :
...
etc

Ca marche mais ça ne me plait pas. Et bonjour les bugs quand je changer ais un nom de colonne un jour.
Et je ne peux pas non plus changer l'ordre des colonnes dynamiquement pen dant l'exécution.

J'aimerais remplir des variables contenant le numéro de colonne automat iquement à l'init.
J'ai pensé à un truc du genre :

self.col_nom = 0
self.col_mouvement = 0
self.col_affectation = 0
self.col_montant = 0
self.col_observation = 0
self.col_date_debut = 0
self.col_date_fin = 0
self.col_periode = 0
self.columns = ((u"Nom"         , self.col_nom),
                 (u"Mouvement"   , self.col_mouvement ),
                 (u"Affectation" , self.col_affectation ),
                 (u"Montant"     , self.col_montant ),
                 (u"Observation" , self.col_observation ),
                 (u"Date début"  , self.col_date_de but),
                 (u"Date fin"    , self.col_date_fi n),
                 (u"Périodicité" , self.col_periode ))
index = 0
for k,v in self.columns :
     self.InsertColumn (index, k)
     # Je fais quoi avec v ?
     index += 1

Mais après je fais comment pour affecter une valeur aux variables self. col_xxx ?
Il n'y a pas de pointeurs en Python mais c'est bien un truc du genre qu'i l me faudrait ici.

Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom"         , "self.col_nom"),
                 (u"Mouvement"   , "self.col_mouvemen t"),
                 (u"Affectation" , "self.col_affectatio n"),
                 (u"Montant"     , "self.col_montan t"),
                 (u"Observation" , "self.col_observatio n"),
                 (u"Date début"  , "self.col_date_d ebut"),
                 (u"Date fin"    , "self.col_date_f in"),
                 (u"Périodicité" , "self.col_period e"))
for k,v in self.columns :
     self.InsertColumn (index, k)
     exec(v+"=%d"%index)
     index += 1

Quelqu'un aurait-il une belle solution à me proposer ?

Nicolas



Bonjour,

Une suggestion : tu peux compléter la liste des colonnes en associant
à chaque nom une méthode qui va gérer l'événement correspondant :

self.columns = [(u"Nom",self.gere_nom),
(u"Mouvement",self.gere_mvt),
etc...
]

L'initialisation devient :

for index,c in enumerate(self.columns) :
self.InsertColumn (index, c[0])
index += 1

Quand tu reçois l'événement référencé par le numéro de colonn e, tu
récupères le gestionnaire d'événement :

gestionnaire = self.columns[x][1]

et après il ne reste plus qu'à l'exécuter, avec les éventuels
paramètres passés par wxPython, genre :

gestionnaire(y)

- Pierre
Avatar
NicolasP
Le 13/10/2010 18:11, cémoi a écrit :
Salut,

ta requête me parait quelque peu confuse, mais je vais essayer de faire quelques
suggestions ...

Le 13/10/2010 10:05, NicolasP a écrit :
Bonjour,

Dans un programme avec interface graphique wxPython, j'ai un objet
graphique de type liste virtuelle qui possède plusieurs colonnes.
Ces colonnes sont initialisées par mon code comme ceci.

self.columns = [u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité"]
index = 0
for c in self.columns :
self.InsertColumn (index, c)
index += 1



Ici on peut faire plus court:

for index, c in enumerate(self.columns):
self.InsertColumn(index, c)



Effectivement, c'est mieux comme ça.

ou même:

[self.insertColumn(index, c) for index, c in enumerate(self.columns)]


<snip>


Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom" , "self.col_nom"),
(u"Mouvement" , "self.col_mouvement"),
(u"Affectation" , "self.col_affectation"),
(u"Montant" , "self.col_montant"),
(u"Observation" , "self.col_observation"),
(u"Date début" , "self.col_date_debut"),
(u"Date fin" , "self.col_date_fin"),
(u"Périodicité" , "self.col_periode"))
for k,v in self.columns :
self.InsertColumn (index, k)
exec(v+"=%d"%index)
index += 1



for i, (k, v) in enumerate(self.columns):
self.InsertColumn(i, k)
v = i



v = i ?
Je te renvoie a ce que tu as écrit ci-dessous ;)


Un peu de relecture du didacticiel Python n'est peut-être pas superflu :)
Tu verras qu'une fois que tu sauras manipuler les listes, les tuples et les
dictionnaires avec aisance tu trouveras certainement un code plus direct
et plus élégant.



C'est justement parce que je n'ai pas trouvé par moi-même que je pose la question ici.
Sinon, à quoi servirait ce news group ?

Nicolas


HTH,

Laurent

Avatar
NicolasP
Le 13/10/2010 20:01, a écrit :
On 13 oct, 10:05, NicolasP wrote:
(snip)

Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom" , "self.col_nom"),
(u"Mouvement" , "self.col_mouvement"),
(u"Affectation" , "self.col_affectation"),
(u"Montant" , "self.col_montant"),
(u"Observation" , "self.col_observation"),
(u"Date début" , "self.col_date_debut"),
(u"Date fin" , "self.col_date_fin"),
(u"Périodicité" , "self.col_periode"))
for k,v in self.columns :



for index, (k, v) in enumerate(self.columns):

self.InsertColumn (index, k)
exec(v+"=%d"%index)




Quelqu'un aurait-il une belle solution à me proposer ?



Tu peux déja supprimer les "self." et utiliser setattr:

self.columns = ((u"Nom" , "col_nom"),
(u"Mouvement" , "col_mouvement"),
(u"Affectation" , "col_affectation"),
(u"Montant" , "col_montant"),
(u"Observation" , "col_observation"),
(u"Date début" , "col_date_debut"),
(u"Date fin" , "col_date_fin"),
(u"Périodicité" , "col_periode"))
for index, (name, attr) in enumerate(self.columns):
self.InsertColumn (index, name)
setattr(self, attr, index)


Ou bien plus simplement utiliser un dict:

self.columns_index = {}
self.columns = (u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité")

for index, name in self.columns:
self.InsertColumn(index, name)
self.columns_index[index] = name

# dans le gestionnaire d'évènements
colname = self.colums_index[x]

Ceci étant, ça continue à me paraitre bancal comme truc, et comme
toutes les solutions bancales, la solution est généralement dans 1/
une meilleure compréhension de l'outil (ici wxWidgets) et 2/ la
structure de données appropriée.




C'est justement ce que je cherche. Un truc pas bancal.

Nicolas
Avatar
NicolasP
Le 14/10/2010 09:39, Pierre Quentel a écrit :
On 13 oct, 10:05, NicolasP wrote:
Bonjour,

Dans un programme avec interface graphique wxPython, j'ai un objet graphique de type liste virtuelle qui possède plusieurs colonnes.
Ces colonnes sont initialisées par mon code comme ceci.

self.columns = [u"Nom",
u"Mouvement",
u"Affectation",
u"Montant",
u"Observation",
u"Date début",
u"Date fin",
u"Périodicité"]
index = 0
for c in self.columns :
self.InsertColumn (index, c)
index += 1

En changeant l'ordre des éléments dans self.columns, je peux changer l'ordre d'affichage des colonnes dans la liste.

Mon problème est que partout ailleurs dans le code, c'est le numéro de colonne qui est utilisé.
Par exemple, wxPython envoie un évènement à mon application pour demander le contenu de la colonne x de la ligne y.
Je fais alors :
if x == self.columns.index(u"Nom") :
...
elif x == self.columns.index(u"Mouvement") :
...
etc

Ca marche mais ça ne me plait pas. Et bonjour les bugs quand je changerais un nom de colonne un jour.
Et je ne peux pas non plus changer l'ordre des colonnes dynamiquement pendant l'exécution.

J'aimerais remplir des variables contenant le numéro de colonne automatiquement à l'init.
J'ai pensé à un truc du genre :

self.col_nom = 0
self.col_mouvement = 0
self.col_affectation = 0
self.col_montant = 0
self.col_observation = 0
self.col_date_debut = 0
self.col_date_fin = 0
self.col_periode = 0
self.columns = ((u"Nom" , self.col_nom),
(u"Mouvement" , self.col_mouvement),
(u"Affectation" , self.col_affectation),
(u"Montant" , self.col_montant),
(u"Observation" , self.col_observation),
(u"Date début" , self.col_date_debut),
(u"Date fin" , self.col_date_fin),
(u"Périodicité" , self.col_periode))
index = 0
for k,v in self.columns :
self.InsertColumn (index, k)
# Je fais quoi avec v ?
index += 1

Mais après je fais comment pour affecter une valeur aux variables self.col_xxx ?
Il n'y a pas de pointeurs en Python mais c'est bien un truc du genre qu'il me faudrait ici.

Je vois bien une solution avec exec mais je trouve ça moche:

self.columns = ((u"Nom" , "self.col_nom"),
(u"Mouvement" , "self.col_mouvement"),
(u"Affectation" , "self.col_affectation"),
(u"Montant" , "self.col_montant"),
(u"Observation" , "self.col_observation"),
(u"Date début" , "self.col_date_debut"),
(u"Date fin" , "self.col_date_fin"),
(u"Périodicité" , "self.col_periode"))
for k,v in self.columns :
self.InsertColumn (index, k)
exec(v+"=%d"%index)
index += 1

Quelqu'un aurait-il une belle solution à me proposer ?

Nicolas



Bonjour,

Une suggestion : tu peux compléter la liste des colonnes en associant
à chaque nom une méthode qui va gérer l'événement correspondant :

self.columns = [(u"Nom",self.gere_nom),
(u"Mouvement",self.gere_mvt),
etc...
]

L'initialisation devient :

for index,c in enumerate(self.columns) :
self.InsertColumn (index, c[0])
index += 1

Quand tu reçois l'événement référencé par le numéro de colonne, tu
récupères le gestionnaire d'événement :

gestionnaire = self.columns[x][1]

et après il ne reste plus qu'à l'exécuter, avec les éventuels
paramètres passés par wxPython, genre :

gestionnaire(y)

- Pierre



Bonjour Pierre,

Ton idée me plait.
J'essaie ça ce soir.

Nicolas
1 2