/dev/blah

things i want to remember, things i want to share

Développeur Python et adepte Linux depuis 2005, passionné par beaucoup trop de choses. Profil Github

Entries tagged “dev”

Git resources + random tips

written by tshirtman, on 1/13/14 1:04 AM.

In the last few years, git has gained a lot of popularity in open source projects, howether, newcommers, and even seasoned contributors, often seems to struggle with its interface.

There is a simple reason to that, git has beautiful internals, but you don’t care about that, you want to use it, the issue is that its interface only make (some) sense (it’s not completly consistent) in the light of its beautiful internal model.

On top of that, the initial git documentation was, to say the least, indigest, technically correct, but not really helpful, again, because it explained how things worked, not how to use them.

Howether, a good number of resources have poped up while git was gaining popularity, here is my shortlist of favorite resource, in order of complexity, to get you accustomed with it.

git - the simple guide (i usually find this one by googling “git no deep shit”, easy to remember), this colorful guide can be read in 5-10 minutes, and will get you started, sure, it glosses over details, but it’s a good startpoint, and the format makes it easy to read.

git for 4 and up This video will show you how git works with toys and manual construction of commit trees (the famous DAG) it’s a great way to understand the model, and behavior of git, you’ll see it’s, in fact pretty simple.

think-like-a-git This one will use, and really deserve, one or two hours of your time, it’s not the best start point, but it will make things a lot clearer if you have been using git for some time and still feel uneasy when less-common situations, it’ll make clearer to you that, really, nothing is ever an unrecoverable mistake with git.

Pro Git Ok, this one is now more or less the official documentation, and i rarely go for it, but when you want a definite answer, or face a complex situation, it’s a really, really, complete resource, and it’s translated in a lot of languages, like even human languages, isn’t that great?

On top of that, i’ll add a few of my own tips:

-p flag

Look for the “-p” flag in commands, you can use it on add/commit/reset/stash and others, its exact behavior of course depend of the situation, but the general idea is that when you want to see/review each part of the change, it’s what you want. I basically never use “git add” without “-p”, this way i see exactly what i’m about to commit.

reflog

git reflog

this one will show you where you’ve been, regarding commit ids, recently, if you are lost after a rebase/reset/checkout, and just want to go back, it can save you a lot of trouble.

aliases

If you do something often, or if you don’t do it often enough to remember the right options, do an alias for it, here are a few of my most useful ones.

    st = status --short
    ci = commit
    co = checkout
    br = branch
    ll = log --graph --pretty=format:\"%C(yellow)%h %C(blue)%ci%C(green) %an %C(red)%d %Creset%s\"
    lla = log --graph --pretty=format:\"%C(yellow)%h %C(blue)%ci%C(green) %an %C(red)%d %Creset%s\" --all
    nopushed = log --branches --not --remotes --simplify-by-decoration --decorate --oneline
    nomerged = branch -a --no-merged
    latest = for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short) [%(committername)]'
    rc = rebase --continue

creating an alias is easy

git config --global alias.aliasname "some git command"

or you can just edit ~/.gitconfig

reset/checkout

Learn the difference! It can save your life^Wfile. ;) You should be comfortable with both pretty soon, they are very useful.

And ask questions, either to your local git guru, or on the ‘net, learn how they think about git, it’s not magical, it’s just a way to think, you just need to get the hang of it :).

Tip me if you like this :)

[Kivy] android-like pulldown menu

written by tshirtman, on 10/22/12 9:29 PM.

kivy all the things

As someone asked how to do such thing in kivy, i spent some time writting it, and as i (sadly) don’t blog on kivy often (if ever?), and since i think this example is quite telling about how kivy make such things quite easy, let’s talk a bit about this code.

To put things in context, what we want is the bar at the top of the android phones, that one can pull down to see notifications, this one is semi transparent and goes over the normal screen.

So, here is the code. first the kv part:

FloatLayout:
    FloatLayout:
        # placeholder for the "normal screen"
        Label:
            center: root.center
            text: 'test content'
            size_hint: None, None
            size: self.texture_size

    ScrollView:
        # container for the "notifications"
        y: dg.top # let's stick it to the top
        x: root.x # and to the left
        size_hint_y: None
        do_scroll_x: False # only vertical scrolling
        do_scroll_y: True
        
        # most of the magic is there, auto adjust size to follow the draggable label
        height: root.top - dg.y

        # let's put a nearly opaque black background
        canvas:
            Color:
                rgba: 0, 0, 0, .8
            Rectangle:
                pos: self.pos
                size: self.size
        
        # the actual notification container, with placeholder content
        BoxLayout:
            size_hint_y: None
            height: 1000
            orientation: 'vertical'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'
            Label:
                text: 'test'

    # the draggable label, which behaviour is defined in python file
    DraggableLabel:
        # some decoration behind the text
        canvas.before:
            Color:
                rgba: 0, 0, 0, 1
            Rectangle:
                pos: self.pos
                size: self.size
            Color:
                rgba: .5, .5, .5, 1
            Rectangle:
                pos: self.pos
                size: self.width, 1

        size_hint_y: None
        top: root.top
        # assign its id to "dg" so we can reference it elsewhere
        id: dg
        height: '20pt'
        text: 'drag me'

then the python part

from kivy.app import App 
from kivy.uix.label import Label
from kivy.animation import Animation


class DraggableLabel(Label):
    '''A label you can drag upside-down'''
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            # assure ourselves we will get the updates of this motion
            touch.grab(self)
            return True

        return super(DraggableLabel, self).on_touch_down(touch)

    def on_touch_move(self, touch):
        if touch.grab_current is self:
            # really straightforward...
            self.y = touch.y
            return True

        return super(DraggableLabel, self).on_touch_move(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            # check if the movement direction was up or down
            if touch.dy < 0:
                a = Animation(y=0) # down? put the bar all the way down
            else:
                a = Animation(top=self.parent.top) # up? put it at the top

            a.start(self) # actually start the animation
            return True

        return super(DraggableLabel, self).on_touch_up(touch)


class TabApp(App):
    pass


TabApp().run()

 

I think it doesn’t really need more explanations, the DraggableLabel is looking for touch events that are for it, first if they are on it, then if they are grabbed by itself, and move accordingly, and the kv auto adjust the size of the ScrollView to take all the distance between top of the screen and top of the DraggableLabel.

Of course, if things are not clear, feel free to ask questions :)

Tip me if you like this :)

PyJNIus mailing list

written by tshirtman, on 9/6/12 3:43 PM.

Since there are some questions/discussions that doesn’t perfectly fit as github issues, i just created a google group to discuss PyJNIus development, i hope this will make collaboration easier.

https://groups.google.com/forum/#!forum/pyjnius-dev

pyjnius-dev@googlegroups.com

Tip me if you like this :)

zine img_upload

written by tshirtman, on 10/24/11 9:20 AM.

Un autre petit plugin zine, tout simple, mais qui simplifie la vie, pour envoyer des images sur le blog pendant qu’on écrit un article.

Le fonctionnement est simple, un bouton javascript “click to upload image” est ajouté entre le formulaire de titre et de texte:

cliquer sur ce lien permet de choisir un fichier sur son disque, une fois validé, le lien vers l’image apparait en dessous du bouton javascript, y’a plus qu’a copier/coller :). Si une image du même nom existait, des caractères aléatoires sont ajoutés avant l’extension jusqu’à trouver un nom disponible, afin de ne pas écraser les images existantes.


Un panneau de configuration simple est disponible, pour configurer les deux paramètres essentiels:

  • Le dossier ou stocker les images, ce dossier dois exister, il n’y a pas de gestion d’erreurs pour l’instant, si c’est mal configuré, vous ne verrez juste pas de lien apparaitre :).
  • L’url pour accéder à ce dossier pour les clients, soit vous configurez votre hébergement pour avoir un dossier pour les fichiers statiques, soit vous vous débrouillez pour poser ce dossier dans la partie statique de zine, et vous donnez l’url correspondante.

Le code est dispo sur github: https://github.com/tshirtman/zine_upload_images.

Tip me if you like this :)

usage de pylint

written by tshirtman, on 7/4/11 3:31 AM.

Pylint

J’ai utilisé pas mal pylint ces dernières semaines, pour me rendre compte de l’état général d’USF, et j’avoue, que c’était pas trop brillant, vu qu’il m’offrait une note généreuse de 2.5/10 environ… pour mes 11000 lignes de codes, ça promettait du boulot.

Et ben oui, d’où le “ces dernières semaines” mais je suis pas mécontent du résultat, beaucoup de namespaces ont été nettoyés, des logiques ont été simplifiées un peu partout, beaucoup de choses ont été documentés, et même certains refactoring conséquents ont été entrepris, et assez bien aboutis

Comment?

Et bien en lançant

pylint usf
à la racine du projet, bien sur (vu que le plus gros de mon code est dans le module usf), voir des cibles plus précises quand on sait qu’on a beaucoup de boulot sur un endroit.

Mais… il y a un mais, en effet, on peut, et on est en droit de ne pas être d’accord avec les opinions de pylint, sur ce qui est bon ou pas, si je suis d’accord sur le fait qu’il applique la pep8 aussi fortement que possible, le voir dénigrer map/filter/reduce, sous prétexte que Guido préfère écrire

[ x for x in S if P(x) ]
plutôt que
filter(P,S)
(parait que c’est “plus simple et plus lisible”…).
ou m’engueuler par ce que mon “i” dans
for i in items:
    i.update()
est une variable d’une lettre, je ne suis pas d’accord, il y a des endroit ou ça fais sens, et même
class Entity(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
Avoir des attributs d’une longueur de 1 caractère n’est pas un crime non plus…

Heureusement, pylint est fortement configurable, et on peut fortement influencer ses messages remontés, ainsi que sa note (héhé) en lui faisant utiliser une configuration alternative… le plus simple pour cela, est de lui faire cracher sa configuration actuelle, de la sauvegarder, et de la modifier:

pylint --generate-rcfile > pylintrc
vim pylintrc # oui, bon, le meilleur éditeur que vous avez sous la main quoi ;)
Le nommer ainsi permet à pylint de le détecter automatiquement s’il est dans le dossier courant, on peut aussi le placer dans son dossier ~/ et le nommer “.pylintrc” si on veux que ce soit le fichier de configuration par défaut.

Qu’est ce que je change (moi, vous c’est vous qui voyez à l’usage ;) ?

disable=W0201
(Warning 0201) Oui, ma classe n’est pas toujours complète au sortir du __init__, c’est notamment le cas pour toutes les classes d’un module, du fait de sa construction particulière, c’est vrai que plus d’utilisation de super() pourrait sans doute éviter ça… on verra si je réactive ce message un de ces 4, dans certains cas, cependant, c’est bien agréable de profiter du dynamisme de notre langage…
include-ids=yes
Je veux voir l’identifiant des erreurs remontées, pour pouvoir les black-lister si je ne suis pas d’accord ;) ou les comprendre en cherchant sur google, si le message n’est pas assez clair (ça n’arrive pas souvent :)).
attr-rgx=[a-z_][a-z0-9_]{0,30}$

argument-rgx=[a-z_][a-z0-9_]{0,30}$

variable-rgx=[a-z_][a-z0-9_]{0,30}$
la regex qui valide les noms de variables locale, d’attribut ou d’argument passé à un callable, afin d’autoriser les noms d’une lettre, comme dit plus haut (à noter que connaître un peu les regexp, ça sert trèèèès souvent… ;))
bad-functions=apply,input,exec,eval
par ce que la prog fonctionnelle (filter/map/reduce) je ne vois pas de raisons de m’en priver…

Voilà, je change pas grand chose en fait, c’est plutôt bon signe :).

Conclusion?

ma note actuelle? ;)

[SNIP]


Report
======
3763 statements analysed.

Messages by category
--------------------

+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |103    |103      |=          |
+-----------+-------+---------+-----------+
|refactor   |55     |55       |=          |
+-----------+-------+---------+-----------+
|warning    |58     |58       |=          |
+-----------+-------+---------+-----------+
|error      |6      |6        |=          |
+-----------+-------+---------+-----------+

[SNIP]


Global evaluation
-----------------
Your code has been rated at 9.35/10 (previous run: 9.35/10)

[SNIP]
Et oui, il manque encore des docstrings, notamment en entête de fichiers, mais ça progresse…

Tip me if you like this :)

usf 0.1.4

written by tshirtman, on 4/10/11 9:19 PM.

Je viens de soumettre ultimate-smash-friends à pypi (mais l’archive, trop grosse, à été rejeté, on peut donc la trouver ), et de créer un deb pour ubuntu, dans les nouveautés, on peut noter principalement de grosses optimisations, et une grosse amélioration de l’AI (qui devient enfin intéressante à affronter).

Bon, c’est toujours de l’alpha, mais, je pense que mon boulot sur l’ai va sérieusement simplifier le boulot pour le mode réseau, mais je promet pas que ça sera rapide, une IA correcte à quand même attendu 2ans pour voir le jour…

Voilà, si ça intéresse des gens de tester, et de faire des retours, c’est tout à fait bienvenu, en espérant que ça vous plaise.

Tip me if you like this :)

Mise en place d'un environnement de dev web python propre...

written by tshirtman, on 2/10/10 1:47 AM.

Explications préliminaire

Lorsqu’on débute dans le développement web en python, la mise en place d’un environnement de développement propre, au vu des différents outils disponibles, peut être un vrai labyrinthe. Je présenterai donc ici trois outils modernes et efficaces permettant de gérer le déploiement de la plupart des frameworks web python: virtualenv, pip et distribute

virtualenv permet de configurer un environnement python séparé de celui du système, l’interpréteur python et toutes les bibliothèques qui nous sont nécessaires seront installé dans cet environnement virtuel et ne perturberont pas le système… cela permet d’avoir un environnement identique sur différents serveurs avec des distributions différentes avec relativement peu de soucis.

pip permet d’installer des paquets python depuis pypi (connu aussi sous le nom de “cheese shop”) et de les installer, soit dans le système, soit dans le virtualenv choisit. Contrairement à easy_install (plus connus car plus ancien) pip est capable de nettoyer derrière lui, si on lui demande de désinstaller un paquet il le fait… il ne gère cependant pas les dépendance lors de la suppression.

distribute, qui sera utilisé par pip pour télécharger et installer les paquets depuis pypi, est une version activement maintenue de setuptools, qui permet d’utiliser et de créer des modules python (appelés eggs).

Passons à la pratique, comment ça marche, concrètement?
La première chose que nous voulons, est une version récente de pip, on peut pour cela utiliser… easy_install.
sudo easy_install pip
C’est la dernière fois que nous toucherons easy_install, une fois fait ceci, on utilise pip pour installer virtualenv et distribute
sudo pip install virtualenv distribute
Il faut maintenant créer notre virtualenv, il faut ici préciser que nous voulons utiliser distribute (sinon il utilise setuptools qui est assez buggé).
export VIRTUALENV_USE_DISTRIBUTE=true
virtualenv my_virtual_python_env
Vous pouvez bien sur donner tout nom qui vous convient à votre virtualenv ;).
Pour travailler avec un virtualenv, il faut l’activer, cela consiste à charger un certain nombre de variables d’environnement, un script fait ça pour nous, il se situe dans my_virtual_env/bin/ et s’appele activate, pour charger les variables d’un script, on utilise “source”:
source my_virtual_env/bin/activate
qui peut s’abrévier
. my_virtual_env/bin/activate
Ouf! Si tout s’est bien passé, on a un virtualenv opérationnel et chargé! (Pour “sortir” d’un virtualenv, utiliser la commande “deactivate”).

Pour aller plus loin:
Mettons que je veuille commencer un projet pylons ou repoze.bfg, ou bluebream, je peux installer ces frameworks via pip.
pip install pylons repoze.bfg bluebream
Ces frameworks utilisent paster pour permettre la création d’un projet aisément, le fait de les installer (via pip) fournis des templates à paster… s’il n’a pas été installé automatiquement (par pip et dans le virtualenv, pas dans le systeme) installez le via
pip install pastedeploy paste pastescript
(s’il a été installé dans le système auparavant, utilisez le très pratique pip uninstall pour faire le ménage).

On peut voir la liste des templates disponibles avec:
paster --list-templates
exemple:
Available templates:
  basic_package:      A basic setuptools-enabled package
  bfg_alchemy:        repoze.bfg SQLAlchemy project using traversal
  bfg_routesalchemy:  repoze.bfg SQLAlchemy project using Routes (no traversal)
  bfg_starter:        repoze.bfg starter project
  bfg_zodb:           repoze.bfg ZODB starter project
  bluebream:          A BlueBream project
  paste_deploy:       A web application deployed through paste.deploy
  pylons:             Pylons application template
  pylons_minimal:     Pylons minimal application template
Créer un projet repoze.bfg? rien de plus simple:
paster create -t bfg_ nom_du_projet
La base est là! Aller dans le dossier du projet, lancer:
python setup.py install
Pour déployer l’application (toujours dans votre virtualenv, et donc sans polluer votre système).

…et (enfin) pour lancer votre application:
paster serve fichier.ini

voila, votre appli par défaut tourne sur 127.0.0.1:6543, le port étant bien sur réglable dans le fichier .ini.
elle est complètement isolée du système et donc aisément reproductible.

Conclusion

Cette mise en place peut paraître un peu laborieuse, mais a l’avantage d’une quasi totale indépendance au système cible, tout en restant simple à mettre à jours (pip install –upgrade), distribuable (création d’eggs avec distribute), et sûrement d’autres dont je n’ai même pas connaissance :P. J’espère que vous avez apprécié, n’hésitez pas à faire des remarques :).

Tip me if you like this :)

Nouvelle migration

written by tshirtman, on 12/12/09 3:03 AM.

Pour un bon moment celle ci j’espère.

Après l’achat (sur un coup de tête) de tshirtman.fr, je me suis dit que j’allais faire blog.tshirtman.fr et sérieusement ce coup ci… on (mon chef au boulot, plus connus sous le pseudo ccomb) m’avait conseillé zine qui à l’avantage d’être en python et de bonne facture, j’ai un peu galéré avant de trouver la bonne méthode d’installation (un buildout sur pypi bien sur >_<) mais en tout cas c’est propre et sympa…

Comme j’utilise apache pour les virtualhost, zine tourne en user normal via paster, sur un port quelconque, et apache lui renvoit les requetes via mod_proxy, c’est simple et efficace.

Je viens de finir d’importer les billets du pybloxom, j’aurais bien aimé retrouver les billets de mon vieux vieux blog, mais il semble que google n’ai pas daigné en garder du cache, que archive.org n’ai pas en la présence d’esprit de remarquer la contribution importante qu’ils représentaient… que je n’ai pas d’accès immédiat à mon serveur de l’époque (présentément eteinds), et que donc, je soit incapable, et sans doute pour un certain moment, de les récupérer.

Life’s life ^^.

sinon en ce moment je lis “the pragmatic programmer” qui contient une foule nombreuse de sages conseils sur le développement, reste à avoir l’intélligence de les mettre en application…

Tip me if you like this :)

tuto backport debian

written by tshirtman, on 11/23/09 4:30 PM.

Backporter un packet debian:

Cas pratique avec ghostcript, depuis lenny vers sarge (old-oldstable >_<)

  • sur une machine debian * à jours *
    apt-get source ghostscript
    # (on peut aussi prendre les sources dans les dépots debian si on a pas de machine
    # debian sous la main, prendre le paquet *.dfsg-src.tar.gz)
    

  • sur la machine de destination (ou un clone)
    # copier le dossier des sources obtenus précédemment.
    sudo apt-get build-dep gs-gpl
    sudo apt-get install autotools-dev fakeroot build-essential dh_make
    cd ghostscript*
    dh_make
    
    vim debian/control
    
    # si on souhaite changer le nom du paquet (dans mon cas de ghostscript à gs-gpl
    # pour coller au nommage de l'époque) il faut faire un grep de l'ancien nom
    # dans debian/* et faire les remplacement avec discernement ;))
    
    # enfin, toujours dans le dossier des sources
    dpkg-buildpackage -rfakeroot
    
    cd ..
    ls *.deb
    # :D
    
Tip me if you like this :)

migration_pyblosxom

written by tshirtman, on 10/27/09 1:48 AM.

N’ayant pas le temps de développer mon moteur de blog, j’ai décidé de switcher vers pyblosxom, qui est simple mais assez complet… très “à la carte”, il me reste pas mal de config à faire mais ça semble fonctionnel, bientot les rss et les commentaires… normalement.

Tip me if you like this :)

Tags

#FIXME 3G absurd ad_sense alterway aléatoire android animation anonymity atheism bach backlog bash bitcoins blog blogging boldness book books boulot bricolage bépo C canvas captcha captures carte SD censure christianity chroot CLI cli cloudwatt code colors comfort zone command line community company life conferences contest copwatch copwatchnord-idf core-devs cours ct705 culture deb debian debug deformation dehors dessin dev distribute distribution débutant déploiement développement ebooks eeepad eeepc effect ego empty en escher event firefly flappy bird flask fosdem foss fr fun game garden gdb geek culture git github goals graphics grrr gödel hack hackathon hacked hacking hooks i3 images IMAP inspirational install isync java jeu jeu video jinja2 jni keyboard keynav kivy kv lame learning lib libre life linux lol macosx magnet mail mailing-list mails maths mbsync meetings memory leak mesh meta mint mirroir MIT module motivational mouse museomix mutt nexus7 no-mouse notmuch nottoomuch offlineimap onycroit opencourseware osc packaging paris passphrase password patch pentacatyl people perte de données ping pip planning plugin positioning pr procrastination programmation progress project projet property proudhon proxy psf publisher/consumer pull-down pygame pyjnius pypi python pythonar qtile raid rapsberry pi reading recorder references release religion responsive review reviews réseau réseaux sociaux résurection salon screenshots script self service shows shutil shyness sizing solib sortie sousous!!! spam spritz stash status systeme système templating terminal texture texture coordinates Thomas Paine thread thème tiling time time management. tip tips tools transformer tutorial tv twitter typematrix typing ubuntu ubuntu-fr ultimate-smash-friends unity upload images useless usf utils value VDM video vie/mort vim virtualenv visite widget windows wm wmii work workflow workflow. zine études