Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#2376 Le 05/01/2016, à 08:09

Dafyd

Re : /* Topic des codeurs [8] */

Salut, première version, non proprée, absolument rien de fini, mais enfin, je la partage quand même tongue
https://github.com/Dafydmdk/Thrawn.git
Nécessite xlib pour python 3, et pyqt5 pour python3.
L'engin écrit un fichier de config dans ~/.config/thrawn/, au format JSON :

{"Focus keys": ["Control_L", "Shift_L"], "Terminal exec option flag": "-x", "Terminal": "xfce4-terminal", "Height": 24}

Les champs sont assez explicites je pense, sinon hésitez pas à demander, car vu que ya encore ni commentaires ni doc ..

Bonne journée les codeurs smile

PS : il faut créer le dossier ~/.config/thrawn avant de faire le premier lancement à cause d'un bug à la con que j'ai pas encore eu le temps de corriger ..

Dernière modification par Dafyd (Le 05/01/2016, à 08:25)

Hors ligne

#2377 Le 05/01/2016, à 09:43

grim7reaper

Re : /* Topic des codeurs [8] */

J’ai jeté un rapide coup d’œil au code.
Je vois que tu utilises % pour formater les chaine, tu devrais plutot utiliser format.
Déjà parce que % est plus au moins dépréciée (surtout en Python 3¹), et aussi parce que format est plus puissant smile

Cela dit, on dirait que Python veux encore ajouter une nouvelle syntaxe dans les versions à venir…
Heureusement que le Zen de Python dit "There should be one-- and preferably only one --obvious way to do it." >_<

Sinon tu vérifies pas si HOME est défini et tu fais comme si thrawn existe déjà dans .config.
Ça serait bien aussi d’avoir un truc qui suit XDG pour savoir où mettre le fichier de conf’.

C'est tout pour le moment, je n’ai pas regardé trop en détails car c'est un premier jet comme tu l’as dit.

¹ : This method of string formatting is the new standard in Python 3, and should be preferred to the % formatting described in String Formatting Operations in new code.

Édit : je viens de voir ton PS ou tu te rends compte d‘un des trucs que j’ai cité ^^

Dernière modification par grim7reaper (Le 05/01/2016, à 10:01)

Hors ligne

#2378 Le 05/01/2016, à 10:41

Dafyd

Re : /* Topic des codeurs [8] */

Résolution du problème du dossier de configuration, et supression des %, modifications pushées.
Chez moi aucune des variables d'environnement XDG ne sont définies...
J'y avais pensé pour la vérification de $HOME, mais je sais pas trop quoi faire si elle est pas définie, quelle est la meilleure pratique en la matière ?

Hors ligne

#2379 Le 05/01/2016, à 11:07

grim7reaper

Re : /* Topic des codeurs [8] */

Dafyd a écrit :

Résolution du problème du dossier de configuration, et supression des %, modifications pushées.

\o/
Quelle réactivité !

Dafyd a écrit :

Chez moi aucune des variables d'environnement XDG ne sont définies...

Ce n’est pas un souci ça. Chez moi non plus elle ne l’est pas (car les emplacements par défaut me conviennent).
Si je me souviens bien, l’algorithme c’est :
- si la variable existe et n’est pas vide, tu l’utilises.
- sinon tu fallback sur la valeur par défaut (qui est indiqué dans la specification).

Ton code actuel prend directement la valeur par défaut, sans tenir compte des variables d’environnements.
C'est dommage car si quelqu’un les a définis pour placer ses trucs ailleurs, bah ça va être ignoré.

Dafyd a écrit :

J'y avais pensé pour la vérification de $HOME, mais je sais pas trop quoi faire si elle est pas définie, quelle est la meilleure pratique en la matière ?

Y’a pas vraiment de façon simple de gérer l’absence de HOME, et comme ça doit etre un cas très rare ça ne justifie pas la complexité supplémentaire je pense.
Perso’ je ferais un logger.critical, puis je quitte.

Hors ligne

#2380 Le 05/01/2016, à 11:28

Dafyd

Re : /* Topic des codeurs [8] */

grim7reaper a écrit :

Quelle réactivité !

C'est l'avantage d'être en cours, ya le temps ... tongue
Merci bien, modifié pushé !

Hors ligne

#2381 Le 05/01/2016, à 13:34

grim7reaper

Re : /* Topic des codeurs [8] */

Tu peux aussi passer pylint sur ton code (fait bien attention de lancer la version Python 3 sur ton code, vu que tu utilises Python 3), il a souvent de bonne remarques (même si je ne suis pas d’accord avec certaines, au sujet de map et filter par exemple (mais ça se configure)).

Par endroit je trouve tes lignes trop longues aussi (la PEP 8 recommande 79 caractères max, 72 pour les docstring).
Je sais pas si tu compte suivre la PEP 8 mais c‘est une bonne idée en général.

Hors ligne

#2382 Le 05/01/2016, à 14:02

Dafyd

Re : /* Topic des codeurs [8] */

grim7reaper a écrit :

Tu peux aussi passer pylint sur ton code (fait bien attention de lancer la version Python 3 sur ton code, vu que tu utilises Python 3), il a souvent de bonne remarques (même si je ne suis pas d’accord avec certaines, au sujet de map et filter par exemple (mais ça se configure)).

J'aimerai bien mais le paquet pour Arch est cassé pour le moment je crois, impossible de l'installer..

Exact pour les 80 caractères, j'étais configuré à 120 max roll
Si je compte bien suivre la PEP8, pour une fois que tout le monde est à peu près d'accord sur un coding style, autant s'y conformer !
Mon IDE (PyCharm) indique quand le code n'est pas PEP8 proof, c'est pratique. A part les 120 caractères par défaut, ça j'ai pas compris x)

Dernière modification par Dafyd (Le 05/01/2016, à 14:04)

Hors ligne

#2383 Le 05/01/2016, à 15:39

Dafyd

Re : /* Topic des codeurs [8] */

Franchement c'est quoi le plus moche ? Une ligne qui dépasse 80 caractères ou ça ?

os.popen('{terminal} {exec_flag} {command}'.format(
                terminal=self.thrawn_config.terminal,
                exec_flag=self.thrawn_config.terminal_exec_flag,
                command=command))

Hors ligne

#2384 Le 05/01/2016, à 16:25

Elzen

Re : /* Topic des codeurs [8] */

Personnellement, j'écrirais probablement quelque chose du style

os.popen(self.thrawn_config.terminal+" "
    +self.thrawn_config.terminal_exec_flag+" "+command)

Après, les histoires de 80 caractères, ce n'est pas une question d'esthétique, mais de compatibilité (pour être lisible sur la majorité des écrans, y compris du vim en tty sur un vieux truc ; et il me semble que ça correspond aussi à la façon dont certains trucs envoient du texte brut vers une imprimante pour relire le code sur papier… oui, il y a des gens qui font ça).

Je suis d'accord avec toi sur le fait que ça puisse être plus moche ; mais c'est aussi pratique (ça t'évite de jongler avec le scroll ou d'avoir des retours à la ligne en trop quand tu ouvres rapidement un fichier dans une fenêtre non-maximisée, tout ça). Donc personnellement, j'ai tendance à appliquer la plupart du temps.

Après, PEP8, ce ne sont pas 80 caractères, mais 79, allez savoir pourquoi. Et leur façon d'indenter les lignes concernées me semble assez zarb', ça fait partie des trucs que je n'applique pas quand je code de ma propre initiative.

Hors ligne

#2385 Le 05/01/2016, à 17:03

HP

Re : /* Topic des codeurs [8] */

Personnellement, j'écrirais probablement quelque chose du style :

items = [self.thrawn_config.terminal, self.thrawn_config.terminal_exec_flag, command]
os.popen(' '.join(items))

Après, bon… avec des nommages d'attributs tel que "thrawn_config"… on fait pas des miracles… pourquoi pas simplement config (sémantique) ?

items = [self.config.terminal, self.config.terminal_exec_flag, command]
os.popen(' '.join(items))

cat /dev/urandom >/dev/null 2>&1 #github

Hors ligne

#2386 Le 05/01/2016, à 17:08

αjet

Re : /* Topic des codeurs [8] */

Elzen a écrit :

Après, PEP8, ce ne sont pas 80 caractères, mais 79, allez savoir pourquoi.

Lu ici : https://www.reddit.com/r/learnpython/co … nd_not_80/

Because an 80 char wide Emacs window starts wrapping at 79.

Maintenant tu sais wink


αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr

Hors ligne

#2387 Le 05/01/2016, à 17:17

Dafyd

Re : /* Topic des codeurs [8] */

Elzen a écrit :

Personnellement, j'écrirais probablement quelque chose du style

os.popen(self.thrawn_config.terminal+" "
    +self.thrawn_config.terminal_exec_flag+" "+command)

Après, les histoires de 80 caractères, ce n'est pas une question d'esthétique, mais de compatibilité (pour être lisible sur la majorité des écrans, y compris du vim en tty sur un vieux truc ; et il me semble que ça correspond aussi à la façon dont certains trucs envoient du texte brut vers une imprimante pour relire le code sur papier… oui, il y a des gens qui font ça).

Je suis d'accord avec toi sur le fait que ça puisse être plus moche ; mais c'est aussi pratique (ça t'évite de jongler avec le scroll ou d'avoir des retours à la ligne en trop quand tu ouvres rapidement un fichier dans une fenêtre non-maximisée, tout ça). Donc personnellement, j'ai tendance à appliquer la plupart du temps.

Après, PEP8, ce ne sont pas 80 caractères, mais 79, allez savoir pourquoi. Et leur façon d'indenter les lignes concernées me semble assez zarb', ça fait partie des trucs que je n'applique pas quand je code de ma propre initiative.

Certes, c'est plus simple !! Me manque de la pratique ..

HP a écrit :

Après, bon… avec des nommages d'attributs tel que "thrawn_config"… on fait pas des miracles… pourquoi pas simplement config (sémantique) ?

Hmmm c'est sur, je vais changer tout ça.

Hors ligne

#2388 Le 05/01/2016, à 18:57

grim7reaper

Re : /* Topic des codeurs [8] */

HP a écrit :

Personnellement, j'écrirais probablement quelque chose du style :

items = [self.thrawn_config.terminal, self.thrawn_config.terminal_exec_flag, command]
os.popen(' '.join(items))

Après, bon… avec des nommages d'attributs tel que "thrawn_config"… on fait pas des miracles… pourquoi pas simplement config (sémantique) ?

items = [self.config.terminal, self.config.terminal_exec_flag, command]
os.popen(' '.join(items))

+1
J’aurais fais comme ça aussi.

Après, il faudrait que je regarde plus en détail mais je pense que cette façon de lancer les commandes risque de ne pas être très robuste/vite limité.
Mais pour un premier jet, tu peux rester là-dessus.

Hors ligne

#2389 Le 05/01/2016, à 19:01

Elzen

Re : /* Topic des codeurs [8] */

J'aurais tendance à dire que créer une autre variable pour ensuite faire une concaténation du contenu est lourd pour pas grand chose, non ? Certes, c'est sans doute optimisé ensuite, mais le plus simple m'a toujours semblé être de faire la concaténation directement à la main…

Hors ligne

#2390 Le 05/01/2016, à 21:19

grim7reaper

Re : /* Topic des codeurs [8] */

Dafyd a écrit :
grim7reaper a écrit :

Tu peux aussi passer pylint sur ton code […]

J'aimerai bien mais le paquet pour Arch est cassé pour le moment je crois, impossible de l'installer..

Bizarre, chez moi (Arch’ aussi) il est installé et j’ai pas vu de problème.

Elzen a écrit :

J'aurais tendance à dire que créer une autre variable pour ensuite faire une concaténation du contenu est lourd pour pas grand chose, non ? Certes, c'est sans doute optimisé ensuite, mais le plus simple m'a toujours semblé être de faire la concaténation directement à la main…

Plus lourd en quoi ?
Nombre de ligne ? Ça en fait deux, dans les deux cas.

« Optimisé » ? Si tu en es à ce niveau d’optimisation c’est qu’il faut arrêter de faire du Python car tu as de gros besoin de performances tongue
En plus il est probable que, si différence visible il y a (ce dont je doute), la version avec join sera plus rapide que celle avec concaténation (moins de réallocation, car chaque concaténation crée une nouvelle chaîne car les string sont immutable en Python).

Du coup, la version avec la variable intermédiaire est :
- de même longueur (deux lignes)
- potentiellement plus performante (mais sur le cas présent je n‘y crois pas trop… (par contre dans le cas général (i.e avec potentiellement beaucoup de chaînes, join est clairement meilleur pour concaténer que des + successifs)))
- plus lisible (subjectif, je sais)



Édit : pour les curieux voilà le bytecode résultant pour les deux versions :

In [1]: import dis
In [2]: elzen = 'os.popen(self.thrawn_config.terminal+" "+self.thrawn_config.terminal_exec_flag+" "+command)'
In [3]: grim = 'items = [self.thrawn_config.terminal, self.thrawn_config.terminal_exec_flag, command];os.popen(" ".join(items))'
In [4]: dis.disassemble(compile(elzen, '<string>', 'exec'))
  1           0 LOAD_NAME                0 (os)
              3 LOAD_ATTR                1 (popen)
              6 LOAD_NAME                2 (self)
              9 LOAD_ATTR                3 (thrawn_config)
             12 LOAD_ATTR                4 (terminal)
             15 LOAD_CONST               0 (' ')
             18 BINARY_ADD
             19 LOAD_NAME                2 (self)
             22 LOAD_ATTR                3 (thrawn_config)
             25 LOAD_ATTR                5 (terminal_exec_flag)
             28 BINARY_ADD
             29 LOAD_CONST               0 (' ')
             32 BINARY_ADD
             33 LOAD_NAME                6 (command)
             36 BINARY_ADD
             37 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             40 POP_TOP
             41 LOAD_CONST               1 (None)
             44 RETURN_VALUE
In [5]: dis.disassemble(compile(grim, '<string>', 'exec'))
  1           0 LOAD_NAME                0 (self)
              3 LOAD_ATTR                1 (thrawn_config)
              6 LOAD_ATTR                2 (terminal)
              9 LOAD_NAME                0 (self)
             12 LOAD_ATTR                1 (thrawn_config)
             15 LOAD_ATTR                3 (terminal_exec_flag)
             18 LOAD_NAME                4 (command)
             21 BUILD_LIST               3
             24 STORE_NAME               5 (items)
             27 LOAD_NAME                6 (os)
             30 LOAD_ATTR                7 (popen)
             33 LOAD_CONST               0 (' ')
             36 LOAD_ATTR                8 (join)
             39 LOAD_NAME                5 (items)
             42 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             45 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             48 POP_TOP
             49 LOAD_CONST               1 (None)
             52 RETURN_VALUE

Y’a pas grand-chose de plus à en tirer par rapport à ce que l’on voit à partir du code Python (le résultat de la compilation est assez fidèle au code d’origine et le nombre d’instructions n’indique rien quand aux performances finales).
Je le poste plus pour la culture de « comment afficher le bytecode d’un bout de code Python » tongue

Ça peut être utile, qui sait…
Par exemple pour essayer de récupérer le code Python à partir d‘un .pyc (si on a fait un malheureux rm sur son .py, bien que le mieux c’est encore d’utiliser un gestionnaire de version pour se sortir de ce genre de situation).

Dernière modification par grim7reaper (Le 05/01/2016, à 21:29)

Hors ligne

#2391 Le 05/01/2016, à 21:38

Elzen

Re : /* Topic des codeurs [8] */

Je n'sais pas, créer des variables qui ne servent que pour la ligne d'en dessous, j'ai un peu de mal, ça pollue l'espace de noms pour pas grand chose.

Vous auriez proposé

os.popen(' '.join([self.config.terminal,
    self.config.terminal_exec_flag, command]))

Ça m'aurait moins choqué ^^

Mais merci pour le code, effectivement très intéressant smile

Hors ligne

#2392 Le 05/01/2016, à 21:49

grim7reaper

Re : /* Topic des codeurs [8] */

Elzen a écrit :

Je n'sais pas, créer des variables qui ne servent que pour la ligne d'en dessous, j'ai un peu de mal, ça pollue l'espace de noms pour pas grand chose.

« polluer », tout de suite les grands mots tongue
C’est local à une fonction et les fonctions sont en général courtes donc ça ne devrait pas poser de problème.

Et puis une variable a un nom, ça sert aussi de documentation (même si dans l’exemple donné ça ne se voit pas, au contraire : les variables intermédiaires sont déjà bien nommées, en revanche la variables items est horriblement mal nommée…)

Mais je peux comprendre que tu préfères ta version, surtout dans ce cas-là où c‘est kif-kif.

Hors ligne

#2393 Le 05/01/2016, à 23:06

grim7reaper

Re : /* Topic des codeurs [8] */

Ça fait très longtemps que ce topic n’avait pas eu un tel pic d’activité, ça fait plaisir smile

Hors ligne

#2394 Le 05/01/2016, à 23:09

Shanx

Re : /* Topic des codeurs [8] */

IRC c'est mieux. big_smile

(je suis déjà dehors)


Mes randos : grande traversées des Alpes, de l'Islande, de la Corse, du Japon (en vélo), etc.
Traversée des États-Unis à pied

Hors ligne

#2395 Le 06/01/2016, à 12:23

Elzen

Re : /* Topic des codeurs [8] */

grim7reaper a écrit :

Ça fait très longtemps que ce topic n’avait pas eu un tel pic d’activité, ça fait plaisir smile

Yep smile Ça fait plaisir qu'il y ait d'autres gens que moi qui viennent causer de leur code ^^

(D'ailleurs, il faut que je m'y remette, moi, même si dans l'immédiat, j'pourrais surtout vous parler du code pour la VM de démo de mon projet de thèse…)

Tiens, pour continuer sur le dernier troll, on peut aussi faire comme ça :

os.popen(' '.join([
    self.config.terminal,
    self.config.terminal_exec_flag,
    command
]))

Ce qui prend largement plus de lignes, mais peut permettre de gagner niveau lisibilité (ça permet notamment d'ajouter des commentaires variable par variable si besoin est, même si besoin il y a peu de chances qu'il y ait quand les noms de variable sont raisonnablement explicites)

Hors ligne

#2396 Le 06/01/2016, à 16:24

grim7reaper

Re : /* Topic des codeurs [8] */

Elzen a écrit :

Tiens, pour continuer sur le dernier troll, on peut aussi faire comme ça :

os.popen(' '.join([
    self.config.terminal,
    self.config.terminal_exec_flag,
    command
]))

Yup, j’aime bien cette version aussi.

Hors ligne

#2397 Le 07/01/2016, à 08:06

Dafyd

Re : /* Topic des codeurs [8] */

Bon en gros il y a plusieurs façon de faire et j'avais choisi la plus pourrie lol
Merci pour vos remarques ! Mais là mon petit DE va devoir attendre un peu, j'ai un mini projet d'objet connecté à faire avec l'école, va falloir papoter avec l'API de openweathermap, celle de Google Calendar, InfluxDB, etc etc, bref, c'est plutôt sympa.
En plus on choisit les technos, donc ce sera.. Python sur une BeagleBone tongue
Sauf que... mon binôme tient absolument à faire sa partie en ... PHP  -____-.
Oui, lui, il script en PHP.
/summon une corde.

Hors ligne

#2398 Le 07/01/2016, à 23:05

grim7reaper

Re : /* Topic des codeurs [8] */

Ha, PHP…
Toutes mes condoléances :]

Hors ligne

#2399 Le 08/01/2016, à 00:34

Dafyd

Re : /* Topic des codeurs [8] */

grim7reaper a écrit :
Elzen a écrit :

Tiens, pour continuer sur le dernier troll, on peut aussi faire comme ça :

os.popen(' '.join([
    self.config.terminal,
    self.config.terminal_exec_flag,
    command
]))

Yup, j’aime bien cette version aussi.

En relisant ça avec attention, ça me paraît lourd d'instancier une liste juste pour concatener 3 chaînes non ? Niveau perf les allocations mémoire c'est pas le top..
Apres je dis ca, je suis plus habitué au C ou C++, en Python je sais pas.

Hors ligne

#2400 Le 08/01/2016, à 02:35

grim7reaper

Re : /* Topic des codeurs [8] */

Si tu commences à vouloir compter les allocations mémoire, va falloir laisser tomber Python (et pas mal d‘autres langages) je pense tongue

Mais pour revenir sur ta remarque : est-ce vraiment plus lourd ?
Naïvement je dirais que non.
La version avec liste doit faire grosso modo deux allocations :
- allocation d‘un tableau de 3 string.
- allocation de la chaîne finale (une seule allocation car tu connais la taille finale directement).

La version avec + en fait grosso modo quatre :
- terminal + " "
- + terminal_exec_flag
- + " "
- + command

Mais bon il est possible (probable ?) que sur ce cas trivial, CPython optimise ce genre de code.
De plus, sur ce cas concret (pas beaucoup de concaténation, chaînes courtes, …) je doute fortement qu’une différence soit visible. Du coup, je privilégierai la version la plus lisible.

Dans tout les cas, avant d’optimiser il faut mesurer (avec timeit par exemple) pour savoir si c’est nécessaire et profiler (avec cProfile par exemple) pour savoir où optimiser, en ensuite re-mesurer pour voir si le gain en vaut la chandelle.

Dafyd a écrit :

Niveau perf les allocations mémoire c'est pas le top..

Les allocations c’est jamais gratuit en effet, par contre le coût dépend très fortement de la stratégie d’allocation utilisée et du pattern d’allocation/libération.
Encore une fois, ça se mesure.

Dernière modification par grim7reaper (Le 08/01/2016, à 02:37)

Hors ligne