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

Faire un relevé de notes plus ou moins automatiquement ...

6 réponses
Avatar
Francois
Bonjour à tous,

en fait j'avais posé la question sur fr.comp.text.tex, car je voulais
utiliser LaTeX (une sorte de traitement de texte pour faire simple) pour
faire mes relevés de notes en pdf. L'aspect LaTeX est réglé, mais LaTeX
ne fait pas tout, il y a Python qui intervient (de manière cruciale)
dans l'histoire. Je voudrais donc avoir des précisions sur l'aspect
Python du problème. Je vais vous expliquer les choses en partant de 0,
mais pour ceux que ça intéresse, voici le lien vers la discussion que
j'ai eu sur fr.comp.text.tex.

http://groups.google.fr/group/fr.comp.text.tex/browse_thread/thread/ee11c3d1199deff3/258ca20017015d6f#258ca20017015d6f

Avec un tableur (OpenOffice chez moi), j'ai toutes les notes des élèves
d'une classe à un bac blanc. Du fichier tableur, je tire un fichier
notes.csv qui est comme ceci : (je simplifie un peu)

Nom;Français;EPS;Mathématiques;Moyennes
frédéric Machin;15;15;12;14
Jean Bidul;19;10,5;2;10,5
Maurice Truc;12;8;10;10

Le séparateur est ";" est à chaque ligne correspond un élève avec toutes
ces notes. Evidemment, il y a bien plus d'élèves (c'est un exemple).

Je voulais trouver un code Python qui me crée, à partir de notes.csv, un
fichier notes.tex qui serait *exactement* comme ça :

\deffield{Nom}{frédéric Machin}
\deffield{Français}{15}
\deffield{EPS}{15}
\deffield{Mathématiques}{12}
\deffield{Moyennes}{14}
\go

\deffield{Nom}{Jean Bidul}
\deffield{Français}{19}
\deffield{EPS}{10,5}
\deffield{Mathématiques}{2}
\deffield{Moyennes}{10,5}
\go

\deffield{Nom}{Maurice Truc}
\deffield{Français}{12}
\deffield{EPS}{8}
\deffield{Mathématiques}{10}
\deffield{Moyennes}{10}
\go

Après, on rentre dans la partie LaTeX du problème. Ce n'est pas le
propos ici. J'explique en bref les étapes :
Le code ci-dessus est en fait du code LaTeX, qui me sert à créer mes
lettres. En fait, une fois que je dispose notes.tex, je tape en ligne de
commande :

pdflatex lettres.tex

où lettres.tex est un fichier LaTeX qui utilise notes.tex (en fait
lettres.tex va tout simplement inclure notes.tex dans son propre code)
pour créer lettres.pdf qui sera un simple pdf avec tout mes lettres (une
page = une lettre pour un parent d'élève).

J'espère que c'est clair.

Bref, de toute façon, c'est la partie Python qui m'intéresse, celle qui
transforme notes.csv ----> notes.tex.


Voici un code (baptisé csv2tex.py) qui marche je crois :

##################################################
# -*- coding:Utf-8 -*-

# Transforme une chaîne de caractères avec des ";"
# en séquence avec dans chaque "cellule" les mots
# délimités pas les ";"
def seq_ligne ( chaine ) :

SEPARATEUR = ";"
i = 0
seq = []
mot = ""

while (i < len(chaine) ) :
if ( chaine[i] == SEPARATEUR or chaine[i] == '\n' ):
seq = seq + [mot]
mot = ""
else :
mot = mot + chaine[i]
i = i + 1

return seq


# On ouvre le fichier source pour générer
# le fichier cible

source = raw_input('Entrer le nom de la source : ')
cible = raw_input('Entrer le nom de la cible : ')

fichier_source = open(source, 'r')
fichier_cible = open(cible, 'w')


noms_de_champs = seq_ligne ( fichier_source.readline() )
seqN = seq_ligne ( fichier_source.readline() )



while ( seqN != [] ) :
i = 0
while ( i < len(noms_de_champs) ) :
fichier_cible.write( "\\deffield{" )
fichier_cible.write( noms_de_champs[i] )
fichier_cible.write( "}{" + seqN[i] + "}\n" )
i = i + 1
fichier_cible.write( "\\go\n\n" )
seqN = seq_ligne ( fichier_source.readline() )


fichier_source.close()
fichier_cible.close()
##################################################


Voici mes questions :

1) Il paraît qu'il y a vraiment plus court avec des modules pour les
csv. Je ne connais absolument pas tout ça, serait-ce possible d'avoir un
exemple, ou des pistes ?

2) En fait, mon code ne fait qu'une simple transformation notes.csv --->
notes.tex. Je suis obligé de taper ensuite à la main (en ligne de
commande dans le répertoire courant)

pdflatex lettres.tex


J'aimerais bien que le script Python fasse aussi cela pour moi. Je ne
sais pas faire. Pourrais-je avoir une piste également ?


Merci d'avance.


François

6 réponses

Avatar
asrenzo
Bonjour,

Voici une piste à arranger à votre sauce.

#########################################
# -*- coding:Utf-8 -*-
import csv, os

MODEL = """deffield{Nom}{%s}
deffield{Français}{%s}
deffield{EPS}{%s}
deffield{Mathématiques}{%s}
deffield{Moyennes}{%s}
go

"""

notes = list(csv.reader(open("notes.csv", "rb"), delimiter=';',
quoting=csv.QUOTE_NONE))

fic = open('notes.tex','w')
for elem in notes[1:]:
fic.write(MODEL %(elem[0], elem[1], elem[2], elem[3], elem[4]))

fic.close

#########################################

Pour lancer la conversion, regardez popen, popen2, popen3, os.system ...




Bonjour à tous,

en fait j'avais posé la question sur fr.comp.text.tex, car je voulais
utiliser LaTeX (une sorte de traitement de texte pour faire simple) pour
faire mes relevés de notes en pdf. L'aspect LaTeX est réglé, mais LaTeX
ne fait pas tout, il y a Python qui intervient (de manière cruciale)
dans l'histoire. Je voudrais donc avoir des précisions sur l'aspect
Python du problème. Je vais vous expliquer les choses en partant de 0,
mais pour ceux que ça intéresse, voici le lien vers la discussion que
j'ai eu sur fr.comp.text.tex.

http://groups.google.fr/group/fr.comp.text.tex/browse_thread/thread/ee11c3d1199deff3/258ca20017015d6f#258ca20017015d6f


Avec un tableur (OpenOffice chez moi), j'ai toutes les notes des élèves
d'une classe à un bac blanc. Du fichier tableur, je tire un fichier
notes.csv qui est comme ceci : (je simplifie un peu)

Nom;Français;EPS;Mathématiques;Moyennes
frédéric Machin;15;15;12;14
Jean Bidul;19;10,5;2;10,5
Maurice Truc;12;8;10;10

Le séparateur est ";" est à chaque ligne correspond un élève avec toutes
ces notes. Evidemment, il y a bien plus d'élèves (c'est un exemple).

Je voulais trouver un code Python qui me crée, à partir de notes.csv, un
fichier notes.tex qui serait *exactement* comme ça :

deffield{Nom}{frédéric Machin}
deffield{Français}{15}
deffield{EPS}{15}
deffield{Mathématiques}{12}
deffield{Moyennes}{14}
go

deffield{Nom}{Jean Bidul}
deffield{Français}{19}
deffield{EPS}{10,5}
deffield{Mathématiques}{2}
deffield{Moyennes}{10,5}
go

deffield{Nom}{Maurice Truc}
deffield{Français}{12}
deffield{EPS}{8}
deffield{Mathématiques}{10}
deffield{Moyennes}{10}
go

Après, on rentre dans la partie LaTeX du problème. Ce n'est pas le
propos ici. J'explique en bref les étapes :
Le code ci-dessus est en fait du code LaTeX, qui me sert à créer mes
lettres. En fait, une fois que je dispose notes.tex, je tape en ligne de
commande :

pdflatex lettres.tex

où lettres.tex est un fichier LaTeX qui utilise notes.tex (en fait
lettres.tex va tout simplement inclure notes.tex dans son propre code)
pour créer lettres.pdf qui sera un simple pdf avec tout mes lettres (une
page = une lettre pour un parent d'élève).

J'espère que c'est clair.

Bref, de toute façon, c'est la partie Python qui m'intéresse, celle qui
transforme notes.csv ----> notes.tex.


Voici un code (baptisé csv2tex.py) qui marche je crois :

##################################################
# -*- coding:Utf-8 -*-

# Transforme une chaîne de caractères avec des ";"
# en séquence avec dans chaque "cellule" les mots
# délimités pas les ";"
def seq_ligne ( chaine ) :

SEPARATEUR = ";"
i = 0
seq = []
mot = ""

while (i < len(chaine) ) :
if ( chaine[i] == SEPARATEUR or chaine[i] == 'n' ):
seq = seq + [mot]
mot = ""
else :
mot = mot + chaine[i]
i = i + 1

return seq


# On ouvre le fichier source pour générer
# le fichier cible

source = raw_input('Entrer le nom de la source : ')
cible = raw_input('Entrer le nom de la cible : ')

fichier_source = open(source, 'r')
fichier_cible = open(cible, 'w')


noms_de_champs = seq_ligne ( fichier_source.readline() )
seqN = seq_ligne ( fichier_source.readline() )



while ( seqN != [] ) :
i = 0
while ( i < len(noms_de_champs) ) :
fichier_cible.write( "deffield{" )
fichier_cible.write( noms_de_champs[i] )
fichier_cible.write( "}{" + seqN[i] + "}n" )
i = i + 1
fichier_cible.write( "gonn" )
seqN = seq_ligne ( fichier_source.readline() )


fichier_source.close()
fichier_cible.close()
##################################################


Voici mes questions :

1) Il paraît qu'il y a vraiment plus court avec des modules pour les
csv. Je ne connais absolument pas tout ça, serait-ce possible d'avoir un
exemple, ou des pistes ?

2) En fait, mon code ne fait qu'une simple transformation notes.csv --->
notes.tex. Je suis obligé de taper ensuite à la main (en ligne de
commande dans le répertoire courant)

pdflatex lettres.tex


J'aimerais bien que le script Python fasse aussi cela pour moi. Je ne
sais pas faire. Pourrais-je avoir une piste également ?


Merci d'avance.


François


Avatar
Francois
Bonjour,

Voici une piste à arranger à votre sauce.


Merci bien.

Je ne comprends pas tout dans ce code, mais j'ai l'impression qu'il
marche pour des csv à "4 colonnes" exactement, non ? Le problème, c'est
que mon csv pourrait en avoir plus et je ne voudrais à avoir à me
préoccuper du nombre de colonnes du csv. Comme je ne maîtrise pas trop
le code, difficile pour moi (pour l'instant) de savoir comment le
modifier. Je vais creuser la question.

Merci pour la piste.


Sinon, pour mettre une instruction en ligne de commande, il suffit de
faire :

################################################
from os import system
system( "mon instruction en ligne de commande" )
################################################

Je ne connaissais pas.



François

Avatar
Jonathan Barnoud
Bonjour,

Voici une piste à arranger à votre sauce.


Merci bien.

Je ne comprends pas tout dans ce code, mais j'ai l'impression qu'il
marche pour des csv à "4 colonnes" exactement, non ? Le problème, c'est
que mon csv pourrait en avoir plus et je ne voudrais à avoir à me
préoccuper du nombre de colonnes du csv. Comme je ne maîtrise pas trop
le code, difficile pour moi (pour l'instant) de savoir comment le
modifier. Je vais creuser la question.

Merci pour la piste.


Sinon, pour mettre une instruction en ligne de commande, il suffit de
faire :

################################################
from os import system
system( "mon instruction en ligne de commande" )
################################################

Je ne connaissais pas.



François


Je propose le code suivant qui fonctionne normalement quelque soit le
nombre et l'intitulé des colonnes :

#!/usr/bin/python
#_*_ coding:utf-8 _*_

import os

SEPARATOR = ";"
MODEL = "deffield{%s}{%s}n"
INFILE = "/home/jonathan/essaisfctt/notes.csv"
OUTFILE = "/home/jonathan/essaisfctt/notes.tex"
FINALFILE = "/home/jonathan/essaisfctt/bac_blanc.tex"

outfile = open(OUTFILE, "w")

infile = open(INFILE, "r")
fields = infile.readline()[:-1].split(SEPARATOR)

for line in infile :
cells = line[:-1].split(SEPARATOR)
for index, cell in enumerate(cells) :
print index, cell
outfile.write(MODEL % (fields[index], cell))
outfile.write("gonn")

outfile.close()
infile.close()

os.chdir(os.path.split(FINALFILE)[0])
os.system("pdflatex %s" % FINALFILE)

On fait sans doute mieux mais j'obtiens avec ça le résultat escompté.

Jonathan Barnoud


Avatar
yves
Le Sun, 16 Mar 2008 19:05:35 +0100, Francois a écrit:

Bonjour,

Je ne comprends pas tout dans ce code, mais j'ai l'impression qu'il
marche pour des csv à "4 colonnes" exactement, non ? Le problème, c'est
que mon csv pourrait en avoir plus et je ne voudrais à avoir à me
préoccuper du nombre de colonnes du csv. Comme je ne maîtrise pas trop
le code, difficile pour moi (pour l'instant) de savoir comment le
modifier. Je vais creuser la question.


Bon, il y a ça aussi qui marche avec tes spécifications:

#########
import csv, os

MODEL = "deffield{%s}{%s}n"

INFILE = 'notes.csv'
OUTFILE = 'notes.tex'

notes = csv.reader(open(INFILE, "r"), delimiter=';')
of = open(OUTFILE,'w')

titres = notes.next()
for ligne in notes:
for paire in zip(titres,ligne):
of.write(MODEL % paire)
of.write("gonn")

of.close()

os.system("pdflatex lettres.tex")

###################

--
Yves

Avatar
Laurent Rahuel
OK, voici une version non limitée sur le nombre de colonnes du CSV.

################################################
import csv

MODEL = "deffield{%s}{%s}n"

notes = list(csv.reader(open("notes.csv", "rb"), delimiter=';',
quoting=csv.QUOTE_NONE))
fields = notes[0]

fic = open('notes.tex','w')
for line in notes[1:]:
for i, note in enumerate(line) : fic.write(MODEL %(fields[i], note))
fic.write('gonn')

fic.close
################################################



Francois wrote:

Bonjour,

Voici une piste à arranger à votre sauce.


Merci bien.

Je ne comprends pas tout dans ce code, mais j'ai l'impression qu'il
marche pour des csv à "4 colonnes" exactement, non ? Le problème, c'est
que mon csv pourrait en avoir plus et je ne voudrais à avoir à me
préoccuper du nombre de colonnes du csv. Comme je ne maîtrise pas trop
le code, difficile pour moi (pour l'instant) de savoir comment le
modifier. Je vais creuser la question.

Merci pour la piste.


Sinon, pour mettre une instruction en ligne de commande, il suffit de
faire :

################################################
from os import system
system( "mon instruction en ligne de commande" )
################################################

Je ne connaissais pas.



François



Avatar
Francois
Merci à tous pour vos réponses et vos solutions. Je n'en demandais pas
tant. :-)

C'est parfait.

A bientôt.


François