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.