614 shaares
Toujours intéressant
"Lavabit's Ladar Levison: 'If You Knew What I Know About Email, You Might Not Use It' " ( http://www.forbes.com/sites/kashmirhill/2013/08/08/email-company-reportedly-used-by-edward-snowden-shuts-down-rather-than-hand-data-over-to-feds/ )
"Lavabit's Ladar Levison: 'If You Knew What I Know About Email, You Might Not Use It' " ( http://www.forbes.com/sites/kashmirhill/2013/08/08/email-company-reportedly-used-by-edward-snowden-shuts-down-rather-than-hand-data-over-to-feds/ )
En direct, journalier et visionnable depuis le monde entier.
À regarder aussi souvent que possible, c'est très souvent remplis de chouettes trucs.
À regarder aussi souvent que possible, c'est très souvent remplis de chouettes trucs.
Quelques trucs avancés Python.
Savoir ça pourrait bien vous sauvez quelques heures de votre vie.
"For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary." → You cannot modify magic method directly from an instance, for instance, doing that wont work:
>>> class C:
... pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()
"In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the __getattribute__() method even of the object’s metaclass:" → When a magic method is used and not called explicitely, then all special methods like __getattribute__ are also bypassed.
For instance:
>>> class Meta(type):
... def __getattribute__(*args):
... print("Metaclass getattribute invoked")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Class getattribute invoked")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10
Savoir ça pourrait bien vous sauvez quelques heures de votre vie.
"For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary." → You cannot modify magic method directly from an instance, for instance, doing that wont work:
>>> class C:
... pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()
"In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the __getattribute__() method even of the object’s metaclass:" → When a magic method is used and not called explicitely, then all special methods like __getattribute__ are also bypassed.
For instance:
>>> class Meta(type):
... def __getattribute__(*args):
... print("Metaclass getattribute invoked")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Class getattribute invoked")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10
Infos intéressantes pour l'utilisation d'sqlite3 avec Python.
Je garde ça sous la main.
EDIT:
" > - Are there any peculiarities with using curs.executemany(...) vs. multiple
> curs.execute(...) ? I read a notice, sqlite3 does internally some caching,
> hence both should be similarly fast, but in my case executemany(...) is
> quite a bit faster
How many times are you calling execute vs a single executemany? The
python call overhead will add up for thousands of calls.
The relevant source code is here if you're interested:
http://svn.python.org/projects/python/trunk/Modules/_sqlite/cursor.c
> Further, I am not quite sure about the standard usage of the cursor object
> and also the proper commiting the transactions and closing the connection.
Standard usage is here:
http://docs.python.org/lib/module-sqlite3.html
If the database supports transactions then cursors automatically use
transactions. Your changes only get committed when you call .commit().
Otherwise your changes are lost.
In the specific case of sqllite, some statements (like CREATE TABLE,
ALTER TABLE, etc) also cause a commit. This is probably where your
confusion comes from. Since this isn't part of the python DB API spec
(http://www.python.org/dev/peps/pep-0249/) I wouldn't rely on it.
Otherwise you will have problems with other databases.
Also, in your specific case you're using an 'in memory' sqllite db. So
there are less concerns with losing data between db sessions, etc. But
with most databases (on disk, running across the network on a server)
this becomes important.
> Should one create a cursor of a connection and call the execute ... methods
> of the cursor -
> or is it better to call the shortcut execute etc. methods of the Connection
> object directly (as suggested in the docs:
> http://docs.python.org/lib/node351.html (or are there specific use cases for
> both approaches)?
I suggest that you use the standard cursor methods instead, so you can
run your code against non-sqllite databases. The performance etc
should be the same as using the direct method. Like the page says,
it's main benefit is consiseness.
>
> When the transactions should be commited? (creating, altering a table, or
> also selecting the results ?)
> There seem to be some implicit handling of the transactions (
> http://docs.python.org/lib/sqlite3-Controlling-Transactions.html#sqlite3-Controlling-Transactions
> ); hence I am not sure about the standard usage of these methods; the same
> is true of connection.close() - or are these calls eventually unnecessary?
As a general rule, always use .commit() and .close(). Otherwise:
- No .commit() - you will lose db changes since the last commit or
"non-DML, non-query statement" (in the case of sqllite)
- No .close() - Your database connection will only close when your db
objects are garbage collected.
> conn_tags_DB = sqlite3.connect(':memory:')
> curs = self.conn_tags_DB.cursor()
> curs.execute('CREATE TABLE IF NOT EXISTS "%s" ("%s", UNIQUE("%s"))' %
> (self.text_name, index_col_name, index_col_name))
> curs.execute(u'INSERT OR REPLACE INTO "%s"("%s") VALUES (?)' %
> (self.text_name, index_col_name), (0,))
> for new_col in act_db_columns[1:]: # adds the needed columns (except of the
> first one: index_col_name)
> curs.execute('ALTER TABLE "%s" ADD "%s" TEXT' % (self.text_name,
> new_col))
> curs.executemany('INSERT OR REPLACE INTO "%s" VALUES (%s)' %
> (self.text_name, question_marks), tags_seq)
> self.conn_tags_DB.commit()
>
> Are there maybe any comments or hints on a more elegant/efficient solution?
>
I think that dynamically creating schema (tables, based on text file
structure is a bad idea. A few reasons:
- This forces you to dynamically generate all your queries dynamically
- Not all strings are valid table/column names
- This forces the app to run as database administrator (maybe not
important for sqllite, but definitely an issue if you change to
another dbm).
- Potentially huge stability/security problems - text files can
potentially break system tables, overwrite users, etc, etc.
You're violating several rules on db design/usage.
I strongly recommend that you use a better database logic. ie, create
tables and records in advance (setup script, as db admin user if
applicable), then only use delete/insert/update/select statements (as
restricted user, if applicable).
If this is too much trouble, then I suggest storing your database in
regular Python structures instead, and use pickle/yaml/etc to write to
disk. Your current version uses a 'in memory' database, so the end
result is the same. You'll get a large performance boost also.
> Now, what's the usual way to access the database? Is it
> possible/wise/standard ... to leave the connection open for the subsequent
> queries during the whole run of the app; could even the cursor eventually be
> present as a class method, or should it rather be created repeatedly with
> each call? (After populating, the db shouldn't be modified, but only read.)
It depends. If your app is simple, single threaded, then a single
connection (global or passed through args) should be fine. Only use
multiple cursors if you need them (multiple threads, multiple
databases, multiple transaction/db isolation levels, etc).
David.
"
Je garde ça sous la main.
EDIT:
" > - Are there any peculiarities with using curs.executemany(...) vs. multiple
> curs.execute(...) ? I read a notice, sqlite3 does internally some caching,
> hence both should be similarly fast, but in my case executemany(...) is
> quite a bit faster
How many times are you calling execute vs a single executemany? The
python call overhead will add up for thousands of calls.
The relevant source code is here if you're interested:
http://svn.python.org/projects/python/trunk/Modules/_sqlite/cursor.c
> Further, I am not quite sure about the standard usage of the cursor object
> and also the proper commiting the transactions and closing the connection.
Standard usage is here:
http://docs.python.org/lib/module-sqlite3.html
If the database supports transactions then cursors automatically use
transactions. Your changes only get committed when you call .commit().
Otherwise your changes are lost.
In the specific case of sqllite, some statements (like CREATE TABLE,
ALTER TABLE, etc) also cause a commit. This is probably where your
confusion comes from. Since this isn't part of the python DB API spec
(http://www.python.org/dev/peps/pep-0249/) I wouldn't rely on it.
Otherwise you will have problems with other databases.
Also, in your specific case you're using an 'in memory' sqllite db. So
there are less concerns with losing data between db sessions, etc. But
with most databases (on disk, running across the network on a server)
this becomes important.
> Should one create a cursor of a connection and call the execute ... methods
> of the cursor -
> or is it better to call the shortcut execute etc. methods of the Connection
> object directly (as suggested in the docs:
> http://docs.python.org/lib/node351.html (or are there specific use cases for
> both approaches)?
I suggest that you use the standard cursor methods instead, so you can
run your code against non-sqllite databases. The performance etc
should be the same as using the direct method. Like the page says,
it's main benefit is consiseness.
>
> When the transactions should be commited? (creating, altering a table, or
> also selecting the results ?)
> There seem to be some implicit handling of the transactions (
> http://docs.python.org/lib/sqlite3-Controlling-Transactions.html#sqlite3-Controlling-Transactions
> ); hence I am not sure about the standard usage of these methods; the same
> is true of connection.close() - or are these calls eventually unnecessary?
As a general rule, always use .commit() and .close(). Otherwise:
- No .commit() - you will lose db changes since the last commit or
"non-DML, non-query statement" (in the case of sqllite)
- No .close() - Your database connection will only close when your db
objects are garbage collected.
> conn_tags_DB = sqlite3.connect(':memory:')
> curs = self.conn_tags_DB.cursor()
> curs.execute('CREATE TABLE IF NOT EXISTS "%s" ("%s", UNIQUE("%s"))' %
> (self.text_name, index_col_name, index_col_name))
> curs.execute(u'INSERT OR REPLACE INTO "%s"("%s") VALUES (?)' %
> (self.text_name, index_col_name), (0,))
> for new_col in act_db_columns[1:]: # adds the needed columns (except of the
> first one: index_col_name)
> curs.execute('ALTER TABLE "%s" ADD "%s" TEXT' % (self.text_name,
> new_col))
> curs.executemany('INSERT OR REPLACE INTO "%s" VALUES (%s)' %
> (self.text_name, question_marks), tags_seq)
> self.conn_tags_DB.commit()
>
> Are there maybe any comments or hints on a more elegant/efficient solution?
>
I think that dynamically creating schema (tables, based on text file
structure is a bad idea. A few reasons:
- This forces you to dynamically generate all your queries dynamically
- Not all strings are valid table/column names
- This forces the app to run as database administrator (maybe not
important for sqllite, but definitely an issue if you change to
another dbm).
- Potentially huge stability/security problems - text files can
potentially break system tables, overwrite users, etc, etc.
You're violating several rules on db design/usage.
I strongly recommend that you use a better database logic. ie, create
tables and records in advance (setup script, as db admin user if
applicable), then only use delete/insert/update/select statements (as
restricted user, if applicable).
If this is too much trouble, then I suggest storing your database in
regular Python structures instead, and use pickle/yaml/etc to write to
disk. Your current version uses a 'in memory' database, so the end
result is the same. You'll get a large performance boost also.
> Now, what's the usual way to access the database? Is it
> possible/wise/standard ... to leave the connection open for the subsequent
> queries during the whole run of the app; could even the cursor eventually be
> present as a class method, or should it rather be created repeatedly with
> each call? (After populating, the db shouldn't be modified, but only read.)
It depends. If your app is simple, single threaded, then a single
connection (global or passed through args) should be fine. Only use
multiple cursors if you need them (multiple threads, multiple
databases, multiple transaction/db isolation levels, etc).
David.
"
Nice pic :) je l'ai rajoutée dans ma galerie.
via https://shaarlimages.net/?i=9O9sWg
Source: http://sebsauvage.net/links/?Sh79RQ
via https://shaarlimages.net/?i=9O9sWg
Source: http://sebsauvage.net/links/?Sh79RQ
Ah tiens, peut être pratique :)
Personnellement, j'ai ma liste de vidéos / musiques qui tournent sur shuffle mode et j'ai organisé mon espace de travail pour que chaque fenêtre occupe une partie de l'écran, mais VLC s'amusait à redimensionner sa fenêtre à chaque vidéo <.<
Donc la solution se trouve dans: Select Tools ⇨ Preferences ⇨ Interface then uncheck the box Resize interface to video size. Finally, restart VLC.
Personnellement, j'ai ma liste de vidéos / musiques qui tournent sur shuffle mode et j'ai organisé mon espace de travail pour que chaque fenêtre occupe une partie de l'écran, mais VLC s'amusait à redimensionner sa fenêtre à chaque vidéo <.<
Donc la solution se trouve dans: Select Tools ⇨ Preferences ⇨ Interface then uncheck the box Resize interface to video size. Finally, restart VLC.
J'aime bien ce talk :)
Je l'ai vu il y a longtemps mais je suis retombé dessus récemment ^^
Je l'ai vu il y a longtemps mais je suis retombé dessus récemment ^^
Je sens que je vais oublier ça …
"Python looks up special methods only on the class, ignoring anything defined on the instance."
"Python looks up special methods only on the class, ignoring anything defined on the instance."
Hey! C'est marrant car sur le net, on peut être lu/vu par des millions (ou pas) sans le savoir et sans ressentir cette peur ;D
Une autre vidéo sur le gaspillage alimentaire …
C'est important, les gens !
Y a des ptits détails que j'aime pas dans ce documentaire par contre :/
EDIT: J'adore (ironie) comment blindés de reportages ne mélangent jamais deux sujets différents même si liés … Pour faire un genre de mashup vous voyez ?
Un exemple : Dans ce reportage et le précédent (fin un ptit peu dans la première partie du premier reportage mais bon),
Pas un mot sur les OGM/BIO, sur les additifs chimiques, etc. Comme si, la problématique n'existait pas, comme si elle était déjà résolue ou que sais-je.
Bref t'es limite obligé de regarder tous les documentaires possibles et immaginables (ce qui prend beaucoup de temps) si tu veux avoir une vision globale correcte des choses. Rrrr.
EDIT 2: Faudrait aussi encore faire des résumés de ces documentaires, trop d'informations dont la moitié passe à la poubelle dans notre cerveau (en parlant de gaspillage),
Déjà que leur diffusion est souvent limitée à un pays (qui sont cons lol) et rarement transcris pour les malentendants et pour faciliter le travaille de traduction pour rendre ce savoir global … Faudrait former des teams pour faire ça : )
C'est important, les gens !
Y a des ptits détails que j'aime pas dans ce documentaire par contre :/
EDIT: J'adore (ironie) comment blindés de reportages ne mélangent jamais deux sujets différents même si liés … Pour faire un genre de mashup vous voyez ?
Un exemple : Dans ce reportage et le précédent (fin un ptit peu dans la première partie du premier reportage mais bon),
Pas un mot sur les OGM/BIO, sur les additifs chimiques, etc. Comme si, la problématique n'existait pas, comme si elle était déjà résolue ou que sais-je.
Bref t'es limite obligé de regarder tous les documentaires possibles et immaginables (ce qui prend beaucoup de temps) si tu veux avoir une vision globale correcte des choses. Rrrr.
EDIT 2: Faudrait aussi encore faire des résumés de ces documentaires, trop d'informations dont la moitié passe à la poubelle dans notre cerveau (en parlant de gaspillage),
Déjà que leur diffusion est souvent limitée à un pays (qui sont cons lol) et rarement transcris pour les malentendants et pour faciliter le travaille de traduction pour rendre ce savoir global … Faudrait former des teams pour faire ça : )
Bon encore une fois, vidéo uniquement visionnable depuis la Belgique… Qu'ils sont cons (désolé…)
J'ai la vidéo mais je cherche toujours comment la rendre disponible via P2P… Si quelqu'un peut m'aider, je prend. ;)
EDIT: Merci à ceux qui m'ont aidé pour le mettre en seed. Seedez aussi ^^ magnet:?xt=urn:btih:75e6bfb8b9096011218a6ecc52ed03233ba1815e&dn=webbe%5F%5Fquestions%5Fa%5Fla%5Fune%5F061120132023.11391.32.mp4&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce
"1 - Nourriture low cost : à qui profitent les prix ? En pleine crise économique, les Français sont à la recherche de solutions pour manger moins cher. Pour répondre à cette demande, les grandes surfaces ont développé des produits premiers prix, ou de marque distributeur. En quelques années, ces aliments low cost ont conquis plus d'un tiers du marché alimentaire. Vendus au moins 30% moins cher, ces produits sont-ils bons pour la santé ? Ce documentaire s'intéresse à quatre produits consommés régulièrement : le saumon fumé, la confiture, les crevettes, et les oeufs bio. L'enquête mène aux usines de fabrication de saumon fumé à Quimper et en Pologne, et au Vietnam Une enquête de Frédérique Mergey adaptée par Franck Istasse 2 - Gaspillage alimentaire : tous responsables ? Avec ce que jette la moitié de la planète, on pourrait nourrir l'autre moitié. L'ampleur du gaspillage alimentaire est indécente. Le scandale est criant. En Belgique, un ménage jette en moyenne 20kg de nourriture par an. Comment en est-on arrivé là ? L'équipe de Questions à la une a cherché à comprendre. Sylvie Duquenoy et Guillaume Wollner ont donc scruté l'ensemble de la chaine alimentaire, depuis les champs jusqu'au frigo de la ménagère en passant par les supermarchés. Au terme de leur enquête, ils chiffrent le gaspillage, en déterminent les causes, pointent les responsabilités et tenter d'apporter des réponses. Elles sont parfois surprenantes. Au départ de ce que l'équipe a déniché dans les poubelles des grandes surfaces, le célèbre étoilé de Bruxelles, le « Comme chez soi » a conçu et réalisé un menu gastronomique."
À un moment dans la seconde partie, un saligot osent prétendre que c'est de la faute du consommateur, MON CUL, après un tel conditionnement et brainwashing, comment espériez-vous qu'ils réagissent ? Foutage de gueule… Grr.
J'ai la vidéo mais je cherche toujours comment la rendre disponible via P2P… Si quelqu'un peut m'aider, je prend. ;)
EDIT: Merci à ceux qui m'ont aidé pour le mettre en seed. Seedez aussi ^^ magnet:?xt=urn:btih:75e6bfb8b9096011218a6ecc52ed03233ba1815e&dn=webbe%5F%5Fquestions%5Fa%5Fla%5Fune%5F061120132023.11391.32.mp4&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce
"1 - Nourriture low cost : à qui profitent les prix ? En pleine crise économique, les Français sont à la recherche de solutions pour manger moins cher. Pour répondre à cette demande, les grandes surfaces ont développé des produits premiers prix, ou de marque distributeur. En quelques années, ces aliments low cost ont conquis plus d'un tiers du marché alimentaire. Vendus au moins 30% moins cher, ces produits sont-ils bons pour la santé ? Ce documentaire s'intéresse à quatre produits consommés régulièrement : le saumon fumé, la confiture, les crevettes, et les oeufs bio. L'enquête mène aux usines de fabrication de saumon fumé à Quimper et en Pologne, et au Vietnam Une enquête de Frédérique Mergey adaptée par Franck Istasse 2 - Gaspillage alimentaire : tous responsables ? Avec ce que jette la moitié de la planète, on pourrait nourrir l'autre moitié. L'ampleur du gaspillage alimentaire est indécente. Le scandale est criant. En Belgique, un ménage jette en moyenne 20kg de nourriture par an. Comment en est-on arrivé là ? L'équipe de Questions à la une a cherché à comprendre. Sylvie Duquenoy et Guillaume Wollner ont donc scruté l'ensemble de la chaine alimentaire, depuis les champs jusqu'au frigo de la ménagère en passant par les supermarchés. Au terme de leur enquête, ils chiffrent le gaspillage, en déterminent les causes, pointent les responsabilités et tenter d'apporter des réponses. Elles sont parfois surprenantes. Au départ de ce que l'équipe a déniché dans les poubelles des grandes surfaces, le célèbre étoilé de Bruxelles, le « Comme chez soi » a conçu et réalisé un menu gastronomique."
À un moment dans la seconde partie, un saligot osent prétendre que c'est de la faute du consommateur, MON CUL, après un tel conditionnement et brainwashing, comment espériez-vous qu'ils réagissent ? Foutage de gueule… Grr.
Génial ce site :D mais en anglais
Vous avez ce 'putain' de mot sur la langue mais ne parvenez plus à le retrouver mais vous savez sa définition, ce site a été conçu pour ça :) Génial !
Vous avez ce 'putain' de mot sur la langue mais ne parvenez plus à le retrouver mais vous savez sa définition, ce site a été conçu pour ça :) Génial !
Interesdasting
Ça y est, je me sers de mon shaarli pour envoyer des messages aux personnes offlines maintenant …
Désolé buddy j'avais pas vu ton message j'étais en mode veille.
Du coup, si tu (ou d'autres) sont intéressés par un projet Python, n'hésite pas à check :
https://github.com/JeromeJ/Devutopia
http://devutopia.net/
Je préviens que le design est pas encore fait :p
(Et pour la licence on va sûrement passer en CopyLeft)
(Wink, wink, les tags ;) à ta demande expresse :D)
Désolé buddy j'avais pas vu ton message j'étais en mode veille.
Du coup, si tu (ou d'autres) sont intéressés par un projet Python, n'hésite pas à check :
https://github.com/JeromeJ/Devutopia
http://devutopia.net/
Je préviens que le design est pas encore fait :p
(Et pour la licence on va sûrement passer en CopyLeft)
(Wink, wink, les tags ;) à ta demande expresse :D)
Commen j'ai pas moyen de te mailer ou autres, je poste ça ici et ptet qu'ainsi tu verras mon message.
J'ai plus simple que ce que la solution que je t'avais proposé.
À savoir, ça : [k for k in myDict if k in myOtherDict] mais avec des .keys() en plus inutile.
En fait c'était tout con, on peut faire ça :
>>> {"a":22, "b":33, "c":24}.keys() & {"a":33, "b":57, "d":78}
{'a', 'b'}
.keys() renvoit une view qui se comporte comme un set, d'où la possibilité d'utiliser l'opérateur "&" normalement propre aux sets. ( http://www.python.org/dev/peps/pep-3106/ )
Et pas vraiment besoin d'utiliser .keys sur le dico de droite (je pense pas que ça impacte les performances), le "set-like" returner par .keys() sait effectuer l'opération "&" sur un dict (car par défaut quand tu itères un dict, ça itère sur les clés, faut utiliser .items() ou .values() sinon).
(Wink, wink, les tags ;) )
J'ai plus simple que ce que la solution que je t'avais proposé.
À savoir, ça : [k for k in myDict if k in myOtherDict] mais avec des .keys() en plus inutile.
En fait c'était tout con, on peut faire ça :
>>> {"a":22, "b":33, "c":24}.keys() & {"a":33, "b":57, "d":78}
{'a', 'b'}
.keys() renvoit une view qui se comporte comme un set, d'où la possibilité d'utiliser l'opérateur "&" normalement propre aux sets. ( http://www.python.org/dev/peps/pep-3106/ )
Et pas vraiment besoin d'utiliser .keys sur le dico de droite (je pense pas que ça impacte les performances), le "set-like" returner par .keys() sait effectuer l'opération "&" sur un dict (car par défaut quand tu itères un dict, ça itère sur les clés, faut utiliser .items() ou .values() sinon).
(Wink, wink, les tags ;) )
Je suis parfois choqué par mes propres shaarlien ...
J'avais complètement oublié cette atrocité :/
J'avais complètement oublié cette atrocité :/
Le sub-SE pour les animaux de compagnie vient de sortir en béta :)
Je l'attendais avec impatience notamment pour les questions relatives aux lapins (tag [rabbits]) et j'ai déjà quelques Q/R liées de très bonne qualité :)
Notre article en français sur les lapins de compagnie: http://www.olissea.com/doc/?artId=3
Je l'attendais avec impatience notamment pour les questions relatives aux lapins (tag [rabbits]) et j'ai déjà quelques Q/R liées de très bonne qualité :)
Notre article en français sur les lapins de compagnie: http://www.olissea.com/doc/?artId=3