Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
pyromaths
pyromaths
Commits
6417e6cb
Commit
6417e6cb
authored
Jun 04, 2013
by
Olivier Cornu
Browse files
Introduit les classes d'exercices.
parent
33a93465
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/pyromaths/Values.py
View file @
6417e6cb
...
...
@@ -73,51 +73,7 @@ ICONDIR = icon_dir()
HOME
=
home
()
CONFIGDIR
=
configdir
()
def
_exercices
(
pkg
):
''' Discover package exercises. '''
exercices
=
[]
# search package modules
for
_
,
name
,
ispkg
in
pkgutil
.
iter_modules
(
pkg
.
__path__
,
pkg
.
__name__
+
'.'
):
# skip sub-packages (discovery is not recursive)
if
ispkg
:
continue
# import discovered module
module
=
__import__
(
name
,
fromlist
=
pkg
.
__name__
)
# search module for exercises: functions with a 'description' attribute
# of UnicodeType
for
element
in
dir
(
module
):
# list module elements
element
=
module
.
__dict__
[
element
]
if
not
type
(
element
)
is
types
.
FunctionType
:
continue
if
'description'
not
in
dir
(
element
):
continue
description
=
element
.
__dict__
[
'description'
]
if
not
isinstance
(
description
,
basestring
):
continue
# store discovered exercise
exercices
.
append
(
element
)
return
exercices
def
_packages
(
pkg
):
''' Discover all packages located in pkg. '''
packages
=
[]
# search packages
for
_
,
name
,
ispkg
in
pkgutil
.
iter_modules
(
pkg
.
__path__
,
pkg
.
__name__
+
'.'
):
# skip modules
if
not
ispkg
:
continue
# import discovered package
package
=
__import__
(
name
,
fromlist
=
pkg
.
__name__
)
# exercise packages must have a description property
if
'description'
not
in
dir
(
package
):
continue
description
=
package
.
__dict__
[
'description'
]
# description property must be a string
if
not
isinstance
(
description
,
basestring
):
continue
# valid exercise package
packages
.
append
(
package
)
return
packages
# Packages d'exercices
PACKAGES
=
_packages
(
ex
)
LESFICHES
=
[]
for
pkg
in
PACKAGES
:
pkg
.
EXERCICES
=
_exercices
(
pkg
)
titles
=
[
ex
.
description
for
ex
in
pkg
.
EXERCICES
]
LESFICHES
.
append
([
pkg
.
description
,
''
,
titles
])
ex
.
load
()
for
level
,
exercices
in
ex
.
levels
.
iteritems
():
LESFICHES
.
append
([
level
,
''
,
exercices
])
src/pyromaths/ex/__init__.py
View file @
6417e6cb
import
os
import
types
import
pkgutil
levels
=
{}
class
Exercise
(
object
):
''' Base class for all exercise types. '''
description
=
u
'Description'
levels
=
u
'Academic level'
thumb
=
'path/to/thumbnail.png'
def
__str__
(
self
):
return
self
.
description
class
TexExercise
(
Exercise
):
''' Exercise with TeX support. '''
def
tex_statement
(
self
):
''' Return problem statement in TeX format. '''
raise
NotImplementedError
()
return
[
"
\\
exercice TODO"
]
def
tex_answer
(
self
):
''' Return full answer in TeX format. '''
return
[
"
\\
exercice* TODO"
]
class
__LegacyExercise
(
TexExercise
):
''' Base class for legacy format exercise proxies. '''
_id
=
0
function
=
[]
def
__init__
(
self
):
self
.
stat
,
self
.
ans
=
self
.
function
[
0
]()
def
tex_statement
(
self
):
return
self
.
stat
def
tex_answer
(
self
):
return
self
.
ans
def
__legacy
(
path
,
i
,
function
):
''' Create a new class proxying for a legacy exercise 'function'. '''
__LegacyExercise
.
_id
+=
1
# Create a proxy class inheriting from LegacyExercise for this function
return
type
(
'LegacyExercise%u'
%
__LegacyExercise
.
_id
,
(
__LegacyExercise
,),
dict
(
description
=
function
.
description
,
levels
=
function
.
level
,
thumb
=
os
.
path
.
join
(
path
,
'img'
,
'ex-%02d.png'
%
i
),
function
=
(
function
,),
)
)
def
__isfunction
(
obj
):
''' Is 'obj' a function? '''
return
type
(
obj
)
is
types
.
FunctionType
def
__hasdescription
(
obj
):
''' Has 'obj' a legit description? '''
if
'description'
not
in
dir
(
obj
):
return
False
description
=
obj
.
__dict__
[
'description'
]
# description must be some kind of string (preferably unicode)
if
not
isinstance
(
description
,
basestring
):
return
False
return
True
def
__isexercise
(
obj
):
''' Is target object an exercise in legacy format? '''
return
__isfunction
(
obj
)
and
__hasdescription
(
obj
)
def
__levels
(
level
):
''' Format academic level(s). '''
# level may be a string or a list (default)
if
not
isinstance
(
level
,
list
):
level
=
[
level
]
return
level
def
__import
(
name
=
__name__
,
parent
=
None
):
''' Import 'name' from 'parent' package. '''
if
not
isinstance
(
name
,
basestring
):
name
=
name
.
__name__
# parent is None: assume 'name' is a package name
if
parent
is
None
:
parent
=
name
elif
not
isinstance
(
parent
,
basestring
):
# assume 'parent' is a package instance
parent
=
parent
.
__name__
return
__import__
(
name
,
fromlist
=
parent
)
def
_exercises
(
pkg
):
''' List exercises in 'pkg' modules. '''
# level defaults to description, then unknown
if
'level'
not
in
dir
(
pkg
):
pkg
.
level
=
u
"Inconnu"
n
=
0
for
_
,
name
,
ispkg
in
pkgutil
.
iter_modules
(
pkg
.
__path__
,
pkg
.
__name__
+
'.'
):
# skip packages
if
ispkg
:
continue
;
# import module
mod
=
__import
(
name
,
pkg
)
if
'level'
not
in
dir
(
mod
):
mod
.
level
=
pkg
.
level
for
element
in
dir
(
mod
):
element
=
mod
.
__dict__
[
element
]
if
not
__isexercise
(
element
):
continue
# found an exercise: work out what level it is
element
.
level
=
__levels
(
element
.
level
if
'level'
in
dir
(
element
)
else
mod
.
level
)
yield
__legacy
(
pkg
.
__path__
[
0
],
n
,
element
)
n
+=
1
def
_subpackages
(
pkg
):
''' List 'pkg' sub-packages. '''
for
_
,
name
,
ispkg
in
pkgutil
.
iter_modules
(
pkg
.
__path__
,
pkg
.
__name__
+
'.'
):
# skip modules
if
not
ispkg
:
continue
;
yield
__import
(
name
,
pkg
)
def
load
(
pkg
=
None
,
recursive
=
True
):
''' Discover exercises. '''
# target package defaults to this package (pyromaths.ex)
if
pkg
is
None
:
pkg
=
__import
()
# load package exercises
for
ex
in
_exercises
(
pkg
):
for
lvl
in
ex
.
levels
:
# new level? create its exercise list
if
lvl
not
in
levels
.
keys
():
levels
[
lvl
]
=
[]
levels
[
lvl
].
append
(
ex
)
if
not
recursive
:
return
# load sub-packages
for
pk
in
_subpackages
(
pkg
):
load
(
pk
)
src/pyromaths/ex/lycee/ExoPolynome.py
View file @
6417e6cb
...
...
@@ -256,7 +256,7 @@ def exo_variation():
return
exo
,
cor
exo_variation
.
description
=
u
"Sens de variations"
exo_variation
.
level
=
u
"1èreS, Term STG"
exo_variation
.
level
=
[
u
"1èreS
"
,
u
"
Term STG"
]
def
exo_variation_lim
():
...
...
src/pyromaths/interface.py
View file @
6417e6cb
...
...
@@ -23,7 +23,7 @@
from
PyQt4
import
QtGui
,
QtCore
import
os
,
lxml
,
codecs
,
sys
from
outils
import
System
from
Values
import
HOME
,
CONFIGDIR
,
DATADIR
,
PACKAGES
,
LESFICHES
,
COPYRIGHTS
,
VERSION
,
ICONDIR
from
Values
import
HOME
,
CONFIGDIR
,
DATADIR
,
LESFICHES
,
COPYRIGHTS
,
VERSION
,
ICONDIR
class
Ui_MainWindow
(
object
):
def
setupUi
(
self
,
MainWindow
):
...
...
@@ -89,8 +89,8 @@ class Ui_MainWindow(object):
#============================================================
self
.
tabs
=
[]
for
pkg_no
in
range
(
len
(
PACKAGES
))
:
self
.
tabs
.
append
(
Tab
(
self
.
tabWidget
,
pkg_no
,
self
.
setNbExos
))
for
level
in
LESFICHES
:
self
.
tabs
.
append
(
Tab
(
self
.
tabWidget
,
level
,
self
.
setNbExos
))
#============================================================
# Onglet options
...
...
@@ -449,13 +449,14 @@ class Ui_MainWindow(object):
for
i
in
range
(
len
(
self
.
liste_creation
)):
niveau
=
self
.
liste_creation
[
i
][
0
]
exo
=
self
.
liste_creation
[
i
][
1
]
list
.
append
(
"%se: %s"
%
(
6
-
niveau
,
LESFICHES
[
niveau
][
2
][
exo
])
)
list
.
append
(
LESFICHES
[
niveau
][
2
][
exo
])
self
.
List
=
QtGui
.
QListWidget
()
for
i
in
range
(
len
(
list
)):
item
=
QtGui
.
QListWidgetItem
(
list
[
i
])
item
=
QtGui
.
QListWidgetItem
(
list
[
i
]
.
description
)
item
.
setFlags
(
QtCore
.
Qt
.
ItemIsEnabled
|
QtCore
.
Qt
.
ItemIsSelectable
|
QtCore
.
Qt
.
ItemIsDragEnabled
)
item
.
exercice
=
list
[
i
]
self
.
List
.
addItem
(
item
)
bmono
=
True
for
i
in
range
(
len
(
list
)):
...
...
@@ -651,14 +652,9 @@ def valide(list, LesFiches, parametres):
""" Permet de choisir les noms et emplacements des fichiers tex, les écrits
et lance la compilation LaTex"""
corrige
=
parametres
[
'corrige'
]
l
=
[]
lesexos
=
[]
for
i
in
range
(
list
.
count
()):
l
.
append
(
unicode
(
list
.
item
(
i
).
text
()))
for
text
in
l
:
niveau
=
6
-
int
(
text
[
0
])
pos
=
LesFiches
[
niveau
][
2
].
index
(
text
[
4
:])
lesexos
.
append
((
niveau
,
pos
))
lesexos
.
append
(
list
.
item
(
i
).
exercice
())
#============================================================
# Choix des noms des fichiers exercices et corrigés
...
...
@@ -695,11 +691,10 @@ def valide(list, LesFiches, parametres):
class
Tab
(
QtGui
.
QWidget
):
"""Gère les onglets permettant de sélectionner des exercices"""
def
__init__
(
self
,
parent
,
pkg_no
,
onchange
):
def
__init__
(
self
,
parent
,
level
,
onchange
):
QtGui
.
QWidget
.
__init__
(
self
)
# Initialise la super-classe
self
.
pkg
=
PACKAGES
[
pkg_no
]
self
.
titre
=
self
.
pkg
.
description
self
.
exos
=
LESFICHES
[
pkg_no
][
2
]
self
.
titre
=
level
[
0
]
self
.
exos
=
level
[
2
]
self
.
layout
=
QtGui
.
QGridLayout
(
self
)
self
.
spinBox
=
[]
# Crée les widgets des exercices
...
...
@@ -732,13 +727,11 @@ class Tab(QtGui.QWidget):
img
=
QtGui
.
QLabel
(
self
)
img
.
setText
(
r
'<img src="%s"/>'
%
os
.
path
.
join
(
DATADIR
,
'images'
,
'whatsthis.png'
))
img
.
setToolTip
(
r
'<img src="%s"/>'
%
os
.
path
.
join
(
self
.
pkg
.
__path__
[
0
],
'img'
,
'ex-%02d.png'
%
i
))
img
.
setToolTip
(
r
'<img src="%s"/>'
%
self
.
exos
[
i
].
thumb
)
layout
.
addWidget
(
img
)
# Label
label
=
QtGui
.
QLabel
(
self
)
label
.
setText
(
self
.
exos
[
i
])
label
.
setText
(
self
.
exos
[
i
]
.
description
)
layout
.
addWidget
(
label
)
# Espacements
spacer
=
QtGui
.
QSpacerItem
(
40
,
20
,
QtGui
.
QSizePolicy
.
Expanding
,
QtGui
.
QSizePolicy
.
Minimum
)
...
...
src/pyromaths/outils/System.py
View file @
6417e6cb
...
...
@@ -26,7 +26,7 @@ from lxml import etree
from
lxml
import
_elementpath
as
DONTUSE
# Astuce pour inclure lxml dans Py2exe
from
re
import
findall
from
.TexFiles
import
mise_en_forme
from
pyromaths.Values
import
HOME
,
VERSION
,
CONFIGDIR
,
PACKAGES
from
pyromaths.Values
import
HOME
,
VERSION
,
CONFIGDIR
#==============================================================
...
...
@@ -156,15 +156,11 @@ def creation(parametres):
copie_tronq_modele
(
f1
,
parametres
,
'entete'
)
for
exercice
in
parametres
[
'liste_exos'
]:
pkg_no
=
exercice
[
0
]
ex_no
=
exercice
[
1
]
# get exercise's TeX code (question & answer)
enonce
,
correction
=
PACKAGES
[
pkg_no
].
EXERCICES
[
ex_no
]()
# write to files
# write exercise's TeX code (question & answer) to files
f0
.
write
(
"
\n
"
)
f0
.
writelines
(
line
+
"
\n
"
for
line
in
e
nonce
)
f0
.
writelines
(
line
+
"
\n
"
for
line
in
e
xercice
.
tex_statement
()
)
f1
.
write
(
"
\n
"
)
f1
.
writelines
(
line
+
"
\n
"
for
line
in
correction
)
f1
.
writelines
(
line
+
"
\n
"
for
line
in
exercice
.
tex_answer
()
)
if
parametres
[
'creer_pdf'
]:
...
...
test/test_creation_fichiers_tex.py
View file @
6417e6cb
...
...
@@ -74,8 +74,8 @@ elif (len(sys.argv) == 1):
parametres
[
'fiche_cor'
]
=
os
.
path
.
join
(
dt
,
'exercices-corrige.tex'
)
lst
=
[]
for
n
in
range
(
len
(
LESFICHES
)):
for
i
in
range
(
len
(
LESFICHES
[
n
][
2
]
))
:
lst
.
append
(
[
n
,
i
]
)
for
exo
in
LESFICHES
[
n
][
2
]:
lst
.
append
(
exo
()
)
parametres
[
'liste_exos'
]
=
lst
creation
(
parametres
)
nettoyage
(
dt
)
...
...
utils/creer-vignettes.py
View file @
6417e6cb
...
...
@@ -5,11 +5,11 @@ from os.path import dirname, normpath, join, abspath, realpath, split
_path
=
normpath
(
join
(
abspath
(
dirname
(
__file__
)),
"../src"
))
sys
.
path
[
0
]
=
realpath
(
_path
)
from
pyromaths
import
pyromaths
from
pyromaths
import
pyromaths
,
ex
#datadir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
#sys.path.append(datadir)
from
pyromaths.Values
import
PACKAGES
,
LESFICHES
,
data_dir
,
configdir
from
pyromaths.Values
import
data_dir
,
configdir
,
LESFICHES
from
pyromaths.outils.System
import
creation
from
subprocess
import
call
,
Popen
...
...
@@ -45,21 +45,30 @@ parametres = {
'openpdf'
:
0
,
}
#for n in range(1):
#for i in range(1):
for
n
in
range
(
len
(
PACKAGES
)):
pkg
=
PACKAGES
[
n
]
imgdir
=
join
(
pkg
.
__path__
[
0
],
"img"
)
for
i
in
range
(
len
(
LESFICHES
[
n
][
2
])):
lst
=
[[
n
,
i
]]
parametres
[
'liste_exos'
]
=
lst
creation
(
parametres
)
call
([
"convert"
,
"-density"
,
"288"
,
"/tmp/test.pdf"
,
"-resize"
,
"25%"
,
"-crop"
,
"710x560+0+85"
,
"-flatten"
,
"-trim"
,
"/tmp/ex-%02d.png"
%
i
],
def
__thumb
(
exercise
,
imgdir
,
i
):
parametres
[
'liste_exos'
]
=
[
exercise
()]
creation
(
parametres
)
call
([
"convert"
,
"-density"
,
"288"
,
"/tmp/test.pdf"
,
"-resize"
,
"25%"
,
"-crop"
,
"710x560+0+85"
,
"-flatten"
,
"-trim"
,
"/tmp/ex-%02d.png"
%
i
],
stdout
=
log
)
call
([
"pngnq"
,
"-f"
,
"-s1"
,
"-n32"
,
"/tmp/ex-%02d.png"
%
i
],
stdout
=
log
)
call
([
"pngnq"
,
"-f"
,
"-s1"
,
"-n32"
,
"/tmp/ex-%02d.png"
%
i
],
stdout
=
log
)
shutil
.
copyfile
(
"/tmp/ex-%02d-nq8.png"
%
i
,
"%s/ex-%02d.png"
%
(
imgdir
,
i
))
Popen
(
args
=
[
"optipng"
,
"-o7"
,
"%s/ex-%02d.png"
%
(
imgdir
,
i
)])
shutil
.
copyfile
(
"/tmp/ex-%02d-nq8.png"
%
i
,
"%s/ex-%02d.png"
%
(
imgdir
,
i
))
Popen
(
args
=
[
"optipng"
,
"-o7"
,
"%s/ex-%02d.png"
%
(
imgdir
,
i
)])
def
__thumbs
(
pkg
):
imgdir
=
join
(
pkg
.
__path__
[
0
],
"img"
)
i
=
0
for
e
in
ex
.
_exercises
(
pkg
):
__thumb
(
e
,
imgdir
,
i
)
i
+=
1
def
thumbs
(
pkg
=
ex
,
recursive
=
True
):
__thumbs
(
pkg
)
if
not
recursive
:
return
for
pk
in
ex
.
_subpackages
(
pkg
):
thumbs
(
pk
)
thumbs
()
log
.
close
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment