;;; code9.rkt - PF2 - 2016 ;;; Racket 6.6 #lang racket (require "utils.rkt") (define (doubler) (printf "Entrez un nombre ou une liste de nombres, et je double : ") (define x (read)) (cond ((number? x) (* x 2)) ((list? x) (map (lambda (e) (* e 2)) x)) (else (doubler)))) (doubler) (define ns (make-base-namespace)) (define (valeur-en-0) (printf "Entrez une fonction f et je calcule (f 0) : ") (define f (eval (read) ns)) (f 0)) (valeur-en-0) (newline) (define (creer-fichier-nombres f) (call-with-output-file f (lambda (p-out) (fprintf p-out "; fichier \"~a\"\n" f) (for ([i (in-range 8)]) (fprintf p-out "~a " (random 100))) (fprintf p-out "\n")) #:exists 'replace)) (printf "Je cree le fichier foo.dat...\n") (creer-fichier-nombres "foo.dat") (newline) (define (somme-fichier f) (call-with-input-file f (lambda (p-in) (define (iter nb somme) (define x (read p-in)) (if (eof-object? x) (printf "j'ai lu ~a nombres de somme ~a\n" nb somme) (iter (+ nb 1) (+ somme x)))) (iter 0 0)))) (printf "Je lis le fichier foo.dat : ") (somme-fichier "foo.dat") (newline) (read-accept-reader #t) ; je vais lire des fichiers Racket debutant par #lang ! (define (chercher-definition symb f) ; f est un module (define (bonne-def? expr) ;(printf "expr =~a\n" expr) (and (pair? expr) (equal? (car expr) 'define) (or (equal? (cadr expr) symb) (and (pair? (cadr expr)) (equal? (caadr expr) symb))))) (call-with-input-file f (lambda (p-in) (define (iter L) (cond ((null? L) #f) ((bonne-def? (car L)) (car L)) (else (iter (cdr L))))) (iter (cdr (cadddr (read p-in))))))) ; <-- attention ! (printf "Je cherche la definition de la fonction somme-fichier :\n") (chercher-definition 'somme-fichier "code9.rkt") ; on pourrait utiliser pretty-print :-) (newline) (define (nb-definitions f) (call-with-input-file f (lambda (p-in) (define (is-def? x) (and (pair? x) (equal? (car x) 'define))) (define (iter-file nb) (define x (read p-in)) (cond ((eof-object? x) nb) ((is-def? x) (iter-file (+ nb 1))) (else (iter-file nb)))) (define x (read p-in)) (if (and (pair? x) (equal? (car x) 'module)) ; le fichier debute par #lang ... (length (filter is-def? (cdr (cadddr x)))) (iter-file 0))))) (when (file-exists? "code9.rkt") (printf "Le fichier ~s contient ~a definitions.\n" "code9.rkt" (nb-definitions "code9.rkt"))) (newline) (define (nb-lines f) ; une iteration classique avec une boucle ligne a ligne (call-with-input-file f (lambda (p-in) (define str (read-line p-in)) (define cpt 0) (while (not (eof-object? str)) (set! cpt (add1 cpt)) (set! str (read-line p-in))) cpt))) ; Ce n'est pas dans le cours mais on peut aussi programmer en style Python avec la boucle for : (define (nb-lines-python-style f) ; une iteration a la Python... (call-with-input-file f (lambda (p-in) ; p_in = open(f,'r',encoding='utf-8') (define cpt 0) ; cpt = 0 (for ([ligne (in-lines p-in)]) ; for ligne in p_in : (set! cpt (+ cpt 1))) ; cpt = cpt + 1 cpt))) ; return cpt ; voire faire du pur Racket : (define (nb-lines-racket-pur f) ; une iteration a la Python-Scheme... (call-with-input-file f (lambda (p-in) (for/sum ([ligne (in-lines p-in)]) 1)))) ; euh, vous avez encore plus court ?... (when (file-exists? "code9.rkt") (printf "Le fichier ~s contient ~a lignes.\n" "code9.rkt" (nb-lines "code9.rkt")) (printf "Le fichier ~s contient ~a lignes.\n" "code9.rkt" (nb-lines-python-style "code9.rkt")) (printf "Le fichier ~s contient ~a lignes.\n" "code9.rkt" (nb-lines-racket-pur "code9.rkt"))) (newline) ; On peut convertir le fichier-texte en une grosse string avec file->string, ; ce qui evite string-length sur chaque ligne : (define (nb-char f) (string-length (file->string f))) (when (file-exists? "code9.rkt") (printf "Le fichier ~s contient ~a caracteres.\n" "code9.rkt" (nb-char "code9.rkt"))) (newline) (require racket/system) ; <---------- oups, je vais faire des APPELS-SYSTEME (Unix) ! (define (get-output-cmd str) ; recuperation d'un affichage Unix dans une string (define p-out (open-output-string)) (define port (current-output-port)) (current-output-port p-out) (system str) ; commande synchrone (close-output-port p-out) (current-output-port port) (get-output-string p-out)) (when (member (system-type 'os) '(macosx unix)) ; Mac ou Linux. Adaptez pour Windows... (show (get-output-cmd "wc -l code9.rkt"))) ; la commande Unix wc (newline) ;;; For information on the Windows command-line conventions, search for "command line parsing" ;;; at http://msdn.microsoft.com/ ; RAPPEL : une commande est SYNCHRONE s'il faut attendre la fin de son execution. ; Elle est ASYNCHRONE si elle termine immediatement et s'execute en tache de fond (exemple : play) (define (ls) (define p-out (open-output-string)) (define port (current-output-port)) (current-output-port p-out) (system "ls -la") ; ls est une commande Unix. Adaptez au shell Windows si besoin... (close-output-port p-out) (current-output-port port) (get-output-string p-out)) (when (member (system-type 'os) '(macosx unix)) (printf "Contenu du repertoire courant avec un appel synchrone a la fonction (ls) :\n") (printf "~a\n" (ls))) (newline) ;(printf "Autre maniere mais asynchrone avec process :\n") ;(define res (process "ls -la")) ; lancement d'un processus asynchrone --> (ip op id iperr mode) ;(printf "Processus ls id=~a :\n~a\n" (third res) (port->string (first res))) ; (first res) est un input port vers le resultat de la commande ;(define (close-port p) ; (if (input-port? p) (close-input-port p) (close-output-port p))) ;(for-each close-port (list (first res) (second res) (fourth res))) ; bof (when (member (system-type 'os) '(macosx unix)) (printf "La date Unix : ~s" ; ~s conserve les guillemets a une string contrairement a ~a (with-output-to-string (lambda () (system "date"))))) (newline) (define (read-line-until p-in pred?) ; la 1ere ligne de p-in verifiant pred? (define (iter) (define str (read-line p-in)) (cond ((eof-object? str) #f) ((pred? str) str) (else (iter)))) (iter)) (require net/url) ; gere aussi les https... ; je vais chercher le numero 1 au tennis aujourd'hui. (define foo 'any) (define (classement n) (define URL "https://www.tennisactu.net/classement-tennis.html") (printf "***** Connexion au Web sur le serveur\n") (define bigstring ; TOUTE la page Web en une seule enorme string ! Comme le f_in.read() de Python... (port->string (get-pure-port (string->url URL)))) ;(printf "--> ~a\n" bigstring)) (define r (format "~a((?!).)*>([A-Za-z ]*)" n)) (define res (regexp-match r bigstring)) (caddr res)) (printf "Le numéro 4 est ~a\n" (classement 4)) ;(define-values (p-in p-out) ; on definit deux valeurs a la fois ; (tcp-connect "www.google.com" 80)) ; car tcp-connect renvoie deux valeurs (multiple values) ;(file-stream-buffer-mode p-out 'none) ;(fprintf p-out (format "GET ~a HTTP/1.0\n\n" URL)) ; ma requete ;(define MAGIC-LINE1 ; (read-line-until p-in (lambda (str) (regexp-match "Content-Type" str)))) ;(define MAGIC-LINE2 ; (read-line-until p-in (lambda (str) (regexp-match "Bond" str)))) ;(close-input-port p-in) ;(close-output-port p-out) ;(printf "MAGIC-LINE1 dans le header ---> ~s\n" MAGIC-LINE1) ;(printf "MAGIC-LINE2 dans le document ---> ~s\n" MAGIC-LINE2)