#lang racket ;;; chap13.rkt (require "while-for.rkt") (require "show.rkt") "Generalites sur les caracteres, page 283" (define arabiser ; ligne 17 (let ((c0 (char->integer #\0))) (lambda (c) (integer->char (+ #x660 (- (char->integer c) c0)))))) (printf "3 et 8 s'ecrivent en arabe : ~a et ~a\n" (arabiser #\3) (arabiser #\8)) (do ((i 32 (+ i 1))) ; ligne 25 ((= i 128) (void)) (when (< i 100) (printf " ")) (printf "~a ~a\t" i (integer->char i)) (when (= 1 (modulo i 6)) (printf "\n"))) (define alphabet ; ligne 59 (let ((cA (char->integer #\A))) (build-string 26 (lambda (i) (integer->char (+ cA i)))))) (show alphabet) (define $gensym ; ligne 70 (let ((n 99)) (lambda (symb) (set! n (+ n 1)) (string->symbol (string-append (symbol->string symb) (number->string n)))))) (show ($gensym 'foo)) (show ($gensym 'foo)) (define (index-of c str) ; ligne 83 (define (iter i) (cond ((>= i (string-length str)) -1) ; -1 si absent ((char=? (string-ref str i) c) i) (else (iter (+ i 1))))) (iter 0)) (show (index-of #\E alphabet)) (define F '?) ; ligne 98 (define (foo) (let/ec return ; return devient lie une fonction (set! F return) ; on peut stocker cette fonction (bar return) ; on peut exporter cette fonction 5)) ; 5 devrait etre le resultat normal de foo (define (bar x) (x 6)) (show (foo)) (define (index-of1 c str) ; ligne 112, utilisation de let/ec et return (let/ec return (for i from 0 to (sub1 (string-length str)) ; for, page 232 (when (char=? (string-ref str i) c) (return i))) (return -1))) (show (index-of1 #\E alphabet)) (define (cesar str k) ; ligne 117 (let ((cA (char->integer #\A))) ; pour ne pas le recalculer (define (code-char c) (if (not (char-upper-case? c)) ; si c n’est pas une majuscule c (let ((dist (- (char->integer c) cA))) (integer->char (+ cA (modulo (+ dist k) 26)))))) (build-string (string-length str) (lambda (i) (code-char (string-ref str i)))))) (show (cesar "ATTAQUEZ CE SOIR !" 3)) (define (tokenizer str) ; ligne 128, a completer en exercice ! (let ((*i* 0)) (define (get-char) '?) (define (unget-char!) '?) (define (digit->int c) '?) (define (char->symbol c) '?) (define (get-number) '?) (define (get-token) '?) get-token)) (define (tokens-list str) ; ligne 158 (let ((tok (tokenizer str))) (do ((t (tok) (tok)) (L '() (cons t L))) ((not t) (reverse L))))) "Les expressions regulieres, page 291" (show (regexp-match "c" "abcdec")) ; ligne 165 (show (regexp-match "p" "abcdec")) (show (regexp-match "." "abcdec")) (show (regexp-match "[.]" "abcdec")) (show (regexp-match* "." "abcdec")) (show (regexp-match* ".." "abcdec")) (show (regexp-match "[.]jpg" "Les images foo.jpg et bar.jpg")) (show (regexp-match* "...[.]..." "Les images catfoo.jpg et bar.gif")) (show (regexp-match-positions "[.]jpg" "Les images foo.jpg et bar.jpg")) (show (regexp-match-positions* "[.]jpg" "Les images foo.jpg et bar.jpg")) (show (regexp-match "[0-9]" "L'an 1023")) (show (regexp-match "[^A-Z]" "THX-sound 2011")) (show (regexp-match "[^a-zA-Z-]" "THX-sound 2011")) (show (regexp-match "[a-z]+" "THX-sound 2005")) (show (regexp-match "[a-zA-Z]*[.]jpg" "Mais foo.jpg est rouge")) (show (regexp-match* "[a-zA-Z]*[.]jpg" "foo.jpg et quux.jpg")) (show (regexp-match "0|1" "45b1d08")) (show (regexp-match "[0-9]+|[a-z]+" "THX-sound 2011")) (show (regexp-match "^ab" "abcde")) (show (regexp-match "^ab" "cdabe")) (show (regexp-match "de$" "decde")) (show (regexp-match "de$" "abdec")) (show (regexp-match "colou?r" "color")) (show (regexp-match "colou?r" "colour")) (show (regexp-replace "gif|jpg" "lion.gif et jaguar.jpg" "png")) (show (regexp-replace* "gif|jpg" "lion.gif et jaguar.jpg" "png")) (show (regexp-match "([a-zA-Z]+) ([0-9]+)" "en juin 2017 je dois")) (show (regexp-replace "([a-zA-Z]+) ([0-9]+)" "en juin 2017 je dois" "\\2 (\\1)")) (define motif #rx"[0-9]+") ; ligne 223 (show motif) (show (regexp? motif)) (show (string->number (car (regexp-match motif "x=1023+15")))) "Les ports de sortie, page 295" ; Juste pour l'illustrer, j'utilise un nouveau generateur de nombres aleatoires chaque fois... ; Ceci n'est pas obligatoire, surtout si l'on veut obtenir les memes sequences aleatoires ! (define (produire-fichier f) ; ligne 234 (call-with-output-file f (lambda (p-out) (let* ((r (make-pseudo-random-generator)) (n (+ 4 (random 7 r)))) ; n dans [4,10] (fprintf p-out "; Un fichier de ~a nombres\n" n) (for i from 1 to n (fprintf p-out "~a " (case (random 4 r) ; un entier, un rationnel, un reel ou un complexe ? ((0) (random 100 r)) ((1) (/ (random 100 r) (+ 1 (random 100 r)))) ((2) (* 100 (random r))) (else (make-rectangular (random 100 r) (random 100 r)))))) (fprintf p-out "\n"))) #:exists 'replace)) (show (produire-fichier "nombres.txt")) ; verifiez que le fichier a bien ete produit sur le disque... (define str (call-with-output-string ; une string comme port de sortie ! (lambda (p-out) (for i from 1 to 10 (fprintf p-out "~a " (sqr i)))))) (show str) "Les ports d'entree, page 297" (define (doubler) ; ligne 260 (printf "Entrez un nombre : ") (let ((n (read))) (if (number? n) (* n 2) (doubler)))) ;(show (doubler)) (define ns (make-base-namespace)) ; ligne 279 (eval '(require scheme/math) ns) ; pour inclure pi (define (valeur-en-0) ; ligne 280 (printf "Entrez une fonction : ") (let ((f (eval (read) ns))) (f 0))) ;(show (valeur-en-0)) (define (toplevel) ; ligne 290 (define (rep-loop) ; la boucle read-eval-print (printf ">> ") (let* ((expr (read)) (val (eval expr ns))) (when (not (void? val)) (printf "~s\n" val)) (rep-loop))) ; boucle infinie ! (printf "Welcome to my Scheme !\n") (rep-loop)) (require mzlib/string) ; pour read-from-string dans la fonction suivante... (define (pdoubler) ; ligne 300 (printf "Enter a number : ") (with-handlers ((exn:fail:read? (lambda (e) (printf "????\n") (pdoubler)))) (let ((n (read-from-string (read-line)))) ; mieux que le simple read du livre ! (if (number? n) (* n 2) (pdoubler))))) ;(show (pdoubler)) (define (test-read-line) ; ligne 315 (printf "Entrez une phrase : ") (let ((str (read-line))) (printf "En majuscules : ~a\n" (string-upcase str)))) ; (show (test-read-line)) (define (somme-fichier f) ; ligne 320 (call-with-input-file f (lambda (p-in) (do ((n (read p-in) (read p-in)) (acc 0 (+ acc n)) (i 0 (+ i 1))) ((eof-object? n) (printf "J'ai lu ~a nombres de somme ~a\n" i acc)))))) (show (somme-fichier "nombres.txt")) (define (my-grep str f) ; ligne 330 (call-with-input-file f (lambda (p-in) (do ((ligne (read-line p-in) (read-line p-in))) ((eof-object? ligne) (void)) (when (regexp-match str ligne) (printf "~a\n" ligne)))))) (show (my-grep "^[(]define alp" "chap13.rkt")) ; le fichier courant ! (read-accept-reader #t) ; pour accepter la syntaxe #lang en debut d'un module (when (call-with-input-file "chap13.rkt" (lambda (p-in) (let* ((expr1 (read p-in)) (expr2 (read p-in))) (eof-object? expr2)))) (printf "Le fichier chap14.rkt contient un seul objet Scheme ! C'est un module...\n")) ; recherche de la definition de la fonction my-grep dans le fichier chap13.rkt debutant par ; #lang racket et dont la veritable structure est (module chap13 racket (#%module-begin ...)) (define (chercher-definition fonc f) ; ligne 351 (define (bonne-def? expr) (and (pair? expr) (equal? (car expr) 'define) (or (equal? (cadr expr) fonc) ; (define fonc ...) (and (pair? (cadr expr)) (equal? (caadr expr) fonc))))) ; (define (fonc ...) ...) (call-with-input-file f (lambda (p-in) (car (filter bonne-def? (list-ref (read p-in) 3)))))) (printf "La definition de la fonction my-grep dans le fichier chap13.rkt est :\n") (pretty-print (chercher-definition 'my-grep "chap13.rkt")) (define description "21 kg (et 456 grammes) pour 55 km") ; ligne 368 (printf "La somme des entiers extraits de la chaine description est ~a\n" (call-with-input-string description (lambda (p-in) (define (iter x acc) (cond ((eof-object? x) acc) ((integer? x) (iter (read p-in) (+ acc x))) ; on ne voit pas le 456 (else (iter (read p-in) acc)))) (iter (read p-in) 0)))) "Un client Web pour la meteo marine, page 302" ; Dans le livre page 304, le nom du serveur est volontairement inexistant ! (define-values (p-in p-out) ; ligne 391 (tcp-connect "france.meteofrance.com" 80)) (file-stream-buffer-mode p-out 'none) (fprintf p-out "GET http://france.meteofrance.com/france/mer?MER_PORTLET.path=merprevisionville/0600451\n\n") (define LINE (do ((str (read-line p-in) (read-line p-in))) ((regexp-match "Vent" str) str))) (define VENT (regexp-match "

Vent

[^\"]+\"([^\"]*)\".*([0-9]+ km/h)" LINE)) (printf "---> Sur le port d'Antibes en ce moment : ~a (~a)\n" (second VENT) (third VENT)) "Travailler avec le systeme d'exploitation (Unix), page 305" ; Les fonctions sur les fichiers utilisent des valeurs de type path et des string. ; On peut passer d'un type a l'autre. (printf "Le repertoire courant est ~s\n" (path->string (current-directory))) (require racket/system) ; ligne 404 (show (system "pwd")) ; ligne 411, appel systeme a une commande Unix (define (get-output-cmd str) ; ligne 414 (let ((port (current-output-port)) ; on sauve le port courant (p-out (open-output-string))) ; une chaine en port de sortie (current-output-port p-out) ; changer de port courant (system str) ; appel systeme ! (close-output-port p-out) ; fermer le port courant (current-output-port port) ; restorer l'ancien port (get-output-string p-out))) ; recuperer la sortie (show (get-output-cmd "pwd")) (show (get-output-cmd "date")) ;;; utilisation de GraphViz (define (gv L) (let ((exe (getenv "gv"))) ; dans ~/.MacOSX/environment.plist ; Pour les variables d'environnement sur Mac, voir : ; http://www.astro.washington.edu/users/rowen/AquaEnvVar.html (printf "exe --> ~s\n" exe) (call-with-output-file "gv-tmp.dot" (lambda (p-out) (define (imprimer arc) (fprintf p-out " ~a -> ~a;\n" (car arc) (cadr arc))) (fprintf p-out "digraph G {\n") (for-each imprimer L) (fprintf p-out "}\n")) #:exists 'replace) (printf "N'oubliez pas de quitter GraphViz qui est peut-etre en arriere-plan !!\n") (system (format "~a gv-tmp.dot&" exe)))) ; regardez la difference entre (system ...) et (process ...) ; (gv '((foo bar) (foo gee) (quux coq) (gee quux) (quux foo)))