Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mon code est lourd

4 views
Skip to first unread message

yves

unread,
May 5, 2022, 3:40:36 PM5/5/22
to
Bonjour,

soit une séquence, un générateur (de tuples en l'occurrence)

('02', 'D', '27')
('02', 'L', '28')
('03', 'M', '01')
('03', 'M', '02')

Pour la petite histoire,
02 et 03 correspondent à Février et Mars
D 27; c'est dimanche 27, etc...


Je voudrais arriver à imprimer:
02
D 27
L 28
03
M 01
M 02

En repassant par un dictionnaire, j'ai ça:

#+begin_src python :results output :exports both

from pprint import pprint

def g():
yield('02', 'D', '27')
yield('02', 'L', '28')
yield('03', 'M', '01')
yield('03', 'M', '02')


dic = {}
l02,l03 = [],[]
for elt in g():
m , d, nd = elt
if m == "02":
l02.append((d,nd))
dic['02'] = l02
elif m == "03":
l03.append((d,nd))
dic['03'] = l03

pprint(dic)


#+end_src
#+RESULTS:
: {'02': [('D', '27'), ('L', '28')], '03': [('M', '01'), ('M', '02')]}

Et à partir du dictionnaire, l'impression finale est facile.

Mais cette méthode de conversion du générateur en dictionnaire me
paraît terriblement lourde, surtout qu'il y aura douze mois, c'est à
dire douze branchement if/elif

Vous auriez des suggestions d'écriture plus élégante ?


@+
--
Yves

yves

unread,
May 5, 2022, 3:42:14 PM5/5/22
to
Le Thu, 05 May 2022 19:40:34 +0000, yves a écrit:

> Je voudrais arriver à imprimer:
> 02 D 27 L 28 03 M 01 M 02

Zut, la mise en page a sautée.
Je voudrais arriver à imprimer:

02
D 27
L 28
03
M 01
M 02


@+
--
Yves

yves

unread,
May 5, 2022, 3:43:07 PM5/5/22
to
Le Thu, 05 May 2022 19:42:13 +0000, yves a écrit:

> Zut, la mise en page a sautée. Je voudrais arriver à imprimer:
>
> 02 D 27 L 28 03 M 01 M 02

Rezut.

yves

unread,
May 5, 2022, 3:47:35 PM5/5/22
to
Le Thu, 05 May 2022 19:43:05 +0000, yves a écrit:

>> Zut, la mise en page a sautée. Je voudrais arriver à imprimer:
>>
>> 02 D 27 L 28 03 M 01 M 02
>
> Rezut.

Bon, la mise en page est bonne dans Gnus, mais pas dans Pan 0.144

@+
--
Yves

Benoit Izac

unread,
May 5, 2022, 4:12:09 PM5/5/22
to
Bonjour,

Le 05/05/2022 à 21:40, yves <yv...@free.invalid> a écrit dans le message
<62742832$0$22051$426a...@news.free.fr> :

> from pprint import pprint
>
> def g():
> yield('02', 'D', '27')
> yield('02', 'L', '28')
> yield('03', 'M', '01')
> yield('03', 'M', '02')
>
>
> dic = {}
> l02,l03 = [],[]
> for elt in g():
> m , d, nd = elt
> if m == "02":
> l02.append((d,nd))
> dic['02'] = l02
> elif m == "03":
> l03.append((d,nd))
> dic['03'] = l03
>
> pprint(dic)
>
> [...]
>
> Mais cette méthode de conversion du générateur en dictionnaire me
> paraît terriblement lourde, surtout qu'il y aura douze mois, c'est à
> dire douze branchement if/elif
>
> Vous auriez des suggestions d'écriture plus élégante ?

dic = {}
for m, d, nd in g():
dic.setdefault(m, []).append((d, nd))
pprint(dic)

--
Benoit Izac

Alain Ketterlin

unread,
May 5, 2022, 4:26:22 PM5/5/22
to
yves <yv...@free.invalid> writes:

> ('02', 'D', '27') ('02', 'L', '28') ('03', 'M', '01') ('03', 'M', '02')

> Je voudrais arriver à imprimer:
> 02
> D 27
> L 28
> 03
> M 01
> M 02
>
> def g():
> yield('02', 'D', '27')
> yield('02', 'L', '28')
> yield('03', 'M', '01')
> yield('03', 'M', '02')
>
>
> dic = {}
> l02,l03 = [],[]
> for elt in g():
> m , d, nd = elt
> if m == "02":
> l02.append((d,nd))
> dic['02'] = l02
> elif m == "03":
> l03.append((d,nd))
> dic['03'] = l03
>
> pprint(dic)

> Vous auriez des suggestions d'écriture plus élégante ?

Note qu'il est inutile de garder tes listes "en double", mais qu'il
faut alors tester leur présence dans le dictionnaire :

for elt in g():
m , d, nd = elt
if m not in dic:
dic[m] = []
dic[m].append ((d,nd))

C'est à peu près exactement ce que fait la méthode setdefault() de dict,
donc on peut raccourcir :

for m, d, nd in g():
dic.setdefault (m, []).append ((d,nd))

Note qu'on s'épargne aussi la variable "elt", puisqu'on peut
destructurer directement dans le "for".

Si ça ne te gène pas d'avoir des listes au lieu des paires, on peut
faire encore un peu plus court :

for m, *r in g():
dic.setdefault (m, []).append (r)

Cela dit, puisqu'il y a douze mois, et que j'imagine que tu auras des
dates dans chaque mois, autant créer d'emblée les listes vides, ce qui
épargne de répéter le test pour chaque date :

dic = { "{:02d}".format (i+1) : [] for i in range (12) }
for m,*r in g():
dic[m].append (r)

(Au passage : pourquoi utiliser des chaînes de caractères pour les mois ?
Un entier serait plus simple à manipuler.)

-- Alain.

Dominique

unread,
May 6, 2022, 12:40:56 AM5/6/22
to
Le 05/05/2022 à 22:26, Alain Ketterlin a écrit :

> dic = { "{:02d}".format (i+1) : [] for i in range (12) }

Je ne connaissais pas du tout cette méthode pour formater un
dictionnaire. C'est très intéressant, merci :-)

Je découvre l'utilisation du d après avoir, par hasard, testé x
(hexadécimal) puis, bien sûr, o pour octal et b pour binaire.

Je comprends moins bien la sortie avec c et surtout au-delà de 8 :

'0\x08': [],
'0\t': [],
'0\n': [],
'0\x0b': [],
'0\x0c': []

Ce qu'il y a de bien avec Python, c'est que je n'en verrai jamais le
bout :-)

Dominique


Alain Ketterlin

unread,
May 6, 2022, 5:30:17 AM5/6/22
to
Dominique <z...@aol.com.invalid> writes:

> Le 05/05/2022 à 22:26, Alain Ketterlin a écrit :
>
>> dic = { "{:02d}".format (i+1) : [] for i in range (12) }
>
> Je ne connaissais pas du tout cette méthode pour formater un
> dictionnaire. C'est très intéressant, merci :-)

Pour être précis : il ne s'agit pas de formater un dictionnaire, mais de
formater des nombres qui servent de clés dans le dictionnaire.

En fait, je préfère « "%02d" % (i+1) » mais c'est parce que j'ai plus
l'habitude de printf en C.

> Je découvre l'utilisation du d après avoir, par hasard, testé x
> (hexadécimal) puis, bien sûr, o pour octal et b pour binaire.

Oui, ce sont toutes les façons de formater un nombre entier. "02d"
signifie "écriture décimale" (d) sur 2 caractères au moins, en
remplissant à gauche avec des "0" si nécessaire.

> Je comprends moins bien la sortie avec c et surtout au-delà de 8 :

"c" signifie caractère, le préfixe "0" est pris comme caractère de
remplissage, et le "2" signifie toujours la largeur minimale du
résultat.

> '0\x08': [],
> '0\t': [],
> '0\n': [],
> '0\x0b': [],
> '0\x0c': []

Cela revient à demander de formater des caractères de codes 8, 9, etc.
sur 2 caractères. Toutes les chaînes ci-dessus ont bien une longueur 2,
mais il faut utiliser des notations pour représenter ceux qui n'ont pas
de glyphe particulier (tous ici). Avec "{:02c}".format(97), on obtient
'0a' ('a' est le caractère de code 97). Le cas de 9 et 10 est spécial
parce qu'il existe une notation, mais '\t' par exemple a exactement le
même sens que '\x09' (et '\n' que '\0x0a').

-- Alain.

yves

unread,
May 6, 2022, 9:22:34 AM5/6/22
to
Le Thu, 05 May 2022 22:12:08 +0200, Benoit Izac a écrit:

>> Vous auriez des suggestions d'écriture plus élégante ?
>
> dic = {}
> for m, d, nd in g():
> dic.setdefault(m, []).append((d, nd))
> pprint(dic)

Merci, c'est en plein dans le mille.

@+
--
Yves

yves

unread,
May 6, 2022, 9:42:17 AM5/6/22
to
Le Thu, 05 May 2022 22:26:20 +0200, Alain Ketterlin a écrit:

> (Au passage : pourquoi utiliser des chaînes de caractères pour les mois
> ?
> Un entier serait plus simple à manipuler.)

Merci pour toute cette matière à réflexion.


Pour ce qui est des chaînes de caractères, c'est surtout que j'ai épuré
au maximum mon exposé du problème.

En réalité, ma source de donnée actuelle c'est plutôt ce code là:

***

#+begin_src python :results output :exports both

from datetime import datetime, timedelta, date

def genereXdates2():
dateDepart = "26012022"
dateFin = "07052022"
depart = datetime.strptime(dateDepart, '%d%m%Y')
fin = datetime.strptime(dateFin, '%d%m%Y')
date = depart
dict_transcodage = {"6": "S", "0": "D", "1":"L", "2":"M", "3":"M",
"4":"J", "5":"V"}
while date != fin:

yield(date.strftime("%m"),dict_transcodage[date.strftime('%w')],date.strftime('%d'))
date = date + timedelta(1)

for elt in genereXdates2():
print(elt)

#+end_src

****


@+
--
Yves

Dominique

unread,
May 6, 2022, 9:43:59 AM5/6/22
to
Le 06/05/2022 à 11:30, Alain Ketterlin a écrit :

> "c" signifie caractère, le préfixe "0" est pris comme caractère de
> remplissage, et le "2" signifie toujours la largeur minimale du
> résultat.
>
>> '0\x08': [],
>> '0\t': [],
>> '0\n': [],
>> '0\x0b': [],
>> '0\x0c': []

Merci Alain. Je vais regarder ça de plus près, quand j'aurai le temps, à
la retraite... dans un mois :-)

Alain Ketterlin

unread,
May 6, 2022, 3:46:04 PM5/6/22
to
yves <yv...@free.invalid> writes:

> Le Thu, 05 May 2022 22:26:20 +0200, Alain Ketterlin a écrit:
>
>> (Au passage : pourquoi utiliser des chaînes de caractères pour les mois
>> ?
>> Un entier serait plus simple à manipuler.)

> Pour ce qui est des chaînes de caractères, c'est surtout que j'ai épuré
> au maximum mon exposé du problème.

C'était juste une remarque en passant.

> En réalité, ma source de donnée actuelle c'est plutôt ce code là:

> from datetime import datetime, timedelta, date
>
> def genereXdates2():
> dateDepart = "26012022"
> dateFin = "07052022"
> depart = datetime.strptime(dateDepart, '%d%m%Y')
> fin = datetime.strptime(dateFin, '%d%m%Y')
> date = depart
> dict_transcodage = {"6": "S", "0": "D", "1":"L", "2":"M", "3":"M",
> "4":"J", "5":"V"}
> while date != fin:
>
> yield(date.strftime("%m"),dict_transcodage[date.strftime('%w')],date.strftime('%d'))
> date = date + timedelta(1)

Je proposais d'utiliser à la place :

yield (date.month, "LMMJVSD"[date.weekday()], date.day)

(attention, weekday() ne suit pas la même convention que "%w" pour strftime).

C'est toi qui voit.

-- Alain.

yves

unread,
May 6, 2022, 4:50:53 PM5/6/22
to
Le Fri, 06 May 2022 21:46:00 +0200, Alain Ketterlin a écrit:

> Je proposais d'utiliser à la place :
>
> yield (date.month, "LMMJVSD"[date.weekday()], date.day)
>
> (attention, weekday() ne suit pas la même convention que "%w" pour
> strftime).
>
> C'est toi qui voit.

Merci, je vais utiliser ta ligne de code.

Mon objectif est d'obtenir sur écran un aspect (graphique) analogue à un
calendrier carton (ces petits calendriers d'un format approximatif A4
qu'on trouve dans toutes les entreprises).


@+
--
Yves

yamo'

unread,
May 9, 2022, 3:56:14 AM5/9/22
to
yves a écrit :
C'est sûrement la fonction wrap de Pan qui te joue des tours...

--
Stéphane

yves

unread,
May 9, 2022, 4:32:25 AM5/9/22
to
Le Mon, 09 May 2022 07:56:13 +0000, yamo' a écrit:

>> Bon, la mise en page est bonne dans Gnus, mais pas dans Pan 0.144
>
>
> C'est sûrement la fonction wrap de Pan qui te joue des tours...

Ah, oui. Misère. Ce n'est pas la première fois, en plus.


@+
--
Yves
0 new messages