lundi 22 février 2010

Bases de l'administration Linux

Je sais que c'est très bateau mais parfois on est content d'avoir un pense bête lorsque l'on a un trou de mémoire:
Attention comme les caractères pipes sont interdits j'ai utilisés celui-ci à la place :"!"

Lister les directory
ls -l ! egrep '^d'

Liste les fichiers
ls -l ! egrep -v '^d'

Rechercher les fichier d'un répertoire qui se terminent par : *.tex
ls -l ! egrep '.tex$'
Ceci est équivallent du dir *.tex du DOS (rappel $ indique la fin de la ligne)

Recherche tous les fichiers ne se terminant pas par .texmoins évident en dos.
ls - l ! egrep -v '.tex$'

Affiche tous les fichiers commençant par a ou A (Linux est case sensitive)
ls ! egrep '^[aA]'

Equivallent du Dir a*dans ce cas le '^' indique le début de la ligne, il n'est pas utilisé comme not.

Affiche tous les fichier commençant par a ou A et finissant par .tex
ls ! egrep '^[aA]' ! egrep '.tex$'
Ceci est equivallent du Dir a*.tex

Rechercher à travers tous les répertoires un fichier se terminant par '.tex'
ls / -Rl ! egrep '.tex$'
soyez prudent avec l'utilisation du -l lors de ce type de recherche récursive.

Espace libre sur le disque
df -kh
le paramètre "h" permet d'afficher en mode humain

Afficher l'espace libre d'un répertoire
du /home/repertoire

Effacer un répertoire et tout son contenu (y compris les sous répertoire) :
rm -rd /home/repertoire/sousrep/*

Decompression d'un tarball zippé au moyen de la commande tar
tar -xwzf .tar.gz

Décompression arj (en tenant compte des sous répertoire)
arj x /home/repertoire/source/fichier.arj /home/repertoire/cible/

Changer les droits sur un fichier
chmod ugo +rwx /home/repertoire/fichier

u vaut pour les droit du user, g pour les droits du groupe, o pour les droits des 'others' (reste du monde) quant à rwx ils représentent (read, write, eXecute). On peut utiliser différentes combinaisons de cela.

mardi 9 février 2010

Accéder des fichiers via Delphi.

Classe TFileStream

Le FileStream est utilisé pour lire ou écrire des informations dans des fichiers. Il s’agit en général de buffer. Il faut donc être prudent quant à l’utilisation de ces méthodes avec du texte.

Unit : classes ;

Concrètement le Filestream ne s’attend pas forcément à écrire du texte, ce qu’il veut c’est un buffer de donnée.
Si vous voulez écrire un texte, il faut utiliser la méthode Write() en lui passant les paramètre suivants :
const
arrCRLF : array [0..1] of Char = ( #13, #10 );
var
sText : string ;
oFileStream : TFileStream;
begin
sText :=’test text file stream’ ;
oFileStream:=TFileStream.Create(‘c:\temp\test.txt’, fmCreate)
oFileStream.Write( sText[1], length(sText);
oFileStream.Write(arrCRLF,2);
oFileStream.Free;
end;

L’avantage de cette méthode est que l’information ne doit pas être contenue en mémoire mais elle peut-être écrite on-fly sur le disque. Ce qui dans certains cas peut franchement vous sauver la vie.
Attention comme on écrit plattement le contenu d’un buffer le CRLF n’est pas géré, il faut donc explicitement indiquer le changement de ligne. C’est l’utilité de la ligne
oFileStream.Write(arrCRLF,2);
Le tableau arrCRLF contenant les caractères #13#10 du carriage return – line feed

samedi 6 février 2010

Connexion à une base de données via Delphi

Il est souvent de bon ton d'utiliser une technologie, telle que ADO ou ADO.NET par exemple, toutefois la question à se poser est : "Est-ce que j'utilise bien cette technologie" en ai-je vraiment compris les fondements, les tenants et les aboutissants...

Nous allons tenter de répondre à ces questions par rapport aux connexions entre Delphi et les bases de données. Tout d'abord il existe deux types de connexions:

Les connexions Explicites se font via un objet de type TCustomConnection qui peut être décliné en TADOConnection.

Il est aussi possible de connecter Implicitement des datasets (ensemble de records provenant d’une base de données formant une sorte de table logique en mémoire, ce concept fondamental sera développé plus tard) vers la base de données (ç-à-d ne pas utiliser l’objet connexion mais passer directement les paramètres du server à la propriété Connectstring). Honnêtement, je ne le conseille pas, car en plus de limiter vos actions ceci peut s’avérer dramatique si vous devez changer les paramètres de la base de données et que vous avez hardcodé les connectstring…

Manipuler l’objet de connexion :

Pour se connecter à la base de données on peut soit utiliser la méthode Open ou mettre la propriété Connected à True. Passer par la seconde méthode permet de lancer l’évènement BeforeConntect et d’éventuellement passer des paramètres de connexion.

Lorsque plus aucun dataset n’utilise l’objet connexion celui-ci est détruit. Dans certains cas, si l’on fait des accès très fréquents à la DB, il est mieux de ne pas autoriser cette destruction pour réduire le trafic réseau et la charge de la DB. Dans ce cas mettre à True la propriété : KeepConnection.

Pour se déconnecter de la DB utiliser la méthode Close ou mettre la propriété Connected à false, faire cela lance un évènement BeforeDisconnect.

Une connexion à une base de données requiert généralement un password, dans le cas d’une connexion ADO, simplement mettre le login/password dans la propriété ConnectString et placer la propriété LoginPrompt à false pour éviter d’avoir la boîte de dialogue.
Noter que hardcoder un password en clair dans une application ou dans un fichier de configuration n’est jamais très intelligent. L’évènement ADO OnWillConnect est appelé à la place du login prompt et permet de définir un login et un password.

Nous n’aborderons pas dans ce billet la gestion des transactions qui est un point fondamental mais qui mérite un billet (voir un livre entier) à lui tout seul.

dimanche 31 janvier 2010

Cours de Biostatistique (V)

Cette partie du cours est relative aux test d'hypothèses T de Student qui s'appliquent aux variables quantitatives.
Dans cette partie vous verrez comment poser une hypothèse sur le comportement d'une population et comment tenter de l'invalider au moyen des données de l'échantillon. La philosophie est simple : Si on rejette l'hypothèse alors l'échantillon permet de démontrer l'invalidité de l'hypothèse, si on ne la rejette pas, nous n'avons pas assez d'information dan sl'échantillon pour prouver qu'elle est fausse. Dans ce cas de figure il est assez difficile de conclure de manière définitive.

Les bases de statistiques touchent à leur fin, il restera encore le test du Khi Carré à documenter.

Les Tests d'hypothèses (I)
Les Tests d'hypothèses (II)

vendredi 22 janvier 2010

L'architecture

Donner une définition claire de l'architecture logiciel est chose parfois peu aisée car le sujet englobe une grande partie du processus de développement.

Dans ce billet, pour clarifier les choses, je vais considérer que l'architecture englobe :

- le design
- l'interaction des composants (organisation des composants)
- l'infrastructure (l'hébergement des composants)

Ces différents éléments qui sont, en réalité, des vues sur le système informatique peuvent se résumer au diagramme suivant:











Ce diagramme nous indique comment percevoir notre système informatique (le système informatique se compose en général d'un logiciel et d'une plateforme physique ou logique permettant de le faire fonctionner).
La vue la plus importante, celle qui dirige et qui induit le système, est la vue de cas d'utilisation.
Les cas d'utilisation représentent les fonctionalités que le système va offrir aux utilisateurs. A chaque cas d'utilisation correspondent différents scénarios : un scénario principal décrivant la fonctionalité attendue, des scénarios alternatifs prenant place lorsqu'une erreur se produit ou qu'une donnée est manquante.

Les quatre vues suivantes ne font qu'implémenter concrètement les spécifications qui ont été définies dans la vue de cas d'utilisation.

La vue logique décrit comment sera organisé le code, comment seront regroupées les fonctions qui réaliseront les cas d'utilisation. Ces fonctions appartiendront à des classes qui pourront collaborer entre elles en vue des réaliser les cas d'utilisation définis. Cette vue est parfois la seule visible pour des petits systèmes d'information.

La vue de processus décrit comment vont fonctionner et comment seront synchroniser les threads ou les processus réalisant des opérations en parallèle. Si le logiciel utilise des services, il génère des threads chaque fois qu'il doit gérer de nouvelles connections, ...

La vue de réalisation (collaboration) décrit comment les composants interagiront ensemble et où ils seront stockés. Ceci peut être représenté par un diagramme de composants. Les noeuds qui contiennent ces composants seront également décris. Cette vue est très utile dans les systèmes distribués.

La vue de déploiement décrit comment le système informatique sera organisé, déployé. Cette vue peut ressembler au diagramme de composant sauf que, ici, l'accent sera mis sur l'agencement du réseau et des serveurs (noeuds).

Les gros systèmes seront généralement décrits par ces quatre vues, les plus petits systèmes se contenteront généralement de la vue logique.


Les types d'architectures logiciels:


Les types d'architecture vont indiquer comment les composants d'un logiciel vont se répartir. On distingue en général des composant utiles à l'affichage, au traitement et au stockage. Une architecture relativement courante dans les systèmes d"information est l'architecture dite
Client/Serveur.
Un logiciel client installé sur un poste de travail accède aux données stockées sur un serveur de base de données. Cette architecture permet de partager facilement des informations entre différents utilisateurs répartis sur des postes différents. En général, cette architecture se limite au réseau physique de l'entreprise. Si les postes de travail sont relativement évolués, les programmes clients pourront aussi effectuer des traitements locaux sur les données. Ceci permet de répartir la charge de travail entre le serveur et les clients.

L'architecture 3 Thiers
Cette architecture est souvent utilisée par les applications Internet (application de eCommerce, de data-capture, ...). Dans ce type d'application, le client est un browser Internet qui permet des traitements relativements légers. Le client accède à un web-serveur qui lui renvoie des pages HTML (HyperText Markup Language) générées dynamiquement. Cette génération dynamique se fait en général par des extensions du web-serveur. Il peut s'agir de DLL, DSO, script CGI(remarquez que PHP par exemple fonctionne sur base d'une DSO).
L'avantage de cette architecture est de s'ouvrir au monde. En effet, il sera possible d'accéder aux données en dehors du réseau local puisque les accès se feront à travers Internet. Toutefois, si on laisse les extensions sur le web-serveur, on arrive très vite au problème de montée en charge. Que se passe-t-il si trop d'utilisateurs se connectent sur le serveur et que le CPU ou la mémoire s'effondre ? Le système deviendra inutilisable. Nous arrivons donc à un problème crucial qui est la "scalabilité" (déjà évoqué dans un précédent billet) c'est-à-dire la faculté de pouvoir fonctionner quel que soit le nombre d'utilisateurs connectés en même temps.

Les architectures distribuées.
Les architectures distribuées utilisent des composants (EJB, COM, COM+, assembly .Net, ...) pouvant s'éxécuter sur un serveur d'application. Ces composants seront sollicités par les extensions du web-serveur. L'avantage de cette approche est que certains composants pourront fonctionner sur un serveur d'application alors que d'autres fonctionneront sur un autre. Ceci permet de répartir la charge et ceci a pu voir le jour grâce à des technologies comme CORBA ou DCOM qui permettait d'invoquer des méthodes de composants à travers le réseau.
Par la suite, DCOM a été remplacé par COM+ qui a lui même évolué en .Net.
D'une manière générale, l'invocation des composants et l'organisation de ceux-ci se fait sur un même réseau local.

Les architectures de services.
L'architecture de service qui a vu le jour dans le début des années 2000 outrepasse la capacité d'utiliser des composants organisés sur un réseau local mais permet d'utiliser des services n'importe où sur Internet.
Un exemple simple serait la possibilité pour le système informatique d'une agence de voyage de communiquer avec le système de réservation d'une compagnie aérienne. Les deux infrastructures sont totalements séparées mais, grâce à l'architecture de service, il serait possible à l'agence de voyage de réaliser automatiquement la réservation du billet d'avion. Cela peut se réaliser au moyen des Web-Services qui sont des composants distribués à travers l'Internet.

mardi 19 janvier 2010

Cours de biostatistique (IV)

Cette partie du cours est consacrée à la fin des distributions de probabilité et à l'inférence statistique.

L'inférence statistique va utiliser l'échantillon et les probabilités pour tenter de prédire le comportement d'une population dont serait extrait l'échantillon.
L'échantillon représente donc un ensemble de données empiriques (provenant des mesures expérimentales).
La population est un modèle théorique décrit par une distribution de probabilité.
Nous distinguerons deux parties importantes dans l'inférence statistique:
  • L'estimation: va nous permettre à partir des données de l'échantillon de définir un intervalle de confiance sur les paramètres de la distribution théorique.
  • Les tests d'hypothèse: nous allons considérer une hypothèse sur la population et tenter d'utiliser l'échantillon pour la démolir.
Dans les cours présentés, nous introduirons brièvement la philosophie du test d'hypothèse.

Inférence statistique (I)
Inférence statistique (II)

lundi 18 janvier 2010

Qualités d’un logiciel

Validité : faculté dont dispose le logiciel de faire ce qu’il doit. Cela s’obtient par l’utilisation d’une bonne méthodologie.

L’intégrité : faculté d’un logiciel à maintenir la justesse de ses données en toutes circonstances, protéger ses accès et ses données d’accès non autorisés. Cela s’obtient par l’utilisation de techniques appropriées (OS capable de gérer les accès mémoire d’une application à l’autre) et d’une bonne méthodologie (utilisation de l’encapsulation provenant de la POO).

La fiabilité : faculté d’un logiciel à gérer ses erreurs correctement. Cela s’obtient par l’utilisation d’une bonne méthodologie de coding, comme, par exemple, l’utilisation et la gestion des exceptions.

La scalabilité : faculté de pouvoir monter en charge, sans devoir modifier le code programme, en changeant simplement l’organisation du logiciel (le scinder sur différents serveurs pour répartir la charge). Ceci s’obtient par un design intelligent.

La reusabilité : faculté de ne pas devoir réinventer la roue à chaque fois que l’on veut ajouter des fonctionnalités mais, au contraire, pouvoir s’appuyer sur une fondation consistante. Ceci s’obtient par un design et une méthodologie corrects.

La maintenabilité : capacité à maintenir sans se noyer ou se faire dépasser par la complexité de celui-ci. C’est avant tout un problème de design et de documentation.

L’extensibilité : capacité d’ajouter de nouvelles fonctionnalités au logiciel. Ceci s’obtient en utilisant un design tenant en compte la reusabilité.

Les performances : faculté de répondre dans des délais raisonnables. Ceci s’obtient par un coding approprié (algorithmes optimisés).

L’interopérabilité : faculté de s'intégrer avec d'autres applications logicielles. On utilise une architecture composant pour achever cet objectif.

La plupart de ces notions de qualité sont dépendantes les unes des autres. Exemple : un logiciel peu fiable peut très bien, à un moment ou à un autre, écrire de mauvaises données au mauvais endroit et avoir un impact sur l’intégrité du logiciel.

Un logiciel basé sur un design de réusabilité pourra facilement être étendu. De plus, ces extensions basées sur des composants ou classes existantes auront un impact positif sur la fiabilité et l’intégritié. La réusabilité facilitera aussi la maintenabilité du logiciel, puisqu’une erreur corrigée à un endroit se répercutera partout. Au final , plus votre logiciel évoluera, plus ses bases se solidifieront.

La scalabilité et les performances, même si elles sont des notions différentes, sont aussi très liées. Avoir des performances extraordinaires qui vont s’effondrer dès que dix utilisateurs vont se connecter n’est pas très intéressant. Avoir une architecture permettant la connexion de millions d’utilisateurs mais mettant dix minutes à produire un résultat qu’il y ait un ou un millions d’utilisateurs n’est pas acceptable non plus.
Toute la finesse consiste à trouver un équilibre, un compromis entre scalabilité et performances.

Ces différents objectifs de qualité, classés ici suivant mon ordre d’importance doivent être traduit par le processus de qualité, qui est lui-même formalisé sous forme de Procedures d’Operation Standard (POS ou SOP en anglais).

L'un des fondements de la qualité est aussi la traçabilité. Son rôle est d'identifier lors de problème où se trouve celui-ci. Ceci semble très bâteau mais, en pratique, c'est parfois très difficile de démêler les faits, en particulier s'il y a un manque de transparence... La traçabilité assure cette transparence.

Il serait intéressant de définir des indicateurs (sorte de KPI) permettant de mesurer ces concepts de qualité.