Warning: Undefined array key "DOKU_PREFS" in /home/clients/a4e6fc1ce1761b72982b805de0f418c4/web/python/mesrecettespython/inc/common.php on line 2082
collate_sqlite3 [Les recettes Python de Tyrtamos]

Outils pour utilisateurs

Outils du site


collate_sqlite3

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
Dernière révision Les deux révisions suivantes
collate_sqlite3 [2010/12/03 09:56]
tyrtamos
collate_sqlite3 [2015/03/03 17:53]
tyrtamos
Ligne 1: Ligne 1:
 ====== Comment faire un tri français avec collate ====== ====== Comment faire un tri français avec collate ======
  
 +[Refonte de la page le 3/3/2015. Passage à Python 3]
  
 ===== Problématique ===== ===== Problématique =====
Ligne 6: Ligne 7:
 Quand on veut extraire d'une base SQL des informations texte triées en utilisant 'ORDER BY', on se heurte au problème habituel: l'ordre de tri coïncide avec l'ordre des caractères dans les polices de caractères, c'est à dire, par exemple, que: Quand on veut extraire d'une base SQL des informations texte triées en utilisant 'ORDER BY', on se heurte au problème habituel: l'ordre de tri coïncide avec l'ordre des caractères dans les polices de caractères, c'est à dire, par exemple, que:
  
-  * 'a' est situé après 'X' (les minuscules sont situées après les majuscules), +  * 'a' est situé **après** 'X' (les minuscules sont situées après les majuscules), 
  
-  * 'à' est situé après 'x' (les caractères accentués sont situés après les caractères non accentués). +  * 'à' est situé **après** 'x' (les caractères accentués sont situés après les caractères non accentués). 
  
 ===== Solution ===== ===== Solution =====
  
 Pour trier selon l'alphabet français, et en fait, selon l'alphabet qu'on veut, on va créer une fonction de comparaison comme cmp(v1, v2), c'est à dire qui compare v1 et v2 et qui renvoie: Pour trier selon l'alphabet français, et en fait, selon l'alphabet qu'on veut, on va créer une fonction de comparaison comme cmp(v1, v2), c'est à dire qui compare v1 et v2 et qui renvoie:
- 
   * un entier <0 si v1<v2   * un entier <0 si v1<v2
- 
   * 0 si v1==v2   * 0 si v1==v2
- 
   * un entier >0 si v1>v2   * un entier >0 si v1>v2
  
-Ceci, comme on peut le faire avec la méthode sort() du Python v2.x.+Ceci, comme on peut le faire avec la méthode sort() du Python.
  
-Prenons la fonction de comparaison qu'on a déjà sur une autre page de ce site ([[http://python.jpvweb.com/mesrecettespython/doku.php?id=tris_alpha]]). On va seulement la modifier dans son titre (compalpha) et dans son encodage (comparaison en 'utf-8' et pas en unicode) :+Voilà le code proposé (Python 3):
  
-<code python> +<code python>import locale
-def compalpha(v1,v2): +
-    """comparaison des chaines de caractères v1 et v2:  +
-       renvoie un entier <0 si v1<v2, 0 si v1==v2, un entier >0 si v1>v2 +
-       v1, v2 doivent être en utf-8 +
-    """ +
-    alpha = ur"""!"#$%&'()*+,-./0123456789:;<=>?@""" + \ +
-            ur"""[\]^_`""" + \ +
-            ur"""{|}~ €""" + \ +
-            ur"""aAàÀâÂæÆbBcCçÇdDeEéÉèÈêÊëËfFgGhHiIîÎïÏjJkKlLmMnNoOôÔœŒpPqQrRsStTuUùÙûÛüÜvVwWxXyYÿŸzZ""" +
-    alpha = alpha.encode('utf-8'+
-    lgalpha = len(alpha) +
-    lg1 = len(v1) +
-    lg2 = len(v2) +
-    lg = min([lg1,lg2]) # on veut lg=longueur du mot le plus court entre V1 et v2 +
-    for i in range(0,lg): +
-        i1 = alpha.find(v1[i]) +
-        if i1<0: +
-            i1 = lgalpha + ord(v1[i]) +
-        i2 = alpha.find(v2[i]) +
-        if i2<0: +
-            i2 = lgalpha + ord(v2[i]) +
-        if i1<i2: +
-            return -1 +
-        if i1>i2: +
-            return 1 +
-    # ici, les lg premiers caractères sont identiques: le mot le plus court est avant l'autre  +
-    return lg1-lg2 +
-</code>+
  
-Le principe est simplec'est vous qui donnez l'ordre de tri avec la définition de la variable alpha. Et les caractères non inclus dans cette variable sont situés après, avec pour indice, l'ordre qu'ils ont dans la police de caractères.+############################################################################# 
 +class Compdicofr(object): 
 +    """comparaison de 2 chaines selon le dictionnaire français"""
  
 +    def __init__(self):
 +        self.loc = locale.getlocale()  # stocke la locale courante
 +        self.espinsec = '\xA0'  # espace insécable
 +
 +    def __call__(self, v1, v2):
 +
 +        # on retire les tirets et les blancs insécables
 +        v1 = v1.replace('-', '')
 +        v1 = v1.replace(self.espinsec, '')
 +        v2 = v2.replace('-', '')
 +        v2 = v2.replace(self.espinsec, '')
 +
 +        # on fait la comparaison selon la locale
 +        locale.setlocale(locale.LC_ALL, '')
 +        comp = locale.strcoll(v1, v2)
 +
 +        # retour à la locale initiale
 +        locale.setlocale(locale.LC_ALL, self.loc)
 +
 +        # on retourne le résultat de la comparaison
 +        return comp
 +
 +compdicofr = Compdicofr()
 +</code>
  
 \\ \\
-Prenons maintenant un exemple: on crée une base sqlite3 contenant une table "test" avec un champ "nom" contenant dans l'ordre d'introduction:+Prenons maintenant un exemple: on crée une base sqlite3 contenant une table "test" avec un champ "mots" contenant dans l'ordre d'introduction:
  
 <code> <code>
Ligne 66: Ligne 62:
 Xabcù Xabcù
 Abcè Abcè
 +êqsdf
 </code> </code>
  
Ligne 71: Ligne 68:
  
 <code python> <code python>
-cur.execute("SELECT nom FROM test ORDER BY nom")+cur.execute(""" 
 +    SELECT 
 +    FROM test  
 +    ORDER BY mot 
 +    """)
 datas = cur.fetchall() datas = cur.fetchall()
  
Ligne 85: Ligne 86:
 abcé abcé
 xabc xabc
 +êqsdf
 </code> </code>
  
-Vous constatez que ce n'est pas terrible: le 'a' est bien ici après le 'X'...+Vous constatez que ce n'est pas terrible: le 'a' est après le 'X' et le 'é' est après le 'x'...
  
 \\ \\
Ligne 93: Ligne 95:
  
 <code python> <code python>
-cnx.create_collation("compalpha", compalpha)+cnx.create_collation("compdicofr", compdicofr)
  
-cur.execute("SELECT nom FROM test ORDER BY nom COLLATE compalpha")+cur.execute(""" 
 +    SELECT 
 +    FROM test  
 +    ORDER BY mot COLLATE compdicofr 
 +    """)
 datas = cur.fetchall() datas = cur.fetchall()
  
Ligne 108: Ligne 114:
 abcé abcé
 Abcè Abcè
 +êqsdf
 xabc xabc
 Xabcù Xabcù
collate_sqlite3.txt · Dernière modification: 2015/03/03 17:55 de tyrtamos