Dictionnaires par clés et valeurs
Représentation des données: types construitsPlan
Introduction
Concrêtement
produit={ 'ordinateur' : 1000 , 'imprimante': 250 , 'bureau':300 } print(produit['imprimante']) #affiche 250 del produit['ordinateur'] produit['chaise']= 180 print(produit) #affiche {'imprimante': 250, 'bureau': 300, 'chaise': 180} print('imprimante' in produit) # affiche True
dico=dict( [('ordinateur',1000), ('souris',50)]) print(dico) #affiche {'ordinateur':1000, 'souris':50} dico2={x: x**2 for x in (2, 4, 6)} print(dico2) #affiche {2: 4, 4: 16, 6: 36} dico3=dict('ordinateur'=1000, 'souris'=50) #ne fonctionne que si la clé est une chaine de caractères print(dico3) # affiche {'ordinateur': 1000, 'souris': 50} print(dico3["ordinateur"]) # affiche 1000
prenom=['johan','nathan','didier'] infos=[['1978-02-20',175],['1990-10-02',180],['1966-12-30',161]] monDico= dict(zip(prenom,infos)) print(monDico) #affiche {'johan': ['1978-02-20', 175], 'nathan': ['1990-10-02', 180], 'didier': ['1966-12-30', 161]}
Pour ajouter un élément il suffit de taper, pour un dico existant, dico[nouvelle clé]=valeur associée! Pour effacer on utilise del dico[clé]. La fonction pop supprime ET renvoie la valeur associée à la clé.
monDico["Laura"]=['1978-02-20',175] del monDico["nathan"] print(monDico) #pour vérifier si une clé existe: booleen="didier" in monDico print("didier fait parti du dico ?",booleen)
Boucles sur dictionnaires
produit={ 'ordinateur' : 1000 , 'imprimante': 250 , 'bureau':300 } for prod, prix in produit.items(): #ou iteritems selon versions python print( prod, prix) for prod in produit.keys(): print(prod) for prix in produit.values(): print(prix)
Un exemple: les données EXIF
Lorsqu'un appareil photo numérique sauvegarde une photo, il enregistre l'image mais aussi tout un tas d'autres informations: marque de l'appareil, date,...et même les coordonnées gps si l'appareil sait se situer! Ces données sont nommées EXIF(Exchangeable Image File).
Dans Windows, un clic droit sur l'image et l'onglet détails donne les informations exif.
En python, la bibliothèque PIL contient les modules Image et ExifTags qui permettent d'acceder rapidement aux tags. Voici le code Python3 ci-dessous. Pour que cela fonctionne il faut installer PIL en le téléchargeant.
Pour installer des bibliothèques non présententes dans Python, vous devez ouvrir lignes de commandes (pour windows) puis taper: pip install leNomDeLabBibliothèque. Il arrive que certaines bibliothèques nécessitent d'être téléchargées avant de faire le pip install
Comme nous n'avons pas accès à ligne de commandes en classe, nous devons abandonner idle. Nous allons utiliser Jupyter qui permet de faire du Python dans un navigateur et lorsqu'il est installé sur les postes, on peut utiliser et installer des bibliothèques directement dans l'éditeur.
Quelques remarques sur l'utilisation de Jupyter. Vous devez passer par anaconda pour accéder à Jupyter:
- Lancer Jupyter
- S'il ne s'ouvre pas dans firefox (ce qui est le cas pour l'instant chez nous), copiez le lien proposé dans une fenêtre firefox. En haut à droite, cliquez sur new et choisissez Python3. Vous êtes alors dans une page notebooks Jupyter.
- Vous pouvez aussi chez vous utiliser Jupyter directement en ligne sans installation préalable mais certaines bibliothèques (webbrowser par exemple) ne fonctionneront pas correctement.
Contrairement à l'idle, vous ne sauvegardez pas un programme mais une page qui contient des entrées. Chaque entrée est un bout de code, ou un programme. Vous pouvez modifier et relancer une entrée plutôt que de retaper tout le code. Vous avez toujours sous les yeux les rendus de vos programmes.
Téléchargez la photo. puis cliquer dans jupyter home et upload pour la mettre dans votre espace de travail de jupyter. Par défaut vous retrouvez vos fichiers dans votre pc dans votre compte utilisateur.
from PIL import Image, ExifTags #premier code d'extraction de exif def get_exif1(image): ret = {} img = Image.open(image) info = img._getexif() for tag, value in info.items(): decoded = ExifTags.TAGS.get(tag, tag) if tag in ExifTags.TAGS: ret[decoded] = value return ret #deuxième code d'extraction de exif #par compréhension def get_exif2(image): img = Image.open(image) exif_data = img._getexif() exif = { ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS } return(exif) #affichage des données gps def gpsInfo(exifData): gpsinfo = {} for key in exifData['GPSInfo'].keys(): decode = ExifTags.GPSTAGS.get(key,key) gpsinfo[decode] = exifData['GPSInfo'][key] return gpsinfo #conversion degrés,minutes,secondes en DD(degrés décimaux) def convertGpsToDd(deg,minute,sec): return(deg+minute/60+sec/3600) #tests data1 = get_exif1('img2.jpg') print(data1) data2= get_exif2('img2.jpg') print(data2) print("nom de l'appareil:",data2['Make']) print("infos gps: ",data2['GPSInfo']) gps=gpsInfo(data2) for i,j in gps.items(): print(i,j)
La ligne print("infos gps: ",data2['GPSInfo']) donne pour ma photo l'affichage suivant (sinon ma fonction gpsinfo donne les infos plus clairement):
infos gps: {1: 'N', 2: ((43, 1), (36, 1), (10791, 1000)), 3: 'E', 4: ((3, 1), (52, 1), (19506, 1000)), 5: 0, 6: (44000, 1000), 7: ((8, 1), (29, 1), (26, 1)), 29: '2016:05:22'}
Un dicitionnaire qui contient ici 8 clés
Photo prise dans l'hémisphère Nord, la lattitude est (43, 1), (36, 1), (10791, 1000) soit 43 degrés, 36 minutes, 10.791 secondes à l'Est du méridien de Greenwich. La longitude est (3, 1), (52, 1), (19506, 1000) donc 3°52'19.506' et une date et même l'heure 8h29'26 et l'altitude de 44m! Utilisez un site qui permet de se localiser. Où a été prise cette photo?
Voici le code pour afficher la carte et l'endroit où la photo a été prise. Il faudra au préalable installer la bibliothèque folium! On peut faire cela directement dans Jupyter en tapant
pip install folium
import folium import webbrowser x=43+36/60+10.791/3600 y=3+52/60+19.506/3600 print(x,y) carte= folium.Map( location=[x, y], zoom_start=17 ) folium.Marker( location=[x, y], popup='Où est-on?', icon=folium.Icon(color='red') ).add_to(carte) folium.CircleMarker( location=[x, y], radius=400, popup='Le quartier', color='#ff0000', fill=True, fill_color='#ccccccc' ).add_to(carte) carte.save('exempleFolium1.html') webbrowser.open('exempleFolium1.html',new=2)
Voici comment modifier les données exifs. Vous pourrez donc faire croire qu'une photo qui n'est pas de vous a été prise avec votre téléphone à la date de votre choix, ou qu'une image d'un lieu de la région est à un autre endroit! Allez sur la doc de piexif pour plus de détails.
Il faut aussi installer la bibliothèque piexif :
pip install piexif
from PIL import Image import piexif im = Image.open('img2.jpg') exif_dict = piexif.load(im.info["exif"]) print(exif_dict["GPS"]) w, h = im.size exif_dict["0th"][piexif.ImageIFD.YResolution] = (h, 1) exif_dict["GPS"][piexif.GPSIFD.GPSVersionID]= (2,0,0,0) exif_dict["GPS"][piexif.GPSIFD.GPSLatitudeRef] = "S" exif_dict["GPS"][piexif.GPSIFD.GPSAltitude] = (20,1) exif_bytes = piexif.dump(exif_dict) im.save('new_file.jpg', "jpeg", exif=exif_bytes)
Afin de pouvoir réaliser l'exercice 2 je vous donne le code suivant qui permet de lire dans un dossier tous les fichiers qui ont pour extension jpg. Pour cela on utilise la bibliothèque operating system de Python os
#1)recuperation du contenu du dossier c: contenu=os.listdir('c:') #donne le chemin complet de chaques fichiers du dossier, par exemple pour le fichier img2.jpg : 'c:/001.jpg' #2)recuperation des noms de fichiers (sans le chemin) qui sont des .jpg: #méthode par compréhension de liste. # Split de la chaine de caractère sur le symbole / -> cela donne une liste # avec le [-1] on ne garde que le dernier de la liste...donc le nom du fichier # mais uniquement si ce nom contient .jpg contenu=[x.split('/')[-1] for x in contenu if '.jpg' in x.split('/')[-1]] #3)Maintenant on trie la liste
Exercices
- Créer un dictionnaire avec pour clé des prénoms et pour valeur une liste contenant les noms des spécialités de ces élèves. L'initialiser avec 2 élèves. Taper le code pour ajouter un élève. Taper le code pour supprimer le premier élève que vous avez saisi. Modifier ensuite une des trois spécialité et la remplacer par 'abandonnée'. Faites ensuite afficher tout le contenu de ce dictionnaire.
- Créer un dictionnaire qui contient les 10 (de 0 à 9) premiers nombres entiers naturels en nombre pour la clé et en français pour la valeur. Faites en sorte qu'une phrase du type "j'ai 3 pommes" se transforme toute seule en 'j'ai trois pommes'. Penser à la leçon sur chr, ord et le codage ASCII (UTF8 dans les faits). Pour être clair, vous direz: "entrez une phrase avec des nombres entiers sous forme de nombres" et votre programme remplacera les nombres par des chaines de caractères. (on s'arrête à 9, mais on peut réfléchir à plus...)
- Réunir les programmes de la partie exif ci-dessus pour passer directement d'un fichier jpg à sa localisation.
- Réunir les programmes de la partie exif ci-dessus pour afficher toutes les images d'un dossier sur une même carte.
- Prenez une photo dans votre téléphone (ou sur internet) et faites moi croire que la photo date du week-end dernier dans un lieu lointain que vous aurez préalablement choisi. Afficher le résultat avec le travail des exercices précédents.