Jean-Jacques BOURDIN

Université Paris 8
Labo IA, Dépt. Informatique
2, rue de la Liberté
93526 Saint-Denis Cedex
FRANCE

Tél : (+33/0) 1 49 40 64 03
Fax : (+33/0) 1 49 40 67 83
E-mail : Jean-Jacques.BourdinNOSPAM@ai.univ-paris8.fr (enlever le NO Spam)


Méthodologie de la Programmation

Septembre-décembre 2017

  1. Présentation
  2. Essayons !
  3. Comparons !
  4. Scriptons !
  5. Les énoncés des projets
  1. Présentation

    • L'université, la formation

    • Ce cours

    • Mail

      Dans tout ce cours il faudra, souvent, m'envoyer des messages par email. Vous devrez utiliser votre compte étudiant (etud.univ-paris8.fr), de façon à ce que je puisse vous répondre facilement. Les pièces jointes sont autorisées à condition que les fichiers portent un suffixe cohérent ("exo.l" si c'est du lisp par exemple). Les messages sans sujet peuvent ne pas être lus.

      Une série de raccourcis est disponible sous emacs, vous en trouverez quelques exemples soit ici , soit en tapant Esc x puis "describe-bindings" sous emacs.

    • Informatique, de quoi est-ce le nom ?

    • Histoire

    • Principes et Classification des langages

  2. Essayons !

    1. Lisp, Scheme, Syntaxe

      1. syntaxe

        (function parameter_1 parameter_2 parameter_3 ... parameter_n)
        (+ 3 2) => 5
        
      2. Facile

        Avec Drracket il suffit de lancer DrRacket, donc de taper drracket & comme commande et vous entrez dans drracket et son interprête. Demandez des évaluations et il les exécute.

        Une fenêtre en deux parties s'ouvre. En haut vous pouvez taper du code et demander son exécution (c'est un bouton au-dessus). En bas vous pouvez demander à utiliser l'interprête directement, comme vous le voyez dans les exemples ci-dessous.
        Dans DrRacket choisir
        #lang racket
        qui nous conviendra.
        [22]> (+ 5 (* 2 6))
        17
        [22]> 
        
        Avec sbcl, c'est presque pareil (on lance sbcl) et le prompt est une étoile *.
      3. Premiers programmes

        (define (foisquatre n)
            (* n 4))
        (define (carre n)
            (* n n))
        (define (cube n)
            (* n (* n n)))
        (define (puis4 n)
        (* (* n n) (* n n)))
        
        Faites maintenant :
        • une fonction qui renvoie le double d'un nombre.
        • une fonction qui renvoie le triple d'un nombre.
        • une fonction qui renvoie la puissance cinq d'un nombre.
      4. Réutilisation
        Éditez votre fichier, sauvegardez-le (par exemple avec le nom premprog.l), lancez lisp (commande drracket &). Tapez
        (load "premprog.l")
        
        Lisp répond = t. Vous pouvez alors vous servir de tout ce qui est défini dans le fichier. Par exemple pour demander un calcul (+ 3 5) ou l'évaluation d'une fonction :
        ? (carre 5)
        = 25
        ? (carre 6)
        = 36
        ? (cube 5)
        = 125
        ?
        
        Plus tard, vous devrez quitter Lisp, par exemple en utilisant la fonction quit :
        [22]> (quit)
        Bye.
        
        Et vous êtes sortis.

      5. Et sinon ?

        Plus grand de deux valeurs

        (define (plgd2 a b)
          (if (< a b) 
              b 
              a))
        

        Exercices à faire et à valider sur ordinateur.

        1. puissance4
        2. puissance5
        3. puissance6
        4. plus grand de trois valeurs
        5. plus grand de quatre valeurs
        6. plus grand de cinq valeurs
        7. plus grand de six valeurs
        8. plus petit de trois valeurs
        9. plus petit de quatre valeurs
        10. second plus grand de trois valeurs
        11. second plus grand de quatre valeurs
        12. second plus grand de cinq valeurs
        Exemples de solutions :

        Plus grand de trois valeurs

        (define (plgd3 a b c)
          (if (< a b)
        	  (if (< b c)
        		  c
        		b)
        	(if (< a c)
        		c
        	  a)))
        

        Plus grand de quatre valeurs

        (define (plgd4 a b c d)
          (if (< a b)
        	  (if (< b c)
        		  (if (< c d)
        			  d
        			c)
        		(if (< b d)
        			d
        		  b))
        	(if (< a c)
        		(if (< c d)
        			d
        		  c)
        	  (if (< a d)
        		  d
        		a))))
        
    2. Récursivité
      1. Définition
      2. Fonctions simples
        Nous verrons ici des fonctions numériques simples (la somme des n premiers entiers, la factorielle), puis leur transformation pour obtenir des fonctions un peu plus complexes, comme la somme des carrés de n premiers entiers.
        (define (som n)
            (if (= n 0)
                0
                (+ n (som (- n 1)))))
        (define (fac n)
            (if (= n 1)
                1
                (* n (fac (- n 1)))))
        
        (define (somcar n) (if (= n 0) 0 (+ (carre n) (somcar (- n 1))))) Vous devrez ensuite faire une série d'exercices :
        • Produit des carrés des n premiers entiers
        • Produit des cubes des n premiers entiers
        • Produit des puissances 4 des n premiers entiers
        • Produit de leur propre puissance des n premiers entiers

          0^0+1^1+2^2+3^3+...+n^n
        • Somme des puissances p des n premiers entiers
          0^p+1^p+2^p+3^p+...+n^p
        • Somme des puissances p des n premiers entiers
          0^n+1^n+2^n+3^n+...+n^n
        • Soustraction par additions et soustractions de 1.
        • Division entière par soustractions successives.
        • Reste de la division entière par soustractions successives.
        • pgcd.
        • Fibonacci.

        Exemple d'erreur :
        (define (div a b)
          (if (= a b)
              1
              (+ 1 (div (sous a b) b))))
        ;test
        ;[6]> (div 10 2)
        ;5
        
        DIV
        * (div 7 2)
        Illegal instruction
        
        
        Vous l'avez essayé et ça vous a plu. Je l'ai testé et détesté !
        il ne vous reste plus qu'à corriger.

      3. Récursivité terminale
        Comment transformer une récursivité en terminale ? En ajoutant un paramètre dans lequel seront faits les calculs intermédiaires.
        Exemple :
        (define (somme n)
           (somrt n 0))
        (define (somrt n acc)
           (if (= n 0)
               acc
               (somrt (- n 1) (+ n acc))))
        
        Reprendre en récursivité terminale tous les exercices faits jusqu'ici.
        Exemple d'erreur : faire la multiplication par additions successives
        ;Multiplication de deux valeurs en récursivite terminale
        (define (mulrtaux a b acc)
          (if (= a 0)
              (* b acc)  ; ceci n'est pas une addition, Hors Sujet
              (mulrtaux (- a 1) b (+ acc 1))))
        (define (mulrt a b)
          (mulrtaux a b 0))
        

        Et pourtant ça commençait bien, non ?

        Reste à refaire tous les exercices récursifs en récursivité terminale, y compris Fibonacci.

        (define (multrt a b)
          (multrtaux a b 0))
        ; il faut bien 0 puisqu on va faire des additions
        (define (multrtaux a b acc)
          (if (= a 0)
             acc
             (multrtaux (- a 1) b (+ b acc))))
        ; et où est la difficulté ?
        
    3. Listes
      1. Définition
        Une liste est, soit une liste vide, soit une construction formée d'un objet et d'une liste.

      2. Fonctions de listes
        Voici une liste :
        (cons (cons 1 ()) (cons 2 ()))
        
        car, cdr, cons, quote, pair?

      3. Fonctions de listes

        (define (estvide l)
          (if (pair? l)
             #f
             #t))
        
        Premières fonctions :
        (define (nonvide l)
          (if (equal? l '())
        	  #f
        	#t))
        (define (vide l)
          (if (equal? l '())
        	  #t
        	#f))
        
        (define (soml l)
          (if (vide l)
        	  0
        	(+ (car l) (soml (cdr l)))))
        
        1. Est-ce que la liste est un singleton (liste d'un élément) ?
        2. Est-ce que la liste est une paire (liste de deux éléments) ?
        3. Est-ce que la liste est un triplet (liste de trois éléments) ?
        4. Est-ce que la liste est un quadreton (liste de quatre éléments) ?
        5. Le troisième élément d'une liste
        6. Le quatrième élément d'une liste
        7. Le n-ième élément d'une liste
        8. Somme des carrés des éléments d'une liste numérique
        9. Plus grand élément d'une liste
        10. Second plus grand élément d'une liste
        11. Troisième plus petit élément d'une liste
        12. Le nombre d'éléments négatifs d'une liste de nombres
        13. Le nombre d'éléments positifs d'une liste de nombres
        14. La somme des éléments de rang impairs (le premier, le troisième, le cinquième, ... dans l'ordre de la liste, pas par ordre décroissant ou autre). Exemple :
          * (somodd '(2 4 1 2 5 6 2))
          = 10
          
        15. Le dernier élément de la liste
        16. L'avant-dernier élément de la liste
      4. Prendre dans une liste tous les éléments plus grands que l'autre paramètre de la fonction.
        (lesgrands '(13 7 15 2) 8)
        = (13 15)
        
      5. Prendre dans une liste tous les éléments inférieurs ou égaux à l'autre paramètre de la fonction. (ce sont les autres !)
      6. Faites une fonction de tri basée sur la méthode suivante :
        • soit une liste l, son premier élément sera nommé "pivot" et le reste de la liste "sous-liste".
        • Fabriquer "petits" une liste de tous les éléments de la "sous-liste" inférieurs ou égaux au pivot.
        • Fabriquer "grands" une liste de tous les éléments de la "sous-liste" supérieurs au pivot.
        • Fabriquer "grandstries" la liste grands une fois triée.
        • Fabriquer "petitstries" la liste petits une fois triée.
        • Concaténer tout cela pour faire une liste ayant tous les éléments de l mais qui soit triée.
  • Petit Précis de Programmation

    1. Principes
    2. Fonctionnel
      Fonctionnel, est-ce pour parler des fonctions qu'on peut manipuler ou pour le mode dans lequel on ne change jamais la valeur d'une variable ?
    3. Impératifs
      1. Assembleurs
      2. Python

        Nous devons essayer Python. Première fonction, offerte par Daniel Goossens :
        def fact(n):
          if n==0: 
             return 1
          else:
             return n*fact(n-1)
        
        print fact(5)
        print fact(6)
        print fact(7)
        

        Pour s'en servir, une fois ce programme mis dans un fichier exo.py

        , on se place dans un terminal et on tape :

        dhcp17.ai.univ-paris8.fr: python prog.py
        120
        720
        
        Mon deuxieme programme, par moi-même, cinq minutes après :
        def fib(n):
          if n==0: 
            return 1
          else:
            if n==1: 
              return 1
            else:
              return fib(n-1)+fib(n-2)
        
        print fib(4)
        print fib(5)
        print fib(6)
        print fib(7)
        
        #neige: python fact.py
        #120
        #720
        #5040
        #5
        #8
        #13
        #21
        

        Comme vous le voyez, pour l'utiliser il suffit de demander l'exécution de python fact.py.

        Vous avez quelques exercices à faire avec python, il suffit de reprendre tout ce que nous avons fait jusqu'ici !


        Voyons maintenant des fonctions numériques itératives :
        def som(n):
           s = 0
           i = 0
           while (i <= n):
              i = i + 1
              s = i + s
           return s
        print 5,som(5)
        
        

        Si les valeurs obtenues ne vous conviennent pas, vous pouvez corriger un peu le programme...

        Vous devez maintenant reprendre toutes vos fonctions récursives (surtout sous la forme récursive terminale) et en faire des fonctions itératives. et maintenant les listes, dites aussi vecteurs

        def soml (L):
            nb = len(L)
            i = 0
            s = 0
            while (i < nb):
                s = s + L[i]
                i = i + 1
            return s
        print soml([3, 2, 5, 4, 1])
        
        On obtient, bien sûr, 15.
        La fonction qui renvoie la longueur, len tient son nom de length.
        def longueur (L):
        	nb = 0
        	for v in L:
        		nb = nb + 1
        	return nb
        print longueur([9,2,3])
        

        def remplirt (n):
            i = 0
            T = []
            while (i <= n):
                T.insert(i)
                i = i + 1
            return T
        print remplirt(10)
        def somt (n):
            L = remplirt (n)
            i = 0
            s = 0
            while i < n:
               s = s + L[i]
               i = i + 1
            return s
        print somt(6)
        print somt(7)
        

        Il vous reste à faire quelques exercices pour vous habituer à Python :

        • Refaire toutes les fonctions vues en Lisp en Python.
        • Refaire toutes les fonctions vues en Lisp en Python mais en itératif.
        • Refaire tout ce qui a été vu sur les listes, mais en Python.
        • Concaténation, en vidant peu à peu la première liste dans la seconde.
        • Inversion avec pgdg, voir ci-dessous.
          NB Voici la fonction vide :
          (define (vide l) (not (pair? l)))
          (define (pgdg l)
            (if (vide l) l
          	(if (vide (cdr l)) l
          	  (if (vide (cddr l)) (inv2 l)
          		(cons (car (pgdg (cdr l)))
          			  (pgdg (cons (car l)
              					  (pgdg (cdr (pgdg (cdr l)))))))))))
          
          

      3. C
        1. Premières fonctions
          /* voici un exemple tres simple */
          
          /* D abord une fonction elementaire */
          
          int som (int n) {
            if (n < 1) {
          	return 0;
            }
            return som (n - 1);
          }
           
        2. main et printf
          main () {
            printf("som (5) == %d\n",som(5));
            printf("som (6) == %d\n",som(6));
            printf("som (7) == %d\n",som(7));
          }
           
        3. Compilation et exécution
          mu.ai.univ-paris8.fr: gcc exo1.c
          mu.ai.univ-paris8.fr: a.out
          som(5) == 15
          som(6) == 21
          som(7) == 28
          mu.ai.univ-paris8.fr:
           
          On peut mettre les mots clé #include<stdio.h> en début de fichier pour éviter quelques "warning" disgrâcieux mais sans conséquence.
          Parfois, à la place de taper "a.out" vous avez besoin de taper "./a.out".
          Faire en C toutes les fonctions vues précédemment.
        4. Vecteurs
          void remplirt (int tab [100], int nb) {
          /* void à la place de int pour signifier qu'il n'y a rien à renvoyer*/  
            int pred, ante, i;
          
            if (nb > 99)
          	return;
            pred = 13;
            ante = 8;
            tab [0] = 8;
            tab [1] = 13;
            i = 2;
            while ( i < nb) {
          	tab [i] = (ante + pred) % 23;
              /* % est le modulo, le reste de la division entière */
          	ante = pred;
          	pred = tab [i];
          	i = i + 1;
            }
          }
          void affichet (int tab [100], int nb) {
            int i;
          
            i = 0;
            while (i < nb) {
          	printf("t[%d]== %d \n", i, tab[i]);
          	i = i + 1;
            }
          }
          main () {
            int nb, t [100];
          
            nb = 20;
            remplirt (t, nb);
            affichet (t, nb);
          }
          

          Vous pouvez maintenant compléter cette fonction main et faire les fonctions suivantes :
          • somme des éléments du vecteur
          • nombre d'éléments positifs d'un vecteur
          • nombre d'éléments impairs d'un vecteur
          • plus grand élément du vecteur
          • second plus grand élément du vecteur
          • troisième plus petit élément du vecteur
          • somme des éléments supérieurs à x (second argument)
          • créer le miroir du vecteur
          • nombre d'éléments supérieurs à un x donné
          • élément médian du vecteur (celui qui, à 1 près, a autant d'éléments supérieurs à lui que d'éléments inférieurs à lui)
          • en supposant un vecteur rangé dans l'ordre croissant, insérer un élément à sa place (et donc décaler les éléments plus grands).
          • Utiliser la dernière fonction, pour, un par un, insérer tous les éléments d'un vecteur dans un vecteur au préalable vide.
        5. COBOL
        6. FORTRAN et BASIC
        7. Pascal et ADA
        8. Autres
      4. Logique
        Nous étudierons le langage PROLOG pour ses capacités à programmer des expressions logiques.
        1. Premières clauses

          Voici maintenant une primitive qui calcule le carré d'un nombre, et celle qui compte la somme des N premiers entiers :
          carre(N,C):- C is N * N.
          somme(0,0).
          somme(N,S):-   N1 is N - 1,
                         somme(N1,S1),
                         S is S1 + N.
          

          Nous les avons mises dans un fichier exo1.pl. Pour s'en servir avec prolog, dans le terminal il suffit de lancer prolog.
          $ swipl
          Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.2.3)
          Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
          SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
          and you are welcome to redistribute it under certain conditions.
          Please visit http://www.swi-prolog.org for details.
          
          For help, use ?- help(Topic). or ?- apropos(Word).
          
          ?- consult(exo).
          true.
          
          ?- carre(5,N).
          
          N = 25 
          
          Yes
          ?- carre(5,7).
          
          No
          
          ?- somme(3,Z).
          
          Z = 6
          
          Yes
          
          ?-
          

          Il vous reste à faire un certain nombre de fonctions numériques (jusqu'à la suite de Fibonacci, par exemple).
        2. Listes
          Une liste en prolog est soit la liste vide ([]) soit formée d'un objet et d'une liste ([A | Bs]), comme dans ([1,2,3,4]). Ici, A vaut 1 et Bs vaut la liste [2,3,4].
          Faisons une fonction qui prend le dernier élément d'une liste.
          dernier([A],A).
          dernier([A|Ls],B):- dernier(Ls,B).
          

          On peut aussi compter les éléments d'une liste :
          total([],0).
          total([A|Ls],T):-total(Ls,V),
                           T is V + 1.
          

          Pour sortir de prolog ?

          la commande est "halt."

           halt.
          sunfire $
          
        3. Hérédité
           pere(chuck, eddie).
           pere(chuck, elvis).
           pere(elvis,john).
           pere(elvis,mick).
           pere(john,janis).
           pere(john,nico).
           
          Ceci énonce une base de faits dans laquelle chuck est le père d'eddie... et ainsi de suite. On peut lancer prolog et poser des questions. Je mets tous ces faits dans le fichier rock.pl dont vous trouvez le contenu ci-dessous.

          Attention, prolog ne fonctionne pas sur toutes les machines, il faut parfois se connecter à un serveur

           $ swipl
           Welcome to SWI-Prolog (Version 3.3.4)
           Copyright (c) 1990-2000 University of Amsterdam. 
           Copy policy: GPL-2 (see www.gnu.org)
          
           For help, use ?- help(Topic). or ?- apropos(Word).
          
           1 ?- consult(rock).
           % rock compiled 0.01 sec, 9,868 bytes
          
           Yes
           2 ?- 
           pere(X,janis).
          
           X = john 
          
           Yes
           3 ?- pere(janis,X).
          
           No
           4 ?- 
           
          Développons la base de faits.
           /* famille du rock, due a J-J Bourdin */
           /* les pères                          */
           pere(chuck, eddie).
           pere(chuck, elvis).
           pere(elvis,john).
           pere(elvis,mick).
           pere(john,janis).
           pere(john,nico).
           pere(john,lou).
           pere(mick,pete).
           pere(mick,robert).
           pere(mick,david).
           pere(lou,vanessa).
           pere(lou,marianne).
           /* les mères                          */
           mere(ella,eddie).
           mere(ella,elvis).
           mere(edith,john).
           mere(edith,mick).
           mere(janis, sinead).
           mere(nico, joan).
          
           feminin(janis).
           feminin(nico).
           feminin(vanessa).
           feminin(marianne).
           feminin(sinead).
           feminin(joan).
          
           masculin(chuck).
           masculin(eddie).
           masculin(elvis).
           masculin(john).
           masculin(mick).
           masculin(lou).
           masculin(david).
           masculin(pete).
           masculin(robert).
          
           fils(X,Y):-pere(Y,X),masculin(X).
           fils(X,Y):-mere(Y,X),masculin(X).
           fille(X,Y):-pere(Y,X),feminin(X).
           fille(X,Y):-mere(Y,X),feminin(X).
          
           /*  quelques primitives généralistes */
           /*  admirez les variables            */
           parent(X,Y):-pere(X,Y).
           parent(X,Y):-mere(X,Y).
           enfant(X,Y):-parent(Y,X).
           gdparent(X,Y) :- parent(X,Z),parent(Z,Y).
          
           
          Note
          Pour tester l'égalité, on peut utiliser == c'est-à-dire :
           egal(A,B):-A==B.
           
          cela fonctionne :
           ?- egal(5,5).
          
           Yes
           ?- egal(4,5).
          
           No
           
          Par contre pour la différence, il faut écrire =\= pour les valeurs numériques (et pas les textes) :
           diffe(A,B):-A=\=B.
           
          Pour les autres cas, l'inverse d'une valeur logique est sa négation:
           egal(A,B):-A==B.
           different(A,B):-not(egal(A,B)).
           
          Il faut maintenant faire les prédicats :
          1. puissance en récursivité terminale,
          2. miroir en récursivité terminale,
          3. tri par insertion,
          4. prédicat ascendant,
          5. prédicat descendant,
          6. prédicat cousin (au sens large).
      5. À objets ?
        Nous allons donner un exemple en Java.
        public class big {
        	public static void main(String[] args) {
        		
        		int i, som, fac, fi;
        		int n;
        		n = 10;
        		int tab[] = new int[100];
        		System.out.println(" ");
        		i = 1;
        		som = 0;
        		fac = 1;
        		while (i <= n) {
        			som = som + i;
        			fac = fac * i;
        			i = i + 1;
        		}
        		System.out.println(" som iteratif " + som + " recursif  " + somme(n));
        		System.out.println(" produit iteratif " + fac + " recursif  " + fact(n));
        		i = 0;
        		n = 10;
        		while (i <= n) {
        			System.out.println("fib  " + i + "  =>  " + fib (i));
        			i = i + 1;
        		}
        		i = 2;
        		tab[0] = 1;
        		tab[1] = 1;
        		while (i < n) {
        			tab[i] = tab[i - 1] + tab[i - 2];
        			i = i + 1;
        		}
        		i = n - 1;
        		while (i >= 0) {
        			System.out.println("tab  " + i + "  =>  " + tab [i]);
        			i = i - 1;
        		}
        		/* vecteurs dans d'autres fonctions*/
        		remplir(n, tab);
        		voir (n, tab);
        					
        	}
        	public static int somme (int n) {
        		if (n < 1)
        			return 0;
        		return n + somme (n - 1);
        	}
        	public static int fact (int n) {
        		if (n < 1) {
        			return 1;
        		}
        		else {
        			return n + fact (n - 1);
        		}
        	}
        	public static int fib (int n) {
        		if (n < 2)
        			return 1;
        		return fib (n - 1) + fib (n - 2);
        	}
        	public static void remplir (int nb, int [] vec) {
        		int i, j, tmp;
        		i = 0;
        		j = nb - 1;
        		tmp = 5;
        		while (i < nb) {
        			vec[i] = j;
        			j = j - tmp;
        			if (j < 0) {
        				tmp = - tmp;
        				tmp++;
        			}
        			if (j > 30) {
        				tmp = - tmp;
        				tmp--;
        			}
        			i = i + 1;
        		}
        	}
        	public static void voir (int nb, int [] vec) {
        		int i;
        		i = 0;
        		while (i < nb) {
        			System.out.println("vec ( "+i+" ) == " + vec[i]);
        			i++;
        		}
        	}
        }
        

        Nous mettons tout cela dans un fichier big.java. Il ne reste plus qu'à compiler puis exécuter pour vérifier que tout cela marche bien.
        $ javac big.java
        $ java big
        Il faut compter jusqu a : 10
        Somme recursive      => 3628800
        Somme vecteur      => 55
        Recursive terminale  => 55
        Produit recursif     => 3628800
        vec ( 0 ) == 9
        vec ( 1 ) == 4
        vec ( 2 ) == -1
        vec ( 3 ) == 3
        vec ( 4 ) == 7
        vec ( 5 ) == 11
        vec ( 6 ) == 15
        vec ( 7 ) == 19
        vec ( 8 ) == 23
        vec ( 9 ) == 27
        vec ( 0 ) == 27
        vec ( 1 ) == 23
        vec ( 2 ) == 19
        vec ( 3 ) == 15
        vec ( 4 ) == 11
        vec ( 5 ) == 7
        vec ( 6 ) == 3
        vec ( 7 ) == -1
        vec ( 8 ) == 4
        vec ( 9 ) == 9
        Fib 1 = 1
        Fib 2 = 2
        Fib 3 = 3
        Fib 4 = 5
        Fib 5 = 8
        Fib 6 = 13
        Fib 7 = 21
        Fib 8 = 34
        Fib 9 = 55
        Fib direct 10 = 89
        Fib recur  10 = 89
        $
        

      6. Divers
        1. LaTeX
        2. Partiel et LaTeX

          Vous trouverez un texte de partiel, en cliquant ici. Il s'agit de la version pdf à afficher avec acroread.
          Le texte lui-même est donné en cliquant là. Il faut le compiler avec LaTeX puis l'afficher ou en faire un ps ou en faire un pdf.
          $ latex ilp10_p.tex
          ...
          Overfull \hbox (5.3039pt too wide) in paragraph at lines 131--135
          []\T1/cmr/bx/n/10.95 SomCar : \T1/cmr/m/n/10.95 ?cri-vez une fonc-tion qui pren
          d
          [1]
          Overfull \hbox (7.47572pt too wide) in paragraph at lines 149--153
          \T1/cmr/m/n/10.95 en pa-ra-m?tre une liste et ren-voie la somme
          [2] (./ilp07_p.aux) )
          (see the transcript file for additional information)
          Output written on 12_ilp_p.dvi (8 pages, 7144 bytes).
          Transcript written on ilp10_p.log.
          
          Ensuite on le passe en ps ou en pdf, selon l'usage souhaité.
          $ dvips -o 12_ilp_p.ps 12_ilp_p.dvi
          . 
          
          [1] [2] 
          $ dvipdf 12_ilp_p.dvi
          $
          

          Maintenant le fichier .ps existe, de même que le fichier .pdf et le fichier .dvi (on peut voir ce dernier grâce à xdvi).
          Un autre exemple, vous voyez tout de suite ce que fait le programme suivant n'est-ce pas ?.
          \batchmode
          
          \documentclass{article}
          \pagestyle{empty}
          \usepackage{ifthen}
          
          \newcounter{mula}
          \newcounter{mulb}
          \newcounter{prod}
          \newcounter{compt}
          \newcounter{fv}
          \newcounter{fi}
          
          \newcommand{\mul}[2]{
             \setcounter{mula}{#1}
             \setcounter{mulb}{#2}
             \setcounter{prod}{0}
             \setcounter{compt}{0}
             \mulaux{#1}
          }
          
          \newcommand{\mulaux}[1]{
          
              \ifthenelse{#1 > \thecompt}{\mulo{#1}}{}
          }
          
          \newcommand{\mulo}[1]{
             \stepcounter{compt}
             \addtocounter{prod}{\themulb}
             \mulaux{#1}
          }
          \newcommand{\fac}[1]{
             \setcounter{fv}{1}
             \setcounter{fi}{1}
             \facaux{#1}
             La factorielle de #1 est \thefv ~\\~\\
          }
          \newcommand{\facaux}[1]{
             \ifthenelse{#1 > \thefi}{\faco{#1}}{}
          }
          \newcommand{\faco}[1]{
             \stepcounter{fi}
             \mul{\thefi}{\thefv}
             \setcounter{fv}{\theprod}
             \facaux{#1}
          }
          
          \begin{document}
          
          \underline{\Huge\bf I.L.I. LaTeX}\\~\\
          on affiche pour 3 et 5 \\~\\
          \fac{3}
          \fac{5}
          \end{document}
          

          le mettre dans un fichier, le compiler et regarder est une bonne méthode...

          Enfin, un rapport

          Voici, ici un exemple de rapport écrit en LaTeX. Le fichier de bibliographie (si vous en avez besoin) est donn de même que le résultat de la compilation de l'ensemble vers un fichier pdf: projet.pdf .
    4. Shell

      1. Principes Premier programme
         #!/bin/sh
         #  affiche les arguments
        
           echo $1
           echo $2
           echo $3
           echo $4
        
         
        Utilisons-le :

        Vous mettez ce code dans un fichier, par exemple de nom voir.sh.

        Vous rendez ce fichier exécutable, par exemple par :

         $chmod 755 voir.sh
         
      2. NB. Si vous voulez vérifier, vous trouvez que le fichier est exécutable.

        Il en ira de même à chaque nouveau shellscript : il doit être exécutable et on doit y avoir accès pour pouvoir l'exécuter.

         $ voir.sh Je fais souvent ce reve etrange
         Je
         fais
         souvent
         ce
         $
         
         #!/bin/sh
         #  affiche les arguments
        
           echo $1
           shift
           echo $1
           shift
           echo $1
           shift
           echo $1
           shift
        
        
         
        Utilisons-le :
         $ voir.sh Je fais souvent ce reve etrange
         Je
         fais
         souvent
         ce
         $
         
        Mais on est limité quant au nombre de paramètres. Ce qui n'est pas le cas avec le programme suivant :
        #!/bin/bash
        n=$#
        i=1
        while test $i -lt $n
        do
          echo $1
          shift
          i=`expr $i + 1`
        done
        
        ou une version plus simple, puisque shift modifie également le nombre d'arguments.

        #!/bin/bash
        while test $# -gt 0
        do
        	echo $1
        	shift
        done
        
      3. Numériques
        Pour commencer, le double d'un nombre :
         if test $# -eq 1
         then
           expr $1 + $1
         else
           echo "usage: $0 n"
         fi
         
        Je mets ceci dans un fichier carre.sh et cela donne à l'usage :
         otake: chmod +x carre.sh 
         otake: carre.sh 5
         10
         otake: carre.sh 6
         12
         
      4. Structures de Contrôle
        1. if

          Comme à notre habitude, nous verrons la fonction somme.
          Fichier som.sh

          #!/bin/sh
          
          #juste la somme
          
          if test $# -lt 1
          then
            echo "usage: $0 nb"
          else
            if test $1 -le 0
            then
              echo 0
            else
              n=`expr $1 - 1`
              f=`som.sh $n`
              expr $f + $1
            fi
          fi
           #jj@aqua$ chmod +x som.sh 
           #jj@aqua$ som.sh 5
           #15
           
          Notez que j'ai modifié mon fichier .bashrc en ajoutant la ligne suivante :
          PATH=$PATH'~/bin/:./:'
           
          pour y rajouter mon répertoire bin (où je mets mes exécutables) et le répertoire courant.
          Pour que ceci soit effectif il faut lancer la commande shell :
             source ~/.bashrc
           
          Donc il faut refaire maintenant tous les exercices numériques en shell.
          • Multiplication par additions successives.
          • Somme des cubes.
          • A puissance B.
          • Reste de la division entière.
          • pgcd.
          • Fibonacci.
          • Plus grand de deux valeurs.
          • Plus grand de trois valeurs.
          • Plus grand de quatre valeurs.
          • Plus grand de cinq valeurs.
          • Second plus petit de cinq valeurs.
            • case
              Voyons le case sur un exemple sans ambition :
              jj@sunfire$ cat essai.sh
              case $# in
                1) echo $1;;
                2) echo $1 $2;;
                3) echo $1 $2 $3;;
                *) echo "trop de parametres"
                esac
              jj@sunfire$ essai.sh 1 2
              1
              2
               
            • while

              Fichier faciter.sh

               #!/bin/sh
              
               if test $# -eq 1
               then
                  n=$1
                  f=1
                  while test $n -ge 1
                  do
                     f=`expr $f \* $n`
              	   n=`expr $n - 1`
                  done
                  echo $f
               else
              	echo "un argument, un !"
               fi
              
               #jj@aqua$ chmod 755 faciter.sh 
               #jj@aqua$ faciter.sh 6
               #720
               
              Refaites tous les exercices numériques en shell itératif.
              • Multiplication par additions successives.
              • Somme des cubes.
              • A puissance B.
              • Reste de la division entière.
              • pgcd.
              • Fibonacci.
              • Produit des puissances n.
                • Les for

                  D'abord prendre et afficher tous les arguments :
                  Fichier louque.sh
                   for i
                   do
                     echo $i
                   done
                   
                  Ensuite prendre et afficher tous les fichiers du répertoire courant :
                  Fichier ici.sh
                   for i in *
                   do
                     echo $i
                   done
                   
                  Enfin, prendre chacun des termes :
                  Fichier tiens.sh
                   f=1
                   for i in 1 2 3 4 5 6
                   do
                     f=`expr $f \* $i`
                     echo $i $f
                   done
                   

      5. Les Tableaux
        Commençons par appeler 11 fois un script que nous allons écrire ensuite, ça aidera :
        #!/bin/sh
        
        for a in 0 1 2 3 4 5 6 7 8 9 10
        do
        #  echo $a
          ./fibt.sh $a
        done
         

        Dernière mise à jour de ce document :

        29/11/2017 11h