Jump to content
Yozz

Introduction décente à l'orienté objet ?

Recommended Posts

Quelqu'un connaît une manière simple, en Java, de classer des mots dans l'ordre décroissant de leur fréquence dans un texte donné ? J'ai réussi à faire une table de hachage (HashMap) qui donne un résultat comme ça :

 

{religieux=5, realphilosophie=1, rallié=1, scientifique=16, efface=1, correspondait=1, nouveaux=5, (...) }

 

Mais on ne peut pas trier un HashMap, donc je bloque et je ne crois pas que ce soit la bonne structure de données.

 

Tu dit que tu doit tout faire en une classe, tu est sur ?

 

Si la question est copiable-collable dans un MP, j'ai un peu de temps pour rigoler.

Share this post


Link to post
Share on other sites

J'ai déjà fait le tour du truc, sans créer une classe de plus c'est pas vraiment possible sans recourir à deux tableaux ce qui est le comble du moche.

Le mieux serait d'avoir une classe qui représente la paire freq/mot dans ta Classe XXFreqList.

Son projet se trouve là.

http://sourceforge.net/p/javacrim/wiki/2012-12-19/

 

EDIT  ceci dit on peut faire le truc à l'envers pour gagner un peu de temps.

Plutôt que de trier la liste complète, tu peux trier les 20 éléments les plus fréquents, mais je sais pas si ça fait partie du TP.

Share this post


Link to post
Share on other sites

Globalement, il n'y a pas de solution non-crado sans type Tuple<CAR,CDR> et cette classe est la premiere que je colle dane xxx.yyy.utils, je ne vois pas comment ils peuvent etre assez cons pour ne pas l'avoir mis par défaut, ou au moins dans google guava...

 

 

Share this post


Link to post
Share on other sites

Oui et à moins de ne pas trop comprendre le problème je n'utiliserais pas une TreeMap pour ça.

L'ordre de la TreeMap se base sur l'ordre défini entre les clés. http://download.java.net/jdk7/archive/b123/docs/api/java/util/TreeMap.html

L'ordre voulu étant entre les valeurs, je ne vois pas trop à quoi servirais une TreeMap dans ce cas.

 

Si jamais tu devrais obtenir comme premier élément temps avec 191 occurrences et développement avec 51 comme dernier.

Classe dédiée à la paire mot/fréquence + hashmap<mot,paire> => transformation de hashmap vers un tableau + triage du tableau comme indiqué dans la page du projet.

Share this post


Link to post
Share on other sites

Mon prof vient de m'écrire et il précise :

 

 

La séance du 19/12/2012 a été consacrée au tri et en dernier exercice il fallait créer une classe triable au sein d'une collection. Je pense que vous disposez de toutes les notions nécessaires.
À vous d'assembler les pièces du puzzle.

 

Je vais me pencher sur la question.

Share this post


Link to post
Share on other sites

Exactement, il te faut une classe supplémentaire qui étende l'interface Comparable comme spécifié dans la partie tri de la page web de ton projet.

Share this post


Link to post
Share on other sites

Pour l'instant, mon truc ressemble à ça :

 

package fr.crim.a2012.freqlist;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



public class TMFreqList extends AbstractFreqlist{
    
    List<MotFreq> motfreq = new ArrayList<MotFreq>();
    
    public TMFreqList() throws IOException {
        
        // Appel du constructeur de la classe abstraite
        super();
    }

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        AbstractFreqlist.test(new TMFreqList());
        
    }

    @Override
    public void afficheTetes(int n) {    
        System.out.println(motfreq);
    }
    
    // Réécriture ("surcharge") de la méthode mot de la classe abstraite
    @Override
    public void mot(String mot) {
        // Affichage du mot
        System.out.println(mot);
        
        // Incrémentation de sa fréquence dans la table de hachage
        ajoutemot(mot);
    }
    
    /**
     * Ajoute un mot à une table de hachage ou incrémente sa valeur
     * @param mot
     */
    public void ajoutemot(String mot2) {
//        // Si le mot existe dans la table de hachage
//                if (lesTermesFreq.containsKey(mot2)) {
//                    
//                    // On récupère son indice (la fréquence du mot)
//                    int tempFreq = lesTermesFreq.get(mot2);
//                    
//                    // On augmente la fréquence de 1
//                    tempFreq++;
//                    
//                    // On met à jour la valeur dans la table de hachage
//                    lesTermesFreq.put(mot2, tempFreq);
//                }
//                
//                // Si le mot n'est pas dans la table, on l'ajoute
//                else {
//                    lesTermesFreq.put(mot2, 1);
//                }
    }
}

/**
 * Objet qui contient un mot et sa fréquence
 * L'interface Comparator permet le tri en fonction des valeurs
 * @author ******
 *
 */
class MotFreq implements Comparator {

    // Attributs
    private String denomination;
    private int occurrence;
    
    // Constructeur de la classe MotFreq
    public MotFreq(String uneDenomination, int uneOccurrence) {
        denomination = uneDenomination;
        occurrence = uneOccurrence;
    }
    
    @Override
    public int compare(Object o1, Object o2) {
        // TODO Auto-generated method stub
        return 0;
    }
    
}

Je remplirai la méthode compare plus tard, mais je pense que mon constructeur pour MotFreq est correct, dites-moi si je me trompe.

 

Ce que je cherche à faire maintenant, c'est de modifier la méthode ajoutemot (qui sera appelé pour chaque mot non-vide détecté dans le texte) de la classe TMFreqList pour créer un objet MotFreq approprié et le foutre dans ma liste (motfreq). Le problème, c'est qu'il va y avoir des doublons, donc j'hésite sur comment programmer ça, d'un point de vue logique. Je pourrais toujours garder ma table de hachage puis créer les objets MotFreq en piochant les clés et les valeurs (comme ça on évite le problème des doublons), mais ça fait bricolage d'utiliser une étape intermédiaire au lieu de le faire en direct à la lecture du fichier (mais comment ?).

Share this post


Link to post
Share on other sites

Oui et à moins de ne pas trop comprendre le problème je n'utiliserais pas une TreeMap pour ça.

L'ordre de la TreeMap se base sur l'ordre défini entre les clés. http://download.java.net/jdk7/archive/b123/docs/api/java/util/TreeMap.html

L'ordre voulu étant entre les valeurs, je ne vois pas trop à quoi servirais une TreeMap dans ce cas.

Comme c'est fait la, ca ne marcherait pas, mais en inversant clé et valeur ca devient plus simple:

 

Map<Integer, List<String>>

 

On peut alors récupérer les éléments dans l'ordre avec une SortedMap qui fonctionnera directement avec les Integer. C'est juste que l'algorithme de parsing nécessitera 2 passes: une première pour construire la hashtable, une deuxième pour inverser clé/valeur.

 

Bon, évidemment ce n'est pas ce que le prof veut, vu que le but est plus probablement d'apprendre l'API Java Collection que de bidouiller des algorithmes.

Share this post


Link to post
Share on other sites

Comme c'est fait la, ca ne marcherait pas, mais en inversant clé et valeur ca devient plus simple:

 

Mais s'il y a des éléments qui ont la même valeur (et c'est forcément le cas), elles vont se retrouver avec la même clé après inversion, et ça va causer des problèmes, non ?

Share this post


Link to post
Share on other sites
import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List;
 

Je viens subitement de me rappeler pourquoi je ne faisais pas d'OO (et ce n'est pas seulement parce que je n'ai pas appris).

Mais s'il y a des éléments qui ont la même valeur (et c'est forcément le cas), elles vont se retrouver avec la même clé après inversion, et ça va causer des problèmes, non ?

Tu me pourrais pas définir la clé comme la paire ordonnée de tes deux champs, (occurrence ; denomination) ? Moi c'est comme ça que je ferais, mais j'ai un point de vue plus pseudo-matheux-BdD qu'objecteur-de-programmes. ;)

Share this post


Link to post
Share on other sites

Je viens subitement de me rappeler pourquoi je ne faisais pas d'OO (et ce n'est pas seulement parce que je n'ai pas appris).

 

C'est moi qui me suis trompé en choisissant la mauvaise option suggérée par Eclipse. En fait il fallait ajouter import java.util.List;, tout bêtement.

Share this post


Link to post
Share on other sites

Mais s'il y a des éléments qui ont la même valeur (et c'est forcément le cas), elles vont se retrouver avec la même clé après inversion, et ça va causer des problèmes, non ?

Non, ca serait une liste associee a la cle:

 

[1, {"pain", "jeux"},

 2, {"soif"},

 .....

]

 

Je viens subitement de me rappeler pourquoi je ne faisais pas d'OO (et ce n'est pas seulement parce que je n'ai pas appris).

Ha non ca c'est juste parceque c'est la mauvaise List qui est importée: c'est java.util.List  le bon import.

 

De toutes façons on ne tape pas ces imports, c'est l'IDE qui le fait tout seul, d'ou les risques d'erreurs (surtout avec Eclipse qui est tout pourri).

Share this post


Link to post
Share on other sites

Est-ce que c'est possible de m'inspirer du code déjà existant et de faire comme ça ?

 

 

 

Pour tel mot (genre "bidule") :

 

-> S'il n'existe pas d'objet MotFreq("bidule", X) dans ma liste motfreq

-----> Rajoute-moi MotFreq("bidule", 1) dans motfreq

 

-> Sinon

----> Trouve-moi dans la liste motfreq l'objet qui a "bidule" comme premier paramètre et rajoute 1 à son deuxième paramètre

 

 

 

Ou l'inverse :

 

 

Pour tel mot  :

 

-> S'il existe un objet MotFreq("bidule", x) dans la liste motfreq

-----> Rajoute 1 à son deuxième paramètre

 

-> Sinon

----> Tu me crées l'objet MotFreq("bidule", 1) et tu l'ajoutes dans la liste motfreq

Share this post


Link to post
Share on other sites

Je remplirai la méthode compare plus tard, mais je pense que mon constructeur pour MotFreq est correct, dites-moi si je me trompe.

 

Ce que je cherche à faire maintenant, c'est de modifier la méthode ajoutemot (qui sera appelé pour chaque mot non-vide détecté dans le texte) de la classe TMFreqList pour créer un objet MotFreq approprié et le foutre dans ma liste (motfreq). Le problème, c'est qu'il va y avoir des doublons, donc j'hésite sur comment programmer ça, d'un point de vue logique. Je pourrais toujours garder ma table de hachage puis créer les objets MotFreq en piochant les clés et les valeurs (comme ça on évite le problème des doublons), mais ça fait bricolage d'utiliser une étape intermédiaire au lieu de le faire en direct à la lecture du fichier (mais comment ?).

 

Dans ta méthode afficher mot il y a 2 trucs pas terribles à mon avis :

Tout d'abord, je pense que c'est pour ça que tu l'as commenté, mais tu ajoutes des int dans ta ArrayList au lieu d'ajouter des MotFreq dans une HashMap ou HashTable en utilisant le mot comme clé.

Si tu fais le premier point correctement, tu aura donc la possibilité de modifier facilement le MotFreq correspondant à un mot déjà saisi. Tu n'auras pas besoin de l'insérer à nouveau dans la HashMap.

 

Le seul petit truc à découvrir c'est comment convertir une HashMap en MotFreq[] pour pouvoir la transmettre au trieur de Java comme montré dans les exemples de ta page.

Edit j'arrive après la guerre, oui c'est tout à fait possible.

Share this post


Link to post
Share on other sites
Le seul petit truc à découvrir c'est comment convertir une HashMap en MotFreq[] pour pouvoir la transmettre au trieur de Java comme montré dans les exemples de ta page.

 

Finalement c'est pas si con. J'ai déjà la hashmap et je ne suis pas obligé de réécrire ma méthode. Autant que je fasse ce que tu as dit avec une méthode dédiée.

Share this post


Link to post
Share on other sites

Bon, alors. Dans mon programme, je lis un fichier texte, et je fais une table de hachage avec les mots et leurs fréquences. Ca, ça va. J'ai créé une classe comparable MotFreq qui contient un String et un int. J'ai écrit une boucle qui parcourt chaque élément de ma table de hachage et donne le mot et la fréquence (la clé et la valeur). Tout ça, c'est bon.

 

Le problème, c'est quant j'essaie de réinjecter ce mot et cette fréquence dans un nouvel objet MotFreq. Quand j'essaie de les afficher au fur et à mesure de leur création, j'obtiens des dizaines de lignes comme ça :

 

fr.crim.a2012.freqlist.MotFreq@7031dcf0
fr.crim.a2012.freqlist.MotFreq@59a04a1b
fr.crim.a2012.freqlist.MotFreq@2a616095
fr.crim.a2012.freqlist.MotFreq@5f0bebef
fr.crim.a2012.freqlist.MotFreq@7aec8a9
fr.crim.a2012.freqlist.MotFreq@63f7d32f

 

C'est pas normal, ça, non ? Du coup, je pense que quelque chose merde au niveau de la classe MotFreq elle-même, qu'en pensez-vous ?

 

Voilà mon code :

 

package fr.crim.a2012.freqlist;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;



public class TMFreqList extends AbstractFreqlist{
	
    // Table de hachage contenant mots et fréquences
    Map<String, Integer> lesTermesFreq = new HashMap<String, Integer>();
    
    /*
     * Liste contenant des objets MotFreq
     * (construite à partir de la table de hachage ci-dessus)
     */
	List<MotFreq> motfreq = new ArrayList<MotFreq>();
	
	
	public TMFreqList() throws IOException {
		
		// Appel du constructeur de la classe abstraite
		super();
	}

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		AbstractFreqlist.test(new TMFreqList()); 		
	}

	@Override
	public void afficheTetes(int n) {	
		// Affiche la table de hachage des mots et fréquence
		System.out.println(lesTermesFreq);
		
		//Convertit la table de hachage en liste d'objets MotFreq
		hashToList(lesTermesFreq);
		
		// Affiche la liste des mots et fréquences
		//System.out.println(motfreq);
	}
	
	// Réécriture ("surcharge") de la méthode mot de la classe abstraite
	@Override
	public void mot(String mot) {
		// Affichage du mot
		System.out.println(mot);
		
		// Incrémentation de sa fréquence dans la table de hachage
		ajoutemot(mot);
	}
	
	/**
	 * Ajoute un mot à une table de hachage ou incrémente sa valeur
	 * @param mot
	 */
	public void ajoutemot(String mot2) {
		 // Si le mot existe dans la liste
		if (lesTermesFreq.containsKey(mot2)) {

			// On récupère son indice (la fréquence du mot)
			int tempFreq = lesTermesFreq.get(mot2);

			// On augmente la fréquence de 1
			tempFreq++;

			// On met à jour la valeur dans la table de hachage
			lesTermesFreq.put(mot2, tempFreq);
		}

		// Si le mot n'est pas dans la table, on l'ajoute
		else {
			lesTermesFreq.put(mot2, 1);
		}
	}

	/**
	 * A partir d'une table de hachage, remplit une liste d'objets MotFreq
	 */
	public void hashToList(Map<String, Integer> uneMap) {
		
		// Pour chaque élément de la table de hachage
		for (Map.Entry<String, Integer> entry : uneMap.entrySet()) {
			
			// On récupère le mot
			String cle = entry.getKey();
			
			// On récupère la fréquence
			int valeur = entry.getValue();
			
			// TEST de la conformité du mot et de la fréquence
			//System.out.println(cle + " " + valeur);
			
			// Création d'un nouvel objet MotFreq
			MotFreq couple = new MotFreq(cle, valeur);
			
			// TEST de la conformité de l'objet MotFreq - PROBLEME ICI
			System.out.println(couple);
			
			// Ajout de celui-ci à la liste motfreq
			motfreq.add(couple);
		}
	}
}


/** 
 * Objet qui contient un mot et sa fréquence
 * L'interface Comparator permet le tri en fonction des valeurs
 * @author ******
 *
 */

class MotFreq implements Comparator {

	// Attributs
	private String denomination;
	private int occurrence;
	
	// Constructeur de la classe MotFreq
	public MotFreq(String uneDenomination, int uneOccurrence) {
		denomination = uneDenomination;
		occurrence = uneOccurrence;
	}
	
	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		return 0;
	}
	
}

 

Share this post


Link to post
Share on other sites

Non c'est tout à fait normal, tu imprimes un Objet Java qui n'a pas surchargé la méthode toString() donc tu vois seulement le nom de la classe et l'adresse de l'élément que tu imprimes.

 

Par contre tu ne crée toujours pas tes MotFreq au bon moment.

Tu devrais les créer dans ta méthode ajoutemot directement avant de les insérer dans la map. (en gros de la même façon que tu créer une instance de ta classe principale en appelant la méthode test())


		else {
			lesTermesFreq.put(mot2, 1);
		}

 

 

Ensuite il existe déjà une méthode dans la classe HashMap qui te permets de récupérer toutes les valeurs existantes.

Ensuite tu pourras convertir ces valeurs en tableau en utilisant une autre méthode. (en fait il suffit d'enchaîner les deux appels de méthodes)

Ce tableau de Comparable tu pourras alors le trier en utilisant la méthode que tu as vu au cours.

 

En gros pour être guider par les erreurs de compilation, tu pourrais supprimer la liste de ta classe, qui ne sert à rien. Et changer le type d'encapsulation de la Map de String,Int  en String,MotFreq.

Share this post


Link to post
Share on other sites

Les gars...

 

Putain...

 

...

 

.......

 

J'ai réussi ! :icon_fete:

 

Il m'a fallu chercher longtemps sur Internet et faire énormément de trial & error, donc si ça se trouve, j'ai codé ça comme un cochon (c'est du Java, vous me direz), mais au moins la consigne est respectée (sauf étourderie).

 

package fr.crim.a2012.freqlist;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class TMFreqList extends AbstractFreqlist{

    // Table de hachage contenant mots et fréquences
    Map<String, Integer> lesTermesFreq = new HashMap<String, Integer>();

    // Liste contenant les mots et les fréquences sous forme d'objet MotFreq
    List<MotFreq> motfreq = new ArrayList<MotFreq>();

    public TMFreqList() throws IOException {

        // Appel du constructeur de la classe abstraite
        super();
    }

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        AbstractFreqlist.test(new TMFreqList());
    }

    @Override
    public void afficheTetes(int n) {

        //Convertit la table de hachage en liste d'objets MotFreq
        hashToList(lesTermesFreq);

        // Tri de la liste MotFreq par les fréquences
        Collections.sort(motfreq);

        // Réduction de la taille de la liste
        for(int i=0; i<n; i++) {
            MotFreq resultat = motfreq.get(i);
            System.out.println(resultat);
        }
    }

    // Réécriture ("surcharge") de la méthode mot de la classe abstraite
    @Override
    public void mot(String mot) {
        // Affichage du mot
//        System.out.println(mot);

        // Incrémentation de sa fréquence dans la table de hachage
        ajoutemot(mot);
    }

    /**
     * Ajoute un mot à une table de hachage ou incrémente sa valeur
     * @param mot
     */
    public void ajoutemot(String mot2) {
         // Si le mot existe dans la liste
        if (lesTermesFreq.containsKey(mot2)) {

            // On récupère son indice (la fréquence du mot)
            int tempFreq = lesTermesFreq.get(mot2);

            // On augmente la fréquence de 1
            tempFreq++;

            // On met à jour la valeur dans la table de hachage
            lesTermesFreq.put(mot2, tempFreq);
        }

        // Si le mot n'est pas dans la table, on l'ajoute
        else {
            lesTermesFreq.put(mot2, 1);
        }
    }

    /**
     * A partir d'une table de hachage, remplit une liste d'objets MotFreq
     */
    public void hashToList(Map<String, Integer> uneMap) {

        // Pour chaque élément de la table de hachage
        for (Map.Entry<String, Integer> entry : uneMap.entrySet()) {

            // On récupère le mot
            String cle = entry.getKey();

            // On récupère la fréquence
            int valeur = entry.getValue();

            // Création d'un nouvel objet MotFreq
            MotFreq couple = new MotFreq(cle, valeur);

            // Ajout de celui-ci à la liste motfreq
            motfreq.add(couple);
        }
    }
}


/**
 * Objet qui contient un mot et sa fréquence
 * L'interface Comparator permet le tri en fonction des valeurs
 * */

class MotFreq implements Comparable<MotFreq>{

    // Attributs
    private String denomination;
    private int occurrence;

    // Constructeur de la classe MotFreq
    public MotFreq(String uneDenomination, int uneOccurrence) {
        setDenomination(uneDenomination);
        setOccurrence(uneOccurrence);
    }

    /*
     * Méthodes permettant de lire ou de changer
     * les paramètres des objets de type MotFreq
     * Utiles pour l'affichage de ces paramètres dans la console
     *
     * @return
     */

    public String toString() {
        return denomination + "\t\t" + occurrence;
    }

    public String getDenomination() {
        return denomination;
    }

    public void setDenomination(String denomination) {
        this.denomination = denomination;
    }

    public int getOccurrence() {
        return occurrence;
    }

    public void setOccurrence(int occurrence) {
        this.occurrence = occurrence;
    }

    /*
     * Comparateur - Sert au tri de la liste d'objets MotFreq
     */
    @Override
    public int compareTo(MotFreq autreMotFreq) {
        return - (this.occurrence - autreMotFreq.occurrence);
    }
}

Le résultat :

 

Les 20 mots les plus fréquemment rencontrés dans le texte :
temps		191
société		160
spectacle		147
histoire		128
pouvoir		112
vie		99
historique		93
monde		92
mouvement		70
production		69
doit		69
classe		67
marchandise		66
économie		64
travail		62
propre		62
sociale		58
conscience		57
révolutionnaire		55
développement		51

(Soit dit en passant, ces mots-clé donnent une certaine idée du texte choisi...)

Share this post


Link to post
Share on other sites

Je donnerais les critiques suivantes :

Tu pourrais supprimer la List de ta classe sans soucis pour les raisons suivantes :

Tout d'abord elle est complètement inutile, et ensuite elle introduit un bug assez méchant.

Si j'appelle deux fois ta méthode hashtolist, avec deux map différentes, j'aurais le contenu des deux map dans la même liste.

Ensuite en supprimant donc la list et la méthode hashtolist, tu pourrais créer tes MotFreq dans la méthode ajoutemot. Ceci te permettrai de supprimer le put dans le if. 

La création des MotFreq se ferait normalement dans la clause else de ta méthode ajoutemot. 

 

Mais champagne !!

Share this post


Link to post
Share on other sites

Je donnerais les critiques suivantes :

Tu pourrais supprimer la List de ta classe sans soucis pour les raisons suivantes :

Tout d'abord elle est complètement inutile, et ensuite elle introduit un bug assez méchant.

Si j'appelle deux fois ta méthode hashtolist, avec deux map différentes, j'aurais le contenu des deux map dans la même liste.

Ensuite en supprimant donc la list et la méthode hashtolist, tu pourrais créer tes MotFreq dans la méthode ajoutemot. Ceci te permettrai de supprimer le put dans le if. 

La création des MotFreq se ferait normalement dans la clause else de ta méthode ajoutemot. 

 

Mais champagne !!

 

Merci :)

Share this post


Link to post
Share on other sites

Ça y est, je viens de me rappeler pourquoi je veux jamais faire du Java ...
 

foreach(explode(" ",$file_content) as $word){
  @ $result[$word]++;
}
arsort($result);

 

 

Share this post


Link to post
Share on other sites

Se faire battre par PHP ça fait mal :P

from collections import defaultdict
words = defaultdict(int)
for word in contents.split():
    words[word] += 1
print sorted(words.items(), key=lambda item: item[1], reverse=True)
5 lignes, faisable en 4 sans defaultdict mais je trouve ça plus moche.

Et pour le lol, en 2.7 :

from collections import Counter
print Counter(contents.split())

Un dernier, court mais peu efficace :

contents = contents.split()
print [(word, contents.count(word)) for word in set(contents)]

Share this post


Link to post
Share on other sites

Se faire battre par PHP ça fait mal :P

from collections import defaultdict
words = defaultdict(int)
for word in contents.split():
    words[word] += 1
print sorted(words.items(), key=lambda item: item[1], reverse=True)
5 lignes, faisable en 4 sans defaultdict mais je trouve ça plus moche.

Et pour le lol, en 2.7 :

from collections import Counter
print Counter(contents.split())

Un dernier, court mais peu efficace :

contents = contents.split()
print [(word, contents.count(word)) for word in set(contents)]

 

Je me suis pas penché sur la question, mais je me demande si on ne peut pas même le faire en une ligne de Bash.

Share this post


Link to post
Share on other sites

Une ligne d'environnement POSIX :

sed 's/\s\+/\n/g' FILE | grep -v '^DOLLAR' | sort | uniq -c | sort -n -r
Mais le niveau d'ajustements que j'ai du faire avant d'y arriver ne vaut pas le coup.

Remplacer le DOLLAR par le signe du dollar ; si je le met, le forum fait nimp.

Share this post


Link to post
Share on other sites

Se faire battre par PHP ça fait mal :P

from collections import defaultdict
words = defaultdict(int)
for word in contents.split():
    words[word] += 1
print sorted(words.items(), key=lambda item: item[1], reverse=True)
5 lignes, faisable en 4 sans defaultdict mais je trouve ça plus moche.

Et pour le lol, en 2.7 :

from collections import Counter
print Counter(contents.split())

Un dernier, court mais peu efficace :

contents = contents.split()
print [(word, contents.count(word)) for word in set(contents)]

 

 

Hmmm, mais c'est pas vraiment du PHP, t'utilises un framework, donc forcement c'est plus concis: il y a tout le code qui provient de l'import et qu'on ne voit pas.

 

Et puis la concision c'est pas tout dans la vie. C'est toujours bon de faire plus avec moins, mais ca doit pas être l'unique critère pour choisir un langage.

Share this post


Link to post
Share on other sites

C'est pas un framework, c'est la bibliothèque standard Python. On fait rarement un programme sans y placer un import (en comparaison le programme Java en a 6).

Quant aux nombres de lignes, oui ; le dernier exemple est court mais pas vraiment mieux que le premier.

Share this post


Link to post
Share on other sites

C'est vrai que python est super concis, j'ai fait assez peu de choses avec, mais rarement je me suis dit que j'aurais pu faire plus court dans un autre langage.

En fait la seul dèche en ce moment en python c'est que la moitié du monde attend que l'autre se décide à migrer vers python 3 pour y passer aussi :icon_wink: .

 

Share this post


Link to post
Share on other sites

En nombre de lignes pas sûr.

Oui c'est assez frustrant ça fait plusieurs fois que je me dis que mon prochain projet sera en Py3 et puis une librairie me bloque… enfin j'ai quand même réussi à sortir une librairie bi-version :)

Share this post


Link to post
Share on other sites

C'est vrai que python est super concis, j'ai fait assez peu de choses avec, mais rarement je me suis dit que j'aurais pu faire plus court dans un autre langage.

 

Perl ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...