Page 1 sur 2

Question de newbie : structures de données

Posté : dim. 15 mai 2016 11:00
par vague nerd
Bonjour.

J'ai un tableau nommé uid contenant 4 colonnes d'entiers.
Je cherche à écrire une fonction (la plus performante possible) retournant vrais ou faux en fonction du contenu de ces 4 colonnes.
Si le tableau contient un quadruplet correspondant à un des quadruplets attendus, elle doit retourner vrais, faux sinon.

Les quadruplet attendus sont par exemple :
- 1,2,3,4
- 4,5,6,7
- 1,3,4,2
Si uid contient 2,3,4,1, la fonction retoune faux, si uid contient 4,5,6,7, la fonction retourne vrais.

Bien sûr, je veux pouvoir ajouter et retirer des quadruplets "corrects" facilement.
J'imagine donc mettre les quadruplet "corrects" dans un fichier, chargé au début du programme (pas de problème de perf au démarrage du programme, même si ça doit pas prendre 3 plombes).

Quelqu'un peut m'aider (notamment pour parser le fichier et mettre les valeurs dans la bonne structure de données, et pour la boucle de comparaison de l'uid et du contenu de cette structure) ?
Cdt.

Re: Question de newbie

Posté : dim. 15 mai 2016 11:04
par vague nerd
Mon implémentation naïve actuelle :

Code : Tout sélectionner

def check_uid(uid):
        if uid[0]==1 and uid[1]==2 and uid[2]==3 and uid[3]==4:
                return True
        if uid[0]==4 and uid[1]==5 and uid[2]==6 and uid[3]==7:
                return True
        if uid[0]==1 and uid[1]==3 and uid[2]==4 and uid[3]==2:
                return True
        return False
Pour reformuler la question : un tableau de tableaux, c'est la bonne idée ?
Comment je remplis ce tableau à partir d'un fichier ? Comme je boucle dessus ?

Le chargement de la structure peut être relativement lent, mais pas la vérification.

Cdt.

Re: Question de newbie

Posté : dim. 15 mai 2016 12:00
par vague nerd
Ce code semble fonctionner :

Code : Tout sélectionner

def check_uid(uid):
        global uids
        for goodUid in uids:
                if str(uid[0])==goodUid[0] and str(uid[1])==goodUid[1] and str(uid[2])==goodUid[2] and str(uid[3])==goodUid[3]:
                        return True
        return False

def read_uids():
        global uids
        myFile = open("uids.txt", "r")
        content = myFile.read()
        lines = content.split("\n")
        for line in lines:
                uid=line.split(",")
                uids.append(uid)
        myFile.close()


uids = []
read_uids()
print uids
print check_uid([1,2,3,4])
print check_uid([2,3,4,1])
Il retourne :

Code : Tout sélectionner

[['1', '2', '3', '4'], ['4', '5', '6', '7'], ['1', '3', '4', '2'], ['']]
True
False
Mais eux choses me gênent :
-Pourquoi le tableau uids contient un 4eme tableau vide (le fichier uids.txt ne contient pas de dernier '\n') ?
-La fonction check_uid() fait 4 conversions en chaine de caractère, alors qu'elle est censée être rapide. Comment créer le tableau uids pour qu'il contient des tableaux d'entiers et non de chaines ?

Les questions de mes posts précédent restent d'actualité...

Cdt.

Re: Question de newbie

Posté : dim. 15 mai 2016 13:59
par Manfraid
Salut,

je te conseille de stocker les données en json, plus pratique pour le lire en plus il existe dans la lib standard pour pouvoir le lire


donc l'idéal c'est une liste de liste (et non pas de tableau comme tu dit car un tableau en python a un nom d'élément)

donc cela ressemblerai à ça et tu peu faire un test direct en python

Code : Tout sélectionner

import json

uids = json.load(open('monfichier.json'))
uid_a_tester = [1,2,3,4]
if uid_a_tester in uids:
    print("ok")
else:
    print("nok")
et dans le fichier 'monfichier.json' il faut simplement mettre dedans

Code : Tout sélectionner

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

Re: Question de newbie

Posté : dim. 15 mai 2016 16:23
par vague nerd
Plus de cast, un algo de recherche optimisé (tout du moins j'espère, puisque fourni par une lib standard) : parfait, merci.

Question subsidiaire.
Je veux associer une chaîne de caractère à chaque quadruplet (pas forcément dans le même fichier), et pouvoir retrouver cette chaîne à partir du quadruplet (comme une Map en java, dont les clés seraient les quadruplets).
Mais là, j'ai pas encore cherché...

Cdt.

Re: Question de newbie

Posté : dim. 15 mai 2016 17:52
par Manfraid
la force de python c'est que les quadruplet peuvent être une clé d'un dictionnaire par contre pour le stockage en fichier c'est plus complexe il faut passez par le module pickle par contre pas d'édition possible par autre chose que python

Re: Question de newbie

Posté : dim. 15 mai 2016 19:34
par Manfraid
une erreur de ma part il faut convertir ta liste en tuple une liste ne peu pas être une étiquette d'un tableau

Re: Question de newbie : structures de données

Posté : lun. 16 mai 2016 16:38
par vague nerd
Impeccable, le code principal avec json marche, je l'ai publié dans ce thread concernant mon rfid-rc522.
Je poursuit avec mon histoire de map...
Merci.
Cdt.

Edit : ps : en plus, je me suis rendu compte d'un bug : je ne traitai que 4 des 5 octets de mon uid !

Re: Question de newbie : structures de données

Posté : lun. 16 mai 2016 17:08
par vague nerd
Je viens de lire que les tuples sont plus rapide à boucler que les listes. Ne devrais-je pas convertir mes listes en tuples ? En d'autre terme, passer de [[1,2,3,4,5],[6,7,8,9]] à ((1,2,3,4,5),(6,7,8,9)) ?
Cela implique de convertir l'uid que j'ai en tableau en tuple à l'aide de la commande tuple(uid) et ajoute donc du temps de traitement (faudrait pas perdre en perf générale pour une soit-disant optimisation !).

De plus, et-ce aussi simple que ça ?
Cdt.

Re: Question de newbie : structures de données

Posté : lun. 16 mai 2016 17:34
par vague nerd
une erreur de ma part il faut convertir ta liste en tuple une liste ne peu pas être une étiquette d'un tableau
Je n'arrive pas à trouver la syntaxe sur le net. Avec :

Code : Tout sélectionner

namedUids = [
		(1,2,3,4,5):'Badge 1',
		(6,7,8,9,10):'Carte 1'
	]
je me fait jetter sur le premier ':'...

Edit : avec des accolades au lieu des crochets, le print namedUids retourne rien...[/strike]

Edit 612 : trouvé.

Code : Tout sélectionner

namedUids = {
	(1,2,3,4,5):'Badge 1',
	(6,7,8,9,10):'Carte 1',
}
print namedUids[(117, 120, 225, 82, 190)]
En fait, c'est une des premières syntaxes que j'ai essayé. Sauf que j'initialisai namedUids dans une fonction, sans avoir l'avoir déclarée 'global'. Et dans le programme, il y avait un namedUids = [] !

Bon, ça marche. Erreur de noob. Merci encore.

Cdt.