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...

0bin s’est fait tej

lundi 17 novembre 2014 à 11:28

On a eu une take down notice pour une page 0bin, et comme on a pas réagit assez vite, on nous a juste coupé le site.

J’adore cette justice qui se passe de l’avis du système judiciaire, qui renverse la charge de la preuve et donne le pouvoir à des sociétés privées qui sont juges et parties. Je n’ai pas encore regardé la page en question, mais que ce soit légitime ou non, la démarche est aberrante.

Je vois bien Mac Do qui arrive chez un boucher :

Monsieur, nous pensons que votre steak imite le notre, nous fermons votre boutique jusqu’à ce que vous ne le vendiez plus. Non on a pas l’autorisation d’un juge, on est pas une société française de toute façon, on a juste fait pression sur le propriétaire de votre immeuble. Non, c’est pas mafieux si c’est légal, monsieur.

En plus, c’est pas comme si le système était pas déjà abusé par les ayant droits ET les criminels.

Bref, 0bin est down le temps qu’on répare tout ça.

Un peu de fun avec les décorateurs

lundi 17 novembre 2014 à 02:06

Puisque la programmation asynchrone est au goût du jour, on se mange des callbacks un peu partout. Et ça alourdit toujours le code. Chaque langage, lib ou framework a essayé de trouver des astuces pour rendre tout ça plus digeste, et on a vu la naissance des Futures, Deferred, Promises, coroutines, yield from et autres joyeusetés.

Prenons par exemple un script Twisted. Déjà, Twisted, c’est pas vraiment l’exemple de la syntaxe Weight Watcher, ou alors si, mais avant le début du régime.

# -*- coding: utf-8 -*-
 
""" Télécharge des pages et affiche leur, de manière asynchrone """
 
import re
 
# Ceci doit être pip installé
import treq
from twisted.internet.task import react
from twisted.internet.defer import inlineCallbacks, returnValue
 
# Soit on utilise la syntaxe 'inlineCallbacks', c'est à dire avec des yields
# qui marquent les appels asynchrones.
@inlineCallbacks
def get_title(url):
    res = yield treq.get(url) # Ceci est asynchrone et non bloquant
    html = yield res.content() # Ça aussi
    try:
        val = re.search(r'', html.decode('utf8')).groups()[0]
    except:
        val = ''
 
    returnValue(val)
 
# Soit on récupère un objet defer et on ajoute un callback manuellement
def main(reactor):
 
    # Ceci est asynchrone et non bloquant
    defer = get_title('http://sametmax.com/quest-ce-quun-callback/')
 
    # Ceci arrive une fois que get_title est terminé
    def cb(title):
        print(title.upper() + '!')
 
    defer.addCallback(cb)
 
    # Pareil
    autre_defer = get_title('https://github.com/sametmax/django-quicky')
 
    def cb(title):
        print(title.upper() + '!!!')
 
    autre_defer.addCallback(cb)
 
    return defer
 
react(main)

D’une manière générale, je préfère la syntaxe à base de yields, même si elle oblige à se trimbaler le décorateur inlineCallbacks partout, à parsemer sa fonction de yields et à utiliser returnValue à la place de return puisque le mot clé est interdit dans les générateurs en Python 2.7.

Mais bon, ça reste facile à lire. On sait que les lignes avec yield, sont les appels bloquant qu’on demande à la boucle d’événements de traiter de manière asynchrone.

La syntaxe à base de callbacks est plus lourde, en revanche elle donne le contrôle sur la concurrence des callbacks puisqu’ils sont explicites au lieu d’être automatiquement ajoutés par magie. Elle parlera aussi plus aux dev Javascript qui ont l’habitude d’ajouter des callbacks manuellement.

Néanmoins, en JS, on a des fonctions anonymes plus flexibles, et on ferait donc plutôt une truc du genre :

get_title(url).then(function(title){
    # faire un truc avec le résultat
})

Et bien il se trouve qu’avec Python, bien qu’on ne le voit pas souvent, on peut avoir cette idée de la déclaration de son appel asynchrone juste au dessus de son callback, en utilisant des décorateurs.

En effet, les décorateurs ne sont que du sucre syntaxique :

@truc
def bidule():
    chose

N’est en fait qu’un raccourci pour écrire :

def bidule():
    chose
 
bidule = truc(bidule)

Du coup, on peut prendre n’importe quelle fonction, ou méthode, et l’utiliser comme décorateur :

@react
def main(reactor):
 
    then = get_title('http://sametmax.com/quest-ce-quun-callback/').addCallback
    @then
    def cb(title):
        print(title.upper() + '!')
 
    then = get_title('https://github.com/sametmax/django-quicky').addCallback
    @then
    def cb(title):
        print(title.upper() + '!!!')
 
    return cb

Et en jouant avec functools.partial, on peut faire aussi des trucs rigolos.

Non pas que cette syntaxe soit le truc indispensable à connaître et à utiliser. Mais les gens n’y pensent jamais. On utilise pas assez les décorateurs.

Par exemple, combien de fois vous avez vu :

def main():
    print('Doh')
 
if __name__ == '__main__':
    main()

Certaines libs, comme begin, font des décorateurs pour ça :

def main(func):
    if __name__ == '__main__':
        func()

Et du coup, dans son prog:

@main
def _():
    print('Doh')

Comme souvent, c’est le genre de feature qui peut être abusée, mais c’est parfois sympa de rapprocher une action juste au dessus de la fonction qui va être dans ce contexte.

J’espère ainsi vous avoir inspiré pour mettre un hack ou deux en production détournant complètement l’usage des décorateurs et ajoutant quelques gouttes de plus dans le vase de la sécurité de votre emploi, ou votre licenciement.

Pas de bras et pas de chocolat

jeudi 6 novembre 2014 à 09:39

On avait pas d’articles, on a pas de forum, et on aura de nouveau pas d’articles.

C’est à peu près le résumé de ces derniers jours.

Je m’étais lancé dans l’installation de Discourse pour avoir un petit forum pour accompagner le blog, et du coup je n’ai pas écrit.

Mais c’est un FAIL. Et du coup on a pas de forum.

Foxmask et Gordon ont proposé d’installer ça sur leurs machines, du coup on aura peut être quelque chose quand ils auront fait leur bidouille.

Mais je me casse dans un endroit où je n’auras pas accès au téléphone ou internet pendant 10 jours, du coup y aura pas d’articles ces deux semaines non plus.

Du coup je fais un post bien long pour dire qu’il ne se passera rien, si c’est pas du vrai journalisme ça !

Des idées que j’aurai jamais le temps de faire.

mercredi 5 novembre 2014 à 12:01

Ceci est un post invité de Réchèr sous licence creative common 3.0 unported.

Mon cerveau est absolument génial. Il trouve tout le temps un tas de projets super. Le problème c’est que mon corps est une grosse feignasse, et ne prend jamais le temps ni le courage de les réaliser. Du coup, je me retrouve avec un tas de bazar dans la tête dont je ne ferais jamais rien. Le mieux, c’est de l’offrir au monde.

Il y a un peu de tout : du potentiellement intéressant, du bien débile, et du carrément glauque. C’est en vrac, faites en ce que vous voulez.

Et puisque ça semble être une tradition pour les articles longs : un peu de musique.

Chocolate DB

“Maintenant, vous savez sur quoi vous allez tomber”

ipad_chocolate_ichocolates

Repas de Noël en famille. Au moment du café, votre grand-mère pose la traditionnelle boîte de chocolat sur la table. Votre tante est allergique aux noix, votre cousin converti à l’islam ne boit plus d’alcool, y compris sous forme de liqueur, et vous, vous voudriez éviter le caramel car ça colle aux dents. Comme chaque année, votre grand-mère a jeté le papier de description de la boîte, parce que “c’est écrit trop petit dessus”.

Le site de recensement Chocolate DB est là pour vous sortir de ce genre de situation délicate, avec des informations détaillées et individuelles de chaque chocolat, dans chaque boîte. Bien évidemment, le site comporte le bataclan habituel : tags, fonctions de recherche, avis des consommateurs, …

Si ça marche bien, on peut ensuite mettre en place un service d’échange entre personnes habitants à proximité. Deux machins dégeux à la noix de coco contre un succulent praliné au gianduja ? Ça marche !

Le concept est généralisable à tous ce qui se vend sous forme d’assortiment : yaourts aux fruits, sachets de thé, bonbons, bières, …

Pub’homme

toilet-paper-ad

Site web de contre-pouvoir à la publicité.

Au début, il y aurait juste des analyses et des recensements, pour mettre en lumière les techniques de fourbe régulièrement utilisées par la publicité :

Sérieusement, quelqu’un pourrait me dire ce qu’il y a de sexuel dans un putain de clacos ?

Ensuite, il serait envisageable de créer des structures de soutien aux victimes de la publicité. Par exemple :

(Parce que tout le monde n’est pas capable de se défendre aussi bien que les Leneuf).

Pour finir, on pourrait s’offrir quelques flash mobs. 500 personnes se retrouvant à une finale de Rolland-Garros pour balancer des Kinder Buenos à la gueule de Jo-Wilfried Tsonga, ça vous tente ?

Un jeu web avec une économie déflationniste

WoW_stats

Si vous lisez ce blog, vous connaissez déjà les bitcoins et les crypto-monnaies. L’une des raisons pour laquelle ce type de monnaie ne se démocratise pas, c’est qu’elles sont déflationnistes, un fonctionnement assez inhabituel. Un jeu web permettrait de le faire découvrir, d’expérimenter des situations, de détecter des comportements émergents, etc.

Pour le jeu en lui-même, pas la peine de se prendre la tête, il suffirait de reprendre un thème classique : gestion d’une ferme / d’un héros / d’un bar à gigolos … L’économie du jeu aurait les particularités suivantes :

Ce dernier point comporte un risque, car les joueurs pourront décider d’utiliser une ressource de base pour leurs échanges, à la place de la monnaie déflationniste. Par exemple, ils définiront leurs prix en caisse de patates, plutôt qu’en pièces d’or. Ce risque est toutefois limité. Si la caisse de patate devient de fait la monnaie universelle, tous les joueurs chercheront à en fabriquer. Comme c’est une ressource de base, elle est très facile à produire, et elle deviendra donc une monnaie hautement inflationniste, en laquelle il sera difficile de faire confiance. Il y aura peut-être cohabitation de plusieurs monnaies. On ne sait pas, mais je pense que ça vaudrait le coup de tester.

YourCryptoCoins

crypto-coins

Un logiciel simple pour créer sa propre crypto-monnaie, avec pleins de paramètres à ajuster, histoire de tester s’il y a plus efficace que le bitcoin :

Ça permettrait aux gens de se créer leur petite crypto-monnaie locale, ce qui est peut-être un peu plus fiable que des bouts de papier imprimés à l’arrache avec écrit “Soleil” dessus.

Un réseau de communication vraiment décentralisé.

semaphore

Le problème d’internet, c’est que les adresses IP sont attribuées par des autorités centrales. Et le support de communication (les fils téléphoniques et le spectre radio) est également sous contrôle central. Je ne sais pas trop comment y remédier, mais ça mérite réflexion.

On pourrait mettre des capteurs et des petites lumières clignotantes sur les toits des maisons, qui se transmettraient les informations entre eux. Concrètement, vous ne pouriez communiquer qu’avec vos voisins, mais des messages pourraient transiter de maison en maison. Et on utiliserait des uuid pour identifier chaque point du réseau. Avec un système de clé publique-machin-truc pour garantir l’identifiant de chaque point et éviter les usurpations d’identité.

Et pour les zones peu densément peuplée, on utiliserait des successions de petites lumières, ou des fils mais gérés de manière décentralisée.

Ce serait sûrement très lent et pas fiable (si vos voisins n’ont pas allumé leurs transmetteurs, vous ne pouvez plus communiquer). Mais ce serait “libre”. Et du coup, pas d’abonnement à payer, juste de l’électricité.

C’est vraiment brumeux comme idée, parce que j’y connais rien en bidouilleries réseau. Si d’autres gens ont des améliorations à proposer, qu’ils n’hésitent pas.

Poilatout

cousin_machin

Algorithme, qui, à partir d’une phrase donnée, renvoie le “poil au” correspondant.
Exemple :
“Quand l’imbécile montre la Lune”
-> “poil aux burnes”
“Le sage lui met un doigt”
-> “poil au foie”

Y’a plus qu’à plugger ça avec Siri, et votre smartphone vous permettra de spammer toutes vos conversations de “poil au”.

Si ça sert à rien, c’est que c’est indispensable.

Mi-tik

“Trouvez votre moitié”.

half_man_Andy_Gross

Vous êtes unijambiste de la jambe gauche. Vous vous inscrivez sur le site Mi-tik. Vous avez alors la possibilité d’être mis en relation avec des unijambistes de la jambe droite. Si vous trouvez quelqu’un qui vous correspond, vous obtenez 50% de réduction sur tous vos achats de chaussures.

Le site permet également de faire se rencontrer les manchots d’un bras, les borgnes, les “Van Gogh”, les hémiplégiques, …

HarDis (Harcèlement Distribué).

“Pensez dystopie globale, agissez dystopie locale”.

dented-car-chuck-norris

La loi française ne vous interdit pas de chier sur le palier de votre voisin, de rayer sa voiture ou de l’appeler à 2 heures du matin. Mais elle vous interdit de le faire de manière répétée. Ça s’appelle du harcèlement.

Le “réseau d’entraide HarDis” permet de s’affranchir de ce détail. Vous vous y inscrivez en déclarant un périmètre géographique d’action. Vous recevez ensuite des missions, vous demandant d’agir chez une personne-cible. Vous ne recevez jamais deux missions sur une même personne. À chaque fois que vous en effectuez une, vous envoyez une preuve de réalisation (photo, vidéo, …) et vous gagnez des points. Vous pouvez dépenser ces points pour créer des missions sur des gens que vous n’aimez pas.

L’identité et l’adresse des personnes-cibles est révélée le plus tard possible. Chaque compte a un indice de confiance, visible par tous, qui augmente lorsqu’on effectue une mission et diminue lorsqu’on en prend une et qu’on ne l’effectue pas. Le but étant de limiter les “espions” (des personnes qui ne veulent pas réaliser de missions, mais qui veulent juste surveiller si elles ne sont pas la cible de missions existantes).

Bien entendu, vous pouvez acheter des points, et bien entendu tous les outils d’anonymat sont disponibles : réseau Tor, crypto-monnaie, …

ADN-Fuck

“Là où y’a des gènes, y’a du plaisir”.

ensalada-de-pasta

La société ADN-Fuck rachète vos petits déchets corporels : salive, poils, sang, peaux mortes, urine, sperme… Elle les mélange avec ceux de centaines de personnes, et revend le tout sous forme de petit sachet.

Quelqu’un souhaitant commettre un acte illégal peut acheter l’un de ces sachet d’anonymisation, et le répandre sur les lieux de son acte. Bonne chance à la police scientifique pour retrouver l’ADN du coupable !

La société ADN-Fuck en elle-même ne commet rien d’illégal. Le commerce de poils de cul est, à priori, toujours autorisé dans la plupart des régions du globe.

RoboCraft

minecraft_robot

Un jeu vidéo comme Minecraft, mais avec des robots programmables (en python, évidemment !). On peut les faire miner, construire, explorer, transformer des ressources, etc.

Il y a déjà un add-on de Minecraft pour ça (ComputerCraft), mais c’est pas quelque chose de très officiel. Du coup, tout l’équilibrage du jeu est fait sans tenir compte de ComputerCraft. Un jeu conçu spécialement avec des robots, ce serait super chouette.

Ça rejoint le concept d’automatic-play, dont on parle ici ou là : http://gamestudies.org/1301/articles/depaoli_automatic_play

Et il faudrait une économie déflationniste dans le jeu. Et des robots à reconnaissance vocale qui disent “poil au cul”.

Multi-versus

multi_versus

Un jeu vidéo composé de mini-jeux, dans lequel deux joueurs ou plus s’affrontent, chacun avec un mini-jeux différent.

Par exemple, le joueur 1 (Tetris) affronte le joueur 2 (Puzzle Bobble). Lorsque le joueur 1 effectue des actions valorisantes, (détruire plusieurs lignes à la fois), il envoie de la difficulté au Puzzle Bobble du joueur 2 (des bulles noires impossible à détruire). Et vice-versa : si le joueur 2 détruit plus de 3 bulles d’un coup, il envoie des lignes de cochonnerie sur l’aire de Tetris du joueur 1.

Ce n’est faisable qu’avec des mini-jeux ou chacun joue sur son terrain (pas de Bomberman ni de Pong, par exemple), et ce serait une galère monumentale pour les équilibrer entre eux, mais ça serait vraiment fun.

Un format de fichier pour décrire des dessins animés.

Ce serait un format human-readable. C’est très important, car ça augmente la potentialité de bidouillage par n’importe qui, y compris des gamins de 8 ans.
Ça pourrait ressembler à ceci par exemple :

img_balle = http://s2.postimg.org/w709hznpx/balle.png
img_balle_ecrase = http://s18.postimg.org/hy41jochx/balle_ecrase.png
area = 147, 275
default_time = 5 ms

ball = Sprite(img_balle, 20, 0)
ball.move(0, 10)
ball.move(0, 10)
ball.move(0, 10)
ball.change_img(img_balle_ecrase)
ball.move(0, -10)
ball.move(0, -10)
ball.move(0, -10)

Et ça donnerait quelque chose de ce genre :

bounce_147

Et ensuite, on pourrait faire plein de trucs avec ce format de fichier :

Vous allez me dire : “mais il y a déjà plein de trucs qui font ça : le flash, les gifs animés, Blender…”

Oui, sauf que le flash c’est pas libre, les gifs c’est pas optimisé et c’est super compliqué à reprendre et à bidouiller, et Blender, il faut des mois de pratique avant de savoir faire quelque chose de correct.

Ce format de fichier permettrait de créer rapidement des petits trucs à l’arrache, des cartes de vœux, des memes animés, etc. Et comme c’est du texte, c’est versionable et éditable collaborativement.

Githubiser pleins de trucs.

github-octocat

Alors voilà, vous êtes un musicien et vous faites un solo de flûte à bec comme ça pour déconner. Vous le mettez sur gitsound. Quelqu’un d’autre arrive et ajoute une ligne de basse. Un autre y met quelques paroles. Un autre refait votre air initial avec une guitare électrique. Un autre reprend le tout en accéléré. Un autre y ajoute un “Cher effect” et colle un flow de rap par dessus. Et ainsi de suite.

Ou alors, vous êtes un modéliseur 3D et vous commencez à créer un arbre géant. Quelqu’un arrive et ajoute des mini-branches pour lui donner un air plus détaillé. Un autre met des textures plus belles pour les feuilles. Un autre creuse un trou à l’intérieur. Un autre le recopie en 1000 exemplaires sur un quadrillage pour en faire un décor de clip de Mark Gormley. Et ainsi de suite.

Il y a plein d’autres trucs qu’on pourrait githubiser afin de faciliter la création collaborative : les images (vectorielles ou pas), les recettes de cuisine, les règles de jeux de société, les dessins animés, les positions du kama-sutra, … Et pour certains médias, le github de base, qui ne permet de traiter que du texte, ne suffit pas.

Un Tolkien de la culture africaine

blackfoot-medicine-man-right

Tolkien connaissait toutes les légendes de son pays et d’ailleurs. Il a défini la plupart des éléments de l’heroic fantasy. Sans lui, pas de Donjons et Dragons, de World of Warcraft, ou de Harry Potter. Maintenant, l’heroic fantasy vole de ses propres ailes et emprunte des éléments à d’autres cultures : momies égyptiennes, ninjas asiatiques, doppelgängers teutons, mind flayer lovecraftien, …

Mais à part les zombis, on trouve très peu de choses empruntés à la mythologie africaine. C’est vraiment dommage, car avec le foisonnement culturel de ce continent, on pourrait créer des mondes imaginaires de dingue, peuplés de créatures étranges et de magie aux règles complexes, très différent de l’heroic fantasy.

Il faudrait une personne qui connaisse tous ces trucs (l’animisme, le vaudou, les totems, les esprits, …) et qui s’en inspire pour écrire une chiée de bouquins. Ensuite, les rôlistes, les gamers et J.K. Rowling feront le reste.


Voilà, ce sera tout pour le moment. Phosphorez mes braves, phosphorez !! Et si l’une de ces idées existe déjà réellement, prévenez-moi, ça m’intéresse.

Automatiser un peu plus SQLAlchemy declarative

mercredi 29 octobre 2014 à 13:34

Avec l’intégration de l’interface déclarative d’SQLAlchemy, le projet Elexir est mort, et bien mort. Mais avec lui, la syntaxe la plus simple de déclaration pour cet ORM. En effet, par défaut, SQLA vous oblige à spécifier le nom de la table et l’attribut ID pour chaque classe :

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
 
Base = declarative_base()
 
class Person(Base):
    # explicit is better than... fuck it !
    __tablename__ = 'person' 
    id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)
 
class Animal(Base):
    __tablename__ = 'animal'
    id = Column(Integer, primary_key=True) # Paie ton DRY
    name = Column(String(250), nullable=False)
 
engine = create_engine('sqlite:///db.db.db...db')
Base.metadata.create_all(engine)

SQLA est très flexible, et il existe des tas de raisons pour vouloir un PK ou un nom de table custo. Mais dans beaucoup de projets, le nom de la table peut être le nom de la classe, et la PK peut être un ID auto incrémenté.

Heureusement, la lib vous permet de customiser absolument tout, même la manière dont on doit la customiser. Si c’est pas méta, tout ça…

Bref, on peut créer sa propre base déclarative qui va faire tout ça pour nous :

from sqlalchemy.ext.declarative import as_declarative, declared_attr
 
# Ceci sera le parent de tout nos objets
@as_declarative()
class Base(object):
 
    # Vu qu'on a pas vraiment envie de se réécrire la
    # métaclasse, SQLA nous file ce gentil décorateur 
    # pour déclarer des attributs qui ne sont pas des 
    # champs
    @declared_attr
    def __tablename__(cls):
        # le nom de la table est le nom de la classe
        return cls.__name__.lower()
    # L'id c'est la vie
    id = Column(Integer, primary_key=True)
 
class Person(Base):
    name = Column(String(250), nullable=False)
 
class Animal(Base):
    name = Column(String(250), nullable=False)

Evidemment il faut que vous soyez certains d’éviter les conflits liés à cette décision, mais c’est quand même vachement pratique.

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/?86 #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}