Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nthiery/wims-info
  • medimegh/wims-info
  • ventos/wims-info
  • bokaris/wims-info
4 results
Show changes
Commits on Source (219)
Showing
with 751 additions and 57 deletions
*.answer
test~coding~readingCppPrograms.fr/data/index
core
Modules:
- `<U2~coding~oefprogramC.fr/>`_: un dérivé du module éponyme déjà
existant dans WIMS, avec quelques menues améliorations.
- `Compréhension de programmes C++ <test~coding~readingCppPrograms.fr/>`_:
deviner l'entrée ou la sortie d'un programme
Le répertoire `<data/>`_ contient des programmes C++, qui peuvent être de deux types.
Pour les programmes du premier type, l'utilisateur doit deviner la sortie du programme.
Ces programmes sont nommés sous la forme ``<theme>_<nom>.cpp``.
Les programme du deuxième type doivent lire un entier entre 0 et 99 sur l'entrée standard, et l'utilisateur doit deviner lequel donne 42; pour l'instant cet entier doit être unique.
Ces programmes sont nommés ``<theme>_<nom>_input.cpp``
Pour les deux types de programme, le thème peut être constitué d'un thème principal et de sous-thèmes, séparés par des ``_`` (p. ex. ``loop_for``, ``loop_while``).
Les noms de fichiers ne doivent contenir que des caractères alphanumériques et le caractère ``_``.
* Liste des thèmes :
file
function
if
io
loop
procedure
struct
variable
vector1D
vector2D
* Sous-thèmes :
1. struct_simple : seulement un type de structure, dans un main (pas de fonction ou procédure)
2. struct_fonction : fonction manipulant et renvoyant des structures
3. struct_procedure : procédures manipulant des structures
4. struct_profond : structure contenant une structure (pas de fonction ou procédure)
5. struct_tableaux : structure contenant un tableau (pas de fonction ou procédure)
6. struct_tableau_struct : structure contenant un tableau contenant des structures (pas de fonction ou procédure)
7. struct_gros : structure contenant un tableau contenant des structures, avec fonctions
8. struct_hard : programmes difficiles manipulant des structures
* Liste et descriptif des programmes par thème :
Thème vector1D_recherche : recherche d'un élément dans un tableau. Les variations a, b, et c l'appliquent sur un tableau contenant 1, 2 ou 0 occurrences de l'élément.
recherche_1 : parcours du tableau de gauche à droite, avec return direct, correct.
recherche_2 : parcours du tableau de gauche à droite, avec return direct, non correct.
recherche_3 : parcours du tableau de gauche à droite, avec variable locale, correct.
recherche_4 : parcours du tableau de gauche à droite, avec variable locale, non correct.
recherche_5 : parcours du tableau de droite à gauche, avec variable locale, non correct.
recherche_6 : parcours du tableau de droite à gauche, avec return direct, correct.
recherche_7 : parcours du tableau de droite à gauche, avec variable locale, correct.
Thème vector1D_tri : teste si un tableau est trié. Les variations a, b, et c l'appliquent sur divers tableaux
tri_1 : avec return direct, correct (tri croissant). Tests sur 2358 8532 2538
tri_2 : avec return direct, non correct (tri croissant). Tests sur 2835 2583 5238
tri_3 : avec variable locale, correct (tri croissant). Tests sur 2358 8532 2538
tri_4 : avec variable locale, non correct (tri croissant). Tests sur 2835 2583 5238
tri_5 : avec return direct, correct (tri décroissant). Tests sur 2358 8532 8352
tri_6 : avec return direct, non correct (tri décroissant). Tests sur 5283 5328 5832
tri_7 : avec variable locale, correct (tri décroissant). Tests sur 2358 8532 8352
tri_8 : avec variable locale, non correct (tri décroissant). Tests sur 5283 5328 5832
Pour le moment, la plateforme d'exercices interactifs pour `WIMS
<http://wims.unice.fr/>`_ contient très peu de chose pour
l'enseignement de l'informatique. L'objectif de ce dépôt est de
développer collaborativement de nouveaux modules.
Modules:
- `<U2~coding~oefprogramC.fr/>`_: un dérivé du module éponyme déjà
existant dans WIMS, avec quelques menues améliorations.
- `Compréhension de programmes C++ <test~coding~readingCppPrograms.fr/>`_:
deviner l'entrée ou la sortie d'un programme
* WIMS questions
- create temporary file
- pass data to input
- boolean arithmetic
* QCM Question logique
- [ ] pour ***que*** l'expression suivante ***retourne*** true.
- [ ]
* Collections de programmes + randomisation + résultat
** Features
- [X] Code colorization
- [X] Code area just of the proper height
- [X] Selection of topic based on file prefix
- [X] Output dans un textarea
- [ ] Why are there empty lines at the top and bottom of the text shown?
- [ ] Randomization of the variable names
- [ ] Randomization of the output by substitution (preprocessing)
- [ ] Implement more logic in WIMS
- [ ] Support for various programming languages, based on file extension (see below)
- [ ] Separate clearly the expected output from the rest of the text
- [ ] Allow for broken programs
** Programs
- variables-assign.cpp est un peu trop long
- ceux avec factorielle sont trop prévisibles sans lire le code
- obfuscated / misindented programs
- programes autour de la division entiere
** Substitution des variables et constantes?
\text{code=\wims(replace internal resultat par \resultat)}
- Mesure intermédiaire:
Définir sur la ligne de commande de G++ un certain nombre de macros
I1,I2,I3, C1,C2,C3, F1,F2,F3, et les utiliser dans les programmes.
Comme ça, le jour de l'examen, on peut facilement travailler sur
d'autres valeurs.
* Onsite compilation and production of the output
** DONE Utility to compile and execute a program in a sandbox (docker container)
See file:docker-compile-and-run/docker-compile-and-run.cpp for an
experimental program.
** DONE rewrite the module to use it.
** TODO [/] Improvements
- [ ] Randomisation
- [ ] Where to put compile-and-run.sh
- [ ] Avoid hardcoding the module data location
- [ ] Avoid hardcoding the location of compile-and-run.sh
- [ ] Afficher la question avant de calculer la réponse?
- [ ] Support for other programming languages
See file:docker-compile-and-run/compile-and-run.sh
** TODO Deployment
Discuss with Bernadette to include that script (or some
equivalent) in Orsay's WIMS server.
** TODO Kernel panic
https://github.com/docker/docker/issues/15057 ?
** References:
http://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo
* Choisir l'entrée pour que ...
* Exercice générique avec base de donnée de programmes à trous
WIMS affiche un programme dont certain bouts sont cachés (les
trous), ainsi que l'affichage dudit programme. L'étudiant doit alors
compléter les trous pour que le programme affiche exactement la même
chose que le programme d'origine.
Typiquement le programme contiendra une fonction avec sa
documentation et ses tests, mais dont le corps et caché.
Pour introduire un peu de variabilité, le programme pourra lire sur
son entrée standard un entier que WIMS choisira aléatoirement.
* Écrire un programme qui ... par exemple pour n=5 ... copier coller le résultat ici
(Comparatif de la sortie par rapport à un programme de référence caché)
* Exercices existant: U1 / algo
Non fonctionnels en l'état (requiers un chroot qui n'est plus fonctionnel)
* Notes techniques sur WIMS
** Créer ses propres utilitaires / plugins / programmes externes
Si un programme est présent dans public_html/bin, il est exécutable
depuis les oef avec:
\text(toto=wims(exec ccc parametres ...)}
Il doit suivre un protocole spécifique. Le plus simple est de
mettre un programme usuel dans other/bin, avec un wrapper. Voir par
exemple toascii.
Ces programmes sont exécutables sans restriction par n'importe quel
auteur de module OEF/... Donc doivent être parfaitement sûr
** Créer ses programmes exécutables seulement par module de confiance
** Créer un index et chercher des infos dedans:
wims(lookup ... in ...)
src2def peut générer de tels index (voir aussi mkindex)
Il est possible qu'il existe déjà un index pour les *.data
** Compiler un module
Depuis la racine du module:
/opt/WIMS/other/bin/src2def
Mettre le module dans
/opt/WIMS/public_html/modules/devel/home/nthiery
** Compiler WIMS
sudo apt-get install libgd-dev
./compile --mathjax
dans bin/apache-config:
- remplacer apache2 par apache2ctl
- forcer confdir=/etc/apache2
- conffile=$confdir/conf-available/wims.conf
mistral-/etc/apache2/conf-enabled> sudo ln -s ../conf-available/wims.conf .
Still getting:
http://127.0.0.1/wims/
You don't have permission to access /wims/ on this server.
Se créer un compte développeur
* A propos des modules WIMS existants exécutant du code
** Modules
Chercher sur programmation sur le serveur
*** U1/algo/progstring.fr
*** ... arithmetic
** Supporte: perl, c, pascal
cf. public_html/bin/c
** Infrastructure:
- Un type de réponse: wims/public_html/scripts/anstype/code
définit:
- comment l'utilisateur rentre la réponse
- comment traiter la réponse (ici exécuter le code dans un chroot)
- le retour: qu'est-ce qui est affiché, note, ...
Objectif: mettre à jour pour utiliser docker à la place du chroot / secure_execq
Voir aussi ~/wims.log/unsecure.
Passe par WIMS/src/Misc/wrap.c à un moment ou un autre
** Variante: public_html/modules/tool/directexec/ (en particulier var.proc)
Outil indépendant permettant à un utilisateur d'exécuter un
programme quelconque écrit dans un des systèmes suivant:
outil,software, language, pari, gp, maxima, octave, macaulay, yacas, gap, scilab, c, perl, sh, python, pascal, fortran,jmol, jsgraph, canvasdraw,graphviz
entrée: une chaîne de caractère contenant le programme
sortie: l'affichage du programme
À confirmer: nécessitait un patch sur le noyau.
Utilise _calc_exec de WIMS/src/calc.c.
Exécute une commande, dans un chroot s'il n'est pas de confiance.
TODO: mettre à jour pour utiliser docker
** Consommation de ressources jugées raisonnables
Cf. src/wimsdef.h
Cf. aussi wims/log/wims.conf: rlimit_cpu et
public_html/bases/sys/defaults.conf pour les valeurs par défaut
** Si on se connecte avec une certaine IP alors on est en mode debug / admin
Affiche en particulier des informations sur l'exécution
* Serveur WIMS de test
https://wimstest2.di.u-psud.fr/
3/11/2015:
Serveur Centos6 similaire à WIMS installé par WIMS
docker.io installé
WIMS svn 4.11 a installé dans ~wims
voir /etc/httpd/conf/httpd.conf
Mainteneur: Julien Nauroy
Compte dévelopeur: nthiery wcloiasdf
service httpd restart FAILS, with selinux message in /var/log/httpd/error.log
2015/12/02: NT disabled selinux: http://www.crypt.gen.nz/selinux/disable_selinux.html
......@@ -8,7 +8,6 @@
\text{code_celibataire=randitem(célibataire, marié(e))}
<!-- Il faut que le source soit logique en fonction de la question 2 (célibataire ou marié(e)) -->
\text{code_etat1=\code_celibataire issametext célibataire ? Mademoiselle : Madame}
\text{code_etat2=\code_celibataire issametext célibataire ? Madame : Mademoiselle}
......
CXXFLAGS=-g -Wall -std=c++0x
WIMSHOST=wimstest
#DOCKERHOST=134.158.75.87# wimsdocker
#DOCKERHOSTADMIN=debian
DOCKERHOST=sage-docker# sage-docker
DOCKERHOSTADMIN=ubuntu
SSH=ssh -x
docker-compile-and-run: docker-compile-and-run.cpp
docker-compile-and-run-remote: docker-compile-and-run-remote.cpp
tests: test-compile-and-run.sh test-docker-compile-and-run test-docker-compile-and-run-client
test-%:
@echo running tests for $*
@echo | $* prog.cpp > prog.out.obtained 2> /dev/null && diff prog.out prog.out.obtained
@echo coucou | $* prog-stdin.cpp > prog-stdin.out.obtained 2> /dev/null && diff prog-stdin.out prog-stdin.out.obtained
@rm prog.out.obtained prog-stdin.out.obtained
test-docker-compile-and-run-client: start-server
stop-server:
-killall docker-compile-and-run-server
start-server: #stop-server
docker-compile-and-run-server &
# ssh wims@$(WIMSHOST) "(echo Host wimsdockerhost; echo Hostname $(DOCKERHOST); echo IdentityFile ~/.ssh/id_rsa_docker) >> .ssh/config; chmod 600 .ssh/config"
dockerhost-preinstall:
scp dockerhost-setup.sh root@$(DOCKERHOST):
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) sudo bash dockerhost-setup.sh
dockerhost-clean: # TODO Add a test that DOCKERHOST <-> WIMSHOST
ssh root@$(DOCKERHOST) userdel -r wims
#scp wimstest2-developers-config wims@$(DOCKERHOST):log/.developers
#ssh root@wimstest service httpd restart
dockerhost-install:
$(SSH) wims@$(DOCKERHOST) mkdir -p other/bin
scp compile-and-run.sh docker-compile-and-run-server wims@$(DOCKERHOST):other/bin
$(SSH) wims@$(DOCKERHOST) chmod 755 other/bin/compile-and-run.sh other/bin/docker-compile-and-run-server
scp docker-compile-and-run.cpp wims@$(DOCKERHOST):
$(SSH) wims@$(DOCKERHOST) "g++ $(CXXFLAGS) docker-compile-and-run.cpp -o other/bin/docker-compile-and-run && rm docker-compile-and-run.cpp"
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) "sudo chown wims:docker ~wims/other/bin/docker-compile-and-run; sudo chmod 2755 ~wims/other/bin/docker-compile-and-run"
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) sudo service docker restart
dockerhost-run:
$(SSH) wims@$(DOCKERHOST) other/bin/docker-compile-and-run-server
dockerhost-test:
$(SSH) $(DOCKERHOSTADMIN)@$(DOCKERHOST) docker run hello-world
scp prog.cpp wims@$(DOCKERHOST):
$(SSH) wims@$(DOCKERHOST) ./other/bin/docker-compile-and-run prog.cpp < /dev/null
docker-compile-and-run-client prog.cpp < /dev/null
wimshost-install:
scp docker-compile-and-run-client wims@$(WIMSHOST):other/bin/docker-compile-and-run
scp docker-compile-and-run-wrapper.sh wims@$(WIMSHOST):public_html/bin/docker-compile-and-run
# $(SSH) root@$(WIMSHOST) service httpd restart
wimshost-test: # Needs to be updated
scp prog.cpp wims@$(WIMSHOST):
$(SSH) wims@$(WIMSHOST) ./other/bin/docker-compile-and-run prog.cpp < /dev/null
install-remote:
xxx
#!/bin/sh
CXXFLAGS="-std=c++11 -Wall -Wno-sign-compare -Wno-unused-value"
usage () {
echo compile-and-run [program.cpp]
echo
echo Compiles and executes a c++ program.
echo The standard input and output is passed down to the program.
echo The exit status is that of the compiler.
}
if [ x"$1" = "x" ]; then
usage
exit 0
fi
# -H does not seem to always work
#ulimit -H -t 100
ulimit -t 5
if g++ $CXXFLAGS $1; then
# ulimit -H -t 1 # Apparently -H -t takes a number >= 10 for hard limit
ulimit -t 1
./a.out
else
exit $?
fi
#!/bin/sh
#host=134.158.75.87 # wims-docker
host=134.158.75.207 # sage-docker
#host=localhost
port=8080
file=$1
curl --form "code=<$file" --form "input=<-" $host:$port/compile-and-run
#!/usr/bin/python
import tempfile
import popen2
import os
from flask import Flask, redirect, url_for, request
docker_compile_and_run="/home/wims/other/bin/docker-compile-and-run"
#docker_compile_and_run="docker-compile-and-run"
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Web service for compiling and running a c++ program in a remote sandbox.\nPost on /compile-and-run with the c++ program uploaded as form input `code` and input as form input `input`\n'
@app.route('/compile-and-run',methods=['POST'])
def compile_and_run():
input = request.form['input']
code = request.form['code']
fd = tempfile.NamedTemporaryFile(suffix=".cpp", prefix="docker-compile-and-run-")
fd.write(code)
fd.flush()
(child_out, child_in) = popen2.popen2(docker_compile_and_run+" "+fd.name)
child_in.write(input)
child_in.flush()
child_in.close()
result = child_out.read()
return result
if __name__ == '__main__':
#app.run(debug=True)
app.run(host="0.0.0.0", port=8080)
#include <vector>
#include <iostream>
#include <cstdlib>
#include <sstream>
using namespace std;
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
/**
* TODO:
* - [X] make this into a program rather than a shell script for a minimum of safety
* - [ ] set tight resources limits
* - [ ] check proper handling of all potential errors
* - [ ] make this into a plain C program to not add a dependency on C++
**/
string compile_and_run = "compile-and-run.sh";
string bin_dir = "/home/wims/other/bin/";
//string bin_dir = "";
string docker = "/usr/bin/docker";
bool verbose = false;
void usage () {
cerr << "docker-compile-and-run [program.cpp]" << endl;
cerr << endl;
cerr << "Compiles and executes a c++ program within a sandbox." << endl;
cerr << "The standard input and output is passed down to the program." << endl;
cerr << "The exit status is that of the compiler." << endl;
}
int my_exec(string cmd, const vector<string> args) {
if (verbose) {
cerr << "exec: " << cmd;
for (unsigned int i=0; i<args.size(); i++)
cerr << " " << args[i];
cerr << endl;
}
vector<const char*> argv;
argv.push_back(cmd.c_str());
for (unsigned int i=0; i<args.size(); i++)
argv.push_back(args[i].c_str());
argv.push_back((char *) 0);
const vector<const char *> argv2(argv.begin(), argv.end());
return execv(cmd.c_str(), (char * const*)argv.data());
}
int my_system(string cmd, const vector<string> args, const string in, const string out, const string err) {
// Taken from man waitpid
int status;
pid_t w;
pid_t cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Code executed by child */
if ( in != "" ) {
FILE* f = fopen(in.c_str(), "r");
dup2(fileno(f), STDIN_FILENO);
fclose(f);
}
if ( out != "" ) {
FILE* f = fopen(out.c_str(), "w");
dup2(fileno(f), STDOUT_FILENO);
fclose(f);
}
my_exec(cmd, args);
perror("exec");
exit(EXIT_FAILURE);
}
w = waitpid(cpid, &status, 0);
if (w == -1) {
perror("waitpid");
exit(EXIT_FAILURE);
}
return EXIT_SUCCESS;
}
int my_system(string cmd, const vector<string> args) {
return my_system(cmd, args, "", "", "");
}
std::string my_popen(const string cmd, vector<string> args) {
int pipefd[2];
pid_t cpid;
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child writes to pipe */
close(pipefd[0]); /* Close unused read end */
dup2(pipefd[1], STDOUT_FILENO);
my_exec(cmd, args);
perror("exec");
exit(EXIT_FAILURE);
}
close(pipefd[1]); /* Close unused write end */
char buffer[128];
std::string result = "";
int n;
while ((n = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
buffer[n] = 0;
result += buffer;
}
wait(NULL); /* Wait for child */
return result;
}
string docker_run(string container, string cmd, vector<string> args) {
// See http://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources
// for the resource limitations
vector<string> docker_args = {"run",
"--detach=true", // Run in background
// With 10M, the compilation and run is much slower
"--memory", "100M", "--memory-swap", "100M",
// Not available with docker 1.7?
// "--kernel-memory", "50M",
// "--cpu-quota" "50000", // Allow for using max 50% of the CPU
// Incompatible with detach
// "--rm=true", // Automatically delete container when done with the command
container, cmd};
for (unsigned int i=0; i<args.size(); i++)
docker_args.push_back(args[i]);
string ID = my_popen(docker, docker_args);
// see http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
ID.erase(ID.find_last_not_of(" \n\r\t")+1);
return ID;
}
void docker_exec(string docker_id, vector<string> args, bool interactive) {
vector<string> docker_args = {"exec"};
if (interactive) docker_args.push_back("-i");
docker_args.push_back(docker_id);
for (unsigned int i=0; i<args.size(); i++)
docker_args.push_back(args[i]);
my_system(docker, docker_args);
}
void docker_cp(string docker_id, string source, string target) {
// See http://stackoverflow.com/questions/22907231/copying-files-from-host-to-docker-container
// TODO: replace with 'docker cp' of docker 1.8 when possible
vector<string> docker_args = {"exec", "-i", docker_id, "/bin/bash", "-c", "cat > "+target};
my_system(docker, docker_args, source, "", "");
}
void docker_rm(string docker_id) {
vector<string> docker_args = {"rm", "-f", docker_id};
my_system(docker, docker_args, "", "/dev/null", "");
}
int main(int argc, char **argv) {
//cout << my_popen("/usr/bin/id", {}) << "|" << endl;
//printf("egid: %d\n", getegid());
//exec("/usr/bin/id", {});
//system("/usr/bin/id");
if (argc != 2) {
usage();
return 0;
}
string program=argv[1];
if (verbose)
cerr << "Compiling and running: " << program << endl;
string program_in_docker="prog.cpp";
string docker_id = docker_run("crosbymichael/build-essential", "sleep", vector<string>({"10"}));
if (verbose) {
cerr << "docker_id: " << docker_id << endl;
cerr << "Current directory: ";
my_system("/bin/pwd", {});
}
docker_cp(docker_id, bin_dir+compile_and_run, compile_and_run);
docker_cp(docker_id, program, program_in_docker);
docker_exec(docker_id, vector<string>({ "chmod", "700", compile_and_run }), false);
docker_exec(docker_id, vector<string>({ "./"+compile_and_run, program_in_docker}), true);
docker_rm(docker_id);
return 0;
}
#!/bin/sh
# TODO:
# - set tight resources limits
# - make this into a program rather than a shell script for a minimum of safety
usage () {
echo docker-compile-and-run [program.cpp]
echo
echo Compiles and executes a c++ program within a sandbox.
echo The standard input and output is passed down to the program.
echo The exit status is that of the compiler.
}
if [ x"$1" = "x" ]; then
usage
exit 0
fi
ID=`sudo docker run -d crosbymichael/build-essential sleep 1000`
sudo docker exec -i $ID sh -c "cat > prog.cpp" < $1
if sudo docker exec $ID g++ prog.cpp; then
sudo docker exec -i $ID ./a.out
else
exit $?
fi
sudo docker rm -f $ID > /dev/null 2>&1
#include<stdio.h>
main()
{
printf("Hello World");
}
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int x = 1+2;
if ( x == 3 ); {
cout << "Bonjour!" << endl;
}
cerr << "Bonjour sur la sortie d'erreur" << endl;
cout << "Au revoir." << endl;
return 0;
}
print "coucou"
main.oef: header.oef programs/guess-output/*.cpp footer.oef Makefile
cd programs/guess-output; make all.oef
cat header.oef programs/guess-output/all.oef footer.oef > main.oef
Randomization
Implement all the logic in WIMS
Onsite compilation and production of the output
Support for various programming languages, based on file extension
Selection of theme based on file prefix
CSS style sheet for colored syntax highlighting
\statement{
<p>
Quel affichage produit le programme C++ suivant? On donnera le
résultat sur une seule ligne, les éléments étant séparés par des
espaces.
\special{expandlines \code}
}
\answer{}{\output}{type=text}
\title{Deviner l'affichage d'un programme C++}
\description{Deviner l'affichage d'un programme C++}
\language{fr}
\niveau{U1}
\author{Nicolas M. Thiry}
\email{Nicolas.Thiery@u-psud.fr}
\format{html}
PROGRAMS=$(wildcard *.cpp)
HTML=$(PROGRAMS:%.cpp=%.html)
OUTPUT=$(PROGRAMS:%.cpp=%.output)
BASENAMES=$(PROGRAMS:%.cpp=%)
all: $(OUTPUT) $(HTML) filelist
%.output: %.bin
./$< > $@
%.bin: %.cpp
g++ $< -o $@
%.html: %.cpp
pygmentize -o $@ -O style=colorful $< # ,linenos=1
clean:
rm *.bin *.output *.html all.oef
all.oef: Makefile $(OUTPUT) $(HTML)
echo "\\\\text{programName=random("`ls -m *.cpp`")}" > $@
for basename in $(BASENAMES); do \
echo "\\\\text{code=\\programName issametext $$basename.cpp ?"; \
cat $$basename.html; \
echo "}"; \
echo "\\\\text{output=\\programName issametext $$basename.cpp ?"; \
cat $$basename.output; \
echo "}"; \
done >> $@
type=first
textarea="data explain"
:Remettre en bon ordre des objets donnés, glisser-déposer.
On présente une liste d'objets, et il faut les trier selon l'ordre précisé
en les tirant vers les cases prévues avec la souris.
<p>
Pour construire un exercice avec ce modèle, il suffit d'entrer la liste
d'objets à trier et changer le texte explicatif.
<p>
Avec une petite modification, une variante de ce modèle peut accepter des
images comme objets.
<p>
Auteur du modèle : Gang Xiao <qualite@wimsedu.info>
:%%%%%%%%%%%%%%%%% ATTENTION %%%%%%%%%%%%%%%%%%%%
Enlevez l'en-tête ci-dessus si vous détruisez les balises pour le modèle !
(Ce sont les lignes qui commencent par un ':'.)
Sinon l'exercice risque de ne pas pouvoir repasser sous Createxo.
:%%%%%%%% Paramètres d'exemples à redéfinir %%%%%%%%%%%%%%%%%
:\title{Complexité}
:\author{Viviane, Pons}
:\email{viviane.pons@lri.fr}
:\credits{}
:Nombre d'objets à trier par exercice. Jusqu'à 20.
Si ce nombre est plus petit que les objets disponibles, une partie tirée au
hasard des objets seront présentés. <p>
Si ce nombre est plus grand que les objets disponibles, il sera ramené au
nombre d'objets.
\integer{tot=4}
:La taille des objets à glisser, en pixels, x fois y.
Pensez aux gens qui augmentent la taille de polices de leurs navigateurs !
Ne mettez pas les cases trop petites.
\text{size=80x40}
:La liste d'objets à réordonner
Ecrivez les objets dans le bon ordre, séparés par des virgules.
\text{data=log(n),n,nlog(n),n^2,n^3,2^n}
:Le texte qui explique ce qu'il faut faire.
\text{explain=Ordonner ces complexités de la plus rapide (à gauche) à la plus lente (à droite) pour n grand.}
:Mise en aléatoire par des accolades emboitables
help
\text{accolade=item(1,1 oui, 2 non)}
:%%%%%%%%%%%%%% Rien à modifier avant l'énoncé %%%%%%%%%%%%%%%%
\text{accolade=wims(word 1 of \accolade)}
\text{data=\accolade=1 ? wims(embraced randitem \data)}
\integer{datacnt=items(\data)}
\integer{tot=min(20,min(\tot,\datacnt))}
\if{\tot<\datacnt}{
\text{sh=shuffle(\datacnt)}
\text{sh=wims(sort numeric items \sh[1..\tot])}
\text{data=item(\sh,\data)}
}
\text{st=wims(makelist r x for x=1 to \tot)}
\steps{\st}
:%%%%%%%%%%%%% Maintenant l'énoncé en code html. %%%%%%%%%%%%%%%%%%%%
::Vous n'avez pas besoin de modifier ceci en général.
\statement{\explain
<table class="wimsnoborder"><tr>
\for{k=1 to \tot}{<td>\embed{r\k,\size}</td>}
</tr></table>}
:%%%%%%%%%%%%% Rien à modifier ci-après. %%%%%%%%%%%%%%%%%5
\answer{1}{\data[1]}{type=dragfill}
\answer{2}{\data[2]}{type=dragfill}
\answer{3}{\data[3]}{type=dragfill}
\answer{4}{\data[4]}{type=dragfill}
\answer{5}{\data[5]}{type=dragfill}
\answer{6}{\data[6]}{type=dragfill}
\answer{7}{\data[7]}{type=dragfill}
\answer{8}{\data[8]}{type=dragfill}
\answer{9}{\data[9]}{type=dragfill}
\answer{10}{\data[10]}{type=dragfill}
\answer{11}{\data[11]}{type=dragfill}
\answer{12}{\data[12]}{type=dragfill}
\answer{13}{\data[13]}{type=dragfill}
\answer{14}{\data[14]}{type=dragfill}
\answer{15}{\data[15]}{type=dragfill}
\answer{16}{\data[16]}{type=dragfill}
\answer{17}{\data[17]}{type=dragfill}
\answer{18}{\data[18]}{type=dragfill}
\answer{19}{\data[19]}{type=dragfill}
\answer{20}{\data[20]}{type=dragfill}