truc2geek

2012/11/18

Carnet d’Adresses, part 7 : v0_008 (CreaData)

Filed under: Carnet d'adresses (Python), Programmation, Projets, Python, SQLite — Étiquettes : , , , — truc2geek @ 16:48

Avec le dernier article, on a développé une première version fonctionnelle (pour les données « adresse ») de CreaData().
Il est temps de rendre cette fonction plus intelligente et flexible, pour permettre ensuite de créer tous les types de données.
Notez bien que pour cet article encore, on traite uniquement des données de type « adresse ».

code v0_008_01

Voici le code actuel de CreaData() :

La façon figée dont on définit les champs, lignes 274 à 278, est à revoir.

La fonction qui gèrera la modification des données, MajData, devra elle aussi connaître les caractéristiques des champs de chaque type de donnée.
Il faut donc créer une fonction séparée qui contiendra la définition de chaque type de donnée, et qui sera appelée partout où nécessaire.

 créer fonction DefData

Créons la fonction DefData(), par exemple juste après la fonction InfoData().

Cette fonction donne 5 informations pour chaque champ par type de donnée, sauf pour trois champs :
le champ clé primaire : sa valeur est déterminée automatiquement par SQLite3
les champs « crea » et « maj » : on leur donne pour valeur la date et l’heure courante, grâce à CURRENT_TIMESTAMP

Les 5 informations sont :

  • le nom du champ
  • valeur obligatoire
  • valeur
  • type de valeur
  • valeur par défaut

modifier fonction CreaData

La fonction CreaData doit récupérer la définition de données par DefData, et boucler sur les champs.

Voici le code de la nouvelle version de CreaData :


En résumé, on récupère la définition des champs, on demande à l’utilisateur de renseigner chaque champ, on crée et exécute la requête SQL et enfin, on va au menu principal.

Explications :
1e étape, lignes 311 à 317 :
on récupère la définition de données, les 5 listes sont affectées chacune à une variable

2e étape, lignes 321 à 338 :
si on utilise la fonction « len » sur une chaîne de caractères, elle retourne le nombre de caractères.
ici on l’utilise sur une liste ; elle retourne alors le nombre d’éléments que contient la liste.
la syntaxe « for x in range(y) » permet de boucler et x aura pour valeur de 0 à y-1.
on boucle donc sur les champs, et pour chacun :

  • on récupère dans les listes, la valeur pour ce champ : nom, valeur obligatoire etc.
  • on définit le texte qui sera affiché à l’utilisateur pour la saisie
  • on appelle la fonction Saisie, qui demande à l’utilisateur de saisir une valeur
  • on enregistre la valeur saisie par l’utilisateur

3e étape, lignes 342 à 364 :

Les valeurs renseignées par l’utilisateur sont stockées dans la liste vLChampVal, on va les utiliser pour générer la requête.

Voici un exemple de requête SQL valide pour créer une adresse :
INSERT INTO T_d_Adresse (adresse1, adresse2, adresse3, cp, ville, crea, maj) VALUES (‘6 rue du Pommier’, ‘immeuble B’,  », ‘64000’, ‘PAU’, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)

On peut voir 3 parties dont le contenu variera :

  • le nom de la table dans laquelle on crée l’enregistrement
  • la liste des champs pour lesquels on définit une valeur
  • la liste des valeurs

La fonction InfoData nous permet d’obtenir le nom de la table.

Le nom des champs est contenu dans la liste vLChampNom : il suffit de les concaténer, en insérant une virgule et un espace entre chaque.
On ajoute à la fin, les champs « crea » et « maj », et on entoure le tout de parenthèses.

Pour la 3e partie, on concatène les valeurs saisies par l’utilisateur et contenues dans la liste vLChampVal.
La valeur d’un champ texte doit être entourée de guillemets simples.
Ce n’est pas le cas de la valeur d’un champ numérique, et on verra plus tard pour les dates.
Là aussi on insère une virgule et un espace entre les valeurs et on entoure le tout de parenthèses.
ligne 364, on concatène ces 3 éléments pour former la requête SQL à exécuter.

4e étape, lignes 370 à 375 :
on se connecte à la BD SQLite, on exécute la requête et on fait un commit pour valider, on se déconnecte.

enfin, ligne 377, on va au menu principal.

Vous pouvez télécharger ici le code de cette version, qu’on appellera CarnetAdresse_v0_008_01.py

on teste

1er test, sans caractères spéciaux :

on lance l’application, on entre « 1 » puis « 3 » pour afficher le menu de gestion des adresses.

« 1 » pour créer une adresse

on renseigne les différents champs comme ci-dessous :

dès qu’on valide la saisie de la valeur pour le dernier champ, on est redirigé vers le menu principal :

On retourne au menu de gestion des adresses, pour vérifier que la création a bien été prise en compte.
On constate avec bonheur que l’adresse saisie a bien été enregistrée :

Ce test est ok.

2e test, avec des caractères spéciaux :

on valide le dernier champ : on est bien redirigé vers le menu principal.

on retourne au menu de gestion des adresses, pour vérifier :

l’application plante.

code v0_008_02

pour localiser le bug, on place quelques instructions raw_input dans le début du code de la fonction GererData :


on lance cette version v0_008_02 :

« 1 » puis « 3 » pour afficher le menu de gestion des adresses :

on tape « entrée », le code continue et stoppe à l’instruction raw-input suivante :

tout se passe bien jusqu’à l’affichage de l’adresse sans accent :

et l’application plante juste après.

On lance SQLite Expert pour voir le contenu de la table T_d_Adresse :

On va modifier le dernier enregistrement à la main :
cela permettra de savoir à quel moment l’appli doit être corrigée : au moment où elle enregistre les données dans la BD SQLite, ou au moment où elle les lit dans la BD et les affiche dans la console.

On teste :

Cette fois tout se passe bien : il faut donc corriger la manière dont les données saisies sont enregistrées dans la BD.

Par contre on a affiché uniquement le code postal et la ville, pas l’adresse : on va changer ça pour commencer.
Voici l’extrait du code de la fonction GererData à modifier ; on voit bien que le même champ est affiché deux fois :

La requête SQL source est définie dans la fonction InfoData, telle que ci-dessous :

Donc dans GererData, pour les adresses, row[0] correspond au champ « id_adresse », row[1] le « cp », row[2] la « ville » et row[3] « adresse1 ».

Ci-dessous, la modification apportée, pour que le champ « adresse1 » soit affiché :

on teste :

Pas de plantage, toutes les données sont bien affichées y compris le dernier enregistrement, sauf qu’il est mal affiché.

TestEncodage, 1e version

Une recherche sur Google avec les mots-clés « python connaître encodage console » nous donne des liens intéressants, par exemple :

On va créer une fonction TestEncodage, qu’on appellera au lancement de l’application :

le code de la fonction TestEncodage :

l’appel au lancement :

le résultat quand on lance l’appli :

Dans GererData, l’encodage spécifié pour afficher les données est cp1252 ; à corriger.
Mais plutôt que de le corriger en dur, et puisqu’on peut connaître dynamiquement l’encodage utilisé, on va stocker l’encodage dans une variable globale qu’on utilisera ensuite pour afficher les données.

TestEncodage, 2e version

Tout d’abord, on déclara la variable vgEncodage en tant que variable globale :

Au passage, on va ajouter le ‘g’ au nom de la variable ‘vChemBase’, pour que ce soit explicite.
On le corrige ici et partout dans le code où elle est utilisée, c’est-à-dire dans les fonctions Connect et TestDb :

On reprend où on en était : utiliser une variable globale vgEncodage :

Le test a montré que l’encodage en entrée est le même que celui en sortie, on va pour l’instant considérer que ce sera toujours
le cas, quitte à corriger ensuite si nécessaire.

La 2e version de la fonction TestEncodage est donc :

On modifie la fonction GererData :

Test :

Oh Yeah! Le dernier enregistrement est affiché correctement.

corriger l’enregistrement des données

On va convertir le plus tôt possible les saisies de l’utilisateur en unicode, donc dans la fonction Saisie :

Test : on crée une nouvelle adresse contenant des caractères spéciaux, puis on affichera le menu de gestion des adresses :

on crée une nouvelle adresse :

on valide, tout se passe bien :

on affiche le menu de gestion des adresses :

Oh yeah! Tout se passe bien!

On renomme cette version v0_008_02.py, on supprime les instructions raw_input() dans la fonction GererData qui ont servi à la corriger.

Au passage, on modifie la fonction Version pour qu’elle remplisse enfin son rôle :

Le code complet de cette version est disponible ici, et la Base de Données est disponible ici.

Fin

Dans cette version on a bien avancé le code de l’appli pour la création de données, bien que seule la création des adresses
soit opérationnelle. On a surtout corrigé le problème de l’encodage.
La prochaine version devrait permettre de créer les données de type « personne » et « groupe ».

Publicités

Laisser un commentaire »

Aucun commentaire pour l’instant.

RSS feed for comments on this post. TrackBack URI

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Propulsé par WordPress.com.

%d blogueurs aiment cette page :