Catégorie : développement – divers

Python : faire un « beep » sur Debian

Le code est simple, il fautt avoir paplay d’installé (je ne sais pas si c’est installé par défaut dans Debian).

A partir de là voici un exemple de code qui joue un fichier ogg :

# python3
>>> import subprocess
>>> subprocess.Popen([
... "paplay",
... "/home/olivier/.local/blah/Mission_Failed.ogg"
... ]).poll()
>>>

Sublime Text : licence. Oui. Licence.

Oui.

TAX INVOICE

TAX INVOICE? One image:

Run away!

Je l’ai fait. OUI.
Sublime Text licence bought

J’ai même choisi toutes les catégories dans lesquelles il peut entrer :

  • développement
  • développement divers
  • développement Internet
  • développement Django
  • Php
  • programmation C
  • programmation JavaScript
  • Python
  • geek
  • gestion de projet
  • euh j’arrête, il peut entrer… partout ! (aucune digression, merci !)

Je lutte activement contre la mentalité Française latine : j’essaie d’expliquer à tout le monde qu’il faut arrêter de scier la branche sur laquelle on (= les développeurs) est assise : si vous pouvez avoir quelque chose de gratuit, mais que vous vous en servez souvent, faites le calcul : s’il vous fait économiser du temps, donc de l’argent, bah la conclusion est simple : il faut que cela continue. Pour que cela continue, payez (moins que ce qu’il vous a fait économiser, sinon c’est pas intéressant) mais payez, bon sang !

J’ai évolué de ce côté et je fais tout pour que les personnes que je fréquente – et étudiants – aillent dans ce sens.

Donc oui, Sublime Text me fait gagner du temps tous les jours depuis plusieurs années, et aujourd’hui, la conclusion est évidente : il m’a fait gagner bien plus que 80 €.

Donc… je résume, une image vaut mille mots. Et même si pour certains c’est vieux, le principe reste éternel :

Anastacia - I paid my dues

PS : pour ceux qui ne savent pas ce que « OMFG » signifie, ne le dites à personne, et allez vite chercher sur Internet. Promis on ne le dira à personne. C’est comme « RTFM ». Promis.

cheatsheet » weechat

weechat hints / aide

Côté utilisateur

La souris Quand on aimerait cliquer :
/mouse disable
Pour la remettre :
/mouse enable
Documentation Raccourci : cliquer sur le lien :
– Message privé
– Raccourcis clavier

Configuration

Toujours installer v2+ et pas moins https://weechat.org/download/
Fichier de conf :
~/.weechat/
Weechat = une seule instance.
Conf. chargée en entier ici :
~/.weechat/
Pour plusieurs instances, copier tout le dossier, ex :
cp -R ~/.weechat ~/.weechat2
Puis lancez en précisant weechat -d ~/.weechat2
Lancement + connexion auto Exemple de code :
weechat -r '/server add freenode irc.freenode.net; /connect freenode -nicks=Olivier; /set irc.server.freenode.username "Olivier2"; /set irc.server.freenode.realname "Olivier Pons"; /set irc.server.freenode.autojoin "#prognosis-dev"'

Plugins

Situés dans :
~/.weechat/
Plugins Python ici :
~/.weechat/python
Chargement manuel Exemple Python / plugin arespond.py :
/script load arespond.py
Chargement automatique Exemple Python / plugin arespond.py :
Faire un lien symbolique :
cd ~/.weechat/python/autoload
ln -s ../arespond.py arespond.py
Options / switches Définir une option manuellement :
/set plugins.var.python.[SCRIPT_NAME].[option]="[valeur]
Appuyer sur TAB pour autocompléter
Au pire lire les options dans le code même.
Exemple Python / plugin arespond.py :
Les options sont en « camelCase », mais elles sont toutes transformées en minuscules dans weechat.
Il y a trois options marquée dans le code:
"muted"
"respondAfterMinutes"
"responderText"
Donc pour y accéder, il suffit de taper :
/set plugins.var.python.arespond.[tab]
Et les trois options seront affichées sur la ligne du dessus, il suffit d’autocompléter.

cheatsheet » Unity

Unity aide-mémoire

Assets et Objets

Pour comprendre comment gérer correctement les données dans Unity, il faut impérativement comprendre comment Unity identifie et sérialise les données.
Le premier point-clé est de faire la distinction entre les Assets et UnityEngine.Objects.

Un Asset est un fichier sur le disque, stocké dans le dossier Assets d’un projet Unity. Les textures, modèles 3D, ou encore clips audio sont des types d’Assets très courants. Quelques Assets contiennent des données au format natif de Unity, tels que les materiaux. D’autres Assets doivent être convertis en format natif, comme par exemple les fichiers FBX.

UnityEngine.Object, ou bien Object avec un ‘O‘majuscule, est un ensemble de données sérialisées qui décrivent une instance spécifique d’une ressource. Cela peut être n’importe quelle ressource utilisée par le Unity Engine, telle qu’un mesh, sprite, AudioClip ou AnimationClip. Tous les objets sont des sous-classes de la classe de base UnityEngine.Object.

Alors que la plupart des types Object sont built-in (= natifs), il y a deux types spéciaux.

  1. Un ScriptableObject fournit un système pratique pour les développeurs qui désirent définir leurs propre types de données. Ces types peuvent être nativement sérialisés et dé-sérialisés par Unity, et manipulés dans la fenêtre « inspecteur » de l’éditeur de Unity
  2. Un MonoBehaviour fournit un wrapper qui est lié à un MonoScript. Un MonoScript est un type de données interne que Unity utilise pour garder une référence à une class spécifique de script à l’intérieur d’un namespace et assembly spécifique. Un MonoScript ne contient pas réellement de code exécutable.

Il y a une relation one-to-many entre Asset et Object. Dit autrement, un fichier Asset peut contenir un ou plusieurs Object.

– Créer l’URL de logout :
url(r'^logout/$', LogoutView.as_view(), name='logout'),

– Créer la vue LogoutView
from django.contrib.auth import views

class LogoutView(views.LogoutView):

    def __init__(self):
        self.next_page = '/'

<form action="{% url 'login' %}" method="post" accept-charset="utf-8">
    {% csrf_token %}
    {% for field in form %}
        <label>{{ field.label }}</label>
        {% if field.errors %}
            {{ field.errors }}
        {% endif %}
        {{ field }}
    {% endfor %}
    <input type="hidden" name="next" value="{{ next }}" />
    <input class="button small" type="submit" value="Submit"/>
</form>

Références entre Object‘s

Tous les UnityEngine.Objects peuvent avoir des références vers d’autres UnityEngine.Objects. Ces derniers peuvent résider dans le même fichier Asset, ou peuvent être importé à partir d’autres fichiers Asset. Par exemple, un Object matériau a habituellement une ou plusieurs références vers des Object texture. Ces Object texture sont généralement importés à partir d’un ou plusieurs autres fichiers Asset (tels que des PNG‘s ou JPG‘s).
Lorsqu’elles sont sérialisées, ces références sont constituées en deux blocs de données : un File GUID et un Local ID.
Le File GUID identifie le fichier Asset. Un Local ID identifie chaque objet à l’intérieur d’un fichier Asset, car un fichier Asset peut contenir plusieurs objets.
L’identification et le système de référence peut être visualisé dans un éditeur de texte : créez un nouveau projet Unity et changez Editor Settings en cochant Visible Meta Files et Serialiaze Assets as text. Créez un nouveau matérieau, puis importez une texture dans le projet. Assignez le matériau à un cube dans la scène et sauvez cette dernière.
Avec un éditeur de texte, ouvrez le fichier .meta associé au matériau. Une ligne guid sera présente parmi les première lignes. Cette ligne définit le GUID du matériau. Pour trouver l’id local, ouvrez le fichier matériau dans un éditeur de texte. La première ligne qui ressemble à ‘--- !u! &2100000‘ correspond à l’id local.

Pourquoi des « File GUIDs » et des Local ID‘s ?

Pourquoi le principe des « File GUIDs » et des Local ID‘s est-il important  ? La réponse est : dans la stabilité et la possibilité d’avoir un workflow indépendant de la plateforme.

Comment faire un affichage 100% proportionnel quelle que soit la résolution de l’écran ?

En fait, d’après ce que j’ai compris, il faut comprendre qu’on ne « devrait » pas toucher à la taille de la fenêtre de l’application : c’est l’utilisateur qui la fixe : téléphone mobile, portrait ou paysage, ou écran 4k voire 8k, l’application doit s’adapter et devrait même être redimensionnable.
L’idée que j’ai retirée de mon expérience, qui est peut-être un peu différente de la réalité « Unity », est la suivante :

  • Il faut créer un Canvas et lui dire de rester proportionnel à l’écran. Comme cela, même sur les écrans géants, il s’adaptera ;
  • Dans ce Canvas, il faut créer un « référent » qui servira de conteneur à tout le reste. Ce conteneur, il faut lui dire de « remplir » son parent (donc de remplir le Canvas) selon une échelle à

Pourquoi ne pas faire ces deux opérations dans le Canvas ? (1) dire de rester proportionnel + (2) dire de « remplir » le parent Parce que le Canvas connaît et gère le composant Canvas Scaler, et le « référent » (qui sera un Pourquoi ne pas faire ces deux opérations dans le Canvas ? Parce que le Canvas connaît et gère le composant Canvas Scaler et que le « référent », ou « conteneur », connaît et gère le composant Aspect Ratio Fitter)

Commentaires fermés sur cheatsheet » Unity Publié dans Mots-clé , , ,

Cheatsheets

Une « cheatsheet » est une page dans laquelle je mets touts les petites astuces que j’ai récoltées ici ou là, et qui m’ont permises de gagner du temps (ou, à l’inverse, qui m’éviteront d’en reperdre beaucoup, car j’en ai perdu beaucoup et que je ne veux plus en perdre…).

Et les astuces qui suivent, je ne sais pas où les mettre :

Comment imprimer une image sur plusieurs feuilles (facilement) ?

  • Lancez Paint et ouvrez l’image concernée
  • Choisissez : Impression »» Mise en page
  • Sous « échelle », changez le nombre de page en X et en Y
  • Cliquez sur « ok »
  • CTRL-P pour imprimer (assurez-vous bien que « toutes les pages » soit coché)
Commentaires fermés sur Cheatsheets Publié dans Mots-clé

2 – Preonic : le clavier parfait. Pour les nerds.

C’est l’Ergodox Infinity, mais en plus petit.

  1. mkdir keyboards && cd keyboards && mkdir preonic && cd preonic
  2. git clone https://github.com/qmk/qmk_firmware
  3. cp -R ./keyboards/preonic/keymaps/default ./keyboards/preonic/keymaps/azerty
  4. make preonic:azerty:dfu

Vous pourrez ainsi éditer le dossier qui est maintenant votre dossier custom azerty

vim ./keyboards/preonic/keymaps/azerty

JavaScript hacks

/*--------------------------------------*/
var loadjQuery = function(cb){
    var scr = document.createElement('script');
    scr.setAttribute('type', 'text/javascript');
    scr.setAttribute('src', 'https://code.jquery.com/jquery-3.3.1.min.js');
    if(scr.readyState){
       scr.onreadystatechange = function(){
           if(scr.readyState === 'complete' || scr.readyState === 'loaded'){
              scr.onreadystatechange = null;
              if(cb === 'function'){
                 args = [].slice.call(arguments, 1);
                 cb.apply(this, args);
              }
           }
       };
    } else {
        scr.onload = function(){
           if(typeof(cb) === 'function'){
              args = [].slice.call(arguments, 1);
              cb.apply(this, args);
           }
        };
    }

    var head = document.getElementsByTagName('head')[0];
    head.insertBefore(scr, head.firstChild);
}

loadjQuery(function() {
    $('body').empty();
    let getRandomInt = function (max) {
        return Math.floor(Math.random() * Math.floor(max));
    };
    let curr=getRandomInt(5000);
    let addNewAvatar=function() {
        $('body').append(
            $('<img />').attr(
                'src', 'https://avatars.githubusercontent.com/u/'+curr
            ).css({
                'max-width': '50px',
                'display': 'inline-block',
                'float': 'left',
                'margin': '0',
                'padding': '0'
            })
        );
        curr += (1+getRandomInt(3));
        setTimeout(addNewAvatar, 100);
    };
    setTimeout(addNewAvatar, 100);
});

/*--------------------------------------*/
var loadjQuery = function(cb){
    var scr = document.createElement('script');
    scr.setAttribute('type', 'text/javascript');
    scr.setAttribute('src', 'https://code.jquery.com/jquery-3.3.1.min.js');
    if(scr.readyState){
       scr.onreadystatechange = function(){
           if(scr.readyState === 'complete' || scr.readyState === 'loaded'){
              scr.onreadystatechange = null;
              if(cb === 'function'){
                 args = [].slice.call(arguments, 1);
                 cb.apply(this, args);
              }
           }
       };
    } else {
        scr.onload = function(){
           if(typeof(cb) === 'function'){
              args = [].slice.call(arguments, 1);
              cb.apply(this, args);
           }
        };
    }
    var head = document.getElementsByTagName('head')[0];
    head.insertBefore(scr, head.firstChild);
}

loadjQuery(function() {
    $('body').empty();
    $.ajax({
        type: 'get',
        url: 'https://api.magicthegathering.io/v1/cards?page=311'
    }).done(function(data) {
        for (var i=0; i<data.cards.length; i++) {
            $('body').append(
                $('<img />').attr('src', data.cards[i].imageUrl)
            );
        }
    });
});

Linux tar : faire une archive au format « AAAA-MM-JJ_HHMMSS.archive.tar.bz2 »

C’est tout simple sous Linux.
Il faut juste savoir, pour ceux qui commencent à faire quelques lignes de commande sous Linux, que le « backquotes », donc le ` demande à exécuter quelque chose et le remplacer par le résultat de l’exécution.

Exemple : si vous tapez `(date '+%Y.%m.%d-%Hh%Mm%Ss')` alors il exécutera l’ordre date, et le remplacera par la date en cours.

Exemple concret :

tar cjf "`(date '+%Y.%m.%d-%Hh%Mm%Ss')`.monarchive.tar.bz2" htdocs/*

Vous archivera tout le dossier htdocs dans l’archive :
2018.02.06-09h45m05s.monarchive.tar.bz2

En espérant que cela serve à quelqu’un !

Comment détecter le père Noël / deep learning, Python, and a Raspberry Pi

Comment détecter le père Noël (détection d’image en Python) ?

C’est un article à la fois super marrant, mais très poussé techniquement, qui apprend au Raspberry Pi comment détecter le père Noël.

Attention, c’est en anglais !

How to build Santa/Not Santa detector with deep learning, Python, and a Raspberry Pi

Windows : les loopbacks. Impossible à surveiller

Si jamais vous faites un site Internet, que vous le mettez sur localhost et que vous lancez un navigateur, il se peut que, comme moi, vous ayez envie de voir exactement ce qui se passe.

Dans ce cadre, un « espion » parfait pour cela est wireshark (analyseur de trames réseau).

Après plusieurs minutes, voire heures, vous verrez que quelles que soient vos actions, rien ne se passe.
L’explication est simple : Windows, peu importe sa version, « coupe » les arrivées réseau si elles sont en loopback = sur localhost.

Un grand merci, encore une fois, pour Windows !

Toute l’explication est là.

Il faut utiliser un outil, RawCap, qui hacke un peu Windows et génère un fichier « .pcap » compatible avec Wireshark.

Sur Linux, vous n’aurez pas ce problème typique Windows

En ligne de commande, on peut faire le dump de tout le traffic, y compris le localhost.
Il vous suffit d’utiliser l’utilitaire tcpdump, exemple :

$
$ sudo tcpdump -vv -i lo port 8000
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes

Et à partir de là il écoutera sur le port 8000. Lancez Chrome, allez sur localhost:8000 et là vous verrez :

(pour la note, même s’il n’y a pas de serveur, ce qui est le cas ici, il écoute et trace vraiment tout)

17:23:14.100160 IP6 (flowlabel 0x52956, hlim 64, next-header TCP (6) payload length: 40) ip6-localhost.44238 > ip6-localhost.8000: Flags [S], cksum 0x0030 (incorrect -> 0xfe61), seq 1512481496, win 43690, options [mss 65476,sackOK,TS val 3860198845 ecr 0,nop,wscale 7], length 0
17:23:14.100165 IP6 (flowlabel 0xe143c, hlim 64, next-header TCP (6) payload length: 20) ip6-localhost.8000 > ip6-localhost.44238: Flags [R.], cksum 0x001c (incorrect -> 0xe6c0), seq 0, ack 1512481497, win 0, length 0
17:23:14.100189 IP (tos 0x0, ttl 64, id 63584, offset 0, flags [DF], proto TCP (6), length 60)
localhost.43918 > localhost.8000: Flags [S], cksum 0xfe30 (incorrect -> 0x631e), seq 4099830766, win 43690, options [mss 65495,sackOK,TS val 1743693574 ecr 0,nop,wscale 7], length 0
17:23:14.100194 IP (tos 0x0, ttl 64, id 12132, offset 0, flags [DF], proto TCP (6), length 40)
localhost.8000 > localhost.43918: Flags [R.], cksum 0x7eb1 (correct), seq 0, ack 4099830767, win 0, length 0
17:23:14.153839 IP6 (flowlabel 0xc30e0, hlim 64, next-header TCP (6) payload length: 40) ip6-localhost.44242 > ip6-localhost.8000: Flags [S], cksum 0x0030 (incorrect -> 0xaa17), seq 1123880506, win 43690, options [mss 65476,sackOK,TS val 3860198859 ecr 0,nop,wscale 7], length 0
17:23:14.153847 IP6 (flowlabel 0xee9c9, hlim 64, next-header TCP (6) payload length: 20) ip6-localhost.8000 > ip6-localhost.44242: Flags [R.], cksum 0x001c (incorrect -> 0x9284), seq 0, ack 1123880507, win 0, length 0
17:23:14.153884 IP (tos 0x0, ttl 64, id 20755, offset 0, flags [DF], proto TCP (6), length 60)
localhost.43922 > localhost.8000: Flags [S], cksum 0xfe30 (incorrect -> 0x1c4e), seq 3564886671, win 43690, options [mss 65495,sackOK,TS val 1743693588 ecr 0,nop,wscale 7], length 0
17:23:14.153891 IP (tos 0x0, ttl 64, id 12140, offset 0, flags [DF], proto TCP (6), length 40)
localhost.8000 > localhost.43922: Flags [R.], cksum 0x37ef (correct), seq 0, ack 3564886672, win 0, length 0
17:23:19.161265 IP6 (flowlabel 0x606b8, hlim 64, next-header TCP (6) payload length: 40) ip6-localhost.44246 > ip6-localhost.8000: Flags [S], cksum 0x0030 (incorrect -> 0x1e75), seq 983670096, win 43690, options [mss 65476,sackOK,TS val 3860200111 ecr 0,nop,wscale 7], length 0
17:23:19.161281 IP6 (flowlabel 0xe0662, hlim 64, next-header TCP (6) payload length: 20) ip6-localhost.8000 > ip6-localhost.44246: Flags [R.], cksum 0x001c (incorrect -> 0x0bc6), seq 0, ack 983670097, win 0, length 0
17:23:19.161360 IP (tos 0x0, ttl 64, id 18581, offset 0, flags [DF], proto TCP (6), length 60)
localhost.43926 > localhost.8000: Flags [S], cksum 0xfe30 (incorrect -> 0xe872), seq 99211285, win 43690, options [mss 65495,sackOK,TS val 1743694840 ecr 0,nop,wscale 7], length 0
17:23:19.161372 IP (tos 0x0, ttl 64, id 13102, offset 0, flags [DF], proto TCP (6), length 40)
localhost.8000 > localhost.43926: Flags [R.], cksum 0x08f8 (correct), seq 0, ack 99211286, win 0, length 0