PROJET AUTOBLOG


Sam & Max: Python, Django, Git et du cul

Site original : Sam & Max: Python, Django, Git et du cul

⇐ retour index

Mise à jour

Mise à jour de la base de données, veuillez patienter...

On a un nouveau projet et on a besoin d’UNE info sur vous

mercredi 17 juillet 2013 à 09:48

On bosse sur un projet (on en parlera à la sortie, si sortie il y a) WebRTC, qui est une techno très peu stable et pas finie.

Problème, le data channel actuellement marche entre Firefox, et entre Chrome, mais pas entre Firefox et Chrome. Safari, IE, Opera et autre ne marchent juste pas.

Histoire de simplifier les choses, on va le lancer pour un seul navigateur et prétendre que ça ne marche pas sur l’autre, pour éviter que l’utilisateur se retrouve avec un comportement “on/off” selon la personne qu’il a en face.

On ne va pas se baser sur les stats générales d’utilisation car on est interessé par les lecteurs qui commentent, c’est à dire ceux qui seront les premiers concernés par le projet quand on le sortira.

Donc petit sondage : quel navigateur utilisez-vous le plus toute la journée ?

Un comment, une réponse : soit Firefox, soit Chrome.

Si autre, ce sera pour une prochaine fois ^^ (évidement on va ajouter les autres nav au fur et à mesure)

flattr this!

Sam et Max en quelques chiffres

mercredi 17 juillet 2013 à 07:51

haaaaa les stats, j’adore ça moi, c’est étroitement lié au métier de webmaster ceci dit. Un jour sans regarder les stats c’est comme un jour sans pignole.

Voici Sametmax.com en quelques chiffres pour les curieux:

Date de création: 4 février 2012
Articles: 505
Tags: 748
Commentaires: 6472
Premier inscrit: roro
Premier commentateur: roro le 2012/04/23 at 01:27
Tampons: 208
Spams: 33,249
Visites par mois: 100,862
Vistes depuis la création du blog: 837,446
Moteurs de recherche (par mois): 38,312
Mots clefs: masturbation feminine, fkk, freeplug, sex japon, abreviation escort, git stash, sublime text 2, ubuntu 12.10, node.js …

Les posts les plus vus:

Home page / Archives More stats 201,116
Masturbation féminine – Un peu de théorie en vidéo More stats 95,796
Synchroniser les freeplugs (les adaptateurs réseaux CPL de free) More stats 33,993
Une journée dans un FKK (maison close Allemande) More stats 32,124
Les Japonais et le sexe – des gros malades… Ou pas… More stats 20,968
10 astuces pour Sublime Text 2 More stats 14,013
Les abréviations de la prostitution et des Escorts, vous connaissez ? More stats 13,430
Il ne faut pas prendre des gens pour des cons mais ne jamais oublier qu’ils en sont More stats 12,302

 

Le pognon que ça nous rapporte:

Non contents d’avoir asséché le trafic des autres blogs du net grâce à nos articles sulfureux écrits d’une plume féérique nous avons également pulvérisé tous les records précédents en terme de monétisation.

Depuis que Sam a mis Flattr sur S&M on a récolté 45€. Ce qui paie le serveur (environ 5€/mois en VPS chez leaseweb).

Si vous voulez d’autres chiffres demandez-nous et nous les rajouterons.

Allez voir le premier post par nostalgie ;)

flattr this!

Pouvez-vous séparer le cul de la programmation SVP ?

mardi 16 juillet 2013 à 10:33

Régulièrement, par twitter, mail ou en comment, on reçoit quelque chose qui ressemble à ça :

Bonjour !

En rapport avec votre dernier article et NSFW toussa toussa, je sais que vous êtes contre la création d’une catégorie NSFW mais est-ce qu’il serait possible de ne pas poster du cul dans la catégorie “programmation” – ou plutôt ne pas mettre de flag programmation dans ce genre de cas ? Vous feriez un heureux.

Parce que si l’image gay était marrante, les images en commentaires étaient moyenne et j’aimerais pouvoir continuer à consulter votre blog que j’apprécie depuis mon boulot.

Sinon, merci pour tous vos articles, j’ai appris beaucoup de choses grâce à vous

En espérant que vous me comprendrez.

Les gens sont toujours très polis et respectueux dans leur demande, et on l’apprécie beaucoup. En fait, même quand l’AFPY nous a annoncé qu’ils nous viraient, ils l’ont fait dans le respect. C’est comme ça que les choses doivent se faire.

Et c’est donc comme ça que je vais essayer de répondre.

Non

Nous mélangeons le cul et la programmation parce que cela nous amuse. Nous écrivons ce blog pour le plaisir. Devoir réfléchir à ce qu’on y met, comment on l’y met, et aller à l’encontre de notre spontanéité pour des raisons autres que pédagogiques irait à l’encontre de cela.

Comprenez bien, tous les jours nous vivons l’intolérance de personnes qui voient le sexe comme quelque chose de mal, à cacher, mais qui par contre n’ont rien contre la violence.

Personnellement (je pense que Max s’en branle un peu plus que moi), j’utilise le blog comme moyen de faire passer ce message : on peut mélanger la double pénétration et la compétence technique, l’osé et le casual, l’arrache et le recherché.

Si vous ne pouvez pas consulter ce blog au travail, le problème ne vient pas du blog.

Il vient de votre lieu de travail.

Le blog lui, est ce qui l’est, avec sa formule annoncée dès le départ.

Vous ne pouvez pas consulter ce blog à cause de cela ? Ce n’est pas grave, ne consultez pas le blog. Il n’y a pas mort d’homme. Internet est grand, le monde aussi. Il y a de la place pour tout, des ressources en masse et des domaines qui conviendrons mieux à vos contraintes.

Personnellement si je travaillais dans un lieu qui m’empêchait d’accéder à des contenus que je considère utile, je changerais de travail.

Sans rancune. Sans jugement. Simplement parce que cela fait partie des choses qui sont importantes pour moi.

Si vous ne voulez pas faire cela, alors c’est que ce travail vous apporte plus que ce que vous retire cette contrainte, et c’est très bien ainsi.

Mais ne nous demandez pas de changer le blog, ça na pas de sens.

Par ailleurs, ce qui me dérange dans ces demandes, c’est que leurs auteurs n’envisagent pas de faire un effort de leur côté, et nous demandent d’en faire un. Le blog est sous Creative Common, quelqu’un pourrait sans problème en faire une version SFW. Il existe un dump du blog, il est donc consultable hors ligne. On peut aussi imaginer que la personne lise uniquement le blog en dehors du bureau. Ou alors qu’elle s’installe un proxy anonymisant. On peut aussi désactiver les images dans un Firefox, pour éviter de se faire griller en Open Space, ou utiliser Lynx. On peut aussi en parler à ses collègues et ses boss, et régler le problème avec le dialogue. Bref, il y a des tas de solutions à ce problème, et étant donné que nous fournissons un travail colossal avec ce blog (on en est à 500 articles, mine de rien, ça fait presque deux bouquins, en moins de 2 ans), je crois qu’il est important que vous vous responsabilisiez un peu.

Oh, et non, je ne pense pas aux enfants. Les enfants ne sont pas traumatisés par la pornographie, les enfants sont traumatisés par les adultes qui sont gênés en parlant de sexe et qui ne sont pas capables de remettre les choses dans leur contexte.

Ceci n’est pas un article destiné à être vindicatif ou moraliste. Je comprends parfaitement la position des personnes qui nous font ces demandes. Comprenez vous aussi, que c’est non.

flattr this!

plist, pickle, hdf5, protocol buffers… : les formats binaires

lundi 15 juillet 2013 à 21:24

Dans un article précédent, on avait fait un petit tour des formats texte, et j’avais promis qu’on verrait les formats binaires.

Contrairement à cette fois là, je vais faire un peu plus technique, et donc il est probable que ça ne parle pas aux non informaticiens.

Avant toute chose, il faut faire un peu de ménage. En effet, tous les formats de données sont des formats binaires, même les formats texte. Quand bien même on retire les formats texte par convention, tout le reste sont des formats binaires.

tar.gz, zip, 7zip, rar, iso, dmg et compagnie sont des formats binaires. Il servent à l’archivage.

doc, xls, ppt, pps, etc. sont des formats binaires. Ils servent à sauvegarder un document édité sous une suite Microsoft Office.

jpg, tiff, png, gif ou webp sont des formats binaires. Ils servent à représenter des images.

wav, mp3, ogg, acc, opus et monkey sont des formats binaires. Ils servent à stocker des données sonores.

mkv, avi, mov, mp4, ogm, webm… sont des formats binaires. Ils servent à contenir des informations vidéos.

Bref, tout fichier est un format binaire, toute donnée transmise d’un système informatique à un autre est un format binaire.

Alors qu’est-ce qu’on entend ici par “format binaire” ?

Principalement, format de sérialisation binaire.

En effet JSON, XML ou CSV sont avant tout, bien que pas uniquement, des formats de sérialisation, et nous allons donc voir des équivalents dans le monde du binaire. Attention cependant, il existe de centaines de formats, et beaucoup sont très utilisés même si je n’en ai jamais entendu parler. Les formats de sérialisation binaires sont en effet moins universels, c’est à dire qu’on les retrouve plus souvent liés à un usage ou un corps de métier. Les scientifiques ont les leurs, les industriels les leurs, les concepteurs d’OS les leurs, les constructeur de matériel les leurs, etc. Le fait que je ne les connaisse pas ne veut pas du tout dire qu’ils ne sont pas massivement utilisés. Cela veut juste dire que je ne les ai jamais croisés dans mon activité.

Par ailleurs je ne présenterai pas tous ceux que j’ai effectivement croisés. Voyez l’article comme une base de travail qui va vous permettre d’évaluer les autres formats binaires plutôt qu’un listing exhaustif.

En théorie, on distingue des données binaires, et des données encodées en binaire. En pratique, on s’en branle.

Séria-quoi ?

A la conception d’un programme se pose la question de savoir comment stocker ses données dans un fichier ou les transmettre par le réseau. Vous avez vos données sous forme de code, par exemple en Python une collections d’instances de vos propres classes, des dictionnaires, des listes, des entiers, des chaînes, etc. Ces objets, il va falloir les transformer en quelque chose qui puisse sauvegardé dans un fichier. Ou envoyé sur le réseau.

Cette opération de transformation, c’est ce qu’on appelle la sérialisation.

Quand on lit le fichier ou que l’on récupère la donnée via un réseau, on doit la transformer pour obtenir des objets manipulables sous forme de code : les collections d’instances de vos propres classes, des dictionnaires, des listes, des entiers, des chaînes qui étaient là à l’origine.

Cette opération de transformation, c’est ce qu’on appelle la dé-sérialisation.

Prenons un exemple en Python. J’ai une classe Personne() :

>>> class Personne(object):
...    def __init__(nom, age):
...         self.nom = nom
...         self.age = age

Et j’ai un calendrier qui liste les personnes présentes selon les jours de la semaine :

>>> gertrude = Personne("Gertrude", 18)
>>> monique = Personne("Monique", 12)
>>> jenifer = Personne("Jenifer", 97)
>>> cal = {
"lundi": [gertrude],
"mardi": [gertrude, monique],
"mercredi": [],
"jeudi": [monique],
"vendredi": [gertrude, jenifer],
"samedi": [gertrude, monique, jenifer],
"dimanche": [gertrude]
}

On a donc un format riche ici, avec plusieurs types imbriqués : du dico, de la liste, de l’instance de classe perso, de l’entier et des strings. On a donc des primitives, des données associatives, des séquences ordonnées et un structure complexe.

Pour sauvegarder ça dans un fichier ou le faire passer sur un réseau, il va falloir écrire un sacré bout de code. Par exemple si vous voulez le transformer en XML ou en JSON, il n’y a pas de type “Personne” dans ces formats. Il va donc falloir vous mettre d’accord sur une convention, écrire le code qui génère les données formatées selon cette convention, et également le code qui permet de lire ces données formatées et recréer les bons objets derrière. Sans parler du fait que la techno qui écrit ne va peut être pas être celle qui lit. C’est ça, la problématique de la sérialisation.

Les formats binaires se prêtent bien au jeu de la sérialisation, bien qu’ils puissent, eux aussi, servir à bien d’autre chose. Il sont compacts, et non limités par un besoin de lisibilité, ils contiennent souvent des moyens de contenir des données au format complexe. Ils sont aussi en général rapides à traiter, et prennent peu de place.

Pickle

Pickle est un format de sérialisation spécialisé pour Python. Seul un programme Python peut écrire et lire du Pickle, même si des projets existent pour faire le pont avec d’autres langages.

Voilà ce que ça donne à l’usage, en reprenant notre calendrier précédent :

>>> import pickle
>>> pickle.dumps(cal)
"(dp0\nVmardi\np1\n(lp2\nccopy_reg\n_reconstructor\np3\n(c__main__\nPersonne\np4\nc__builtin__\nobject\np5\nNtp6\nRp7\n(dp8\nS'nom'\np9\nVGertrude\np10\nsS'age'\np11\nI18\nsbag3\n(g4\ng5\nNtp12\nRp13\n(dp14\ng9\nVMonique\np15\nsg11\nI12\nsbasVsamedi\np16\n(lp17\ng7\nag13\nag3\n(g4\ng5\nNtp18\nRp19\n(dp20\ng9\nVJenifer\np21\nsg11\nI97\nsbasVvendredi\np22\n(lp23\ng7\nag19\nasVjeudi\np24\n(lp25\ng13\nasVlundi\np26\n(lp27\ng7\nasVdimanche\np28\n(lp29\ng7\nasVmercredi\np30\n(lp31\ns."

Ce blougi blouga est une représentation sérialisée de notre calendrier. Si vous le sauvegardez dans un fichier ou que vous l’envoyez à un autre programme Python, il peut récupérer les objets initiaux :

>>> cal2 = pickle.loads("(dp0\nVmardi\np1\n(lp2\nccopy_reg\n_reconstructor\np3\n(c__main__\nPersonne\np4\nc__builtin__\nobject\np5\nNtp6\nRp7\n(dp8\nS'nom'\np9\nVGertrude\np10\nsS'age'\np11\nI18\nsbag3\n(g4\ng5\nNtp12\nRp13\n(dp14\ng9\nVMonique\np15\nsg11\nI12\nsbasVsamedi\np16\n(lp17\ng7\nag13\nag3\n(g4\ng5\nNtp18\nRp19\n(dp20\ng9\nVJenifer\np21\nsg11\nI97\nsbasVvendredi\np22\n(lp23\ng7\nag19\nasVjeudi\np24\n(lp25\ng13\nasVlundi\np26\n(lp27\ng7\nasVdimanche\np28\n(lp29\ng7\nasVmercredi\np30\n(lp31\ns.")
>>> type(cal2)
<type 'dict'>
>>> for jour, personnes in cal2.items():
...     print(jour)
...     for personne in personnes:
...         print("\t- {}".format(personne.nom))
...
mardi
    - Gertrude
    - Monique
samedi
    - Gertrude
    - Monique
    - Jenifer
vendredi
    - Gertrude
    - Jenifer
jeudi
    - Monique
lundi
    - Gertrude
dimanche
    - Gertrude
mercredi

On utilisera Pickle essentiellement par fainéantise, quand on veut sauvegarder des objets Python et qu’on souhaite les récupérer plus tard, mais qu’on ne veut pas coder un code de sérialisation. Il existe des formes hybrides de cette approche, comme cette lib qui essaye de mélanger JSON et une forme de sérialisation d’objets complexes.

Quel que soit l’approche choisit, restaurer des objets complets, et non juste des primitives, comporte sont lot de risques de sécurité. En effet, un fichier Pickle malicieux sera exécuté comme code Python valide sans aucune vérification.

A noter que Python vient avec un autre format de sérialisation : marshall. Il est utilisé par Python en interne pour les fichiers .pyc et n’est pas recommandé pour un usage de persistance de données car le format évolue avec les versions de Python.

plist

Il existe de nombreux formats binaires qu’utilisent les OS comme .DS_store ou Thumbs.db. plist est l’un deux, et on va le voir parce qu’il est relativement simple à comprendre par rapport aux autres. Le principe est le même pour tous : on a des données, on les stock dans le fichier.

plist est un format qui existe aujourd’hui en XML, preuve que le même rôle peut très bien être rempli par deux formats différents. Il sert à stocker les réglages qu’on effectue dans le finder de Mac OS X, et ceux pour chaque dossier. Il sait représenter les types suivant : string, nombre, boolean, date, array, dictionnaire et des données arbitraires en base64 (un encodage binaire représentable sous forme de texte. Qu’est-ce qu’on se marre ^^).

Ce qui signifie par exemple, qu’il n’est pas capable de représenter un objet Personne() tel quel. Par contre il a des équivalents des types list, int, str, etc, ce qui en fait un format facile à manipuler en Python, surtout étant donné que la lib standard contient un module pour ça :

gertrude = ("Gertrude", 18)
monique = ("Monique", 12)
jenifer = ("Jenifer", 97)
cal = {
"lundi": [gertrude],
"mardi": [gertrude, monique],
"mercredi": [],
"jeudi": [monique],
"vendredi": [gertrude, jenifer],
"samedi": [gertrude, monique, jenifer],
"dimanche": [gertrude]
}
 
>>> gertrude = ("Gertrude", 18)
>>> monique = ("Monique", 12)
>>> jenifer = ("Jenifer", 97)
>>> cal = {
... "lundi": [gertrude],
... "mardi": [gertrude, monique],
... "mercredi": [],
... "jeudi": [monique],
... "vendredi": [gertrude, jenifer],
... "samedi": [gertrude, monique, jenifer],
... "dimanche": [gertrude]
... }
>>> plistlib.writePlistToString(cal)
'<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>\n\t<key>dimanche</key>\n\t<array>\n\t\t<array>\n\t\t\t<string>Gertrude</string>\n\t\t\t<integer>18</integer>\n\t\t</array>\n\t</array>\n\t<key>jeudi</key>\n\t<array>\n\t\t<array>\n\t\t\t<string>Monique</string>\n\t\t\t<integer>12</integer>\n\t\t</array>\n\t</array>\n\t<key>lundi</key>\n\t<array>\n\t\t<array>\n\t\t\t<string>Gertrude</string>\n\t\t\t<integer>18</integer>\n\t\t</array>\n\t</array>\n\t<key>mardi</key>\n\t<array>\n\t\t<array>\n\t\t\t<string>Gertrude</string>\n\t\t\t<integer>18</integer>\n\t\t</array>\n\t\t<array>\n\t\t\t<string>Monique</string>\n\t\t\t<integer>12</integer>\n\t\t</array>\n\t</array>\n\t<key>mercredi</key>\n\t<array>\n\t</array>\n\t<key>samedi</key>\n\t<array>\n\t\t<array>\n\t\t\t<string>Gertrude</string>\n\t\t\t<integer>18</integer>\n\t\t</array>\n\t\t<array>\n\t\t\t<string>Monique</string>\n\t\t\t<integer>12</integer>\n\t\t</array>\n\t\t<array>\n\t\t\t<string>Jenifer</string>\n\t\t\t<integer>97</integer>\n\t\t</array>\n\t</array>\n\t<key>vendredi</key>\n\t<array>\n\t\t<array>\n\t\t\t<string>Gertrude</string>\n\t\t\t<integer>18</integer>\n\t\t</array>\n\t\t<array>\n\t\t\t<string>Jenifer</string>\n\t\t\t<integer>97</integer>\n\t\t</array>\n\t</array>\n</dict>\n</plist>\n'

Bon, là j’ai un peu foiré mon exemple parce que la lib standard, elle pond la version XML (puisque la version binaire est obsolète), pas la version binaire de plist, et maintenant que j’ai écris tout ça, ça me fait chier de tout refaire. Heureusement j’ai trouvé une lib sur le net qui va sauver mon honneur :

>>> biplist.writePlistToString(cal)
'bplist00bybiplist1.0\x00\xd7\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0ee\x00m\x00a\x00r\x00d\x00if\x00s\x00a\x00m\x00e\x00d\x00ih\x00v\x00e\x00n\x00d\x00r\x00e\x00d\x00ie\x00j\x00e\x00u\x00d\x00ie\x00l\x00u\x00n\x00d\x00ih\x00d\x00i\x00m\x00a\x00n\x00c\x00h\x00eh\x00m\x00e\x00r\x00c\x00r\x00e\x00d\x00i\xa2\x0f\x10\xa2\x11\x12h\x00G\x00e\x00r\x00t\x00r\x00u\x00d\x00e\x10\x12\xa2\x13\x14g\x00M\x00o\x00n\x00i\x00q\x00u\x00e\x10\x0c\xa3\x15\x16\x17\xa2\x11\x12\xa2\x13\x14\xa2\x18\x19g\x00J\x00e\x00n\x00i\x00f\x00e\x00r\x10a\xa2\x1a\x1b\xa2\x11\x12\xa2\x18\x19\xa1\x1c\xa2\x13\x14\xa1\x1d\xa2\x11\x12\xa1\x1e\xa2\x11\x12\xa0\x15$/<MXct\x85\xb2\xd0\xd9\xde\xe3\xe8\x88\x9e\x8b\x9c\xa1\xb0\xb6\xb9\xbc\xbf\xce\xd3\xd6\xdb\xe0\xe5\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9'
>>> biplist.readPlistFromString(r'bplist00bybiplist1.0\x00\xd7\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0ee\x00m\x00a\x00r\x00d\x00if\x00s\x00a\x00m\x00e\x00d\x00ih\x00v\x00e\x00n\x00d\x00r\x00e\x00d\x00ie\x00j\x00e\x00u\x00d\x00ie\x00l\x00u\x00n\x00d\x00ih\x00d\x00i\x00m\x00a\x00n\x00c\x00h\x00eh\x00m\x00e\x00r\x00c\x00r\x00e\x00d\x00i\xa2\x0f\x10\xa2\x11\x12h\x00G\x00e\x00r\x00t\x00r\x00u\x00d\x00e\x10\x12\xa2\x13\x14g\x00M\x00o\x00n\x00i\x00q\x00u\x00e\x10\x0c\xa3\x15\x16\x17\xa2\x11\x12\xa2\x13\x14\xa2\x18\x19g\x00J\x00e\x00n\x00i\x00f\x00e\x00r\x10a\xa2\x1a\x1b\xa2\x11\x12\xa2\x18\x19\xa1\x1c\xa2\x13\x14\xa1\x1d\xa2\x11\x12\xa1\x1e\xa2\x11\x12\xa0\x15$/<MXct\x85\xb2\xd0\xd9\xde\xe3\xe8\x88\x9e\x8b\x9c\xa1\xb0\xb6\xb9\xbc\xbf\xce\xd3\xd6\xdb\xe0\xe5\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9')
{u'mardi': [('Gertrude', 18), ('Monique', 12)], 'samedi': [('Gertrude', 18), ('Monique', 12), ('Jenifer', 97)], 'vendredi': [('Gertrude', 18), ('Jenifer', 97)], 'jeudi': [('Monique', 12)], 'lundi': [('Gertrude', 18)], 'dimanche': [('Gertrude', 18)], 'mercredi': []}

Pourquoi utiliser plist ? A part quand on est en Objectif-C où c’est le format le plus simple à parser ou si on veut communiquer avec finder, il n’y a pas vraiment de raison. C’est le cas typique d’un format qui a été créé parce qu’à l’époque il n’y avait rien d’aussi bien, les parsers XML étaient alors trop lents pour scanner toutes les plist de tous les dossiers récursivement.

hdf5

hdf5 est très intéressant, c’est le cas typique d’un format qui existe pour un usage très très particulier, et que des formats ordinaires ne comblent pas, ne peuvent pas par nature combler. C’est un format cross-plateforme qui peut contenir de très grosses quantités de données numériques (un fichier peut avoir une taille virtuellement illimitée), et les manipuler pour faire des calculs complexes. Cela ressemble à un système de fichiers… qui tient dans un fichier. En effet, il peut contenir une arborescence de données, et gère la compression transparente, mais les données sont essentiellement des arrays à plusieurs dimensions, appelés ici datasets.

On peut y mettre des arrays, des labels, des attributs, organiser tout ça par groupe et même avoir des références vers des données extérieures. L’avantage c’est qu’on peut bosser dessus presque de manière transparente, comme si c’était en RAM. Tout ce qui est array est stocké tel quel, et donc très rapide d’accès (bien plus qu’une colonne de base SQL), pour le reste, c’est indexé avec arbre binaire, donc facilement triable.

Pour manipuler ce format avec Python, on va utiliser la lib h5py :

sudo apt-get install libhdf5-serial-dev python-dev # sur ubuntu en tout cas
pip install numpy
pip install h5py

La normalement, ça compile à mort pendant 10 minutes.

Et pif paf pouf :

>>> import numpy # hdf5 s’utilise beaucoup avec les libs scientifiques type numpy
>>> import h5py
>>> array = numpy.ones((1000000000, 1000000000)) # une grosse matrice
>>> f = h5py.File(‘data.hdf5′)
>>> dset = f.create_dataset(“Nom du dataset”, data=array)
>>> dset

>>> f.close()

Et voilà, on vient de créer array contenant 1000000000 lignes de 1000000000 de 1000000000 de int ayant pour valeur “1″, et stocké tout ça dans un fichier au format hdf5. Ca prend quelques secondes, et le fichier fait quand même 800 Mo !

On le voit ici, hdf5 est entre le format de sérialisation et la base de données, et il est très orienté chiffre. Il existe tout un tas de formats binaires spécialisés pour un usage en particulier comme hdf5, à votre charge, donc, de chercher si il en existe un pour le votre. Ou même si vous en avez besoin d’un.

Des libs de haut niveau ont été construite en utilisant hdf5, telles que pytables, qui permettent de traiter très facilement d’énormes jeux de données tabulaires.

Protocol Buffers

Aussi appelé protobuf par ses amis, c’est un format de sérialisation inventé par Google qu’il utilise pour communiquer entre ses machines. On a donc vu un format de sérialisation orienté persistance avec Pickle, un orienté configuration, un orienté “grosse quantité de données” et voilà un dernier orienté communication réseau.

Protocol Buffers est un espèce d’hybride, puisqu’il utilise une description du schéma pour générer du code qui va sérialiser les donner en binaire. Vous suivez ? Non ?

Attendez ça va devenir plus clair.

Reprenons notre bonne vielle personne. Pour utiliser protobuf, vous allez décrire à quoi ressemble votre personne, dans un format texte spécialement conçu :

message Personne {
  required string nom = 1;
  required int32 age = 2;
}

Vous constatez qu’on décrit ici un message, qui va devoir contenir au minimum un nom et un age, de type string et entier. Les chiffres représentent des identifiants uniques de champs qui seront utilisés dans le message binaire.

Ceci n’est pas du code d’un langage particulier, c’est la syntaxe de modèle de protobuf.

On sauvegarde tout ça dans un fichier personne.proto, et on utilise la commande protoc pour transformer cette description en code dans le langage de son choix. C++ et Java sont supportés, nous on va utiliser Python :

protoc personne.proto --python_out=.

Et il va nous pondre un fichier personne_pb2.py, qui est un module Python valide qui va contenir une classe Personne :

>>> from personne_pb2 import Personne
>>> p = Personne(nom="Gertrude", age=12)
>>> p.SerializeToString()
'\n\x08Gertrude\x10\x0c'

Il vous suffit d’envoyer ça par un socket, et de l’autre côté, une machine qui possède le même fichier .proto peut le lire et récupérer la donnée sous forme d’un objet Python, Java ou C++. Il a donc l’avantage d’un pickle, multi langages.

Parmi les bénéfices de protobuf, il y a que sa sortie est assez courte :

>>> json.dumps({"nom":"Gertrude", "age":12})
'{"nom": "Gertrude", "age": 12}'
>>> pickle.dumps({"nom":"Gertrude", "age":12})
'(dp0\nVnom\np1\nVGertrude\np2\nsVage\np3\nI12\ns.'

Ca fait moins de données à envoyer par le réseau.

Et en prime on a la validation des données :

>>> p.age = "12"
Traceback (most recent call last):
  File "<ipython-input-4-d897accc3848>", line 1, in <module>
    p.age = "12"
  File "/usr/lib/python2.7/dist-packages/google/protobuf/internal/python_message.py", line 435, in setter
    type_checker.CheckValue(new_value)
  File "/usr/lib/python2.7/dist-packages/google/protobuf/internal/type_checkers.py", line 104, in CheckValue
    raise TypeError(message)
TypeError: u'12' has type <type 'unicode'>, but expected one of: (<type 'int'>, <type 'long'>)

Du coup on peut utiliser protobuf en lieu et place d’un XML + DTD, en tout cas pour les cas simples.

Normalement, c’est aussi un format très rapide à parser.

Bref, Google a voulu le format pour les utilisations industrielles : c’est un peu chiant à mettre en place, mais c’est performant, robuste et ça marche avec les 3 langages qu’ils utilisent en interne.

Néanmoins ce n’est pas le seul à avoir pensé à ça : msgpack est une sorte de JSON binaire plus rapide à parser et qui prend moins de place. Il est assez utilisé avec les outils de file d’attente genre celery ou de communication type ZeroMq. Mais il perd un intérêt fort du JSON : sa transparence pour javascript, et n’a pas la vérification des données comme protobuf. BSON existe aussi dans le même genre, et sert de format de stockage pour mongodb, en supportant nativement des types avancées comme les dates.

Comme je vous le disais, des formats binaire, il y en a une bonne chiée.

La prochaine et dernière session, on se fera un petit tour des bases de données SQL et NoSQL.

flattr this!

Ca y est on est célèbres

dimanche 14 juillet 2013 à 20:18

Après l’apfy et reddit qui nous ont retiré de leur flux, et django-fr qui a refusé de nous y mettre du fait de nos articles NSFW, voici le grand Norton himself qui nous qui nous donne le traitement VIP.

Merci au lecteur qui nous a envoyé ça par email :

Capture d'écran du blocage de sam et max par Norton

Achievement unlocked

Heureusement, WOT nous aime toujours. Et puis, who wants MORE Norton ?

Évidement il me faut conclure sur un visuel qui convient au thème, et il m’est venu à l’esprit que vous avions négligé notre lectorat gay pendant trop longtemps.

Photo d'une partouze gay

C'est un peu un croisement entre une pub jean-paul gauthier et une station de métro du marais

flattr this!

Error happened! 0 - count(): Argument #1 ($value) must be of type Countable|array, null given In: /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php:428 http://ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/?144 #0 /var/www/ecirtam.net/autoblogs/autoblogs/autoblog.php(999): VroumVroum_Blog->update() #1 /var/www/ecirtam.net/autoblogs/autoblogs/sametmaxcom_a844ada43a979e3b1395ab9acb6afafb84340999/index.php(1): require_once('...') #2 {main}