;;; 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)