Deuxième défi Qt : les résultats de l'application mobile pour hôpital

Thibaut Cuvelier

Les défis Qt sont des petits exercices à faire soi-même ou en équipe sur un sujet précis. Le sujet de ce deuxième défi était l'application mobile pour hôpital. Le défi étant terminé, nous vous présentons les résultats ainsi que le gagnant !

Retrouvez ce défi sur le forum.

- Titre : Deuxième défi Qt : les résultats de l'application mobile pour hôpital

- Auteur : Thibaut Cuvelier

- Parution : 19 septembre 2011

- Mise à jour : 7 août 2012

- Licence : Copyright ® 2011 Developpez.com. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation

- II. DrCute and MrHyde (0x4e84)

- II-A. Juré 7

- II-B. Juré 9

- III. Amnell

- III-A. Juré 7

- III-B. Juré 9

- IV. MedCenter (les geekologues : LittleWhite, std_abdel, Nass)

- IV-A. Juré 9

I - Présentation

L'équipe Qt vous souhaite la bienvenue sur la page du deuxième défi Qt.

Les défis Qt sont des petits exercices à faire soi-même ou en équipe sur un sujet précis, à la manière des examens ou des exercices de livres. Ces codes à écrire sont étudiés de sorte que tous y trouvent leur compte : parfois de l'algorithmique, mais pas uniquement, car Qt ne fait pas que dans ce domaine spécifique. Il s'agit d'un framework complet : les défis essayent d'exploiter cette richesse. Ceci ne signifie pas qu'aucune réflexion n'est nécessaire : il faut connaître Qt, il ne s'agit pas d'écrire quelques lignes sans y réfléchir.

Retrouvez ce défi sur le forum.

Les membres du jury avaient à leur disposition une grille afin de les aider dans la cotation des programmes rendus. Elle leur laissait un certain degré de liberté, notamment dans la sévérité de certains éléments : chaque juré a fait selon ses critères personnels, ce qui peut donner des résultats complètement différents d'un juré à l'autre pour une même application. La voici pour rappel.

Certains critères étaient obligatoires : tous les points cités compteront dans la note finale. D'autres étaient optionnels : seul la meilleure cote des deux sera retenue. Les derniers, enfin, étaient supplémentaires : des bonus en cas de dépassement de nos demandes, ou des malus en cas de régression profonde (avertissements à la compilation, par exemple).

Vous trouverez ce tableau complété pour chaque participant et pour chaque juré ayant évalué le programme, avec ses commentaires. Les noms des jurés n'apparaîtront jamais à proximité de leurs commentaires, pour des raisons d'anonymat (personne ne saura qui a corrigé qui, qui a fait quels commentaires : personne ne pourra juger de la partialité de tel juge, cela évitera les MP excessifs si un juge a mis une cote trop basse aux yeux du participant, par exemple ; cependant, chaque juré a un numéro, qu'il gardera tout au long de la page, afin que chaque candidat puisse se comparer face à un seul juré pour tous les critères aux autres membres et voir ses forces et faiblesses). Les participants sont invités à regarder les commentaires afin de s'améliorer : il s'agit d'un regard externe sur la participation rendue, qui peut vous faire remarquer vos points faibles et vos points forts. Ils sont utiles à tous aussi : que faut-il faire, que faut-il éviter ? Les programmes sont présentés en fonction de l'ordre alphabétique des participants. Bonne consultation.

Critère

Points à accumuler
(60 au total)

Fonctionnement minimal du programme

Total : 18

Fonctionnement de base

8

Esthétisme

5

Fluidité

5

Qualité du code

Total : 13

Qualité d'un point de vue du code

4

Qualité d'un point de vue Qt

4

Gestion de la mémoire

2

Gestion des données

2

Documentation minimale

1

Interface graphique (critère optionnel)

Total : 5

Ergonomie

(5)

Design

(5)

Fonctionnalités obligatoires

Total : 24

Utilisation d'une base de données distante (gestion de patients, des chambres, du planning des médecins...)

4

Affichage de graphiques et d'images (ECG, scanners, radios...)

4

Affichage 3D (IRM, squelette...)

4

Communication entre clients (envoi de messages, textuels ou vidéos, à une autre instance sur une autre machine)

4

Saisie d'informations (rapports médicaux, prescriptions, facturation...)

4

Organisation interne (allocation de chambres, de locaux, de membres du personnel, etc. en fonction des besoins)

4

Bonus (critères facultatifs)

Total : + 38

Autres fonctionnalités (proposées)

1 chaque, avec un maximum de 3

Autres fonctionnalités (non proposées)

2 chaque, avec un maximum de 6

Documentation en suffisance

3

Ajout de modules à chaud

4

Conception préalable poussée, avec explications

6

Utilisation de Qt Quick

8

Surprenez-nous !

8

Malus

Total : -16

Utilisation d'un autre langage (sont autorisés tous les langages qui peuvent utiliser Qt directement (C++, Python, Java...) ainsi que tous les langages que Qt utilise (en ce compris ECMAScript/JavaScript, QML, (X)HTML, Lua via QtLua/LQt, etc.))

-4

Utilisation d'une autre bibliothèque non prévue pour Qt (GMP, GnuPlot...), sauf pour la base de données

-4

Application peu robuste

-2

Application semblant plantée

-2

Erreurs à la compilation

-2

Avertissements à la compilation (sauf si justification dans le README)

-1

Fichiers inutiles dans l'archive

-1

II - DrCute and MrHyde (0x4e84)

Les tests réseau ont été effectués en local, car les possibilités de la participation ne le permettaient pas.

Moyenne obtenue : 29,75/60.

Les sources.

II-A - Juré 7

Critère

Points à accumuler
(60 au total)

29,5

Fonctionnement minimal du programme

Total : 18

12

Fonctionnement de base

8

4

Je trouve dommage qu'il soit nécessaire de se connecter deux fois, une fois au serveur et une fois en tant que docteur, un seul système aurait surement été plus rapide pour l'utilisateur (aucun intéret de se connecter au serveur si on a pas l'intention de se connecter en tant que docteur). On regrette la possibilité d'ajouter des informations dans la base de donnée par l'intermédiaire de l'interface utilisateur (patient). Pas de réussi à se connecter un client et un serveur via Internet, l'adresse IP utilisée pour le serveur ne semble pas être l'IP externe du PC (IP Internet). Pas de retour utilisateur en cas de problème de connexion, d'intéraction avec la base de donnée. L'exècution du client sans serveur donne une interface dans laquelle la plus part des boutons ne font strictement rien. Bonnes idées pour la communication par messages sur la socket cependant.

Esthétisme

5

4

J'aime baucoup l'interface utilisateur créative, elle s'adapte très bien à un support tablette ce qui est l'objectif du sujet. Les animations sont sympa et il n'y en a pas non plus trop, ce qui peut être vite soulant. Elle me paraît assez évolutive dans l'état actuel d'un point de vue design, on a des informations utiles à tout moment sur les cotés mais qui ne prennent pas trop de place, ce qui laisse un grand espace au milieu pour le travail du docteur/médecin. Une version multilangue aurait été la bienvenue.

Fluidité

5

4

Application légére et donc extrêmement fluide, aucun lag en local concernant la connexion au serveur, requête des docteurs/patients ou encore de l'image (récupérer dans un fichier source et non une base de données). N'ayant pas de 3D, cela paraît normal que l'application soit fluide.

Qualité du code

Total : 13

8,5

Qualité d'un point de vue du code

4

2

Adopter une notation différent pour les variables locales et les variables membres d'une classe est une habitude à prendre, cela permet une relecture plus facile et surtout une meilleure compréhension pour des lecteurs extérieurs.

Préférer l'utilisation d'enum plutôt que de bool en paramètres de fonction (surtout constructeur) :

Server(false);
Server(true);

Quand on commence à avoir plus de deux booléens en paramètres, on est vite perdu.

Server(Mode_Local);
Server(Mode_Remote);

C'est beaucoup plus lisible. De plus, on peut également utiliser des QFlags avec des bits pour définir plusieurs options exclusives ou pas.

Éviter les #includes inutiles dans les fichier d'en-tête et favoriser la prédéclaration. Par exemple, dans server.h, les deux inclusions (servernode.h et sql.h) peuvent être déplacées dans le .cpp et classe Sql prédéclarées. De plus, la classe QTextStream est inutilisée (penser au nettoyage des includes, lors des nettoyages). Le temps de compilation est rapide sur un petit projet mais c'est une bonne habitude à prendre pour un grand projet. Il est très ennuyant d'attendre que trente fichiers recompilent lorsqu'on a fait une petite modification alors que, au final, seulement quinze fichiers avaient besoin de la déclaration dans l'en-tête.

QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));

Ça sent le code copier/coller, utiliser sa propre organisation.

if ((config.state() & QNetworkConfiguration::Discovered) != QNetworkConfiguration::Discovered)

Je trouve ça personellement compliqué à lire, j'aurais plus tendance à utiliser :

!config.state().testFlag(QNetworkConfiguration::Discovered)

Ne pas hésiter à utiliser des assertions Q_ASSERT() pour valider les préconditions et post-conditions de certaines fonctions critiques.

Exemple de code sale :

int cols = rec.count();
for( int c=0; c<cols; c++ )

for( int r=0; query.next(); r++ ) {
for( int c=0; c<cols; c++ ) {
resultList << query.value(c).toString();
}
doctorCount++;

// ...

On a ici trois boucles, dont deux avec le même nom de variable et une sans crochet, ce qui est une mauvaise habitude.

Qualité d'un point de vue Qt

4

3

Qt : bonne utilisation de QSettings pour la gestion des préférences utilisateurs (infos de connexion), conservées entre deux lancements de l'application, de QNetworkConfiguration et QTcpSocket pour le réseau, QDataStream pour les messages et QBuffer pour les images. Développeur connaissant Qt et utilisant les bons éléments comme il faut. La gestion des signaux/slots entre Qt et QML ainsi que le QMetaObject pour invoquer des fonctions QML sont maîtrisés. QML : utilisation relativement basique de QML concernant l'interface mais qui fait ce que l'on veut. D'un point de vue de la gestion des patients et des docteurs, je pense qu'il aurait été plus intéressant de créer les classes C++ Patient et Docteur et mapper les différentes propriétés plutôt que d'avoir des variables définis dans le main.qml (currentPatientId, currentPatientTitle, etc.). À partir de là, un docteur peut par exemple se connecter, se déconnecter, demander des infos, etc. Ta logique est alors du côté C++ et non du coté de la vue qui ne fait que répondre à des signaux/slots envoyés par le code C++. De même, pour la liste, n'aurait-il pas été possible de venir avec une solution plus générique à base de colonnes facilement ajoutables ?

Gestion de la mémoire

2

2

Rien vue de problématique, globalement utilisation du système de parent de Qt, ce qui garantit la destruction des pointeurs.

Gestion des données

2

1

Gestion basique d'une base de donnée avec SQLITE mais suffisante pour le défi. Une base de donnée plus sérieuse serait à envisager en cas de déploiement d'une telle application en grandeur nature. Le schéma de la base de donnée est très basique et permet difficilement d'évaluer le candidat sur des notions de base de données. Il aurait été intéressant de développer plus la place de la base de donnée dans le projet (entrées pour les images ? opérations ? traitements ?). La création des tables est écrit en dur dans le code, ce qui est moyen en cas de changement, il aurait été préférable d'avoir des requêtes SQL dans des fichiers externes possiblement modifiables par un logiciel de schéma de base de données. Il est dommage de ne pas pouvoir insérer des données par l'interface utilisateur et d'avoir aucun retour de la base dans l'interface utilisateur QML.

Documentation minimale

1

0,5

Il y a un peu d'explication dans les fichiers .cpp sur le codage des fonctions, pourquoi on fait ça, dans quel but, etc. Il s'agit de commentaires individuels par ligne de code quand nécessaire. C'est très bien mais loin d'être suffisant. Ce qui est vraiment intéressant à documenter, ce sont les fichiers d'en-tête. La simple et bonne raison est qu'il s'agit de l'interface publique et donc, si quelqu'un veut utiliser une de tes classes, il a envie de savoir ce que font tes classes et fonctions publiques. À la limite, l'implémentation interne, c'est utile pour quelqu'un qui veut changer ou améliorer le fonctionnement d'une classe, mais inutile pour l'utilisateur de tes classes; pour qui l'implémentation interne n'a rien d'important. La fonction fait ça, je lui demande de le faire, je suis censé être assurer que le résultat est correct car il y a des tests unitaires derrière. De plus, la documentation Doxygen que tu as généré, c'est très bien, mais encore une fois c'est basé sur la documentation des fichier d'en-tête et non des fichiers sources. À aucun moment, je n'ai vu un commentaire utiliser la syntaxe Doxygen, seulement des commentaires C-style //. Commentaire en anglais, très bien ça permet à tout le monde de les comprendre et éventuellement reprendre le code, bon critère de maintenabilité. J'aurais vraiment aimé en savoir plus sur le rôle de tes classes. Client hérite de Config ? Pourquoi ? ImageProvider, quelle est sont rôle ?

Interface graphique (critère optionnel)

Total : 5

2

Ergonomie

(5)

2

Éviter l'affichage de boutons inutiles et ne faisant rien (par exemple : se déconnecter pour un docteur est inutile avant de s'être connecter et vice-versa, un seul bouton avec deux états aurait été mieux). Ouverture de Settings quand un patient ou docteur est sélectionné ? Bouton Help n'affichant rien, frustrant pour l'utilisateur. Pas de demande si on veut vraiment quitter en appuyant sur "Quit".

Design

(5)

2

Voir section esthétisme, mérite un bonus.

Fonctionnalités obligatoires

Total : 24

4

Utilisation d'une base de données distante (gestion de patients, des chambres, du planning des médecins...)

4

2

Lecture seulement, pas possibilité d'écrire dans la base de données à l'aide de l'interface graphique.

Affichage de graphiques et d'images (ECG, scanners, radios...)

4

2

Ajout d'une seule image provenant dans .qrc, manque de temps pour faire mieux.

Affichage 3D (IRM, squelette...)

4

0

Pensé mais manque de temps.

Communication entre clients (envoi de messages, textuels ou vidéos, à une autre instance sur une autre machine)

4

0

Pas de communication

Saisie d'informations (rapports médicaux, prescriptions, facturation...)

4

0

Rien pour le moment.

Organisation interne (allocation de chambres, de locaux, de membres du personnel, etc. en fonction des besoins)

4

0

Rien pour le moment.

Bonus (critères facultatifs)

Total : + 38

+5

Autres fonctionnalités (proposées)

1 chaque, avec un maximum de 3

0

Autres fonctionnalités (non proposées)

2 chaque, avec un maximum de 6

0

Documentation en suffisance

3

0

Voir documentation minimale

Ajout de modules à chaud

4

0

Non pensé.

Conception préalable poussée, avec explications

6

2

Bonne gestion du réseau et des messages, ce qui est quand même la base d'une application client/serveur, avec explications dans le fichier Readme.txt. Je ne comprends pas pourquoi Client hérite de Config ? La configuration pour moi est plus facilement gérable par un manager externe. Explication ? La classe client gère pour le moment un peu tout (même la configuration via sa classe parente), ce qui va encore dans le cas d'une petite application mais, avec l'ajout de fonctionnalités, cela va vite devenir une usine à gaz. Une séparation des différentes tâches dans plusieurs classes serait très vite la bienvenue.

Utilisation de Qt Quick

8

3

Utilisation de QML pour l'interface graphique, ce qui donne un très bon design à l'interface pour une application tablette. Séparation entre l'interface et la logique métier pas très nette, ce qui ne facilite pas forcément l'évolutivité. Pour un premier usage de Qt Quick, c'est bien.

Surprenez-nous !

8

0

À part l'interface, qui est surprenante et récompensée dans la section ergonomie, rien de surprenant par rapport à ce qui a été demandé.

Malus

Total : - 16

-2

Utilisation d'un autre langage (sont autorisés tous les langages qui peuvent utiliser Qt directement (C++, Python, Java...) ainsi que tous les langages que Qt utilise (en ce compris ECMAScript/JavaScript, QML, (X)HTML, Lua via QtLua/LQt, etc.))

-4

0

Rien vue d'illégal.

Utilisation d'une autre bibliothèque non prévue pour Qt (GMP, GnuPlot...), sauf pour la base de données

-4

0

Rien vue de tel.

Application peu robuste

-2

0

MrHyde : aucun plantage. DrCute : aucun plantage.

Application semblant plantée

-2

0

MrHyde : aucun plantage. DrCute : aucun plantage.

Erreurs à la compilation

-2

-1

#include "config.h" dans server.h non trouvé (fichier inutile), de même pour #include "sessionmanager.h" dans main.cpp. Erreur bête de nettoyage à la dernière minute.

Avertissements à la compilation (sauf si justification dans le README)

-1

-0.5

MrHyde : const QStringList &msgList dans la fonction ServerNode::interpretCommandAndAnswer() n'est pas utilisé. DrCute : arguments non utilisés dans ImageProvider::requestImage.

Fichiers inutiles dans l'archive

-1

-0.5

MrHyde : preview.jpg, radio.png, drcute80.png et MrHyde.png non utilisés. DrCute : Images SVG ? drcute.rc ? qtc_packaging ? Une explication sur ces fichiers Debian aurait été la bienvenue si utiles.

II-B - Juré 9

Critère

Points à accumuler
(60 au total)

30

Fonctionnement minimal du programme

Total : 18

13

Fonctionnement de base

8

5

Pas besoin de mot de passe pour se connecter ? Quid si un malheureux vient sur un terminal et tout mettre en l'air ? Même si cela a été envisagé, cela semble un prérequis pour ce genre d'application. Pas moyen de se connecter sur un serveur en dehors du réseau local (le serveur ne veut bien se connecter que sur des IP en 169., ce qui a été assez ennuyant pour des tests).

Esthétisme

5

4

Dans le genre moderne, assez minimaliste... mais efficace !

Fluidité

5

4

Rien à redire, on est pleinement dans ce qui est demandé, dans l'intégralité de l'application !

Qualité du code

Total : 13

9

Peu à ajouter par rapport à ce qui a déjà été dit.

Qualité d'un point de vue du code

4

2

Qualité d'un point de vue Qt

4

3

Gestion de la mémoire

2

2

Gestion des données

2

1,5

Impossible d'insérer des données en base (ajout de patient impossible)

Documentation minimale

1

0,5

Générer une documentation Doxygen sans rien lui donner comme contenu, c'est assez inutile. Heureusement qu'il y a un readme, mais c'est strictement insuffisant.

Interface graphique (critère optionnel)

Total : 5

3

Ergonomie

(5)

3

Dans la boîte de connexion, il est impossible d'effacer des caractères, on doit les remplacer ; pas moyen de valider le formulaire d'une autre manière qu'avec le bouton. On regrettera l'absence d'un quelconque signal indiquant que la connexion s'est bien déroulée, il faut d'abord se connecter en tant que médecin pour voir une modification, ainsi que les boutons ne faisant rien (ajout de données, aide).

Design

(5)

3

L'écran d'accueil est pour le moins austère : énormément de noir, juste quelques zones sur les côtés, pas vraiment besoin de plus mais pas forcément accueillant.

Fonctionnalités obligatoires

Total : 24

3,5

Utilisation d'une base de données distante (gestion de patients, des chambres, du planning des médecins...)

4

1,5

Lecture seule, bouton d'ajout de patient non fonctionnel, pas de possibilité d'ajout de scanners ou autres. On peut voir les données de patients sans être identifié ! Étonnament, on peut toujours voir la liste des patients, leurs scanners, etc., alors que le serveur est coupé, sans le moindre avertissement.

Affichage de graphiques et d'images (ECG, scanners, radios...)

4

2

Une seule image en tout et pour tout, mais quand même envoyée depuis le serveur, peu de choses supplémentaires requises pour que ça fonctionne comme il faudrait.

Affichage 3D (IRM, squelette...)

4

0

Communication entre clients (envoi de messages, textuels ou vidéos, à une autre instance sur une autre machine)

4

0

Saisie d'informations (rapports médicaux, prescriptions, facturation...)

4

0

Organisation interne (allocation de chambres, de locaux, de membres du personnel, etc. en fonction des besoins)

4

0

Bonus (critères facultatifs)

Total : + 38

+4

Autres fonctionnalités (proposées)

1 chaque, avec un maximum de 3

0

Autres fonctionnalités (non proposées)

2 chaque, avec un maximum de 6

0

Documentation en suffisance

3

0

Ajout de modules à chaud

4

0

Conception préalable poussée, avec explications

6

2

Surtout réseau dans le readme.

Utilisation de Qt Quick

8

2

Séparation présentation/logique pas toujours très claire.

Surprenez-nous !

8

0

Malus

Total : - 16

- 2,5

Quel dommage d'avoir fait des modifications de dernière minute sans trop tester...

Utilisation d'un autre langage (sont autorisés tous les langages qui peuvent utiliser Qt directement (C++, Python, Java...) ainsi que tous les langages que Qt utilise (en ce compris ECMAScript/JavaScript, QML, (X)HTML, Lua via QtLua/LQt, etc.))

-4

0

Utilisation d'une autre bibliothèque non prévue pour Qt (GMP, GnuPlot...), sauf pour la base de données

-4

0

Application peu robuste

-2

0

Application semblant plantée

-2

0

Erreurs à la compilation

-2

-2

Avertissements à la compilation (sauf si justification dans le README)

-1

0

Fichiers inutiles dans l'archive

-1

-0,5

III - Amnell

Les tests réseau ont été effectués en local, car les possibilités de la participation ne le permettaient pas.

Moyenne obtenue : 57/60.

Les sources.

III-A - Juré 7

Critère

Points à accumuler
(60 au total)

55,5

Fonctionnement minimal du programme

Total : 18

15

Fonctionnement de base

8

7

Connexion client/serveur (unique connexion), information de connexion (ping de latence), gestion de plusieurs connexions. Il manque la posibilité de se déconnecter du serveur sans avoir à fermer le client et le ré-ouvrir (ou alors pas trouvé). Il arrive, dans le résultat des analyses, que la liste des patients devienne vide et impossible de la récupérer à moins de redémarer le client. Aucun succès en ce qui concerne la connexion par Internet. L'opcode est une bonne idée pour connaître le type de paquet. Est-ce vraiment nécessaire d'envoyer le login et mot de passe avec chaque paquet ? On aurait pu penser à un système de connexion unique dans le même genre que la base de donnée et un identifiant unique attribué au client à ce moment-là, puis passé dans chaque paquet pour l'identifier.

Esthétisme

5

4

Design adapté à un petit écran. Bon design dans l'ensemble, parfois un peu chargé (suivi des patients) mais nécessaire pour un contrôle poussé. On regrette l'impossibilité d'avoir l'application en plein écran (sur desktop) ou de pouvoir déplacer la fenêtre.

Fluidité

5

4

Application extrêmement fluide sous Windows, que ce soit l'interface avec les transitions QML ou les chargements des images depuis le serveur. De plus, un système de cache des images rend le chargement des images unique. La connexion unique à la base de donnée favorise également la fluidité en éliminant des requêtes répétées.

Qualité du code

Total : 13

12

Qualité d'un point de vue du code

4

4

Globalement, code de très bonne qualité avec une bonne séparation de la logique client/serveur, de la base de données et de l'interface graphique. Possibilité d'utilise la notion de "pimpl" pour cacher les variables membres d'une classe, évitant de les exposer publiquement. Éviter les pointeurs de fonctions quand c'est possible. Attention aussi à l'utilisation des singletons pour tout et n'importe quoi (voir singletons en C++). Pourquoi ne pas prendre l'habitude de ne pas commencer les enum à 0 pour être sûr que la valeur par défaut et la première valeure soient différentes ?

Qualité d'un point de vue Qt

4

4

Utilisation des bonnes classes en fonction de leur usage : QTcpSocket, QTcpServer, QSql mais, au final, peu d'utilisation de classes Qt coté C++. Utilisation des macros Qt à bon escient pour couplage avec QML, ainsi que les signaux et slots, etc.

Gestion de la mémoire

2

1,5

Pas beaucoup d'utilisation du système de parent QObject du coté C++, une raison (exemple TCPServer dans master.h) ? Sinon, pas de problème majeur.

Gestion des données

2

1,5

Pas de nettoyage du cache des images quand le client se termine ? Après requête d'une image par un client et modification manuelle sur le serveur, la nouvelle image n'est jamais récupérée. J'ai dû supprimer manuellement le cache pour voir la modification.

Documentation minimale

1

1

Documentation plus que minimale, voir documentation en suffisance.

Interface graphique (critère optionnel)

Total : 5

2,5

Ergonomie

(5)

2,5

Très facile de compréhension. Seul le premier menu défilant (flicker) n'est pas très intuitif si on n'a pas l'habitude des applications QML. Je m'attendais personellement à un défilement automatique en survolant l'une des icônes grisées. On aimerait bien quelque bulles d'aide à certains endroits, comme le H en bas à droite, qui est un retour au sommaire (j'ai cliqué dix fois dessus en étant déjà sur le sommaire et ne comprenais pas pourquoi rien ne se passait, je croyais que H était pour Help). Le menu principal toujours accessible par la gauche est très pratique, idem pour les informations de connexion. J'ai toujours un peu de mal avec les listes qui affichent le plus récent en bas (personellement), surtout sur un petit terminal : on n'a pas envie de défiler pendant trop longtemps. Une possibilité de trier par ordre chronologique serait un bon plus.

Design

(5)

2

Design sympa avec un jeu d'icônes attrayantes. Utilisation d'une police de caractère particulière pas forcément très facile à lire. Le design est d'une bonne taille pour être adapter à un dispositif tactile, bon point.

Fonctionnalités obligatoires

Total : 24

13

Utilisation d'une base de données distante (gestion de patients, des chambres, du planning des médecins...)

4

4

La base de données est chargé côté client lors de la connexion au serveur et des requêtes sont effectués uniquement lors d'un ajout ou d'une modification. Les accès concurrents sont gérés en envoyant toute modification ou ajout à chaque client connecté. Très bon travail de ce coté-là, j'étais inquiet pour les accès concurrents mais ça marche très bien. La gestion de la base de donnée coté serveur sous forme de template pour les différentes tables est bien pensée, cela dit, d'un point de vue dev, quand une colonne est à ajouter à une table, la classe correspondante doit être mise à jour. Recherche des patients pratique, dommage que ce soit case-sensitive. La colonne level n'est pas utilisé dans la table account, on aurait bien voulu avoir une explication de l'utilisation future. Pareil pour la gestion de facture (table invoice) ou alors aurait dû être retiré de la base pour soumission au jury.

Affichage de graphiques et d'images (ECG, scanners, radios...)

4

3

Les images sont chargés une par une (notamment pour les scanners), ce qui permet d'un affichage progressif, une bonne chose pour le temps d'attente. Les chemins des images sont stockés dans la base de données, mais les images elles-mêmes sont stockés dans le .qrc, ce qui n'est pas une solution viable pour de la production.

Affichage 3D (IRM, squelette...)

4

0

Pas d'affichage 3D.

Communication entre clients (envoi de messages, textuels ou vidéos, à une autre instance sur une autre machine)

4

3

Chat intégré à l'application permettant aux médecins de communiquer entre eux.

Saisie d'informations (rapports médicaux, prescriptions, facturation...)

4

3

Saisie d'information sur les patients, symptômes, diagnostiques et prescriptions. Information basique mais suffisante pour montrer un bon fonctionnement, les données sont passés sous la forme d'une liste de chaînes de caractères montrant, il est sûrement facile d'en ajouter. On apprécie la liste des médicaments disponibles. Manque un système de validation, j'ai réussi à rentrer une personne avec un âge de 1500 ans, mais, d'après l'ECG, son cœur bat toujours, donc tout va bien ;). On peut également définir une personne comme morte et prête à sortir (par la morgue), c'est un peu glauque.

Organisation interne (allocation de chambres, de locaux, de membres du personnel, etc. en fonction des besoins)

4

0

Non implementé.

Bonus (critères facultatifs)

Total : + 38

+14

Autres fonctionnalités (proposées)

1 chaque, avec un maximum de 3

0

Autres fonctionnalités (non proposées)

2 chaque, avec un maximum de 6

0

Documentation en suffisance

3

2.5

Très bonne documentation C++ au format Doxygen avec génération en HTML. Même format utilisé pour le code JavaScript. On regrette peut-être le manque d'une explication de chaque fichier QML, de son utilité au sein de l'interface (pas de commentaire ligne par ligne, car déclaratif, mais plus une description).

Ajout de modules à chaud

4

0

Non supportés.

Conception préalable poussée, avec explications

6

4.5

On sent bien que la conception a été bien pensée avant la phase de programmation et bien détaillée dans le fichier Readme.

Utilisation de Qt Quick

8

7

Utilisation poussé de Qt Quick et QML avec séparation forte entre la couche métier et l'interface graphique. Gestion du parsing des messages au format JSON effectué en JavaScript via QML.

Surprenez-nous !

8

0

Rien d'inattendu.

Malus

Total : - 16

-1

Utilisation d'un autre langage (sont autorisés tous les langages qui peuvent utiliser Qt directement (C++, Python, Java...) ainsi que tous les langages que Qt utilise (en ce compris ECMAScript/JavaScript, QML, (X)HTML, Lua via QtLua/LQt, etc.))

-4

0

Rien vu d'illégal.

Utilisation d'une autre bibliothèque non prévue pour Qt (GMP, GnuPlot...), sauf pour la base de données

-4

0

Rien vu d'illégal.

Application peu robuste

-2

0

Pas de plantage du client ou serveur pendant l'utilisation du client.

Application semblant plantée

-2

-1

Une forward declaration dans le fichier opcodes.h fait planter le serveur quand le client essaye de se connecter. Remplacer class TcpServer; par #include "TcpServer.h" corrige le problème.

Erreurs à la compilation

-2

0

Aucune

Avertissements à la compilation (sauf si justification dans le README)

-1

0

Aucun

Fichiers inutiles dans l'archive

-1

0

Aucun

III-B - Juré 9

Critère

Points à accumuler
(60 au total)

58,5

Fonctionnement minimal du programme

Total : 18

15,5

Fonctionnement de base

8

7

À part l'impossibilité programmée de se connecter à un serveur distant, tout correspond à ce qui a été demandé.

Esthétisme

5

4,5

Plus que globalement, très bonne esthétique !

Fluidité

5

4

Il manque quelques animations entre le menu principal et les premiers modules, ça fait tache avec le reste.

Qualité du code

Total : 13

11

Qualité d'un point de vue du code

4

3,5

Très bonne qualité de code, peut-être trop de singletons. Code prévu pour fonctionner avec plusieurs versions de Qt avec des instructions préprocesseur. On verra d'un plus mauvais œil les quelques commentaires en anglais, possiblement des copier-coller. On regrettera amèrement que certaines données soient codées en dur dans le code (l'IP ou le port pour la connexion au serveur), obligeant à recompiler avant de tester en réseau (ce qui n'a d'ailleurs pas fonctionné).

Qualité d'un point de vue Qt

4

3,5

Mais surtout beaucoup côté QML !

Gestion de la mémoire

2

1,5

Gestion des données

2

1,5

Quelques problèmes de cache.

Documentation minimale

1

1

Pas minimale, un cran plus haut !

Interface graphique (critère optionnel)

Total : 5

4

Ergonomie

(5)

3,5

Un plaisir à utiliser, on trouve un moyen d'arriver à ses fins, notamment grâce au menu disponible en permanence à gauche (bien qu'on pourrait croire qu'il permette l'accès à une autre série de boutons). Par contre, la gestion des patients pourrait être améliorée : ne permettre l'accès aux données des patients qu'après avoir choisi un patient, au lieu de d'abord choisir le type de données souhaitées puis un patient. De même, on ne comprend pas trop ce que vient faire l'ECG dans le service des urgences, le titre n'est pas très explicite.

Design

(5)

4

On regrettera l'utilisation du souligné à certains endroits et une police somme toute peu professionnelle et pas forcément agréable à utiliser tout au long de la journée, ainsi que l'impossibilité de modifier la taille de la fenêtre (quid d'un périphérique avec un écran légèrement plus grand ?).

Fonctionnalités obligatoires

Total : 24

13,5

Utilisation d'une base de données distante (gestion de patients, des chambres, du planning des médecins...)

4

3,5

Ah, au fait... comment créer des utilisateurs ?

Affichage de graphiques et d'images (ECG, scanners, radios...)

4

3,5

Chargement progressif, mais on doit attendre la fin du chargement avant de faire quoi que ce soit (il serait mieux de laisser une barre de progression modale tant que le premier fichier n'est pas chargé, puis d'en intégrer une dans l'interface libérée lors du chargement des images suivantes).

Affichage 3D (IRM, squelette...)

4

0

Communication entre clients (envoi de messages, textuels ou vidéos, à une autre instance sur une autre machine)

4

3

Pourquoi devoir appuyer sur un bouton pour entrer dans le chat ? Pourquoi le bouton Quitter permet-il de quitter d'abord le chat puis l'interface sans que ce soit signalé d'une quelconque manière ? Quelques options supplémentaires pour notamment grouper les messages envoyés consécutivement par une personne sans répéter l'expéditeur.

Saisie d'informations (rapports médicaux, prescriptions, facturation...)

4

3,5

Organisation interne (allocation de chambres, de locaux, de membres du personnel, etc. en fonction des besoins)

4

0

Bonus (critères facultatifs)

Total : + 38

+ 14,5

Autres fonctionnalités (proposées)

1 chaque, avec un maximum de 3

0

Autres fonctionnalités (non proposées)

2 chaque, avec un maximum de 6

0

Documentation en suffisance

3

2,5

Excellente documentation Doxygen ! Seul élément manquant : une page d'accueil (et quelques descriptions manquantes).

Ajout de modules à chaud

4

0

Conception préalable poussée, avec explications

6

5

Ce n'est pas du tout un projet qui a été imaginé dans une cave en cinq minutes ou une nuit, la phase de conception a été bien poussée.

Utilisation de Qt Quick

8

7

Utilisation très poussée de Qt Quick.

Surprenez-nous !

8

0

Malus

Total : - 16

- 0

Utilisation d'un autre langage (sont autorisés tous les langages qui peuvent utiliser Qt directement (C++, Python, Java...) ainsi que tous les langages que Qt utilise (en ce compris ECMAScript/JavaScript, QML, (X)HTML, Lua via QtLua/LQt, etc.))

-4

0

Utilisation d'une autre bibliothèque non prévue pour Qt (GMP, GnuPlot...), sauf pour la base de données

-4

0

Application peu robuste

-2

0

Application semblant plantée

-2

0

Erreurs à la compilation

-2

0

Avertissements à la compilation (sauf si justification dans le README)

-1

0

Fichiers inutiles dans l'archive

-1

0

IV - MedCenter (les geekologues : LittleWhite, std_abdel, Nass)

Les tests réseau ont été effectués en local, rien n'a été fait autrement, malheureusement.

Moyenne obtenue : 42,5 / 60.

Les sources.

IV-A - Juré 9

Critère

Points à accumuler
(60 au total)

42,5

Fonctionnement minimal du programme

Total : 18

15

L'application correspond à ce qui a été demandé, globalement.

Fonctionnement de base

8

7

Esthétisme

5

3

Globalement, l'application est esthétique. À l'usage, il appert que l'on peut déplacer certains éléments et que le résultat n'est plus des plus esthétiques, ainsi que le redimensionnement (mauvais comportement sur de petits écrans, soit sur smartphones, tablettes graphiques, etc., pourtant l'objectif du défi).

Avant agrandissement.

(cliquez ici pour aggrandir l'image)

Après agrandissement.

(cliquez ici pour aggrandir l'image)

Quand on redimensionne, on perd une partie importante des fonctionnalités, on doit les garder et n'afficher qu'une liste (ou autre) des items.

Avant agrandissement.

(cliquez ici pour aggrandir l'image)

Après agrandissement.

(cliquez ici pour aggrandir l'image)

On voit que tout n'est pas vraiment bien à l'échelle, on perd des informations, ce n'est pas un problème isolé.

Avant agrandissement.

(cliquez ici pour aggrandir l'image)

Après agrandissement.

(cliquez ici pour aggrandir l'image)

Même dans la barre de boutons. On remarquera aussi l'absence d'une icône pour l'ECG.

Lors d'un déplacement.

(cliquez ici pour aggrandir l'image)

Lors d'un déplacement, tout se chevauche, c'est illisible. Dans la gestion des ressources, on peut utiliser la molette de la souris, ce qui donne un résultat figé du même acabit.

Avec la molette.

(cliquez ici pour aggrandir l'image)

Finalement, quand on ajoute de nouveaux éléments, tout n'est pas forcément visible non plus :

Nouveaux éléments.

(cliquez ici pour aggrandir l'image)

Fluidité

5

5

Qualité du code

Total : 13

9,5

Qualité d'un point de vue C++

4

2,5

À regarder la section de la création de la base et de son remplissage, on est assez loin d'un code lisible :

QSqlQuery query(QSqlDatabase::database());
if ( query.exec("INSERT INTO Users VALUES('Tortue Caroline', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 0, 0)") )
if (query.exec("INSERT INTO Users VALUES('Dr Grocha Roucoud', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 1, 0)") )
if (query.exec("INSERT INTO Users VALUES('Dr Bush Jonnn', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 1, 0)") )
if (query.exec("INSERT INTO Users VALUES('Dr GaBi Duvers', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 1, 0)") )
if (query.exec("INSERT INTO Users VALUES('Litlwayt Spirit', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 2, 0)") )
if (query.exec("INSERT INTO Users VALUES('Hafidi Abdel', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 3, 0)") )
if (query.exec("INSERT INTO Users VALUES('admin', 'd033e22ae348aeb5660fc2140aec35850c4da997', 1000, 0)") )
if (query.exec("INSERT INTO Users VALUES('doctor', '1f0160076c9f42a157f0a8f0dcc68e02ff69045b', 100, 0)") )
if (query.exec("INSERT INTO Users VALUES('nurse', '285f9a003f671c2486a3f87ea1ad5e37699ebc38', 0, 0)") )
return true;

On aurait pu largement éviter une telle imbrication de if et un non-alignement total des requêtes :

if (   query.exec("INSERT INTO Users VALUES('Tortue Caroline', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 0, 0)")
&& query.exec("INSERT INTO Users VALUES('Dr Grocha Roucoud', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 1, 0)")
&& query.exec("INSERT INTO Users VALUES('Dr Bush Jonnn', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 1, 0)")
&& query.exec("INSERT INTO Users VALUES('Dr GaBi Duvers', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 1, 0)")
&& query.exec("INSERT INTO Users VALUES('Litlwayt Spirit', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 2, 0)")
&& query.exec("INSERT INTO Users VALUES('Hafidi Abdel', '16ce0a28dba46bc6e211389ce8a27cb89d7bc623', 3, 0)")
&& query.exec("INSERT INTO Users VALUES('admin', 'd033e22ae348aeb5660fc2140aec35850c4da997', 1000, 0)")
&& query.exec("INSERT INTO Users VALUES('doctor', '1f0160076c9f42a157f0a8f0dcc68e02ff69045b', 100, 0)")
&& query.exec("INSERT INTO Users VALUES('nurse', '285f9a003f671c2486a3f87ea1ad5e37699ebc38', 0, 0)") )
return true;

On retrouve également pas mal de code commenté, ne laissant que très peu de code réellement compilé dans certaines fonctions, avec un résultat visiblement totalement différent de ce qui est annoncé par le commentaire :

Patient* MedDatabase::patient(int) // Retourne un patient particulier.
{
/*
QSqlQuery query(QSqlDatabase::database());
query.prepare("SELECT * FROM Patients WHERE Id=:idPatient");
query.bindValue(":idPatient", idPatient);
if ( query.exec() && query.first() )
return Patient(query.value(0).toInt(), // Id
query.value(1).toString(), // Name
query.value(2).toInt()); // Room
// TODO
// age
// + Item
// + Version
else
qDebug() << query.lastError().text();*/

return new Patient(); // invalid patient
}

On remarque aussi que, une fois lancée, l'application consomme toutes les ressources processeur disponibles (sur un octocore) :

Consommation folle des ressources processeur.

(cliquez ici pour aggrandir l'image)

Qualité d'un point de vue Qt

4

3

Gestion de la mémoire

2

2

Gestion des données

2

1,5

La base de données semble bien conçue ; on regrettera probablement que le versionnage proposé n'est pas très efficace (on ne peut pas retenir les modifications - juste un message concernant la modification sans qu'il soit possible de le préciser).

Documentation minimale

1

0,5

Tous les sous-projets n'ont pas de documentation, seulement le code principal. Notamment, le composant de logging utilisé n'a pas de documentation à part, bien que les sources soient commentées à cet effet - surtout que c'est le composant qui semble le plus prévu pour réutilisation. On remarquera en passant qu'une copie des sources de l'application principale est cachée dans le dossier dudit logueur, seul résultat pour une recherche sur "doc" dans le dossier. On aurait aimé une documentation globale du projet, notamment avec une page d'accueil présentant le projet (ou au moins donnant des liens vers les pages expliquant la manière de créer un nouveau module ou simplement vers les classes à réimplémenter dans cet objectif).

Interface graphique (critère optionnel)

Total : 5

3

Ergonomie

(5)

2

Le plus gros reproche à ce niveau : la gestion des ressources des examens. On ne doit pas gérer les ressources soi-même, on peut gérer un examen médical qui contient plusieurs ressources, sinon ce n'est pas utilisable par un médecin sans qu'il perde la majorité de ses cheveux. On doit là choisir le fichier concerné et entrer manuellement la catégorie concernée : pour le premier point, on aurait pu simuler une interaction avec du matériel médical, mais ce n'était pas primordial ; pour le second, c'est inacceptable au niveau de l'ergonomie, on ne doit pas d'abord maîtriser l'application puis être capable de s'en servir.

Après agrandissement.

(cliquez ici pour aggrandir l'image)

Design

(5)

3

C'est un très bon début de design, il faut encore cependant améliorer tous les points précédemment cités.

Fonctionnalités obligatoires

Total : 24

8

Utilisation d'une base de données distante (gestion de patients, des chambres, du planning des médecins...)

4

2

L'enregistrement des données ne se fait qu'à la déconnexion, rendant les modifications concurrentes impossibles (bien que le concept de l'absence de bouton de validation est intéressant : on aurait pu aller plus loin et envoyer en base de données chaque modification d'un champ, avec un concept de session de modification - toutes les modifications apportées à un patient avant de passer au suivant, par exemple - pour la gestion des versions). On dirait même que la base de données est mise en cache lors du lancement de l'application et jamais rechargée.

Affichage de graphiques et d'images (ECG, scanners, radios...)

4

2

Rien ne s'affiche (page blanche) pour l'ECG (au lieu du plantage annoncé) ni pour les radios. Ajout de données impossibles pour un néophyte de l'application. Par contre, le scanner fonctionne (si ce n'est qu'il faut sélectionner manuellement un fichier et entrer manuellement la catégorie).

Affichage 3D (IRM, squelette...)

4

0

Rien ne s'affiche (page bleue). Ajout de données impossibles pour un néophyte de l'application.

Communication entre clients (envoi de messages, textuels ou vidéos, à une autre instance sur une autre machine)

4

1

C'est disponible par le biais d'un chat. Par contre, on ne voit pas les transferts d'un client à l'autre ; tout le monde ne voit pas les personnes soi-disamment connectées alors que l'onglet est disponible ; les personnes affichées connectées ne dépendent pas des personnes réellement connectées, on affiche directement toutes les personnes en base.

Saisie d'informations (rapports médicaux, prescriptions, facturation...)

4

3

À part les modifications concurrentes impossibles, les problèmes pour l'ajout de ressources (aussi compté dans ces modules), l'affichage capricieux (impossible d'ajouter complètement une quatrième opération par manque de place, par exemple).

Organisation interne (allocation de chambres, de locaux, de membres du personnel, etc. en fonction des besoins)

4

0

Rien de disponible.

Bonus (critères facultatifs)

Total : + 38

8

Autres fonctionnalités (proposées)

1 chaque, avec un maximum de 3

0

Autres fonctionnalités (non proposées)

2 chaque, avec un maximum de 6

0

Documentation en suffisance

3

1

Quand il y a de la documentation, elle n'est pas mauvaise ; malheureusement, tous les fonctions, slots, classes, projets ne sont pas documentés.

Ajout de modules à chaud

4

0

Même si ce n'était pas loin.

Conception préalable poussée, avec explications

6

4

Utilisation de Qt Quick

8

2

C'est bien de vouloir utiliser Qt Quick, je suis pourtant persuadé que le résultat aurait été de bien meilleure qualité s'il n'avait pas été utilisé et si les participants avaient utilisé une partie de Qt qu'ils connaissent mieux - l'objectif a probablement été d'apprendre QML, ce qui a été atteint mais pas complètement.

Surprenez-nous !

8

1

On apprécie que, à la fermeture de l'application, on réouvre le menu de login ; par contre, pas de bouton de déconnexion - quid des plateformes plus restreintes, où l'application s'ouvre en plein écran ?

Malus

Total : - 16

- 1

Utilisation d'un autre langage (sont autorisés tous les langages qui peuvent utiliser Qt directement (C++, Python, Java...) ainsi que tous les langages que Qt utilise (en ce compris ECMAScript/JavaScript, QML, (X)HTML, Lua via QtLua/LQt, etc.))

-4

0

Utilisation d'une autre bibliothèque non prévue pour Qt (GMP, GnuPlot...), sauf pour la base de données

-4

0

Application peu robuste

-2

0

Application semblant plantée

-2

0

Erreurs à la compilation

-2

0

Avertissements à la compilation (sauf si justification dans le README)

-1

0

Fichiers inutiles dans l'archive

-1

-1

Doublon des fichiers de MedCenter.

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article