« INFO424 : Projet en informatique » : différence entre les versions
Aucun résumé des modifications |
|||
(78 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
Responsable pour 2016--2017: [http://www.lama.univ-savoie.fr/~provencal Xavier Provençal] |
|||
= Présentation du projet = |
|||
* [http://lama.univ-savoie.fr/~provencal/enseignement/INFO424/presProjet.pdf Diaporama d'introduction.] |
|||
* [http://lama.univ-savoie.fr/~provencal/enseignement/INFO424/objectifs.pdf Liste des objectifs.] |
|||
= Serveur SVN = |
|||
== Premier checkout du dépôt SVN == |
|||
Cette manipulation n'est à effectuer '''une seule fois''' par chacun des membres de l'équipe. Le résultat sera la création d'un dossier qui sera '''synchronisé''' entre les membres de l'équipe par un '''gestionnaire de versions'''. |
|||
* Avec un éditeur de texte, ouvrir le fichier '''~/.ssh/config''' et y ajouter les lignes suivantes (VOTRENOM doit être remplacé par votre nom d'utilisateur) : |
|||
Host serveursvn |
|||
Hostname os-vps418.infomaniak.ch |
|||
User VOTRENOM |
|||
Port 622 |
|||
* Ouvrir un terminal et entrer la commande : |
|||
ssh serveursvn |
|||
* Une fois connecté, entrez la commande : |
|||
hostname |
|||
* Si la réponse '''n'est pas''' "depots", c'est que la connexion a échouée... vérifiez les étapes précédentes. Si la réponse '''est''' "depots" alors changez votre mot de passe en entrant la commande : |
|||
passwd |
|||
* Changer votre mot de passe '''n'est pas optionnel'''. D'ici quelques jours un script tentera de se connecter en utilisant votre ancien mot de passe. S'il réussi, il '''supprimera''' tout vos fichiers ! |
|||
* Déconnectez vous en faisant CTRL-D. |
|||
* Dans le terminal, positionnez vous dans un dossier approprié pour effectuer le "checkout". Le "checkout" va créer un dossier du même nom que votre équipe de projet. Pour effectuer le "checkout" faites (EQUIPE doit être remplacé par votre nom d'équipe tel qu'écrit au champs GROUP sur la feuille qui vous a été distribuée) : |
|||
svn checkout svn+ssh://serveursvn/var/svn/EQUIPE |
|||
* C'est fini ! Un des membres de l'équipe va maintenant ajouter au dépôt les guides et les fichiers java réalisés lors de la première séance. |
|||
== Ne plus entre son mot de passe à chaque connexion == |
|||
Lorsque vous interragissez avec votre dépôt '''svn''' vous établissez d'avord une connexion '''ssh'''. Il existe deux façons de s'identifier lorsqu'on établie une connexion '''ssh''' : |
|||
* Entrer un mot de passe. |
|||
* Échanger des clés. |
|||
Pour s'identifier par échange de clé, il faut posséder une paire '''clé publique / clé privée'''. Tout d'abord, vérifiez si vous possédez déjà des clés, entrez la commande : |
|||
ls ~/.ssh/id_rsa* |
|||
Si les deux fichiers '''id_rsa''' et '''id_rsa.pub''' sont listés alors vous possédez déjà des clés. Sinon, entrez la commande : |
|||
ssh-keygen |
|||
Acceptez les valeurs pas défaut et n'entre rien comme '''passphrase'''. Voilà, vos clés ont été générées. |
|||
'''Activez l'identification par échange de clés'''. Entrez la commande : |
|||
ssh-copy-id serveursvn |
|||
Vous entrez alors votre mot de passe pour la dernière fois. À partir de ce moment vous serez identifier pas échange de clés. |
|||
= Aide à la programmation = |
|||
== Lister les fichiers présents dans un dossier == |
|||
En entête du fichier, ajoutez la ligne : |
|||
<code> |
|||
import java.io.File; |
|||
</code> |
|||
La fonction suivante, affiche la liste des fichiers et dossiers présents dans le dossier ``chemin``. |
|||
<code> |
|||
static void listeFichiersDansDossier( String chemin ) |
|||
{ |
|||
File dossier = new File( chemin ); |
|||
File[] listeDesFichiers = dossier.listFiles(); |
|||
for ( File f : listeDesFichiers ) { |
|||
if ( f.isFile() ) { |
|||
System.out.println("Fichier : " + f.getName()); |
|||
} else if ( f.isDirectory() ) { |
|||
System.out.println("Dossier " + f.getName()); |
|||
} |
|||
} |
|||
} |
|||
</code> |
|||
== Identifier les mots == |
|||
Après avoir retiré les balises html du coprs d'un message, il faut être en mesure de la découper en mots. Voici une méthode très simple afin de découper les lignes de texte en mots. |
|||
<code> |
|||
// on suppose que 'ligne' de type String et contient une ligne de texte |
|||
for ( String s : (subject + " " + body).split( "[ ,.!?'’…]" ) ) |
|||
{ |
|||
s = s.toLowerCase(); |
|||
if ( estMot(s) ) |
|||
{ |
|||
// ajouter ce mot à la l'ensemble des mots de ce message. |
|||
} |
|||
} |
|||
</code> |
|||
Dans le code ci-dessus, on utilise la fonction ``estMot``. Cette fonction prend en entrée une chaîne de caractères et retourne un booléen indiquant s'il s'agit bien d'un mot ou non. Par exemple, les courriels contiennent souvent des images dont le code est inclus dans le corps du message, format des suites de caractères incompréhensibles. La fonction ``estMot`` doit être en mesure de détecter ce genre de suites de caractères qui ne correspondent pas à des mots. |
|||
<code> |
|||
private boolean estMot(String s) |
|||
{ |
|||
// Si la longueur de s est zéro ou supérieure à 25 alors ``s`` n'est pas un mot. On fixe la limite à 25 car 'anticonstitutionnellement' est de longueur 25 ! |
|||
// Pour chaque lettre ``c`` de ``s``, on teste : |
|||
// si ``c`` est une lettre majuscule ( 'A' <= c && c <= 'Z' ) |
|||
// si ``c`` est une lettre minuscule ( 'a' <= c && c <= 'z' ) |
|||
// si ``c`` est une lettre accentuée ( "àÀâÂéÉèÈêÊëÊîÎïÏôÔöÖùÙ".indexOf(c) != -1 ) |
|||
// Si ``c`` ne satisfait pas l'un des trois tests, alors ``s`` n'est pas un mot! |
|||
} |
|||
</code> |
|||
= Calcul des probabilités = |
|||
Une fois votre programme d'analyse terminé, votre second programme, le juge, détermine si un courriel donné est un spam ou non. Le détail des calcul est bien expliqué sur la page wikipedia : |
|||
Probabilité pour un mot : https://fr.wikipedia.org/wiki/Filtrage_bay%C3%A9sien_du_spam#Calculer_la_probabilit.C3.A9_qu.27un_message_contenant_un_mot_donn.C3.A9_soit_un_spam |
|||
Combiner les probabilités : https://fr.wikipedia.org/wiki/Filtrage_bay%C3%A9sien_du_spam#Combiner_les_probabilit.C3.A9s_individuelles |
|||
Comme suggéré, nous feront l'hypothèse que, de manière générale, la probabilité qu'un message reçu soit un spam, est de 1/2. Cela permet de simplifier significativement les calculs. |
|||
Ainsi, étant donné un mot ``m`` dont l'Analyseur a déterminé les probabilités suivantes : |
|||
- Le mot ``m`` a la probabilité ``p_ham`` d'apparaître dans un courriel de type ``ham``. |
|||
- Le mot ``m`` a la probabilité ``p_spam`` d'apparaître dans un courriel de type ``spam``. |
|||
On calcule ``p_m``, la probabilité que le message soit un spam en faisant : ``p_spam / ( p_ham + p_spam )``. |
|||
Une fois qu'on a calculé tous ces probabilités pour tous les mots ``m1, m2, m3, ..., mk``, on calcule la probabilité que le message soit un spam en calculant : |
|||
<code> |
|||
p_m1*p_m2*p_m3*...*p_mk |
|||
--------------------------------------------------------------------- |
|||
(p_m1*p_m2*p_m3*...*p_mk) + ((1-p_m1)*(1-p_m2)*(1-p_m3)*...*(1-p_mk)) |
|||
</code> |
|||
<B>ATTENTION</B> afin d'obtenir des résultat pertinents, ignorez tous les ``p_m`` dont la valeur est 0 ou 1. Si vous les incorporez dans votre calcul, tous les autres ``p_mi`` seront ignorés et le résultat final sera systématiquement 0 ou 1 (ou ``Nan`` car vous risqueriez de faire une division par zéro). |
|||
= Bases de données à télécharger = |
|||
Afin de tester votgre code, vous pouvez utiliser la banque de courriels suivants : |
|||
- [http://lama.univ-smb.fr/~provencal/enseignement/INFO424/emails.zip emails.zip] |
|||
<!-- |
|||
- Convertir une image ( ex : ``fichierEntree.jpg`` ) d'un format quelconque en ppm : |
|||
'''$ convert fichierEntree.jpg -compress none fichierSortie.ppm''' |
|||
(Nécessite la librarie ``imagemagick``) |
|||
- Script pour saisir une image depuis la webcam et la convertir au format ppm : [http://lama.univ-savoie.fr/~provencal/enseignement/INFO424/takePicture.sh takePicture.sh] |
|||
(requiert d'avoir installé les pacquets ``streamer`` et ``imagemagick``) |
|||
Sous une architecture Debian (Ubuntu, Mint, etc.) il suffit d'entrer la commande suivante : |
|||
'''$ sudo apt-get install streamer imagemagick''' |
|||
- Un peu de lecture sur les deux éditeurs de texte les plus célèbres : [https://fr.wikipedia.org/wiki/Guerre_d'%C3%A9diteurs Wikipedia] |
|||
- Feuille TODO au format pdf : [http://lama.univ-savoie.fr/~provencal/enseignement/INFO424/projet424.pdf projet424.pdf] |
|||
- Feuille TODO à ajouter à votre dépôt : [http://lama.univ-savoie.fr/~provencal/enseignement/INFO424/projet424.tex projet424.tex] |
|||
- Courbe en S, afin d'éviter d'avantage de confusion, voici le calcul de la courbe en S |
|||
pour modifier le contraste d'une image. Dans le bout de code qui suit, '''x''' est la valeur |
|||
du pixel considéré, '''moy''' la valeur moyenne de tous les pixels de l'image, '''d''' est le |
|||
degré de la courbe (valeur choisie par l'utilisateur) et '''y''' est la nouvelle valeur du pixel. |
|||
<code> |
|||
if ( x <= moy ) { |
|||
tmp = x/moy; |
|||
tmp = Math.pow( tmp, d ); |
|||
y = tmp*moy; |
|||
} else { |
|||
tmp = 1.0 - ( (x-moy) / (1.0-moy) ); |
|||
tmp = Math.pow( tmp, d ); |
|||
y = (1.0-tmp)*(1.0-moy) + moy; |
|||
} |
|||
</code> |
|||
--> |
|||
<!-- |
|||
Lire sur l'entrée standrad ligne par ligne : |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/liresurentreestandard.adb En Ada.] |
|||
Lire sur l'entrée standrad ligne par ligne et découpe ces lignes mot à mot : |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/LireSurEntreeStandard.java En Java.] |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/LireSurEntreeStandard.py En Python.] |
|||
Récupérer les arguments de la ligne de commande : |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/arguments.adb En Ada.] |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/arguments.java En Java.] |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/arguments.py En Python.] |
|||
Un makefile pour compiler un programme Ada, compiler une classe Java et vérifier la syntaxe d'un fichier Python : |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/exempleMakefile.tgz Exemple de makefile.] |
|||
--> |
|||
<!-- |
|||
Responsable pour 2013--2014: [http://www.lama.univ-savoie.fr/~provencal Xavier Provençal] |
Responsable pour 2013--2014: [http://www.lama.univ-savoie.fr/~provencal Xavier Provençal] |
||
Ligne 4 : | Ligne 210 : | ||
* [http://lama.univ-savoie.fr/~provencal/INFO424/projet.pdf Description du projet.] |
* [http://lama.univ-savoie.fr/~provencal/INFO424/projet.pdf Description du projet.] |
||
Code fourni : télécharger une des archives ci-dessous. Pour savoir quelle version télécharger, exécutez la commande : |
|||
<-- |
|||
$ dpkg -l libjava-gnome-java |
|||
et regardez la version de la libraire. |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/code_de_base-v4.0.tgz code_de_base-v4.0.tgz] |
|||
* [http://lama.univ-savoie.fr/~provencal/INFO424/code_de_base-v4.1.tgz code_de_base-v4.1.tgz] |
|||
== Utilisation du clavier sous java-gnome == |
|||
* Dans la classe Interface, ajouter les imports : |
|||
<pre> |
|||
import org.gnome.gdk.EventKey; |
|||
import org.gnome.gdk.Keyval; |
|||
import org.gnome.gdk.ModifierType; |
|||
</pre> |
|||
# Dans le constructeur de la classe Interface, après la ligne |
|||
<pre> |
|||
w = new Window(); |
|||
</pre> |
|||
Il suffit de définir les fonction qui seront appelées lorsqu'on appuie (Press) et/ou relâche (Release) une touche. |
|||
<pre> |
|||
w.connect(new Widget.KeyPressEvent() { |
|||
public boolean onKeyPressEvent(Widget source, EventKey event) { |
|||
final Keyval key; |
|||
final ModifierType mod; |
|||
key = event.getKeyval(); |
|||
mod = event.getState(); |
|||
if (key == Keyval.Up) { |
|||
System.out.println( "On a appuyé sur UP!" ); |
|||
} |
|||
return false; |
|||
} |
|||
}); |
|||
w.connect(new Widget.KeyReleaseEvent() { |
|||
public boolean onKeyReleaseEvent(Widget source, EventKey event) { |
|||
final Keyval key; |
|||
final ModifierType mod; |
|||
key = event.getKeyval(); |
|||
mod = event.getState(); |
|||
if (key == Keyval.Up) { |
|||
System.out.println( "On a relaché UP!" ); |
|||
} |
|||
return false; |
|||
} |
|||
}); |
|||
</pre> |
|||
--> |
|||
<!-- |
|||
Code et exemples fourni : |
Code et exemples fourni : |
||
* Exemple d'interface graphique et de lecteur ligne par ligne. |
* Exemple d'interface graphique et de lecteur ligne par ligne. |
||
Ligne 26 : | Ligne 290 : | ||
# [http://lama.univ-savoie.fr/~provencal/INFO424/exempleInterface-avec-menu.zip Exemple d'interface graphique avec un petit menu.] |
# [http://lama.univ-savoie.fr/~provencal/INFO424/exempleInterface-avec-menu.zip Exemple d'interface graphique avec un petit menu.] |
||
-- |
--> |
Dernière version du 8 mars 2017 à 11:07
Responsable pour 2016--2017: Xavier Provençal
Présentation du projet
Serveur SVN
Premier checkout du dépôt SVN
Cette manipulation n'est à effectuer une seule fois par chacun des membres de l'équipe. Le résultat sera la création d'un dossier qui sera synchronisé entre les membres de l'équipe par un gestionnaire de versions.
- Avec un éditeur de texte, ouvrir le fichier ~/.ssh/config et y ajouter les lignes suivantes (VOTRENOM doit être remplacé par votre nom d'utilisateur) :
Host serveursvn Hostname os-vps418.infomaniak.ch User VOTRENOM Port 622
- Ouvrir un terminal et entrer la commande :
ssh serveursvn
- Une fois connecté, entrez la commande :
hostname
- Si la réponse n'est pas "depots", c'est que la connexion a échouée... vérifiez les étapes précédentes. Si la réponse est "depots" alors changez votre mot de passe en entrant la commande :
passwd
- Changer votre mot de passe n'est pas optionnel. D'ici quelques jours un script tentera de se connecter en utilisant votre ancien mot de passe. S'il réussi, il supprimera tout vos fichiers !
- Déconnectez vous en faisant CTRL-D.
- Dans le terminal, positionnez vous dans un dossier approprié pour effectuer le "checkout". Le "checkout" va créer un dossier du même nom que votre équipe de projet. Pour effectuer le "checkout" faites (EQUIPE doit être remplacé par votre nom d'équipe tel qu'écrit au champs GROUP sur la feuille qui vous a été distribuée) :
svn checkout svn+ssh://serveursvn/var/svn/EQUIPE
- C'est fini ! Un des membres de l'équipe va maintenant ajouter au dépôt les guides et les fichiers java réalisés lors de la première séance.
Ne plus entre son mot de passe à chaque connexion
Lorsque vous interragissez avec votre dépôt svn vous établissez d'avord une connexion ssh. Il existe deux façons de s'identifier lorsqu'on établie une connexion ssh :
- Entrer un mot de passe.
- Échanger des clés.
Pour s'identifier par échange de clé, il faut posséder une paire clé publique / clé privée. Tout d'abord, vérifiez si vous possédez déjà des clés, entrez la commande :
ls ~/.ssh/id_rsa*
Si les deux fichiers id_rsa et id_rsa.pub sont listés alors vous possédez déjà des clés. Sinon, entrez la commande :
ssh-keygen
Acceptez les valeurs pas défaut et n'entre rien comme passphrase. Voilà, vos clés ont été générées.
Activez l'identification par échange de clés. Entrez la commande :
ssh-copy-id serveursvn
Vous entrez alors votre mot de passe pour la dernière fois. À partir de ce moment vous serez identifier pas échange de clés.
Aide à la programmation
Lister les fichiers présents dans un dossier
En entête du fichier, ajoutez la ligne :
import java.io.File;
La fonction suivante, affiche la liste des fichiers et dossiers présents dans le dossier ``chemin``.
static void listeFichiersDansDossier( String chemin )
{
File dossier = new File( chemin );
File[] listeDesFichiers = dossier.listFiles();
for ( File f : listeDesFichiers ) {
if ( f.isFile() ) {
System.out.println("Fichier : " + f.getName());
} else if ( f.isDirectory() ) {
System.out.println("Dossier " + f.getName());
}
}
}
Identifier les mots
Après avoir retiré les balises html du coprs d'un message, il faut être en mesure de la découper en mots. Voici une méthode très simple afin de découper les lignes de texte en mots.
// on suppose que 'ligne' de type String et contient une ligne de texte
for ( String s : (subject + " " + body).split( "[ ,.!?'’…]" ) )
{
s = s.toLowerCase();
if ( estMot(s) )
{
// ajouter ce mot à la l'ensemble des mots de ce message.
}
}
Dans le code ci-dessus, on utilise la fonction ``estMot``. Cette fonction prend en entrée une chaîne de caractères et retourne un booléen indiquant s'il s'agit bien d'un mot ou non. Par exemple, les courriels contiennent souvent des images dont le code est inclus dans le corps du message, format des suites de caractères incompréhensibles. La fonction ``estMot`` doit être en mesure de détecter ce genre de suites de caractères qui ne correspondent pas à des mots.
private boolean estMot(String s)
{
// Si la longueur de s est zéro ou supérieure à 25 alors ``s`` n'est pas un mot. On fixe la limite à 25 car 'anticonstitutionnellement' est de longueur 25 !
// Pour chaque lettre ``c`` de ``s``, on teste :
// si ``c`` est une lettre majuscule ( 'A' <= c && c <= 'Z' )
// si ``c`` est une lettre minuscule ( 'a' <= c && c <= 'z' )
// si ``c`` est une lettre accentuée ( "àÀâÂéÉèÈêÊëÊîÎïÏôÔöÖùÙ".indexOf(c) != -1 )
// Si ``c`` ne satisfait pas l'un des trois tests, alors ``s`` n'est pas un mot!
}
Calcul des probabilités
Une fois votre programme d'analyse terminé, votre second programme, le juge, détermine si un courriel donné est un spam ou non. Le détail des calcul est bien expliqué sur la page wikipedia :
Probabilité pour un mot : https://fr.wikipedia.org/wiki/Filtrage_bay%C3%A9sien_du_spam#Calculer_la_probabilit.C3.A9_qu.27un_message_contenant_un_mot_donn.C3.A9_soit_un_spam Combiner les probabilités : https://fr.wikipedia.org/wiki/Filtrage_bay%C3%A9sien_du_spam#Combiner_les_probabilit.C3.A9s_individuelles
Comme suggéré, nous feront l'hypothèse que, de manière générale, la probabilité qu'un message reçu soit un spam, est de 1/2. Cela permet de simplifier significativement les calculs.
Ainsi, étant donné un mot ``m`` dont l'Analyseur a déterminé les probabilités suivantes :
- Le mot ``m`` a la probabilité ``p_ham`` d'apparaître dans un courriel de type ``ham``. - Le mot ``m`` a la probabilité ``p_spam`` d'apparaître dans un courriel de type ``spam``.
On calcule ``p_m``, la probabilité que le message soit un spam en faisant : ``p_spam / ( p_ham + p_spam )``.
Une fois qu'on a calculé tous ces probabilités pour tous les mots ``m1, m2, m3, ..., mk``, on calcule la probabilité que le message soit un spam en calculant :
p_m1*p_m2*p_m3*...*p_mk
---------------------------------------------------------------------
(p_m1*p_m2*p_m3*...*p_mk) + ((1-p_m1)*(1-p_m2)*(1-p_m3)*...*(1-p_mk))
ATTENTION afin d'obtenir des résultat pertinents, ignorez tous les ``p_m`` dont la valeur est 0 ou 1. Si vous les incorporez dans votre calcul, tous les autres ``p_mi`` seront ignorés et le résultat final sera systématiquement 0 ou 1 (ou ``Nan`` car vous risqueriez de faire une division par zéro).
Bases de données à télécharger
Afin de tester votgre code, vous pouvez utiliser la banque de courriels suivants :
- emails.zip