show 316 results

Blog entries

  • Paris Web 2010 - Le texte et le web

    2010/10/20

    J'ai eu la chance d'assister à l'ensemble des conférences données à Paris Web sur le rôle du texte et de la typographie dans le web d'aujourd'hui.

    La présentation Le texte: parent pauvre du web ? (par Jean-Marc Hardy) rappela les points les plus pertinents sur l'usage des éléments textuels par rapport à l'image.

    Outre l'exemple classique sur les outils de référencement qui ne savent aujourd'hui utiliser que le texte brut d'une page (au grand dam des "flasheurs"), D'autres résultats d'études furent donnés:

    • le taux de suivi des liens publicitaires textuels (ceux de Google par exemple sont 10 fois plus efficaces que les bannières classiques qui ont un taux de suivi de 2‰).
    • des cartes de température montrent que les titres (surtout si ceux-ci sont inférieurs à 11 caractères) restent très structurants pour la lecture et le prise d'informations à la différence des images qui restent floues pour le cerveau pendant les premiers dixièmes de secondes
    • l'usage de phrases explicatives plutôt que des infinitifs vagues dans les boutons de formulaires rassurent l'utilisateur ѕur des étapes cruciales d'enregistrement.

    Un dernier contre-exemple étonnant fut donné au sujet d'une boutique en ligne qui en voulant mettre en valeur la corbeille d'achats par une image très colorée a provoqué l'effet inverse: un sentiment de rejet des utilisateurs qui croyaient voir alors une publicité ;-)

    Jean-Marc Hardy a évoqué brièvement le rôle du texte dans l'accessibilité mais a préféré laisser cette partie à d'autres orateurs de Paris Web (l'accessibilité étant à l'honneur cette année).

    J'aurais bien aimé avoir son avis sur l'esthétique souvent utilisée pour les sites dits Web2.0 qui se rapprochent finalement assez bien de ses recommandations.

    Le deuxième jour, j'ai particulièrement apprécié les sujets autour de la typographie et le rhythme des pages...


  • Retour sur paris-web 2010

    2010/10/18 by Adrien Di Mascio
    http://www.paris-web.fr/telechargements/logotype-paris-web.png

    La semaine passée avait lieu Paris-Web 2010. C'était la 5ème édition de cet événement mais je n'avais pas eu l'occasion d'y assister les années précédentes.

    Tout d'abord, félicitations aux organisateurs pour l'organisation, notamment pour les sessions du grand amphithéâtre avec la traduction simultanée pour les conférences en anglais (j'avoue ne pas avoir testé le casque audio), les interprètes en langue des signes ainsi que la vélotypie. Un petit bémol toutefois : il n'y avait pas assez de prises de courant pour que les personnes présentes puissent recharger leur ordinateur !

    Quant aux conférences elles-mêmes, pas mal de choses orientées utilisabilité, design, accessibilité et HTML5. Bien que je n'aie pas eu le sentiment d'apprendre beaucoup de choses techniquement, en particulier sur HTML5 où le contenu des présentations se recoupait trop et n'apportait de mon point de vue pas grand chose de nouveau, les orateurs ont su animer et rendre vivante leur présentation. Je retiendrai en particulier trois présentations :

    • Let’s interface - how to make people as excited about tech as we are de Christian Heilmann que je résumerai (très) rapidement en disant : réutiliser les outils et les données qui sont disponibles, ne pas repartir de zéro et rajouter une petite couche qui offre une réelle valeur ajoutée, ce n'est pas forcément très compliqué. Parmi les exemples cités : http://isithackday.com/hacks/geo/addmap.html
    • Innover de 9 à 5 par Olivier Thereaux : ou comment créer des espaces d'échange pour faire émerger de nouvelles idées puis les transformer en projets. Au final, aucune solution concrète ou miracle évidemment, et il me semble que c'était un des buts ("pas de recette de cuisine"), mais je retiens que d'après son expérience, il faut des gens avec l'esprit hacker, entendre bidouilleur. Ensuite, toutes les idées qui émergent ne sont pas bonnes, toutes les bonnes idées n'aboutissent pas et si celui qui a l'idée n'est pas directement celui qui s'occupe de la concrétiser, il y a peu de chances que ça fonctionne. Enfin, il faut ne pas avoir les yeux plus gros que le ventre et tempérer ses envies en fonction du temps (ou moyens) que l'on pourra y accorder et y aller petit pas par petit pas.
    • HTML5 et ses amis par Paul Rouget : une très belle présentation avec des démonstrations HTML5 (version Firefox4) très bien choisies : utilisation des websockets pour diffuser les slides sur ordinateurs clients, utilisation de FileReader pour la prévisualisation d'images côté client et une belle démonstration des capacités WebGL !

    Je n'ai entendu que des retours positifs sur la macrographie de la page Web à laquelle je n'ai malheureusement pas assisté personnellement mais d'autres logilabiens y étaient. J'ai également noté l'absence du web sémantique, ou alors je n'étais pas dans le bon amphi. En tout cas, tout ça m'a remotivé pour jouer avec HTML5 dans cubicweb. J'ai d'ailleurs commencé à faire une démo websocket dans cubicweb, affaire à suvire...


  • AgileFrance 2010: retour d'expérience sur la gestion agile du projet Pylos

    2010/10/07

    J'ai présenté au printemps dernier à l'occasion de la conférence AgileFrance2010 un retour d'expérience sur la gestion agile du projet Pylos. Mon "client" m'a fait la gentillesse de participer à l'élaboration de cette présentation et de venir co-présenter.

    Après avoir longtemps tardé, voici le support de la présentation (le texte se trouve à la fin, avec les notes pour les orateurs). Bonne lecture.

    Merci à Christine, et aux organisateurs de la conférence.

    http://blog.xebia.fr/wp-content/uploads/2010/05/speaker-2010.png

  • Notes on making "logilab-common" Py3k-compatible

    2010/09/28 by Emile Anclin

    The version 3 of Python is incompatible with the 2.x series. In order to make pylint usable with Python3, I did some work on making the logilab-common library Python3 compatible, since pylint depends on it.

    The strategy is to have one source code version, and to use the 2to3 tool for publishing a Python3 compatible version.

    Pytest vs. Unittest

    The first problem was that we use the pytest runner, that depends on logilab.common.testlib which extends the unittest module.

    Without major modification we could use unittest2 instead of unittest in Python2.6. I thought that the unittest2 module was equivalent to the unittest in Python3, but then realized I was wrong:

    • Python3.1/unittest is some strange "forward port" of unittest. Both are a single file, but they must be quite different since 3.1 has 1623 lines compared to 875 from 2.6...
    • Python2.x/unittest2 is a python package, backported from the alpha-release of Python3.2/unittest.

    I did not investigate if there are other unittest and unittest2 versions corresponding.

    What we can see is that the 3.1 version of unittest is different from everything else; whereas the 2.6-unittest2 is equivalent to 3.2-unittest. So, after trying to run pytest on Python3.1 and since there is a backport of unittest2 for Python3.1, it became clear that the best is to ignore py3.1-unittest and work on Python3.2 and unittest2 directly.

    Meanwhile, some work was being done on logilab-common to switch from unittest to unittest2. This was included in logilab.common-0.52.

    'python2.6 -3' and 2to3

    The -3 option of python2.6 warns about Python3 incompatible stuff.

    Since I already knew that pytest would work with unittest2, I wanted to know as fast as possible if pytest would run on Python3.x. So I run all logilab.common tests with "python2.6 -3 bin/pytest" and found a couple of problems that I quick-fixed or discarded, waiting to know the real solution.

    The 2to3 script (from the 2to3 library) does its best to transform Python2.x code into Python3 compatible code, but manual work is often needed to handle some cases. For example file is not considered a deprecated base class, calls to raw_input(...) are handled but not using raw_input as an instance attribute, etc. At times, 2to3 can be overzealous, and for example do modifications such as:

    -                for name, local_node in node.items():
    +                for name, local_node in list(node.items()):
    

    Procedure

    After a while, I found that the best solution was to adopt the following working procedure:

    • run the tests with python2.6 -3 and solve the appearing issues.
    • run 2to3 on all that has to be transformed:
    2to3-2.6 -n -w *py test/*py ureports/*py
    

    Since we are in a mercurial repository we don't need backups (-n) and we can write the modifications to the files directly (-w).

    • create a 223.diff patch that will be applied and removed repeatedly.

      Now, we will push and pop this patch (which is much faster than running 2to3), and only regenerate it from time to time to make sure it still works:

    • run "python3.2 bin/pytest -x", to find problems and solutions for crashes and tests that do not work. Note that after some quick fixes on logilab.common.testlib, pytest works quite well, and that we can use the "-x" option. Using Python's Whatsnew_3.0 documentation for hints is quite useful.

    • hg qpop 223.diff

    • write the solution into the 2.x code, convert it into a patch or a commit, and run the tests: some trivial things might not work or not be 2.4 compatible.

    • hg qpush 223.diff

    • repeat the procedure

    I used two repositories when working on logilab.common, one for Python2 and one for Python3, because other tools, like astng and pylint, depend on that library. Setting the PYTHONPATH was enough to get astng and pylint to use the right version.

    Concrete examples

    • We had to remove "os.path.walk" by replacing it with "os.walk".

    • The renaming of raw_input to input, __builtin__ to builtins and IOString to io could easily be resolved by using the improved logilab.common.compat technique: write a python version dependent definition of a variable, function, or class in logilab.common.compat and import it from there.

      For builtin, it is even easier: as 2to3 recognizes direct imports, so we can write in compat.py:

    import __builtin__ as builtins # 2to3 will tranform '__builtin__' to 'builtins'
    

    The most difficult point is the replacement of str/unicode by bytes/str.

    In Python3.x, we only use unicode strings called just str (the u'' syntax and unicode disappear), but everything written on disk will have to be converted to bytes, with some explicit encoding. In Python3.x, file descriptors have a defined encoding, and will automatically transform the strings to bytes.

    I wrote two functions in logilab.common.compat. One converts str to bytes and the other simply ignores the encoding in case of 3.x where it was expected in 2.x. But there might be a need to write additional tests to make sure the modifications work as expected.

    Conclusion

    • After less than a week of work, most of the logilab.common tests pass. The biggest remaining problem are the tests for testlib.py. But we can already start working on the Python3 compatibility for astng and finally pylint.
    • Looking at the lib2to3 library, one can see that 2to3 works with regular expressions which reproduce the Python grammar. Hence, it can not do much code investigation or static inference like astng. I think that using astng, we could improve 2to3 without too much effort.
    • for astng the difficulties are quite different: syntax changes become semantic changes, we will have to add new types of astng nodes.
    • For testing astng and pylint we will probably have to check the different test examples, a lot of them being code snippets which 2to3 will not parse; they will have to be corrected by hand.

    As a general conclusion, I found no need for using sa2to3, although it might be a very good tool. I would instead suggest to have a small compat module and keep only one version of the code, as far as possible. The code base being either on 2.x or on 3.x and using the (possibly customized) 2to3 or 3to2 scripts to publish two different versions.


  • SemWeb.Pro - first french Semantic Web conference, Jan 17/18 2011

    2010/09/20 by Nicolas Chauvat

    SemWeb.Pro, the first french conference dedicated to the Semantic Web will take place in Paris on January 17/18 2011.

    One day of talks, one day of tutorials.

    Want to grok the Web 3.0? Be there.

    Something you want to share? Call for papers ends on October 15, 2010.

    http://www.semweb.pro/semwebpro.png

  • MiniDebConf Paris 2010

    2010/09/09 by Arthur Lutz
    http://france.debian.net/debian-france.png

    Debian France organise le 30 et 31 octobre prochain une minidebconf à Paris. Le wiki de la conférence est en train de s'étoffer, et pour le moment c'est là qu'il faut s'inscrire. À Logilab nous sommes utilisateurs et contributeurs de Debian, c'est donc naturellement que nous allons essayer d'aller participer à cette conférence. Alexandre Fayolle, développeur Debian ira assister (entre autres) à la présentation de Carl Chenet sur l'état de Python dans Debian.


  • Discovering logilab-common Part 1 - deprecation module

    2010/09/02 by Stéphanie Marcu

    logilab-common library contains a lot of utilities which are often unknown. I will write a series of blog entries to explore nice features of this library.

    We will begin with the logilab.common.deprecation module which contains utilities to warn users when:

    • a function or a method is deprecated
    • a class has been moved into another module
    • a class has been renamed
    • a callable has been moved to a new module

    deprecated

    When a function or a method is deprecated, you can use the deprecated decorator. It will print a message to warn the user that the function is deprecated.

    The decorator takes two optional arguments:

    • reason: the deprecation message. A good practice is to specify at the beginning of the message, between brackets, the version number from which the function is deprecated. The default message is 'The function "[function name]" is deprecated'.
    • stacklevel: This is the option of the warnings.warn function which is used by the decorator. The default value is 2.

    We have a class Person defined in a file person.py. The get_surname method is deprecated, we must use the get_lastname method instead. For that, we use the deprecated decorator on the get_surname method.

    from logilab.common.deprecation import deprecated
    
    class Person(object):
    
        def __init__(self, firstname, lastname):
            self._firstname = firstname
            self._lastname = lastname
    
        def get_firstname(self):
            return self._firstname
    
        def get_lastname(self):
            return self._lastname
    
        @deprecated('[1.2] use get_lastname instead')
        def get_surname(self):
            return self.get_lastname()
    
    def create_user(firstname, lastname):
        return Person(firstname, lastname)
    
    if __name__ == '__main__':
        person = create_user('Paul', 'Smith')
        surname = person.get_surname()
    

    When running person.py we have the message below:

    person.py:22: DeprecationWarning: [1.2] use get_lastname instead
    surname = person.get_surname()

    class_moved

    Now we moved the class Person in a new_person.py file. We notice in the person.py file that the class has been moved:

    from logilab.common.deprecation import class_moved
    import new_person
    Person = class_moved(new_person.Person)
    
    if __name__ == '__main__':
        person = Person('Paul', 'Smith')
    

    When we run the person.py file, we have the following message:

    person.py:6: DeprecationWarning: class Person is now available as new_person.Person
    person = Person('Paul', 'Smith')

    The class_moved function takes one mandatory argument and two optional:

    • new_class: this mandatory argument is the new class
    • old_name: this optional argument specify the old class name. By default it is the same name than the new class. This argument is used in the default printed message.
    • message: with this optional argument, you can specify a custom message

    class_renamed

    The class_renamed function automatically creates a class which fires a DeprecationWarning when instantiated.

    The function takes two mandatory arguments and one optional:

    • old_name: a string which contains the old class name
    • new_class: the new class
    • message: an optional message. The default one is '[old class name] is deprecated, use [new class name]'

    We now rename the Person class into User class in the new_person.py file. Here is the new person.py file:

    from logilab.common.deprecation import class_renamed
    from new_person import User
    
    Person = class_renamed('Person', User)
    
    if __name__ == '__main__':
        person = Person('Paul', 'Smith')
    

    When running person.py, we have the following message:

    person.py:5: DeprecationWarning: Person is deprecated, use User
    person = Person('Paul', 'Smith')

    moved

    The moved function is used to tell that a callable has been moved to a new module. It returns a callable wrapper, so that when the wrapper is called, a warning is printed telling where the object can be found. Then the import is done (and not before) and the actual object is called.

    Note

    The usage is somewhat limited on classes since it will fail if the wrapper is used in a class ancestors list: use the class_moved function instead (which has no lazy import feature though).

    The moved function takes two mandatory parameters:

    • modpath: a string representing the path to the new module
    • objname: the name of the new callable

    We will use in person.py, the create_user function which is now defined in the new_person.py file:

    from logilab.common.deprecation import moved
    
    create_user = moved('new_person', 'create_user')
    
    if __name__ == '__main__':
        person = create_user('Paul', 'Smith')
    

    When running person.py, we have the following message:

    person.py:4: DeprecationWarning: object create_user has been moved to module new_person
    person = create_user('Paul', 'Smith')

  • pdb.set_trace no longer working: problem solved

    2010/08/12

    I had a bad case of bug hunting today which took me > 5 hours to track down (with the help of Adrien in the end).

    I was trying to start a CubicWeb instance on my computer, and was encountering some strange pyro error at startup. So I edited some source file to add a pdb.set_trace() statement and restarted the instance, waiting for Python's debugger to kick in. But that did not happen. I was baffled. I first checked for standard problems:

    • no pdb.py or pdb.pyc was lying around in my Python sys.path
    • the pdb.set_trace function had not been silently redefined
    • no other thread was bugging me
    • the standard input and output were what they were supposed to be
    • I was not able to reproduce the issue on other machines

    After triple checking everything, grepping everywhere, I asked a question on StackOverflow before taking a lunch break (if you go there, you'll see the answer). After lunch, no useful answer had come in, so I asked Adrien for help, because two pairs of eyes are better than one in some cases. We dutifully traced down the pdb module's code to the underlying bdb and cmd modules and learned some interesting things on the way down there. Finally, we found out that the Python code frames which should have been identical where not. This discovery caused further bafflement. We looked at the frames, and saw that one of those frames's class was a psyco generated wrapper.

    It turned out that CubicWeb can use two implementation of the RQL module: one which uses gecode (a C++ library for constraint based programming) and one which uses logilab.constraint (a pure python library for constraint solving). The former is the default, but it would not load on my computer, because the gecode library had been replaced by a more recent version during an upgrade. The pure python implementation tries to use psyco to speed up things. Installing the correct version of libgecode solved the issue. End of story.

    When I checked out StackOverflow, Ned Batchelder had provided an answer. I didn't get the satisfaction of answering the question myself...

    Once this was figured out, solving the initial pyro issue took 2 minutes...


  • EuroSciPy'10

    2010/07/13 by Adrien Chauve
    http://www.logilab.org/image/9852?vid=download

    The EuroSciPy2010 conference was held in Paris at the Ecole Normale Supérieure from July 8th to 11th and was organized and sponsored by Logilab and other companies.

    July, 8-9: Tutorials

    The first two days were dedicated to tutorials and I had the chance to talk about SciPy with André Espaze, Gaël Varoquaux and Emanuelle Gouillart in the introductory track. This was nice but it was a bit tricky to present SciPy in such a short time while trying to illustrate the material with real and interesting examples. One very nice thing for the introductory track is that all the material was contributed by different speakers and is freely available in a github repository (licensed under CC BY).

    July, 10-11: Scientific track

    The next two days were dedicated to scientific presentations and why python is such a great tool to develop scientific software and carry out research.

    Keynotes

    I had a very great time listening to the presentations, starting with the two very nice keynotes given by Hans Petter Langtangen and Konrad Hinsen. The latter gave us a very nice summary of what happened in the scientific python world during the past 15 years, what is happening now and of course what could happen during the next 15 years. Using a crystal ball and a very humorous tone, he made it very clear that the challenge in the next years will be about how using our hundreds, thousands or even more cores in a bug-free and efficient way. Functional programming may be a very good solution to this challenge as it provides a deterministic way of parallelizing our programs. Konrad also provided some hints about future versions of python that could provide a deeper and more efficient support of functional programming and maybe the addition of a keyword 'async' to handle the computation of a function in another core.

    In fact, the PEP 3148 entitled "Futures - execute computations asynchronously" was just accepted two days ago. This PEP describes the new package called "futures" designed to facilitate the evaluation of callables using threads and processes in future versions of python. A full implementation is already available.

    Parallelization

    Parallelization was indeed a very popular issue across presentations, and as for resolving embarrassingly parallel problems, several solutions were presented.

    • Playdoh: Distributes computations over computers connected to a secure network (see playdoh presentation).

      Distributing the computation of a function over two machines is as simple as:

      import playdoh
      result1, result2 = playdoh.map(fun, [arg1, arg2], _machines = ['machine1.network.com', 'machine2.network.com'])
      
    • Theano: Allows to define, optimize, and evaluate mathematical expressions involving multi-dimensional arrays efficiently. In particular it can use GPU transparently and generate optimized C code (see theano presentation).

    • joblib: Provides among other things helpers for embarrassingly parallel problems. It's built over the multiprocessing package introduced in python 2.6 and brings more readable code and easier debugging.

    Speed

    Concerning speed, Fransesc Alted has showed us interesting tools for memory optimization currently successfully used in PyTables 2.2. You can read more details on these kind of optimizations in EuroSciPy'09 (part 1/2): The Need For Speed.

    SCons

    Last but not least, I talked with Cristophe Pradal who is one of the core developer of OpenAlea. He convinced me that SCons is worth using once you have built a nice extension for it: SConsX. I'm looking forward to testing it.


  • HOWTO install lodgeit pastebin under Debian/Ubuntu

    2010/06/24 by Arthur Lutz

    Lodge it is a simple open source pastebin... and it's written in Python!

    The installation under debian/ubuntu goes as follows:

    sudo apt-get update
    sudo apt-get -uVf install python-imaging python-sqlalchemy python-jinja2 python-pybabel python-werkzeug python-simplejson
    cd local
    hg clone http://dev.pocoo.org/hg/lodgeit-main
    cd lodgeit-main
    vim manage.py
    

    For debian squeeze you have to downgrade python-werkzeug, so get the old version of python-werkzeug from snapshot.debian.org at http://snapshot.debian.org/package/python-werkzeug/0.5.1-1/

    wget http://snapshot.debian.org/archive/debian/20090808T041155Z/pool/main/p/python-werkzeug/python-werkzeug_0.5.1-1_all.deb
    

    Modify the dburi and the SECRET_KEY. And launch application:

    python manage.py runserver
    

    Then off you go configure your apache or lighthttpd.

    An easy (and dirty) way of running it at startup is to add the following command to the www-data crontab

    @reboot cd /tmp/; nohup /usr/bin/python /usr/local/lodgeit-main/manage.py runserver &
    

    This should of course be done in an init script.

    http://rn0.ru/static/help/advanced_features.png

    Hopefully we'll find some time to package this nice webapp for debian/ubuntu.


show 316 results