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

Réaction à ReactJS 14   Recently updated !

mercredi 10 mai 2017 à 20:39

Grand utilisateur de jQuery, formateur Angular et maintenant adorateur de VueJS, vous vous demandez sûrement ce que je pense de React. Si, je le sais, mon avis est pour vous comme un phare dans la nuit sombre du frontend engluée dans le brouillard de Javascript.

Après tout, facebook est codé avec cette techno pixel par pixel, et ils servent des milliards de pages chaque jour. Ça ne peut pas être mauvais. Ce ne sont pas de cons quand même.

Et puis tout le monde en parle, les asticots gigotent autour des restes du gigot d’ordre que les devs des GAFAS tentent de mettre au menu dans leur régime sans sel et sans typage.

Alors merde, quoi, react, keskeçavo ?

Je vais passer peut être pour un réact (hashtag lol), mais franchement le gigot au brouillard, c’est pas mon plat préféré.

Taillons un peu JS, ça m’avait manqué.

Mon royaume pour un hello world

React est tellement chiant à setuper que la doc officielle vous propose le hello world dans un code pen histoire de pas vous faire fuir tout de suite.

En fait, si pour vous installer un module avec npm/yarn/bower (plutôt que de copier le truc directement ou d’utiliser un CDN) est déjà un truc qui vous fait grogner, vous êtes loin derrière.

Il va vous falloir un outil de build (gulp, grunt ou l’usine à Vespene Webpack) et la série de recettes obsolètes customisées trouvées sur un coin de github pour connecter tous les bouts de votre pipeline. React bien sûr, mais aussi babel pour transformer le JSX en JS.

Babel suit la left-pad philosophie, à savoir que tout est configurable et éclaté en centaines de petites dépendances et settings. C’est tellement chiant que des packages existent, appelés “presets”, dont l’unique but est de configurer babel pour une tâche particulière.

Une fois que vous avez tout ça up, vous vous allez à la pêche au tuto, seulement pour remarquer que tout le monde code en ES6, voir ES7, et vous rajoutez donc un peu plus de plugins à tout ce bordel. Allah vous garde si vous tentez d’utiliser typescript.

Et vient alors le moment tant attendu pour faire coucou de la main programmatiquement. Ça foire, bien entendu. Le debugger vous pointe sur un bundle.js de plusieurs Mo, et vous apprenez que le support des sources maps est inégale d’un navigateur à l’autre.

Bienvenue.

Le X c’est pas toujours excitant.

Une fois passée la douloureuse expérience de mettre en place votre environnement de travail, vous trouvez un certains confort. L’autoreload de la page est franchement pratique, et pouvoir utiliser l’unpacking (pardon le spread), les valeurs de paramètres par défaut et les arrow functions sans vous soucier de la compat du navigateur c’est quand même cool. Avec un webpack tout bien huilé avec amour (et douleur), vous pouvez faire des imports en JS et on a presque l’impression d’utiliser un langage de programmation.

Et puis le JSX, de loin ça à l’air pas mal ! Du HTML directement dans le JS ça parait un peu bizarre mais on vous le vend comme un avantage : finit les langages de templates limités, vous pouvez utiliser la pleine puissance (hum…) du langage Javascript pour créer vos balises.

Sauf que non, le JSX, ça pue du cul.

D’abord, il y a le fait que toutes les structures sont à faire en JS. Les conditions, les concaténations et bien entendu, les boucles. Donc vous avez une liste de noms et numéros de téléphone, en VueJS, vous faites:

<ul>
    <li v-for="pers in persons" v-if="pers">
        <strong>{{ pers.nom }} </strong>: {{ pers.tel }} 
    </li>
    <li v-else>
        <em>Nobody's here!</em>
    </li>
</ul>

Mais en React, vous allez faire péter une expression ternaire et une fonction anonyme en plein milieu rien que pour l’occasion:

<ul>
    {
      (this.state.persons)
        ? this.state.persons.map((pers) => (
            <li><strong>{ pers.nom } </strong>: { pers.tel } </li>
        ))
        : (
            <li>
                <em>Nobody's here!</em>
            </li>
        )
    }
</ul>

Vous la sentez bien la puissance de Javascript là ?

Et attention à ces boucles, car dedans vous guette cette erreur qui va vous poursuivre jusque dans vos cauchemars:

SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag

Babel vous signale gentiment que ne pouvez pas produire un snippet de JSX qui contienne plus d’un élément à la racine. Donc il faut TOUT wrapper dans un container. TOUT. Vous allez avoir vite des DIVs et des SPANs inutiles partout, juste pour faire plaisir à React. C’est absurde. C’est à vomir. Ca nique votre CSS et rempli vos sessions “examinez un élément” de tendinites dues aux clics pour déplier tout l’arbre des emballages cadeaux de vos balises. Et aussi, nique la sémantique.

Pour éviter ça vous allez tenter d’inliner un maximum de truc dans une seule expression JSX ou tout foutre dans des arrays. Car je ne l’ai pas précisé ? Les arrays de JSX sont automatiquement et magiquement convertis en sous-elements. Et du coup vous pourrez profitez au maximum des qualités de lisibilités de JS.

JSX est bourré de petits trucs comme ça, pour faire plaisir. Par exemple, j’ai un button, quand je le clique il delete la personne de la ligne de mon agenda. Je mets aussi une classe pour tous et une selon que la personne est importante ou non. Un prevent default pour éviter que le browser recharge la page si je suis dans un form.

En Vue, je passe un objet qui dit quelle classe afficher ou non. Le click handler contient une instruction prevent qui me permet d’appeler preventDefault automatiquement. Et j’appelle deletePerson tout naturellement :

<button class="{'delete-person': true, 'important-person': pers.isImportant}" 
        v-on:click.prevent="deletePerson(pers)">
    Delete
</button>

En react, on ne peut pas passer de paramètre à son handler. Il faut le passer dans une closure. Mais alors la closure va recevoir l’objet event, qu’on doit donc faire suivre à notre handler, afin qu’il puisse appeler preventDefault à la main. A noter aussi que class s’appelle className. Et n’accepte que des strings donc la concaténation se fait à la mano.

// plus haut on appelle preventDefault dans handleDelete
 
<button className={'delete-person ' + (pers.isImportant ? 'important-person': '')}
        onClick={(e) => this.deletePerson(pers, e)}>
    Delete
</button>

Ce n’est pas juste chiant à lire, c’est surtout hyper chiant à trouver, à taper et à debugger.

Un peu de nutella sur votre confiture ?

React, c’est verbeux, il va falloir vous y faire. Il suffit de comparer le code nécessaire pour faire une TODO en react avec les autres frameworks.

Mais ce n’est pas juste ça qui est lourd.

Non, le vrai truc qui est super pesant, c’est que react est un cancer. Quand il est utilisé, il contamine tout.

Par principe, une fois que vous utilisez react, il faut mettre TOUTE VOTRE PAGE en react. Pas juste un petit bout. Par là j’entends que 90% de votre HTML va devoir migrer dans le code JSX. Votre beau code HTML bien propre, converti en cette monstruosité de mélange entre le langage le plus dégueulasse du monde et un monstre mimic qui essaye de se faire passer pour du HTML pour vous bouffer.

Or, toute l’idée c’est de faire des composants, de diviser votre pages en plus petits bouts. Mais voilà, React n’a rien prévu de simple pour la communication. Pour passer des données des composants enfants, il faut les passer via les attributs de balise HTML (appelés les props, pour faciliter la rechercher Google). Si vous avez 5 niveaux d’imbrications, vous vous tapez ça 5 fois.

Plus amusant, il n’y a aucun mécanisme pour passer des infos de l’enfant aux parents. La méthode standard est d’écrire puis passer manuellement un callback du parent à l’enfant, via props, et appeler ce callback dans l’enfant avec la valeur que le parent utilise ensuite. POUR. CHAQUE. PUTAIN. DE. VALEUR.

Passer des callbacks, ça va 5 minutes. Et ca ne résout pas un problème de communication entre composants parallèles, c’est à dire ni parent, ni enfant. Du coup tout le monde finit par utiliser une lib supplémentaire type EventEmitter pour servir de bus de communication.

Quand vous entendez les gens se plaindre de la difficulté d’utiliser l’écosystème de react, les fans répondent souvent que l’écosystème n’est pas obligatoire. On peut très bien s’en passer sur un petit projet.

Sauf que react est absolument inutilisable sans. Sans un bus d’event, un transpiler ES6 + JSX, un builder et un hot reloader au mininum, le projet ne dépasse jamais le stade du prototype.

Mais bon soyons franc, beaucoup de projets react tout court ne dépassent jamais le stade du prototype. On parle de codeurs JS là.

Etat

Les props ne doivent jamais changer. Seul l’état d’un composant react peut changer, ce qui trigger un nouveau rendu du composant.

Mais l’état lui-même est en read-only. On est supposé uniquement créer un nouvel état à chaque fois et remplacer l’ancien.

Au début on le fait à la main, mais JS n’est pas vraiment fait pour faire de l’immutabilité, et ça devient uber chiant très vite. Changer la propriété d’un objet qui est lui même dans un array demande de recréer tout l’array et l’objet. A chaque fois.

On se tourne alors vers des libs (encore une) type immutable.js qui fournit des listes et maps qui sont immutables et permettent de faire ces opérations sans y laisser ses jours de congé.

Une fois de plus, les connards qui vous disent qu’on peut faire du react sans la tonne de boiler plate qu’on voit dans les tutos ne le font jamais eux-mêmes. Parce que oui, on peut faire Paris-Amien à pied en théorie, mais bon…

Des décisions à la con

Clairement, react a été fait pour créer des UI. Mais au bout d’un moment, les utilisateurs se sont réveillés et ont voulu une encapsulation pour des composants non UI. Mais react ne sait pas faire. Quand vous avez donc un composant non UI, par exemple la déclaration de votre routing, vous le déclarez… en JSX:

  render((
      <Router history={browserHistory}>
        <Route path="/foo" component={FooView}/>
        <Route path="/bar" component={BarViw}/>
      </Router>
  ), document.getElementById('app'))

Votre app va devenir très vite une pyramide de composants, certains qui s’affichent, d’autres non, tous se passant en cascade des données les un aux autres.

Et au passage, quel est l’abruti qui a décidé des noms des méthodes des cycles de vie comme

getInitialState

,

componentWillMount

et

componentDidMount

?

Surtout que vos méthodes et les méthodes héritées de la classe du component sont dans le même espace de nom.

Le bonheur des stores

Un truc dont on peut vraiment se passer par contre, ce sont les stores. Flux, redux, vuex, etc. On peut utiliser n’importe quelles solutions pour stocker l’état de son projet côté client.

Mais si vous voulez profiter des promesses de react, comme le time travel et la concurrence parfaite, il vous faudra un store.

“store” c’est le nom huppé que react donne à ses modèles. Je ne vais pas rentrer dans les détails, et vous laissez décider par vous même du truc. Voici, comment la doc vous recommande d’ajouter une personne dans une liste d’un agenda avec redux, la store la plus populaire:

// Les imports
import React from 'react';
import { render } from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
 
// creation du store
const initialState = {'agenda': []};
 
function reducer(state=initialState, action){
  switch (action.type) {
    case 'ADD_PERSON':
      return {
        'agenda': [..., action.object]
      }
    default:
      return state
  }
}
 
const store = createStore(reducer);
 
 
// creatin de l'action d'ajouter un objet dans le store
 
function addPersonAction(obj){
    return {
        'type': 'ADD_Person',
        'object': obj
    };
}
 
 
export function addPerson(Person){
    store.dispatch(addPersonAction(Person));
}
 
 
// composant qui affiche le form de l'agenda et la liste des personnes
var Agenda = React.createClass({
 
  handleAdd: function(){
      addPerson({
        "name": this.refs.name.value,
        "tel": this.refs.tel.value
      })
  },
 
  render: function(){
 
    return <form onClick={this.handleAdd}>
        <p><input ref="name" /><input ref="tel" /><button>Add</button></p>
    </form>
 
    <ul>
        {
            this.store.agenda.map((pers) => (
                <li><strong>{ pers.nom } </strong>: { pers.tel } </li>
            ))
        }
    </ul>
  }
 
 
});
 
 
// adapter qui permet de passer le store à l'agenda
const AgendaContainer = connect(function(state){
    return {'agenda': state.get("agenda")};
})(Agenda);
 
 
// affichage du bouzin
render((
<Provider store={store}>
  <AgendaContainer>
</Provider>
), document.getElementById('app'))

Vous imaginez bien que trouver ça tout seul a été un bonheur. Parce que oui, la doc est absolument à chier, dans la longue tradition des stacks JS moderns.

Le don du mois : vue.js

lundi 1 mai 2017 à 10:37

Le pognon rentre à nouveau et c’est donc le retour du don du mois.

Ça ne fait que quelques temps que j’utilise cette lib, mais globalement c’est déjà mon outil par défaut pour toute UI en JS.

J’ai encore des demandes de formations et projets pour Angular 1 et React, mais si j’ai le choix il n’y a aucune hésitation.

J’ai essayé quelques alternatives, comme Riot, mais on arrive jamais à cette combinaison parfaite de simplicité, légèreté, puissance et performance. Ce projet est un petit bijoux du monde de l’open source. Un truc rare en Javascript.

Bref, c’est bien beau de cracher toujours sur JS, mais ça résout pas le problème. Il faut aussi aider, et c’est donc pour ça que je fais un don de 50 €, par ici.

Et si vous regrettiez l’époque de la simplicité de jQuery mais que vous avez envie de quelque chose qui automatise bien plus comme un framework moderne, vous savez ce qu’il vous reste à essayer :)

Comment garder des lignes courtes ? 9   Recently updated !

vendredi 28 avril 2017 à 15:02

Arg, j’ai plein de commentaires sans réponse sur le blog, indexerror aussi. Des tickets millénaires sur 0bin et les impôts qui arrivent. Dois fois ce qu’il faut c’est une petit victoire pour relativiser.

Du coup, un petit post pour me donner l’impression de ne pas être inutile à l’humanité.

De toutes les recommandations du PEP8, garder des lignes courtes, souvent moins de 80 caractères, est celle qui fait le plus râler.

On rétorque parfois que c’est une règle qui n’a pas de sens de nos jours avec nos grands écrans HD.

Sauf que:

D’une manière générale, garder des lignes courtes est une bonne habitude et incitera à écrire un code sain. Le processus de réduire la taille des lignes passe par l’expressivité, la clarté, le refactoring, etc. Au final, c’est excellent pour la santé du projet.

N’oubliez pas non plus que le PEP8 indique clairement qu’il ne faut jamais suivre une règle de manière rigide. Si votre ligne est absolument plus adéquate sur une ligne, alors mettez là sur une ligne.

Maintenant qu’on a expliqué le pourquoi, parlons du comment. En effet beaucoup de bonnes pratiques ne sont pas appliquées parce qu’on ne sait pas faire. Faire des lignes courtes demande une certaine connaissance, et un peu de pratique.

Voici quelques pistes pour vous aider dans vos prochaines sessions.

Python est fait pour ça

Python force à indenter, et c’est une de ses meilleures caractéristiques. Jamais vous ne vous retrouverez comme dans d’autres langages face au code de votre collègue, ce gros porc, aligne ses accolades avec le groin.

Mais pour garder des lignes courtes, l’indentation joue contre vous.

Python vient heureusement avec tout un tas d’outils pour qui rendre votre code court, rapide et peu gourmand on mémoire. C’est tout bénef.

itertools, all(), any(), filter(), map(), collections, les listes en intension, functools et les générateurs sont tous d’excellents moyens de créer un code plus beau, plus court, et plus efficace. Apprenez à les utilisez ! Vous serez un meilleur programmeur, plus productif, et les lignes seront naturellement plus courtes.

Exemples…

Le module itertools permet de faire un tas de choses, comme remplacer les boucles imbriquées.

Remplaçons :

>>> for lettre in "abc":
...     for chiffre in (1, 2, 3):
...         print(lettre, chiffre)
...
a 1
a 2
a 3
b 1
b 2
b 3
c 1
c 2
c 3

Par :

>>> from itertools import product
>>> products = product("abc", (1, 2, 3))
>>> for lettre, chiffre in products:
...     print(lettre, chiffre)

Les built-ins ont un tas d’outils pour pour manipuler les données.

Si vous avez des collections dont vous voulez vérifier tout le contenu:

>>> from random import randint
>>> data = [randint(0, 10) for x in range(0, randint(0, 10))]
>>> max(data)  # pas besoin de boucler pour trouver le max
9
>>> if any(x > 3 for x in data): # any est un super "or"
...    print('Un élément est supérieur à 3')

Le module collections possède d’ailleurs tout un tas d’outils pour faire le travail à votre place :

>>> from collections import Counter
>>> Counter("aaaaaaaaabbbbbbccccc")
Counter({'a': 9, 'b': 6, 'c': 5})

On peut éviter un tas de try/except avec les helpers qui retournent une valeur par défaut:

>>> {"foo": 1}.get('bar', 3)  # et next, iter, setdefault... 
3

Sans parler de l’unpacking, le slicing, le paramétrage dynamique, etc.

Bref, si votre ligne est trop longue, c’est peut être parce que vous être en train de sous utiliser Python.

De même, apprenez les libs les plus célèbres en Python.

pytest, pendulum, request, pandas…

Dès qu’un usage particulier intervient, elles seront généralement plus efficaces que la stdlib. Moins de code !

Refactorisez

Un bloc de code qui commence à être long sera aventageusement déplacé dans une méthode ou une fonction. Avec un joli nom bien explicite qui va naturellement rendre votre code mieux documenté, et testable.

Tant qu’on y est, faites usages des variables intermédiaires.

res = [foo for foo in objet.attribut['cle'] if foo > wololo]

Gagnera à devenir:

nom_explicite = objet.attribut['cle']
res = [foo for foo in nom_explicite if foo > wololo]

Les parenthèses pour les sauts de ligne

Les parenthèses en Python, c’est magique.

Avant :

from module_de_la_mort_qui_tue import foo, bar, et, toute, la, clique

Après

from module_de_la_mort_qui_tue import (
	foo, 
	bar, 
	et, 
	toute, 
	la, 
	clique
)

Ca marche partout, dans les appels de fonctions, l’accès des attributs, les chaînes de caractères…

On part de :

queryset = ModelDeDjango.objects.filter(attribut=val).first()

Et bim :

queryset = (ModelDeDjango.objects
                         .filter(attribut=val)
                         .first())

Si des parenthèses sont déjà là, inutile d’en rajouter:

Aller :

raise OverkillError("Arrrrrrrrrrrrrrrrrrrrrrrrrrrrggggggg")

Hop :

raise OverkillError(
	"Arrrrrrrrrrrrrrrrr"
	"rrrrrrrrrrrggggggg"
)

Aidez-vous de l’environnement

Vous outils sont là pour vous faciliter la vie. Votre éditeur par exemple, a certainement un moyen d’afficher un indicateur vertical pour symboliser la limite de 80 caractères.

Les bons IDES et les linters vous signalerons le dépassement. Ca vaut le coup d’investir dedans. Si votre éditeur ne le supporte pas par défaut, il a peut être un plugin pour utiliser un linter.

VSCode et Sublime Text ont tout deux des plugins pour Python qui permettent cela. Notamment ils peut exploiter l’excellent linter flake8, qui sinon peut s’utiliser à la main.

Pour certains lignes, vous allez dépasser. Ce n’est pas la mer à boire tant que c’est un choix conscient et pas de la flemme.

Par exemple, les commentaires avec des URLS dedans dépassent souvent. Beaucoup de linters ont un réglage pour les autoriser (ou un pattern au choix), activez le.

Si vous avez une ligne qui dépasse et que le signalement de votre IDE/linter vous casse les couilles, il est souvent possible de le désactiver en ajoutant en fin de ligne le commentaire:

# noqa

Qui signifie tanto “no question asked” ou “no quality assessment”.

Sheepit – Le rendering pour tous, accessible sans trop de difficultés et gratos 1   Recently updated !

mardi 18 avril 2017 à 12:20

Entre deux bars à putes et les restaux faut bien prendre un peu de temps pour se relaxer, il y a les salons de massage branlette vous me direz, mais pas que.

Dans une galaxie lointaine il y a fort fort longtemps je m’amusais à faire de la 3D, je vous parle d’un temps que les jeunes ne peuvent pas connaîtres…
A l’époque reignaient en maîtres absolus 3DS MAX, MAYA, CINEMA 4D, etc et les outils maisons des studios Pixar. Pour les simples mortels comme moi on avait droit à Truespace, Vue D’esprit, Poser et sûrement d’autres dont j’ai oublié le nom. Truespace était mon favoris, plutôt sympa, pas compliqué à prendre en main et pas cher (voir gratos quand on se démerdait).

Pour faire mumuse c’était super mais voilà, c’était long, long, longggggg………..

De nos jour on a droit à de supers cartes graphiques comme les Titans X  et pas mal de logiciels de 3D gratuits aussi, certe on peut faire dans le warez et se procurer Maya, 3D Studio, Cinema4D et plein de nouveaux que je ne connais pas mais restons dans le légal pour une fois car ce qui se passe est intéressant.

Donc le monde du gratos a super bien évolué, il y a plein de tutos sur youtube, des logiciels gratuits concurrencent les plus gros soft de 3D sur le marché et si ses derniers ont du succès c’est surtout parceque les studios en ont fait leur standard.

Je vais vous parler de Blender , c’est un projet open source que je suis de très loin mais qui a attiré mon attention depuis peu avec quelques superbes vidéos sur youtube sur lesquelles je suis tombé:
https://www.youtube.com/watch?v=-TksegJETqI
https://www.youtube.com/watch?v=kSp3pHA_tRM
https://www.youtube.com/watch?v=7lY9SlQ8gjY
https://www.youtube.com/watch?v=Q1VCLFJY250
https://www.youtube.com/watch?v=143k1fqPukk
https://www.youtube.com/watch?v=LcCQKuWPhXk

Il y a vraiment une bonne communauté 

Des milliers de tutos sur youtube pour s’en sortir avec les millions d’options que possède le logiciel.

Bref tout ça c’est merveilleux, pour perdre son temps y a pas mieux. Mais il y a un hic, le temps de rendu justement. Je me souviens de cette époque où j’attendais 1 heure, voire 2 pour rendre une seule image et m’apperçevoir que le résultat était moyen.
Et de ce côté ça n’a pas changé ! C’est même plus long avec toutes les nouvelles options de raytracing possibles même avec des cartes graphiques surpuissantes comme cité plus haut. Alors une animation….

Blender possède un plugin de network rendering, à savoir partager le temps de calcul sur plusieurs serveurs du réseau, c’est sympa mais c’est pas tout le monde qui a 10 ordis à la maison…

Une solution a vu le jour il y a quelques années et quelques milliers de membres font vivre une véritable ferme de rendu.

Le principe de la ferme de rendu:
Via un réseau d’ordinateurs on partage le temps cpu entre plusieurs machines, accélérant ainsi le temps de rendu.

Cette solution c’est Sheepit.

Ok on décolle ! Vous installez leur app java sur un serveur qui traîne au garage ou sur votre ordi et vous avez droit à des points en fonction du temps machine que vous consacré à l’application. Ces points vont vous permettre “d’acheter” du temps de calcul parmi tous les participants.
Ainsi un projet d’animation qui d’ordinaire me prend 5 jours est rendu en quelques heures, gratos en plus !

Je trouve le concept très sympa, tout est gratuit, il y a une admin avec le nombres de personnes qui partagent vos calculs, on peu former des équipes pour se tirer la bourre ou privilégier les cpu à ses coéquipiers, bref c’est bien pensé et je voulais en parler pour, qui sait, leur ramener un peu de monde.

Aux dernières nouvelles il y a environ 350 machines connectées en permanence, vous imaginez le temps de calcul offert !

Une petite ligne de code pour mettre un serveur dans la pool:

inscrivez-vous sur sheepit : https://www.sheepit-renderfarm.com/getstarted.php
Il y a une version applet java pour le navigateur mais je n’ai pas testé, je préfère laisser tourner leur app sur un serveur h24:
téléchargez l’app java: https://www.sheepit-renderfarm.com/media/applet/sheepit-client-5.366.2818.jar

Sur Centos j’ai créé un user sheepit pour pas lancer leur app en root:

useradd sheepit

ensuite dans un screen je lance l’app avec les paramètres suivants:

sudo -u sheepit java -jar /sheepit/sheepit-client-5.366.2818.jar -ui text -login mon_login_sheepit -password mon_pass_sheepit -cores 3 -compute-method CPU

-ui text : Pour lancer l’app java en headless (pour les serveur sans GUI)
-login mon_login_sheepit : Le login que vous avez choisit lors de l’inscription à sheepit
-password mon_pass_sheepit : Le mot de passe que vous avez choisit lors de l’inscription à sheepit
-cores 3 : Le nombres de processeurs que vous voulez dédier à Sheepit, plus vous en dédiez plus vous gagnerez des points et plus vos projet passerons en priorité dans la pool de rendu.
-compute-method CPU: N’utilise que le cpu de votre serveur, vous pouvez mettre GPU si vous en avez.

Ce système a beaucoup d’avantages, il vous permet enfin de faire de supers rendus en peu de temps, sans dépenser d’argent, c’est vraiment magique. (je ne vous partagerais pas les merdes que j’ai fait car je suis une quiche en 3D). L’inconvénient c’est qu’il faut ensuite télécharger toutes les frames du projet, là j’ai 24 Go de frames à télécharger, ça fait lourd si on a pas la fibre.

Ils ont un forum qui ne demande qu’à grandir

Il y a des artistes en herbe qui n’ont pas les moyens de s’offrir des cartes graphiques à 2000€ et je trouve ce système juste fantastique pour eux et même pour les gros projets. J’espère que vous ferez passer le mot et si vous avez un serveur ou deux soyez cool, ça prend 5 minutes.

Allez le meilleur pour la fin:

A poil les putes!

Django, une app à la fois, mis à jour   Recently updated !

lundi 20 mars 2017 à 09:23

Django, une app à la fois fonctionnait avec une vielle version de Django, donc je l’ai mis à jour pour marcher avec la 1.10.

J’ai trop attendu et la travail a été plus long que prévu car plein de choses avait du coup changé dans le framework. Des petits détails, mais déjà tout le routing ne marchait plus.

N’oubliez pas que la branche master est en anglais, mais il a y a une branche traduite en français. Les deux sont téléchargeables sous forme de zip sur la page d’accueil du projet github si vous ne souhaitez pas utiliser git. Il n’y a rien à installer : unzip, lire, lancer.

D’une manière générale, le projet est toujours très pratique pour enseigner ou apprendre les bases de django en complément des supports traditionnels. Il faudra que je rajoute la partie ORM un de ces 4.

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