• Aucun résultat trouvé

Fonction textread

Dans le document Cours MATLAB et GNU Octave en pdf (Page 117-120)

[vec1, vec2, vec3 ...] = textread(file_name, format {,n})

Fonction simple et efficace de lecture d'un fichier-texte nommé file_name dont l'ensemble des données répond à un format homogène. Les données peuvent être délimitées par un ou plusieurs espace, tab, voire même saut(s) de ligne newline. La lecture s'effectue ainsi en "format

libre" (comme avec sscanf et fscanf).

• Le vecteur-colonne vec1 recevra la 1ère "colonne" du fichier, le vecteur vec2 recevra la 2e colonne, vec3 la 3e, et ainsi de suite... La lecture s'effectue jusqu'à la fin du fichier, à moins que l'on spécifie le nombre n de fois que le format doit être réutilisé.

• Le nombre de variables vec1 vec2 vec3... et leurs types respectifs découlent directement du format

• Si vec-i réceptionne des chaînes de caractères, il sera de type "tableau cellulaire", en fait vecteur-colonne cellulaire

Les "spécifications de conversion" de format %f, %s, %u et %d peuvent être utilisées avec textread sous MATLAB et Octave. Sous Octave seulement on peut en outre utiliser les spécifications %o et %x.

Sous MATLAB, les spécifications %u et %d génèrent un vecteur réel double précision. Mais ATTENTION, sous Octave elles génèrent un vecteur entier 32 bits !

Sous MATLAB seulement on peut encore utiliser :

%[...] : lit la plus longue chaîne contenant les caractères énumérés entre [ ]

%[^...] : lit la plus longue chaîne non vide contenant les caractèrens non énumérés entre [ ]

Ex:

Soit le fichier-texte de données ventes.txt suivant : 10001 Dupond Livres 12 23.50 10002 Durand Classeurs 15 3.95 10003 Muller DVDs 5 32.00 10004 Smith Stylos 65 2.55 10005 Rochat CDs 25 15.50 10006 Leblanc Crayons 100 0.60 10007 Lenoir Gommes 70 2.00 et le script MATLAB/Octave suivant :

[No_client, Nom, Article, Nb_articles, Prix_unit] = textread('ventes.txt', '%f %s %s %f %f') ; Montant = Nb_articles .* Prix_unit ;

disp(' Client [No ] Nb Articles Prix unit. Montant ') disp(' --- --- --- --- --- ---') format = ' %10s [%d] %5d %-10s %8.2f Frs %8.2f Frs\n' ;

for no=1:1:length(No_client)

fprintf(format, Nom{no}, No_client(no), Nb_articles(no), Article{no}, Prix_unit(no), Montant(no) ) ; end

fprintf('\n\n TOTAL %8.2f Frs \n', sum(Montant) )

Attention : bien noter, ci-dessus, les accolades pour désigner éléments de Nom{} et de Article{}. Ce sont des "tableaux cellulaires" dont on pourrait aussi récupérer les éléments, sous forme de chaîne, avec : char(Nom(no)), char(Article(no)).

L'exécution de ce script: lit le fichier, calcule les montants, et affiche ce qui suit :

Client [No ] Nb Articles Prix unit. Montant --- --- --- --- --- --- Dupond [10001] 12 Livres 23.50 Frs 282.00 Frs Durand [10002] 15 Classeurs 3.95 Frs 59.25 Frs Muller [10003] 5 DVDs 32.00 Frs 160.00 Frs Smith [10004] 65 Stylos 2.55 Frs 165.75 Frs Rochat [10005] 25 CDs 15.50 Frs 387.50 Frs Leblanc [10006] 100 Crayons 0.60 Frs 60.00 Frs Lenoir [10007] 70 Gommes 2.00 Frs 140.00 Frs TOTAL 1254.50 Frs

Fonctions classiques de manipulation de fichiers (de type ANSI C)

file_id = fopen(file_name, mode)

[file_id, message_err ] = fopen(file_name, mode)

Ouvre le fichier de nom défini par la variable/chaîne file_name, et retourne l'identifiant file_id qui permettra de le manipuler par les fonctions décrites plus bas.

Si file_name ne définit qu'un nom de fichier, celui-ci est recherché dans le répertoire courant. Si l'on veut ouvrir un fichier se trouvant dans un autre répertoire, il faut bien entendu faire précéder le nom du fichier de son chemin d'accès (path) relatif ou absolu. S'agissant du séparateur de

répertoire, bien que celui-ci soit communément \ sous Windows, nous vous conseillons de toujours utiliser / (accepté par MATBAL/Octave sous Windows) pour que vos scripts/fonctions soient portables, c'est-à-dire utilisables dans les 3 mondes Windows, macOS et GNU/Linux.

Le mode d'accès au fichier sera défini par l'une des chaînes suivantes : • 'rt' ou 'rb' ou 'r' : lecture seule (read)

'wt' ou 'wb' ou 'w' : écriture (write), avec création du fichier si nécessaire, ou écrasement s'il existe 'at' ou 'ab' ou 'a' : ajout à la fin du fichier (append), avec création du fichier si nécessaire'rt+' ou 'rb+' ou 'r+' : lecture et écriture, sans création

'wt+' ou 'wb+' ou 'w+' : lecture et écriture avec écrasement du contenu

'at+' ou 'ab+' ou 'a+' : lecture et ajout à la fin du fichier, avec création du fichier si nécessaire Le fait de spécifier t ou b ou aucun de ces deux caractères dans le mode a la signification suivante : • t : ouverture en mode "texte"

b ou rien : ouverture en mode "binaire" (mode par défaut)

Sous Windows ou macOS, il est important d'utiliser le mode d'ouverture "texte" si l'on veut que les fins de ligne soient correctement interprétées !

9/14/2018

MATLAB et Octave - 7. Programmation : interaction, structures de contrôle, scripts, fonctions, entrées-sorties, debu…

https://enacit1.epfl.ch/cours_matlab/mfiles.shtml#editeur_debugger

17/22

En cas d'échec (fichier inexistant en lecture, protégé en écriture, etc...), file_id reçoit la valeur "-1". On peut aussi récupérer un message d'erreur sous forme de texte explicite sur message_err

Identifiants prédéfinis (toujours disponibles, correspondant à des canaux n'ayant pas besoin d'être "ouverts") :

1 ou stdout : correspond à la sortie standard (standard output, c'est-à-dire fenêtre console MATLAB/Octave), pouvant donc être utilisé pour l'affichage à l'écran

2 ou stderr : correspond au canal erreur standard (standard error, par défaut aussi la fenêtre console), pouvant aussi être utilisé par le programmeur pour l'affichage d'erreurs

0 ou stdin : correspond à l'entrée standard (standard input, c'est-à-dire saisie au clavier depuis console MATLAB/Octave).

Pour offrir à l'utilisateur la possibilité de désigner le nom et emplacement du fichier à ouvrir/créer à l'aide d'une fenêtre de dialogue classique (interface utilisateur graphique), on se référera aux fonctions uigetfile (lecture de fichier) et uiputfile (écriture de fichier) présentées au chapitre "Fenêtres de sélection de fichiers". Pour sélectionner un répertoire, on utilisera la fonction uigetdir.

[file_name, mode] = fopen(file_id)

Pour un fichier déjà ouvert avec l'identifiant file_id spécifié, retourne son nom file_name et le mode d'accès. freport()

Affiche la liste de tous les fichiers ouverts, avec file_id, mode et file_name. On voit que les canaux stdin, stdout et stderr sont toujours pré-ouverts {status=} fclose(file_id)

fclose('all')

Referme le fichier ayant l'identifiant file_id (respectivement tous les fichiers ouverts). Le status retourné est "0" en cas de succès, et "-1" en cas d'échec.

A la fin de l'exécution d'un script ayant ouvert des fichiers, tous ceux-ci sont automatiquement refermés, même en l'absence de fclose. variable = fscanf(file_id, format {,size})

[variable, count] = fscanf(file_id, format {,size})

Fonction de lecture formatée ("file scan formated") du fichier-texte spécifié par son identifiant file_id. Fonctionne de façon analogue à la fonction sscanf vue plus haut (à laquelle on renvoie le lecteur pour davantage de précision), sauf qu'on lit ici sur un fichier et non pas sur une chaîne de caractères.

Remarque importante : en l'absence du paramètre size (décrit plus haut sous sscanf), fscanf tente de lire (avaler, "slurp") l'intégralité du fichier (et non pas seulement de la ligne courante comme fgetl ou fgets).

Ex:

Soit le fichier-texte suivant : 10001 Dupond

Livres 12 23.50 10002 Durand

Classeurs 15 3.95

La lecture des données de ce fichier avec fscanf s'effectuerait de la façon suivante : file_id = fopen('fichier.txt', 'rt') ; no = 1 ; while ~ feof(file_id) No_client(no) = fscanf(file_id,'%u',1) ; Nom{no,1} = fscanf(file_id,'%s',1) ; Article{no,1} = fscanf(file_id,'%s',1) ; Nb_articles(no) = fscanf(file_id,'%u',1) ; Prix_unit(no) = fscanf(file_id,'%f',1) ; no = no + 1 ; end status = fclose(file_id) ; [variable, count] = scanf(format {,size})

Fonction spécifiquement Octave de lecture formatée sur l'entrée standard (donc au clavier, identifiant 0). Pour le reste, cette fonction est identique à fscanf.

line = fgetl(file_id)

Lecture, ligne par ligne ("file get line"), du fichier-texte spécifié par l'identifiant file_id. A chaque appel de cette fonction on récupère, sur la variable line de type chaîne, la ligne suivante du fichier (sans le caractère de fin de ligne).

string = fgets(file_id {,nb_car})

Lecture, par groupe de nb_car ("file get string"), du fichier-texte spécifié par l'identifiant file_id. En l'absence du paramètre nb_car, on récupère, sur la variable string, la ligne courante inclu le(s) caractère(s) de fin de ligne (<cr> <lf> dans le cas de Windows).

{count=} fskipl(file_id ,nb_lignes)

Avance dans le fichier file_id en sautant nb_lignes ("file skip lines"). Retourne le nombre count de lignes sautées (qui peut être différent de

nb_lignes si l'on était près de la fin du fichier).

{status=} feof(file_id)

Test si l'on a atteint la fin du fichier spécifié par l'identifiant file_id : retourne "1" si c'est le cas, "0" si non. Utile pour implémenter une boucle de lecture d'un fichier.

Ex: voir l'usage de cette fonction dans l'exemple fscanf ci-dessus frewind(file_id)

Se (re)positionne au début du fichier spécifié par l'identifiant file_id. Pour un positionnement précis à l'intérieur d'un fichier, voyez les fonctions :

fseek(file_id, offset, origin) : positionnement offset octets après originposition = ftell(file_id) : retourne la position courante dans le fichier {count=} fprintf(file_id, format, variable(s)... )

Fonction d'écriture formatée ("file print formated") sur un fichier-texte spécifié par l'identifiant file_id, et retourne le nombre count de caractères écrits. Fonctionne de façon analogue à la fonction sprintf vue plus haut (à laquelle on renvoie le lecteur pour davantage de précision), sauf qu'on écrit ici sur un fichier et non pas sur une chaîne de caractères.

{count=} fprintf(format, variable(s)... ) {count=} printf(format, variable(s)... )

Utiliser fprintf en omettant le file_id (qui est est identique à utiliser le file_id "1" représentant la sortie standard) ou printf (spécifique à Octave), provoque une écriture/affichage à l'écran (i.e. dans la fenêtre de commande MATLAB/Octave).

Ex: affichage de la fonction y=exp(x) sous forme de tableau avec :

x=0:0.05:1 ; exponentiel=[x;exp(x)] ; fprintf(' %4.2f %12.8f \n',exponentiel) {status=} fflush(file_id)

Pour garantir de bonnes performances, Octave utilise un mécanisme de mémoire tampon (buffer) pour les opérations d'écriture. Les écritures ainsi en attente sont périodiquement déversées sur le canal de sortie, au plus tard lorsque l'on fait un fclose. Avec la fonction fflush, on force le vidage (flush) du buffer sur le canal de sortie.

Dans des scripts interactifs ou affichant des résultats en temps réel dans la fenêtre console, il peut être utile dans certaines situations de flusher la sortie standard avec fflush(stdout). Voyez aussi la fonction page_output_immediately pour carrément désactiver le buffering.

Fonction textscan

Cette fonction est capable à la fois de lire un fichier ou de décoder une chaîne.

vec_cel = textscan(file_id, format {,n})

Lecture formatée d'un fichier-texte spécifié par l'identifiant file_id (voir ci-dessus) et dont l'ensemble des données répond à un format homogène.

La lecture s'effectue jusqu'à la fin du fichier, à moins que l'on spécifie le nombre n de fois que le format doit être réutilisé.

Dans le format, on peut notamment utiliser \r, \n ou \r\n pour matcher respectivement les caractères de fin de lignes "carriage-return" (macOS), "line-feed" (Unix/Linux) ou "carriage-return + line-feed (Windows)

La fonction retourne un vecteur-ligne cellulaire vec_cel dont la longueur correspond au nombre de spécifications du format. Chaque cellule contient un vecteur-colonne de type correspondant à la spécification de format correspondante.

Ex: on peut lire le fichier ventes.txt ci-dessus avec : file_id = fopen('ventes.txt', 'rt');

vec_cel = textscan(file_id, '%u %s %s %u %f'); fclose(file_id);

et l'on récupère alors dans vec_cel{1} le vecteur de nombre des No, dans vec_cel{2} le vecteur cellulaire des Clients, dans vec_cel{3} le vecteur cellulaire des Articles, etc...

vec_cel = textscan(string, format {,n}) Opère ici sur la chaîne string

7.8.5 Fonctions de lecture/écriture de fichiers spécifiques/binaires

fread(...) et fwrite(...)

Fonctions de lecture/écriture binaire (non formatée) de fichiers, pour un stockage plus compact qu'avec des fichiers en format texte. Voyez l'aide pour davantage d'information.

xlsread(...) et xlswrite(...)

Fonctions de lecture/écriture de classeurs Excel (binaire). Voyez l'aide pour davantage d'information. odsread(...) et odswrite(...)

Fonctions de lecture/écriture de classeurs OpenOffice/LibreOffice (binaire). Voyez l'aide pour davantage d'information.

7.9 "Publier" un code MATLAB/Octave

7.9.1 La fonctionnalité "publish"

Se rapprochant du concept de notebook, la fonction publish permet d'exécuter un script MATLAB/Octave en produisant un rapport comportant 3 parties : le code source du script

les résultats d'exécution du script

les éventuels graphiques produits par le script

publish('script{.m}' {, 'format','fmt_rapport', 'imageFormat','fmt_images', 'showCode',true|false, 'evalCode',true|false } )

Le rapport est créé dans le sous-répertoire nommé "html", mais on peut désigner un autre répertoire avec 'outputDir', 'path' Les paramètres optionnels sont :

format : valeurs possibles : html, latex, doc, pdf (ce dernier nécessitant pdflatex c-à-d. texlive sous Linux) ; les valeurs par défaut sont : html sous MATLAB, latex sous Octave

imageFormat : valeurs possibles : png, jpg, pdf ; les valeurs par défaut sont : - si format html : png

- si format pdf : jpg

showCode : affichage du code dans le rapport, par défaut true

evalCode : exécution du code, par défaut true ; si mis à false, le code n'est pas exécuté et aucun graphique n'est bien évidement produit

grabcode('URL')

Récupère le code qui a été publié en HTML à l'URL spécifiée avec publish

Ex: Soit le script ci-dessous nommé code.m :

9/14/2018

MATLAB et Octave - 7. Programmation : interaction, structures de contrôle, scripts, fonctions, entrées-sorties, debu…

https://enacit1.epfl.ch/cours_matlab/mfiles.shtml#editeur_debugger

19/22

% Données

x= 4*rand(1,50) -2 % val. aléatoires entre -2 et +2 y= 4*rand(1,50) -2 % val. aléatoires entre -2 et +2 z= x.*exp(-x.^2 - y.^2) % Z en ces points

% Premier graphique (double, de type multiple plots) figure(1)

subplot(1,2,1) plot(x,y,'o')

title('semis de points aleatoire') grid('on')

axis([-2 2 -2 2]) axis('equal') subplot(1,2,2)

tri_indices= delaunay(x, y); % form. triangles => matr. indices trisurf(tri_indices, x, y, z) % affichage triangles

title('z = x * exp(-x^2 - y^2) % sur ces points') zlim([-0.5 0.5])

set(gca,'ztick',-0.5:0.1:0.5) view(-30,10)

% Second graphique (simple) figure(2)

xi = -2:0.2:2 ; yi = xi';

[XI,YI,ZI] = griddata(x,y,z,xi,yi,'nearest'); % interp. grille surfc(XI,YI,ZI)

title('interpolation sur grille')

publish('code.m', 'format','html', 'imageFormat','png')

produit le rapport accessible sous ce lien

7.9.2 Les noteboks Jupyter

Il s'agit d'une fonctionnalité moderne et extrêmement élégante que nous présentons dans un support de cours indépendant.

7.10 Debugging, profiling et optimisation de codes MATLAB/Octave

7.10.1 Debugging

Lorsqu'il s'agit de débuguer un script ou une fonction qui pose problème, la première idée qui vient à l'esprit est de parsemer le code d'instructions d'affichages intermédiaires. Plutôt que de faire des disp, on peut alors avantageusement utiliser la fonction warning présentée plus haut, celle-ci permettant en une seule instruction d'afficher du texte et des variables ainsi que de désactiver/réactiver aisément l'affichage de ces warnings. Mais il existe des fonctionnalités de debugging spécifiques présentées ci-après.

Commandes de debugging simples

Dans le document Cours MATLAB et GNU Octave en pdf (Page 117-120)