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.

#1476 Le 27/06/2013, à 19:53

The Uploader

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

Rolinh a écrit :

Je ne suis pas sûr de comprendre la question pour le coup.

En fait, je rajoute ceci :

  position: relative;

À ce code de app/assets/stylesheets/application.css :

#preview {
  float:left;
  width: 46%;
  height: 100%;
  border-left:5px solid gray;
  overflow: auto;
  padding: 10px;
}

Et ça ne change rien (l'article est toujours partiellement recouvert par la splitbar)
Si je le fais dans la propriété "style" de la balise <div id="preview"> dans Firebug, ça fonctionne.
Et dans l'onglet Style de Firebug, j'ai :

#preview {
[...]
position: relative;

qui est barré. Ça confirme qu'il est ignoré.
Pourquoi, j'en sais rien. J'me dis que c'est le style du div parent qui prend effet à la place, mais il y a rien de ce côté là.

Rolinh a écrit :

Ok. Des bonnes nouvelles?

Pas de nouvelles. hmm

(sinon j't'ai envoyé un mail sur RReader)

Dernière modification par The Uploader (Le 27/06/2013, à 19:59)


- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10

Hors ligne

#1477 Le 27/06/2013, à 19:59

Rolinh

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

Je t'avoue que quand ça touche au CSS... je t'avoue que je suis limité ^^
Faire des GUI m'a toujours emm****, spécialement pour le web ou chaque navigateur interprète les choses différemment. Pour le coup, l'utilisation de Twitter bootstrap rend la chose moins pénible smile
Je vais faire quelques tests et voir si je trouve ce qui cloche

Et j'ai répondu à ton mail. wink

EDIT: j'ai essayé d'ajouter juste ça. Pour moi ça ne change absolument rien. Tu avais apporté d'autres changements?

Dernière modification par Rolinh (Le 27/06/2013, à 20:02)

Hors ligne

#1478 Le 27/06/2013, à 20:05

The Uploader

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

Pareil. D'où l'appel à l'aide. ^^
37311019.jpg

Ok pour le mail. smile

Rolinh a écrit :

EDIT: j'ai essayé d'ajouter juste ça. Pour moi ça ne change absolument rien. Tu avais apporté d'autres changements?

Par ici : ./viewtopic.php?pid=13957101#p13957101

Dernière modification par The Uploader (Le 27/06/2013, à 20:06)


- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10

Hors ligne

#1479 Le 27/06/2013, à 20:12

Rolinh

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

Tu pourrais pusher ta branche pour le coup?

(oups, ça devient IRC ici ^^)

Hors ligne

#1480 Le 27/06/2013, à 20:20

The Uploader

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

C'est fait. smile


- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10

Hors ligne

#1481 Le 27/06/2013, à 20:45

grim7reaper

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

Rolinh a écrit :
grim7reaper a écrit :

Un jour j’avais eu un TP de ce genre (mais sur un truc encore moins puissant que ça encore). On avait utilisé Boa comme serveur web.

J'étais tombé sur Boa en faisant quelques recherches. Tu l'avais trouvé bien? Quel langage avais-tu utilisé?

Je viens de vérifier, le CPU que l’on avait était cadencé à 200 Mhz.

Pour situer le contexte, on avait deux cartes qui communiquait en RS232.
L’une des cartes avec un prog’ en C multithread qui simulait un capteur de température (on utilisait deux threads car il fallait envoyer les mesures + recevoir et traiter les commandes en provenance de l’autre carte).
L’autre carte, sur laquelle on avait une interface web qui permettait d’afficher les info’ du capteurs et d’envoyer des commandes (genre changement de fréquence d’acquisition ou arrêt du capteur).
Pour le coup, on avait pas de gros besoin au niveau de l’interface web donc ouais ça allait bien.

Pour le langage je sais que Boa prends au moins les CGI en Perl et en C (nous on devait le faire en C, m’enfin c’est mon partenaire qui s’est fait chier à générer du HTML à base de printf big_smile, perso moi j’avais préférer faire mumuse avec les threads et le RS232 tongue)

Édit :

http://www.osnews.com/story/2217/An_Overview_of_the_Boa_Web_Server/page3/ a écrit :

Thus, any language that can be used as a CGI will work just fine, and this includes the popular scripting languages Python, Perl, and PHP.

Dernière modification par grim7reaper (Le 27/06/2013, à 20:49)

Hors ligne

#1482 Le 27/06/2013, à 20:46

Rolinh

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

J'ai la solution pour le coup.
Vu que tu as mis un margin-left de 20px à la vsplitbar, il suffit de mettre un margin-left de 20px également à  #preview. wink

EDIT:
@grim: Je suis pas assez mazot pour faire du web en Perl (que je ne connais pas d'ailleurs) ou en C. Si je peux me faciliter la vie avec un langage haut-niveau, je ne vais pas me gêner ^^
Je n'ai pas non plus un énorme besoin au niveau de l'interface web mais bon, un minimum quand  même.
Pour ton edit, je crois que je vais partir sur du Python avec bottle pour le coup. A moins que quelqu'un me suggère un autre framework web simple et léger.

Dernière modification par Rolinh (Le 27/06/2013, à 20:52)

Hors ligne

#1483 Le 27/06/2013, à 21:03

The Uploader

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

Ah cool. smile
J'avais testé différentes marges, mais peut-être pas ça.
J'm'étais aussi sûrement focalisé sur "position: relative;" parce que ça m'avait l'air plus élégant que des marges "en dur".


- Oldies PC : Intel Pentium 3 @ 800 Mhz sur CM ASUS P2B-F, GeForce 4 Ti4800 SE, Disque Dur Hitachi 160 Go, 512 Mo de RAM, 3DFX Voodoo 2, Sound Blaster 16 ISA PnP, Windows 98 SE / XP)
- Desktop : Intel Core i7 6700K @ 4 GHz sur CM ASUS Z170-P, GeForce GTX 1070, SSD Samsung 850 EVO 1 To, 16 Go de RAM, Disque Dur Seagate Barracuda 3 To, Windows 10

Hors ligne

#1484 Le 28/06/2013, à 17:56

Didier-T

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

Bonjour à tous,
c'est le premier code que je souhaite soumettre à vos avis experts.

Et j'aurais une petite question à vous poser.
Est-il possible de conserver un menu ouvert après lui avoir demandé de lancer une action (en l’occurrence démarrer / arrêter un Conky)?

ConkyControl.py

#!/usr/bin/python3
# coding: utf-8
# ========================================================================================
#
# Script de Didier-T
# license GPL V3 or later
#
# Description : script permettant la gestion simplifier d'une bibliothèque de conky.
#
# ========================================================================================
# -----------------------------------------------
# Ajout de bibliothèques utiles
# -----------------------------------------------
from tkinter import Menubutton, Menu, Canvas, Frame, GROOVE, LEFT, IntVar, filedialog, Toplevel, Label, Tk, Entry
from tkinter.filedialog import askopenfilename
from tkinter.simpledialog import askstring, askinteger
from tkinter.messagebox import askokcancel, showinfo, CANCEL
from subprocess import check_output, Popen
from os import path, system
from re import search, findall

Version='1'

## Données utiles ##
homedir = path.expanduser('~')
listfichier=[["Perso", "~/.scripts/Conky/conky_liste"], ## Attention à ne pas modifier cette ligne ##
             ["Base", "~/.scripts/Conky/conky_liste1"],
             ["Bar", "~/.scripts/Conky/conky_liste2"],
             ["Extra", "~/.scripts/Conky/conky_liste3"],
             ["Cover", "~/.scripts/Conky/conky_liste4"]]
Fichier_Demarrage_Auto="~/DemConky.sh"


class fonctions():
    def __init__(self):
        self.listfichier=[]
        for chemin in listfichier:
            chemin[1]=chemin[1].replace("~", homedir)
            if path.isfile(chemin[1]):
                self.listfichier.append(chemin)
                
    def initialisation(self):
        ## Récupération du temps de latence fichier de démarrage automatique ##
        fichier=Fichier_Demarrage_Auto.replace("~", homedir)
        if path.isfile(fichier):
            fiche = open(fichier, "r")
            lines = fiche.readlines()
            fiche.close()
            for line in lines:
                if search("sleep", line) is not None:
                    Latence=findall('-?\d+', line)[0]
                    break
        else:
            Latence=5
        ## Initialisation des bases de données et vérification des conkys lancés ##
        ### Scan Conky lancés ###
        ConkyLances=fonctions.scan()
        ### Création bases de données ###
        BasesConky=[]
        for base in self.listfichier:
            BasesConky.append([base[0],fonctions.lecture(base[1], ConkyLances)])
        return BasesConky, ConkyLances, Latence

    def scan():
        ## Scan processus extraction des conkys actifs ##
        Scan=check_output("ps ax | awk '/\ conky\ .*-c/'", shell=True).decode('utf-8').split('\n')
        index=0
        retour={}
        while index < len(Scan)-1:
            Scan[index]=Scan[index].split()
            retour[Scan[index][len(Scan[index])-1]]=Scan[index][0]
            index=index+1
        return retour

    def lecture(fichier, ConkyLances):
        ## Extraction liste conky + chemin de lancement ##
        fiche = open(fichier, "r")
        lines = fiche.readlines()
        fiche.close()
        base1 = []
        base_de_donnee = []
        index=0
        index1=0
        for line in lines:
            line=line.replace("\n", '')
            index=index+1
            if index % 2:
                base1.append(line)
            else:
                line=line.replace("~", homedir)
                base1.append(line)
                if ConkyLances.get(line) is not None:
                    base1.append(1)
                else:
                    base1.append(0)
                base_de_donnee.append(base1)
                base1=[]
        return base_de_donnee
    
    def ecriture(self, BasesConky):
        ## modification d'un fichier base de données ##
        fichier=self.listfichier[0][1]
        fiche = open(fichier, "w")
        for Bases in BasesConky:
            information = Bases[0]+"\n"+Bases[1]+"\n"
            fiche.write(information)
        fiche.close()
    
class MenuBar(Frame):
    ## Barre de menu déroulant ##
    def __init__(self, boss = None):
        self.MenuConky={}
        self.SuppConky={}
        self.ConkyLances={}
        self.BasesConky, self.ConkyLances, self.TempLat = fonctions.initialisation(fonctions())

        Frame.__init__(self, borderwidth = 2, bd = 1, relief = GROOVE)
        
        ## Menu Fermer ##
        fermeMenu = Menubutton(self, text = 'Fermer', relief = GROOVE)
        fermeMenu.pack(side = LEFT)
        ### Partie déroulante ###
        fM = Menu(fermeMenu, tearoff=0)
        fM.add_command(label='Terminer', underline = 0, command = boss.quit)
        #### Intégration du menu ####
        fermeMenu.configure(menu = fM)
        
        ## Menu Conky liste ##
        self.ListeMenu = Menubutton(self, text = 'Conky Listes', relief = GROOVE)
        self.ListeMenu.pack(side = LEFT)
        ### Partie déroulante ###
        self.menuliste()
        
        ## Menu Conky gestion ##
        self.GestionMenu = Menubutton(self, text = 'Conky Gestion', relief = GROOVE)
        self.GestionMenu.pack(side = LEFT)
        ### Partie déroulante ###
        self.menuSup()
        
        ## Menu Gestion démmarage ##
        AutoRunMenu = Menubutton(self, text = 'Démarrage Automatique', relief = GROOVE)
        AutoRunMenu.pack(side = LEFT)
        ### Partie déroulante ###
        ARM = Menu(AutoRunMenu, tearoff=0)
        ARM.add_command(label='Latence démarrage', underline = 0, command=self.latence)
        ARM.add_command(label='Enregistrement', underline = 0, command=self.DemAuto)
        #### Intégration du menu ####
        AutoRunMenu.configure(menu = ARM)
    
    ## Réglage latence démarrage ##
    def latence(self):
        self.TempLat=askinteger(title='Réglage latence', prompt='Temps en secondes', initialvalue=self.TempLat)
    
    ## Enregistrement du fichier de démarrage automatique ##
    def DemAuto(self):
        fichier=Fichier_Demarrage_Auto.replace("~", homedir)
        FichDem=["#!/bin/bash",
                "# License GPL",
                "",
                "sleep "+str(self.TempLat)+";"]
        for conky in self.ConkyLances:
            FichDem.append('sh -c "conky -c '+conky+' &"')
        fiche = open(fichier, "w")
        fiche.write('\n'.join(FichDem))
        fiche.close()
        system("chmod ugo+x "+fichier)
        showinfo(title="Démarrage automatique",message="Fichier "+Fichier_Demarrage_Auto+" modifié")
    
    ## Mise à jour des menus ##
    def MajMenu(self):
        self.GM.destroy()
        self.menuSup()
        self.lM.destroy()
        self.menuliste()
    
    ## Création / Mise à jour des sous menus lancement conky ##
    def menuliste(self):
        self.lM = Menu(self.ListeMenu, tearoff=0)
        for name in self.BasesConky:
            listeC=Menu(self.lM)
            self.MenuConky[name[0]]={}
            index=0
            for val in name[1]:
                self.MenuConky[name[0]][val[1]]=IntVar()
                listeC.add_checkbutton(label=val[0], variable=self.MenuConky[name[0]][val[1]], command=self.choixactifs)
                self.MenuConky[name[0]][val[1]].set(val[2])
                index=index+1
            self.lM.add_cascade(label=name[0], underline = 0, menu=listeC)
        #### Intégration du menu ####
        self.ListeMenu.configure(menu = self.lM)
        
    ## Création / Mise à jour du sous menu suppression conky ##
    def menuSup(self):
        self.GM = Menu(self.GestionMenu, tearoff=0)
        self.GM.add_command(label='Ajout', command=self.ajouter, underline = 0)
        listeS=Menu(self.GM, tearoff=0)
        for val in self.BasesConky[0][1]:
            self.SuppConky[val[1]]=IntVar()
            listeS.add_checkbutton(label=val[0], variable=self.SuppConky[val[1]], command=self.supp)
        self.GM.add_cascade(label='Suppression', underline = 0, menu=listeS)
        #### Intégration du menu ####
        self.GestionMenu.configure(menu = self.GM)
        
    ## Lancement ou extinction d'un conky choisi par l'utilisateur ##
    def choixactifs(self):
        self.ConkyLances=fonctions.scan()
        for name in self.MenuConky:
            for chemin in self.MenuConky[name]:
                if self.ConkyLances.get(chemin) is not None:
                    if self.MenuConky[name][chemin].get() == 0:
                        Popen('kill '+self.ConkyLances.get(chemin), shell=True)
                else:
                    if self.MenuConky[name][chemin].get() == 1:
                        Popen('conky -c '+chemin+' &', shell=True)
        
    ## Suppression d'un conky au Conky Preso ##
    def supp(self):
        index=0
        while index < len(self.BasesConky[0][1]):
            if self.SuppConky.get(self.BasesConky[0][1][index][1]) is not None:
                if self.SuppConky[self.BasesConky[0][1][index][1]].get() == 1:
                    rep=askokcancel(title='Suppréssion', message='Êtes-vous certain de vouloir supprimer le conky '+self.BasesConky[0][1][index][0]+' de conky contrôle ?', default=CANCEL)
                    if rep==True:
                        self.BasesConky[0][1].remove(self.BasesConky[0][1][index])
                        fonctions.ecriture(fonctions(), self.BasesConky[0][1])
                        self.MajMenu()
                    else:
                        self.SuppConky[self.BasesConky[0][1][index][1]].set(0)
                    break
            index=index+1
   
    ## Ajout d'un conky au Conky Preso ##
    def ajouter(self):
        Chemin=askopenfilename()
        if Chemin:
            NomNouvConky=askstring(title='nouveau conky', prompt='Nom du nouveau conky')
            if NomNouvConky is not None:
                self.BasesConky[0][1].append([NomNouvConky, Chemin, 0])
                fonctions.ecriture(fonctions(), self.BasesConky[0][1])  
                self.MajMenu()
   
class application(Frame):
    ## Application principal ##
    def __init__(self, boss = None):
        Frame.__init__(self)
        self.master.title('Conky Contrôle')
        mBar = MenuBar(self)
        mBar.pack()
        self.can = Canvas(self, bg='light grey', borderwidth=2)
        self.can.pack()
        self.pack()
        
if __name__ == '__main__':
    app = application()
    app.mainloop()

Edit : comme vous pouvez le voir j'aime bien faire mes courses au détail big_smile

Dernière modification par Didier-T (Le 28/06/2013, à 21:30)

Hors ligne

#1485 Le 28/06/2013, à 20:29

:!pakman

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

@Rolinh : merci smile


...

Hors ligne

#1486 Le 29/06/2013, à 18:54

:!pakman

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

@ux pythonneux : Je me posait la question, utilisez-vous souvent Python (voir même Ruby ou autres langages interprétés, d'ailleurs) pour des applications coté client et à destination du grand public (plus ou moins novice donc) ?

Vu que la plateforme Python, contrairement à Java, n'est sans doute pas installée chez madame Michu, vous gérez le cas comment ?

  1. Vous utilisez un autre langage (Python n'étant pas forcément très adapté à la distribution)

  2. Vous envoyez mme Michu sur le site de python pour qu'elle le télécharge et l'installe

  3. Vous embarquez une version de Python, qui s'installe automatiquement si la plateforme n'est pas présente sur la machine de mme Michu

  4. Tant pis pour madame Michu, elle ne fait pas partie du public ciblé par mon application (mon public visé est censé s'y connaitre un minimum)

  5. Autre...

Dernière modification par :!pakman (Le 29/06/2013, à 19:09)


...

Hors ligne

#1487 Le 29/06/2013, à 20:45

xapantu

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

Déjà, ça dépend beaucoup de ta plateforme cible, si c'est pour une distribution gnu/linux, tu as toujours python installé (ou de toutes façons, avec le packaging, ça passe), dès que tu as une distribution grand public du moins. Sur Windows, il y a py2exe qui permet d'embarquer python directement qui marche pas mal (c'est pas d'une grande légèreté, mais quand c'est bien fait et qu'il n'y a pas trop de dépendances, ça marche vraiment bien). Pour Mac OS X, je ne sais pas trop comment ça fonctionne. Et pour Android, il y a des procédés qui permettent d'embarquer un interpréteur dans un apk directement je crois.

Hors ligne

#1489 Le 30/06/2013, à 13:49

:!pakman

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

Merci pour les pistes wink


...

Hors ligne

#1490 Le 01/07/2013, à 02:41

grim7reaper

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

@Rolinh :
Dans words_processing.py :

def tf(data):
    mat = numpy.asarray(data.values())
    return TfidfTransformer(use_idf=False).fit_transform(mat)

def tf_idf(data):
    mat = numpy.asarray(data.values())
    return TfidfTransformer(use_idf=False).fit_transform(mat)

Pour la seconde fonction, use_idf ne devrait pas être à True ?


Dans le même fichier, pour la fonction remove_stopwords :

chars = ['.', '/', "'", '"', '?', '!', '#', '$', '%', '^', '&', '*', '(',
             ')', ' - ', '_', '+' ,'=', '@', ':', '\\', ',', ';', '~', '`', '<',
             '>', '|', '[', ']', '{', '}', '"', '-',]

Il y a deux fois ", et ça pourrait être remplacé par :

chars = list(punctuation) + [' - ']

avec un from string import punctuation bien sûr


Et enfin, pour la fonction filter_tweet_words tu peux remplacer

    filtered_words = []
    tokeep = ['JJ', 'JJR', 'JJS', 'NN', 'NNS', 'NNP', 'NNPS',
              'VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ']
    text = preprocessing(tweet.text)
    token = nltk.word_tokenize(text)
    tags = nltk.pos_tag(token)

    for tag in tags:
        if tag[1] in tokeep:
            filtered_words.append(tag[0])
    return filtered_words

par

    tokeep = ['JJ', 'JJR', 'JJS', 'NN', 'NNS', 'NNP', 'NNPS',
              'VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ']
    text = preprocessing(tweet.text)
    token = nltk.word_tokenize(text)
    return filter(lambda tag: tag[1] in tokeep, nltk.pos_tag(token))

Dans utils.py, json_to_tweets_helper :

        if bad_data:
            screen_name = ''
            in_reply_to_status_id = \
                    in_reply_to_user_id =\
                    favorite_count = \
                    retweet_count = \
                    user_favorite_count = \
                    followers_count = \
                    friends_count = \
                    statuses_count = 0
            verified = False

Ça c’est pas très joli et en plus c’est inutile (tu n’économises même pas une ligne). Autant faire :

        if bad_data:
            screen_name = ''
            in_reply_to_status_id = 0
            in_reply_to_user_id =0
            favorite_count = 0
            retweet_count = 0
            user_favorite_count = 0
            followers_count = 0
            friends_count = 0
            statuses_count = 0
            verified = False

Et ça :

        hashtags = []
        for hashtag in tw['entities']['hashtags']:
            hashtags.append(h.Hashtags(hashtag['text']))

        urls = []
        for url in tw['entities']['urls']:
            urls.append(u.Url(url['display_url']))

Ça pourrait être fait à coup de map :

        hashtags = map(lambda hashtag: h.Hashtags(hashtag['text']), tw['entities']['hashtags'])
        urls = map(lambda url: u.Url(url['display_url']), tw['entities']['urls'])

Sinon, de manière générale, je préfère utilisé format plutôt que %.

Dernière modification par grim7reaper (Le 01/07/2013, à 04:02)

Hors ligne

#1491 Le 01/07/2013, à 21:30

Rolinh

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

grim7reaper a écrit :

Pour la seconde fonction, use_idf ne devrait pas être à True ?

Tout à fait. Seulement, on devait rendre le projet et avec use_idf à True, le classifieur plante (alors que sans l'idf il passe sans problèmes...).
Il faut que je revienne dessus pour comprendre ce qui ne joue pas.

grim7reaper a écrit :

Il y a deux fois ", et ça pourrait être remplacé par :

chars = list(punctuation) + [' - ']

avec un from string import punctuation bien sûr

Bien vu et élégant. smile

grim7reaper a écrit :

Et enfin, pour la fonction filter_tweet_words tu peux remplacer (...)

Bien vu le coup de la fonction lambda.

grim7reaper a écrit :

Dans utils.py, json_to_tweets_helper  (...) Ça c’est pas très joli et en plus c’est inutile (tu n’économises même pas une ligne).

J'en conviens.

Bien vu le coup du map pour les hashtags et urls. Je n'y avais même pas pensé...

grim7reaper a écrit :

Sinon, de manière générale, je préfère utilisé format plutôt que %.

Une raison particulière à ça?

Sinon, merci bien pour cette revue. smile
Toujours bon à prendre. Bon, il faut aussi se dire que ce code à été écrit en 8-10 jours à des heures pas possibles alors que je bossais à 50%. Bref, on était pas mal à la bourre mais au final ça a bien fini. smile

Sinon, un de mes anciens prof (François Flückiger) a été nominé pour les internet hall of fame 2013 dans la catégorie Innovators (Recognizing individuals who made outstanding technological, commercial, or policy advances and helped to expand the Internet’s reach), aux cotés notamment de Richard Stallman, Aaron Swartz (à titre posthume) et Jimmy Wales pour les noms qui vous évoquent forcément quelque chose. On verra le 3 août qui sera le "gagnant".
Il était dans l'équipe de Tim Berners Lee quand ils ont mis au point le www au CERN et a repris la direction du l'équipe suite à son départ. Actuellement, c'est le grand manitou de l'informatique au CERN. J'ai eu la chance d'avoir eu droit à une visite privée des installations informatiques du CERN en 2009, présenté par F.Flückiger. C'était hyper intéressant pour moi qui n'avait jamais visité de datacenter auparavant, surtout avec la mise en perspective des défis informatiques liés aux expériences du CERN.

Hors ligne

#1492 Le 02/07/2013, à 01:21

grim7reaper

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

Rolinh a écrit :
grim7reaper a écrit :

Pour la seconde fonction, use_idf ne devrait pas être à True ?

Tout à fait. Seulement, on devait rendre le projet et avec use_idf à True, le classifieur plante (alors que sans l'idf il passe sans problèmes...).
Il faut que je revienne dessus pour comprendre ce qui ne joue pas.

Ha ok, ça me semblait bizarre aussi.

Rolinh a écrit :
grim7reaper a écrit :

Sinon, de manière générale, je préfère utilisé format plutôt que %.

Une raison particulière à ça?

Je trouve ça moins moche tongue
Plus sérieusement, même si % n’est pas déprécié il semblerait que format soit son successeur.

http://docs.python.org/3.2/library/string.html#format-examples a écrit :

This section contains examples of the new format syntax and comparison with the old %-formatting.

Et format me semble aussi plus souple et plus puissant, mais ne connaissant pas trop % je me trompe peut-être.

Sinon il y a aussi des import inutilisés, mais ça doit être à cause des bouts de code en commentaire.

Rolinh a écrit :

Sinon, merci bien pour cette revue. smile
Toujours bon à prendre. Bon, il faut aussi se dire que ce code à été écrit en 8-10 jours à des heures pas possibles alors que je bossais à 50%. Bref, on était pas mal à la bourre mais au final ça a bien fini. smile

Bah de rien.
Et ça va, le code reste plutôt propre quand même smile

Rolinh a écrit :

Sinon, un de mes anciens prof (François Flückiger) a été nominé pour les internet hall of fame 2013 dans la catégorie Innovators (Recognizing individuals who made outstanding technological, commercial, or policy advances and helped to expand the Internet’s reach), aux cotés notamment de Richard Stallman, Aaron Swartz (à titre posthume) et Jimmy Wales pour les noms qui vous évoquent forcément quelque chose. On verra le 3 août qui sera le "gagnant".
Il était dans l'équipe de Tim Berners Lee quand ils ont mis au point le www au CERN et a repris la direction du l'équipe suite à son départ. Actuellement, c'est le grand manitou de l'informatique au CERN. J'ai eu la chance d'avoir eu droit à une visite privée des installations informatiques du CERN en 2009, présenté par F.Flückiger. C'était hyper intéressant pour moi qui n'avait jamais visité de datacenter auparavant, surtout avec la mise en perspective des défis informatiques liés aux expériences du CERN.

J’ai entendu parler de ce Hall of Fame.
Tu as eu un sacré prof’ on dirait ^^

Ouais, le CERN c’est un truc assez impressionnant ^^

Hors ligne

#1493 Le 02/07/2013, à 17:52

Shanx

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

Je continue dans le python. Cette fois, je dois faire un data logger qui reçois des données en entrée (pour le moment, une température pour une zone à chaque heure), les stocke et les modifie au cours du temps (moyenne journalière pour les données vieille d’une semaine, et suppression au bout d’un an). Je n’ai pas encore la fonction pour recevoir les données, du coup une certaine partie de celles-ci est écrite en dur (et le reste est généré par un second script).

Voici le script qui s’occupe de gérer la base de donnée, et le script de simulation qui me permet de remplir cette dernière. J’ai en partie repris du code que j’avais déjà fait, tout en réadaptant. Par contre, c’est moitié en français, moitié en anglais. Je sais que c’est un peu dégueulasse, je vais changer ça. De plus, comme vous vous en doutez, j’ai pas mal de question :

  • j’ai placé tout ce qui concernait le curseur de la base de donnée en dehors du main, en tant que variable globale. Il me semble qu’en faire une classe serait un peu mieux, mais j’avoue ne pas du tout savoir comment faire

  • la connexion à la bdd pourrait se faire avec un with ou pas ? Est-ce que j’y gagnerai quelque chose ?

  • d’une manière plus générale, avez-vous des remarques pour le code (robustesse, conventions, erreurs, etc.) ?

Sans vraiment parler de ce code, j’ai encore quelques autres questions :

  • J’utilise des tabulations pour indenter, et pas des espaces. À titre personnel, je trouve les tabulations vraiment plus pratiques. Quels sont les arguments expliquant que PEP8 conseille les espaces ?

  • À partir des données stockées dans la bdd, je vais devoir faire des graphiques et des courbes. Que conseillez-vous pour le faire ? J’ai rapidement jeté un œil à GChartWrapper, mais je n’ai pas réussi à l’installer (je suis passé rapidement sur la question, si vous me dites que ça convient je verrais ça plus en profondeur demain)


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

#1494 Le 02/07/2013, à 20:05

Rolinh

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

grim7reaper a écrit :

Tu as eu un sacré prof’ on dirait ^^

Ouep, j'ai eu de la chance. smile
Par contre, ce qui est dommage c'est qu'il n'est pas professeur ordinaire mais juste chargé de cours. Il a assez à faire au CERN j'imagine...
Du coup, il donne juste 2 cours de première année donc pas de matière bien avancée, ce qui est carrément dommage.

grim7reaper a écrit :

Ouais, le CERN c’est un truc assez impressionnant ^^

Carrément.

Shanx a écrit :

(...) faire une classe serait un peu mieux, mais j’avoue ne pas du tout savoir comment faire

class Foo:
    """Foobar class."""

    def __init__(self, bar='bar'):
        self.bar = bar

    def putfoo(self):
        print("foo")
        print(self.bar)

Le __init__ c'est ton constructeur (enfin, pas exactement, c'est une méthode qui est exécutée quand une classe est instanciée).
Si tu mets ce code dans foo.py, tu peux l'importer depuis un autre fichier source et instancier ta classe comme ça:

import foo

blah = foo.Foo()
Shanx a écrit :

d’une manière plus générale, avez-vous des remarques pour le code (robustesse, conventions, erreurs, etc.) ?

J'ai juste jeté un très bref coup d’œil à ton code et oui, je vois des améliorations. Mais comme je me vraiment mis à Python il y a environ 3 semaines, je ne vois certainement pas tout.^^
Par exemple, ça:

heures=['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23']

Peut se remplacer par ça, qui est bien plus élégant:

heures = ["%02d" % h for h in range(0,24)]

Si tu veux, je peux jeter un vrai coup d’œil et te faire part de mes remarques (qui vaudront ce qu'elles vaudront).

Shanx a écrit :

J’utilise des tabulations pour indenter, et pas des espaces.

Tu vas te faire fusilier toi. ^^
Non, plus sérieusement, c'est bien de suivre les recommandations/bonnes pratiques d'un langage. Surtout que pour le coup, en Python l'indentation compte vraiment...
Il suffit qu'un mec édite ton code source, ait un tab réglé sur 2 ou 8 (enfin, pas le même tab que toi quoi), il modifie 2 lignes et il flingue tout.
Pour le côté pratique, il suffit de bien réglé son éditeur et du coup, l'utilisation d'espaces à la place de tabs devient transparent. J'ai des réglages spéciaux pour python dans mon vim par exemple:

[robin@thor ~] % cat .vim/ftplugin/python.vim
setlocal omnifunc=pythoncomplete#Complete
setlocal shiftwidth=4
setlocal tabstop=4
setlocal textwidth=80
setlocal softtabstop=4
setlocal expandtab
setlocal autoindent
setlocal nowrap
setlocal formatoptions+=c
setlocal formatoptions+=r
Shanx a écrit :

je vais devoir faire des graphiques et des courbes. Que conseillez-vous pour le faire ?

Si tu as juste besoin de faire des courbes en 2D, alors je pense que pyplot via matplotlib devrait te suffire.


Sinon, j'ai finalement utilisé web.py en combinaison avec twitter bootstrap en faisant tourner le tout via lighttpd et fastcgi pour l'appli web embarquée. Ça fonctionne plutôt bien et je dois avouer que comme petit framework, webpy est plutôt bien foutu. Il intègre son propre moteur de template qui permet d'incruster du python dans les templates html, ce qui rend la chose très pratique et évite de se farcir des tonnes de js et il gère bien l'url rewriting avec les définitions des routes. Pour un framework web, il permet de faire beaucoup en python. Le seul truc dommage, c'est qu'il n'est pas encore compatible python 3 (bien que le portage semble être en cours). Je dois avouer qu'il m'a même donné une idée pour une petite application. Vous en saurez plus bientôt. wink

Hors ligne

#1495 Le 02/07/2013, à 20:14

Shanx

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

Merci Rolinh pour tes remarques. smile

Concernant la classe, je ne voyais pas comment en faire une pour mon curseur. Je re-regarderai demain, je pense qu’en fouillant encore un peu je devrais arriver à quelque chose.

Pour ton astuces pour remplir la liste des heures, ça a l’air franchement plus élégant, en effet.

Si tu veux, je peux jeter un vrai coup d’œil et te faire part de mes remarques (qui vaudront ce qu'elles vaudront).

Ce serait bien volontiers ! smile


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

#1496 Le 02/07/2013, à 20:27

Rolinh

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

Shanx a écrit :

Merci Rolinh pour tes remarques. smile

Pas de quoi. wink

Shanx a écrit :

Concernant la classe, je ne voyais pas comment en faire une pour mon curseur.

Ah pardon, j'avais mal compris. Personnellement, je verrais ton problème différemment: se farcir du SQL, bah heu... faut vraiment le vouloir. ^^
D'autant plus qu'en passant directement tes requêtes SQL comme tu le fais, tu es directement dépendant de sqlite (ce qui n'est pas un problème en soi dans un simple script, j'en conviens). Donc à ta place, moi je ferais de l'ORM. Bien que je ne l'ai jamais utilisé, sqlalchemy à l'air pas mal pour ça (et il gère sqlite, évidemment). Il y a un tutoriel qui à l'air pas mal sur la doc. Tu risques de passer un petit moment à comprendre comment ça fonctionne mais je suis sûr que ça va te simplifier la vie par la suite. wink

Sur ce, je vais jeter un coup d’œil à ton code et revenir avec quelques remarques supplémentaires si j'en ai.

Hors ligne

#1497 Le 02/07/2013, à 20:44

Rolinh

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

@Shanx:
Dans move:

	# Valeurs initiales normalement jamais atteinte (sinon ça ne va pas fonctionner)
	# Je trouve pas ça très propre, à revoir
	mini = 500
	maxi = -50

Ça m'a un peu surpris. mini à 500 et max à -50 ?
Toujours dans la même méthode:

		for row in cur:
			if (row[2] < mini):
				mini = row[2]
			if (row[2] > maxi):
				maxi = row[2]
			moy += row[2]

row[2] ne mériterait pas une affectation là vu que tu l'utilises plusieurs fois? Avec un nom parlant ça aide aussi à comprendre de quoi il s'agit.

Dans main:

def main():
	# Valeurs définies en dur pour les tests
	title = "temp_zone_1"
	date = "2013-07-03 00"
	value = 26

Tant qu'à faire, procède ainsi puisque ces paramètres semblent requis:

def main(title="temp_zone_1", date="2013-07-03 00", value=26):

Toujours dans le main, il sert à quoi i=0? Il n'est pas utilisé par la suite.

Sinon, pour ta gestion de la db, cf mon post précédent. Des méthodes comme present1 ou present2 seront inutiles (par ailleurs, les noms de ces méthodes ne sont vraiment pas parlant...).

Hors ligne

#1498 Le 02/07/2013, à 21:04

Shanx

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

Merci. smile
En vrac :

  • c’est pas la première fois que je “me farcis” du SQL, et je ne trouve pas ça très compliqué. J’irais même plus loin et dirais que c’est pratique, mais je ne connais pas les autres alternatives. Du coup, je ne vois pas trop ce que l’ORM va m’apporter… La bdd gérée par sqlite3 me permet d’avoir plusieurs applis qui la consultent, ce qui m’est pratique. Ce sera aussi le cas avec l’ORM ?

  • Concernant les valeurs données à min et max, comme dit en commentaire je n’en étais pas content (je ne sais pas ce qu’il m’a pris de faire ça comme ça roll). Ça a depuis été changé. wink

  • Bien vu pour l’affectation de row[2]. Après, ça fait partie du code de test qui me sert uniquement à remplir la base de donnée, donc c’est pas non plus le plus important. Mais c’est bien pour moi de prendre les bonnes habitudes.

  • Enfin, les valeurs définies dans le main ne sont là qu’à fin de test, et elles sont vouées à disparaitre. Ça me paraît donc aussi simple de les définir comme je le fais, plutôt que de les passer en paramètres. Et la variable i est un vieux reste que je vais supprimer de ce pas.


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

#1499 Le 02/07/2013, à 21:18

Rolinh

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

Shanx a écrit :

c’est pas la première fois que je “me farcis” du SQL, et je ne trouve pas ça très compliqué. J’irais même plus loin et dirais que c’est pratique, mais je ne connais pas les autres alternatives. Du coup, je ne vois pas trop ce que l’ORM va m’apporter… La bdd gérée par sqlite3 me permet d’avoir plusieurs applis qui la consultent, ce qui m’est pratique. Ce sera aussi le cas avec l’ORM ?

Ce n'est pas tellement le fait que SQL soit compliqué ou pas le problème. Passer par de l'ORM te permettra de notamment de "mapper tes objets en base de données". mais apporte aussi une couche d'abstraction, ce qui n'est pas une mauvaise chose. Évidemment, cela n'est utile que si tu rends ton code plus orienté objet. Ceci dit, je pense que tu n'as pas bien compris le principe. Si tu choisis une base sqlite, c'est toujours du sqlite qu'il y aura derrière en passant par sqlalchemy. Donc tu pourras évidemment toujours utiliser cette bdd comme bon te semble...

Hors ligne

#1500 Le 02/07/2013, à 21:25

Shanx

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

Rolinh a écrit :

Évidemment, cela n'est utile que si tu rends ton code plus orienté objet.

Ça, c’est mon grand problème : j’ai du mal à réfléchir (et à codé) en orienté objet. hmm Et je ne sais pas comment faire pour avoir le déclic (c’est d’ailleurs pour ça que j’ai beaucoup de mal avec le java).

Sinon, je ne vois toujours pas les avantages de l’ORM. Je vais lire attentivement la doc demain, et voir ce que je peux en faire. Merci beaucoup. smile


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