Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[débat] Quel langage pour les "quick-hacks" ?
View unanswered posts
View posts from last 24 hours

Goto page Previous  1, 2, 3, 4  Next  
Reply to topic    Gentoo Forums Forum Index French
View previous topic :: View next topic  
Author Message
killerwhile
Tux's lil' helper
Tux's lil' helper


Joined: 16 May 2005
Posts: 130
Location: Switzerland

PostPosted: Mon Apr 24, 2006 1:35 pm    Post subject: Reply with quote

Allez hop une contribution : un petit script minute maid sans prétention et pas optimisé qui pourrait être utilisé pour gagner une voiture ou comme tout autre traffic booster...

En gros il télécharge une URL à une certaine fréquence, et peut utiliser un nombre configurable de proxy...
Et je décline toute responsabilité en cas d'utilisation abusive (et si ça sortirait du cadre éthique du forum, n'hésitez pas à supprimer le post)

Code:
#!/bin/bash

#
# Get remote web page at an average given frequency
#
#  written by Ki11erwhi1e
#
# Usage : ./wget_url.sh http://www.target.com/
#
# The script is designed to be called by a crontab each minute
# This makes 60 calls per hour, 1440 calls per day
#

#
# For a call in average every hours, set PERIOD=547
# For a call every day, set PERIOD=23
#
PERIOD=547

#
# The page which must be called
# It can also be passed in argument of the script
#
URL="http://www.target.com"

#
# User agent which get the page
#
USER_AGENT="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"

#
# Referer of the page (to simulate a click to the page
#
REFERER="http://www.google.ch/search?q=target"

#
# Number of proxy to use.
# 0 means don't use a proxy
# n > 0 means use max n proxies (and perform n call)
#
USEMAXPROXY=5

WGET=`which wget`

getUrl() {
   $WGET --user-agent="$USER_AGENT" --page-requisites --no-verbose --delete-after \
   --convert-links --referer="$REFERER" \
   --tries=1 --timeout=5 --proxy \
   "$1"
}

if [ "$1" != "" ]
then
   URL=$1
fi

if [ $RANDOM -lt $PERIOD ]
then

   if [ $USEMAXPROXY -gt 0 ]
   then
      PROXYRAWFILE=/tmp/proxyrawfile.txt
      PROXYLIST=/tmp/proxylist.txt
      PROXYLIST2=/tmp/proxylist2.txt
      wget --timestamping --no-verbose -O $PROXYRAWFILE http://www.publicproxyservers.com/page1.html;
      sed "s/<[^>]*>//g" < $PROXYRAWFILE | egrep "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$|^[0-9]{2,4}$" > $PROXYLIST
      for l in `cat $PROXYLIST`; do if [ "$p" == "" ]; then p=$l; else echo $p:$l >> $PROXYLIST2; p=""; fi; done
   fi
   
   #VALUE=$RANDOM
   #echo $VALUE
   
   if [ $USEMAXPROXY -gt 0 ]
   then
      for p in `cat $PROXYLIST2 | head -n $USEMAXPROXY`
      do
         echo "# "
         echo "# Use proxy $p"
         echo "# "
         http_proxy=$p getUrl $URL
      done
      
      rm -f $PROXYRAWFILE
      rm -f $PROXYLIST
      rm -f $PROXYLIST2
      
   else
      getUrl $URL
   fi
fi

_________________
Je motive bien mes collègues. Quand je suis au travail, ils doivent toujours travailler le double -- Homer Simpson.
Back to top
View user's profile Send private message
Oupsman
Veteran
Veteran


Joined: 19 Jul 2004
Posts: 1027

PostPosted: Mon Apr 24, 2006 3:35 pm    Post subject: Reply with quote

Moi c'est :

Korn SHell au taf (je suis administrateur AIX)
Bourne Again SHell chez moi. Je suis en train de réécrire mon script de sauvegarde, pour en faire un truc un peu plus facilement paramétrable.
Perl dans certains cas (d'ailleurs, mon script de sauvegarde, je suis en train de me tâter pour le réécrire en Perl)
_________________
--
Un seul mot d'ordre : don't feed the troll anymore
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Wed Apr 26, 2006 12:28 pm    Post subject: Reply with quote

Pour moi, c'etait Perl, mais depuis 2 ou 3 ans c'est Ruby.

Oupsman wrote:

Bourne Again SHell chez moi. Je suis en train de réécrire mon script de sauvegarde, pour en faire un truc un peu plus facilement paramétrable.
Perl dans certains cas (d'ailleurs, mon script de sauvegarde, je suis en train de me tâter pour le réécrire en Perl)


Arf ... le classique ... j'ai commence y'a quelque temps a en re-ecrire un, mais j'ai pas le temps (ni l'envie ;) de le terminer. Le but etait de faire un truc propre: le fichier de config des backups ressemble a qq chose comme:

Code:

Backup::Full.new('configs') {
  frequency :daily
  located_in "/users/fros/essais/ruby/bck/"  # Where tarballs will be saved
  includes Dir['/users/fros/essais/ruby/*.yaml'] # What we do want to save
}

Backup::Incremental.new( 'repository' ) do
  frequency :monthly
  located_in "/foo/bar"
  use_working_dir toto   ## Will issue a <cd toto> before anything (tarball and so on)
  includes Dir['**/*,v']
end
Back to top
View user's profile Send private message
GuillaumeB
n00b
n00b


Joined: 24 Aug 2004
Posts: 71

PostPosted: Thu Apr 27, 2006 1:27 pm    Post subject: Reply with quote

scout wrote:
Ruby est excellent, et contrairement à python on peux faire des one-liners, puisque ruby ne considère pas l'indentation.

pour preuve sireyessire me parlais de code de césar l'autre jour.

Code:
irb(main):001:0> str='coucou voici le truc a crypter'
=> "coucou voici le truc a crypter"
irb(main):005:0> offset=5; res=''; str.each_byte { |b| if b.chr==' ' then res << ' '; else res << ((b-?a)+offset)%26 + ?a; end }; res
=> "htzhtz atnhn qj ywzh f hwduyjw"
irb(main):006:0> offset=-5; str=res; res''; str.each_byte { |b| if b.chr==' ' then res << ' '; else res << ((b-?a)+offset)%26 + ?a; end }; res
=> "coucou voici le truc a crypter"


Rien compris au code :) ?a << >> ! ² ~ !! ^ (des fans de la lib aa ici ?) Disont qu'il faut de l'experience pour lire le Ruby.
Et contrairement aux idees reçu, python peut faire des onlines :

Code:

>>> subject = 'coucou voici le truc a crypter'
>>> offset=5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97),' ')[i == ' '] for i in subject])
'htzhtz atnhn qj ywzh f hwduyjw'
>>> subject=_
>>> offset=-5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97),' ')[i == ' '] for i in subject])
'coucou voici le truc a crypter'


J'admet, c'est immonde, Python 2.5 ameliorera un peut cela avec l'ajout des structure conditionelle, cela donnera :

Code:

>>> subject = 'coucou voici le truc a crypter'
>>> offset=5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97) if i == ' ' else ' ') for i in subject])
'htzhtz atnhn qj ywzh f hwduyjw'


Bon, je readmet, c'est ultra immonde, mais python n'est pas fait pour ça (j'avoue que des fois Ruby me tente pour les trucs funs faisables avec ;o)

Pour répondre à la question originel: Scripting bash onliners rapide quand je sais faire, après je saute dans le Python si la réflexion en bash me prend plus de 30 secondes.

Quote:

Tout ça pour dire que j'aime bien faire des one liners en ruby; et je me sers très souvent de irb comme calculette


Pareil ici en ce qui concerne le shell python :)

Quote:

Autre exercice de style; la transformée de Burrows-Wheeler, que j'ai découvert en faisant un tour sur la page de bzip2 de wikipedia.
en ruby: (top chrono départ du codage à 20h05; fin à 20h20 sans les commentaires)

En python, top chrono depart 14:58 fin 15:11
Code:
# -*- coding: iso-8859-1
# module permetant de crée des listes tournantes
from collections import deque
EOF = 'Z'

def BWT(s):
   assert EOF not in s
   
   # On convertit notre chaine en liste d'éléments tournants
   s = deque(s + EOF)

   liste = []
   # Iterations sur la longueur de la chaine
   for i in range(len(s)):
      
      # on ajoute à la liste la chaine et on tourne
      liste.append(''.join(s))
      s.rotate()
   
   # Sort + retour des derniers elements de la liste
   liste.sort()
   return ''.join([i[-1] for i in liste])

def unBWT(s):
   # création d'une liste vide de longeur de s
   liste = [''] * len(s)
   
   for i in range(len(s)):
      # On ajoute les valeurs et on classe
      liste = [s[i] + liste[i] for i in range(len(s))]
      liste.sort()

   # Un peut crade ici :)
   # On renvoie le premier element d'une
   # liste qui contient tous les elements
   # de la liste précedent qui finissent par Z
   # On oublie pas de virer le EOF
   return [i for i in liste if i.endswith('Z')][0].strip(EOF)

if __name__ == '__main__':
   subject = 'hello world of gentooists under gentoo on gentoo computers'
   trans = BWT(subject)
   assert unBWT(trans) == subject


Bref, c'est kiff kiff :)

Voilà, c'était rigolo aussi, je crois que les deux langages se valent (on va dire que j'ai mis deux minutes de moins parce que je suis doué :)
Back to top
View user's profile Send private message
ultrabug
Developer
Developer


Joined: 24 Jan 2005
Posts: 698
Location: Paris

PostPosted: Thu Apr 27, 2006 4:32 pm    Post subject: Reply with quote

Salut

Moi exactement pareil que TGL, Bash ou Python selon la complexité finale de la chose :)
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Thu Apr 27, 2006 8:20 pm    Post subject: Reply with quote

GuillaumeB wrote:

Rien compris au code :) ?a << >> ! ² ~ !! ^ (des fans de la lib aa ici ?) Disont qu'il faut de l'experience pour lire le Ruby.

Et contrairement aux idees reçu, python peut faire des onlines :

Code:

>>> subject = 'coucou voici le truc a crypter'
>>> offset=5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97),' ')[i == ' '] for i in subject])
'htzhtz atnhn qj ywzh f hwduyjw'
>>> subject=_
>>> offset=-5;''.join([(chr((ord(i) - 97 + offset) % 26 + 97),' ')[i == ' '] for i in subject])
'coucou voici le truc a crypter'



T'es pas un peu de mauvaise foi ? C'est sur que 97 c'est bcp plus parlant que ?a ;)

Ce dont voulait sans doute parler Scout c'est de vrai one-liner ... Par exemple sur une des becanes que j'utilise au boulot, je n'ai pas wget ... par contre y'a ruby ... donc je fait un one-liner que j'appellerai le wget du pauvre:

Code:

ruby -r'open-uri' -e'open("http://linuxfr.org"){ |f| puts f.read }' > index.html


et honnetement, le join sur un for .. in ... c'est pas mega clair .... J'aime bien mais c'est pas forcement clair. Tant quà faire autant utiliser inject:

Code:
'coucou voici le truc a crypter'.split('').inject("") {|res,c| res << (c == " " ? " " : ((c[0]-?a)+5)%26+?a)}


Note au passage qu'on pourrait faire plus simple, en utilisant une translation:

Code:

irb> src = ('a'..'z').to_a.join
=> "abcdefghijklmnopqrstuvwxyz"
irb> dest = src.slice(5..-1) + src.slice(0,5)
=> "fghijklmnopqrstuvwxyzabcde"
irb> "coucou voici le truc a crypter".tr(src,dest)
=> "htzhtz atnhn qj ywzh f hwduyjw"


Ce qui est interessant avec Ruby (et je pense que Python doit aussi savoir le faire) c'est de pouvoir ré-ouvrir toutes les classes (même celles de base)... Par exemple, si on veut ajouter notre methode "codage" à la classe String:

Code:

irb(main):008:0> class String
irb(main):009:1> def codage( offset = 5 )
irb(main):010:2> src = ('a'..'z').to_a.join
irb(main):011:2> dest = src.slice(offset..-1) + src.slice(0,offset)
irb(main):012:2> tr(src,dest)
irb(main):013:2> end
irb(main):014:1> end
=> nil
irb(main):015:0> "coucou voici le truc a crypter".codage
=> "htzhtz atnhn qj ywzh f hwduyjw"
irb(main):016:0> "coucou voici le truc a crypter".codage(1)
=> "dpvdpv wpjdj mf usvd b dszqufs"


Toute chaine a alors accès à la méthode codage .. :)
Back to top
View user's profile Send private message
GuillaumeB
n00b
n00b


Joined: 24 Aug 2004
Posts: 71

PostPosted: Thu Apr 27, 2006 9:50 pm    Post subject: Reply with quote

[quote="Sleeper"]
T'es pas un peu de mauvaise foi ? C'est sur que 97 c'est bcp plus parlant que ?a ;)
[quote]

Un peu :) J'aurais dû dire ord('a').

Quote:

Ce dont voulait sans doute parler Scout c'est de vrai one-liner ... Par exemple sur une des bécanes que j'utilise au boulot, je n'ai pas wget ... par contre y'a ruby ... donc je fait un one-liner que j'appellerai le wget du pauvre:


Ils vous mettent Ruby mais pas wget... C'est qui ces admins ?

Quote:

Note au passage qu'on pourrait faire plus simple, en utilisant une translation:

Code:

irb> src = ('a'..'z').to_a.join
=> "abcdefghijklmnopqrstuvwxyz"
irb> dest = src.slice(5..-1) + src.slice(0,5)
=> "fghijklmnopqrstuvwxyzabcde"
irb> "coucou voici le truc a crypter".tr(src,dest)
=> "htzhtz atnhn qj ywzh f hwduyjw"



estétique... On peut aussi le faire en Python, mais cela prendre quelques lignes de plus :

Code:

>>> import string
>>> offset = 5
>>> tr = string.maketrans(string.ascii_lowercase,string.ascii_lowercase[offset:] + string.ascii_lowercase[:offset])
>>> out = "coucou c'est nous".translate(tr)
>>> offset = -5
>>> tr = string.maketrans(string.ascii_lowercase,string.ascii_lowercase[offset:] + string.ascii_lowercase[:offset])
>>> out.translate(tr)
"coucou c'est nous"


Ce que j'aime beaucoup en Ruby c'est les ensembles sur les lettres (a..z) ainsi que le nombre impressionnant de méthode pour chaque classe.

Quote:
Ce qui est intéressant avec Ruby (et je pense que Python doit aussi savoir le faire) c'est de pouvoir ré-ouvrir toutes les classes (même celles de base)... Par exemple, si on veut ajouter notre méthode "codage" à la classe String:

Code:

irb(main):008:0> class String
irb(main):009:1> def codage( offset = 5 )
irb(main):010:2> src = ('a'..'z').to_a.join
irb(main):011:2> dest = src.slice(offset..-1) + src.slice(0,offset)
irb(main):012:2> tr(src,dest)
irb(main):013:2> end
irb(main):014:1> end
=> nil
irb(main):015:0> "coucou voici le truc a crypter".codage
=> "htzhtz atnhn qj ywzh f hwduyjw"
irb(main):016:0> "coucou voici le truc a crypter".codage(1)
=> "dpvdpv wpjdj mf usvd b dszqufs"


Toute chaîne a alors accès à la méthode codage .. :)


Alors oui et non. On peut et on ne peut pas :

Code:

>>> from datetime import datetime
>>> def whatthedaytoday(self):
...     return "Aujourd'hui on est le %d" % self.day
...
>>> datetime.whatthedaytoday = whatthedaytoday
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't set attributes of built-in/extension type 'datetime.datetime'

>>> from decimal import Decimal
>>> def to_int(self):
...     return int(self)
...
>>> Decimal.to_int = to_int
>>> i = Decimal('50.25')
>>> i
Decimal("50.25")
>>> i.to_int()
50


C'est un de mes regrets, les modules builtins (généralement ceux fait en C et non pas en Python) ne permettent pas ce genre de mécanisme.

Maitenant les avis divergent à ce sujet. Certains disent qu'il ne vaut mieux pas modifier le langage, c'est plus simple à relire. Exemple, en Ruby quelqu'un va lire machaine.codage(), il va se demander si codage est un ajout de ta part ou alors fournit avec la librairie standard. En Python on préfère sacrifier l'estétique au profit de la vitesse de relecture. Un amis disais : « Python c'est très bien pour monter un projet, mais si tu as envie de te faire plaisir, fait du Ruby. » Un jour je m'y mettrais sérieusement. Un autre exemple qui fait la force et la faiblesse de Ruby, il fait tout à la fois avec des effets de bords étonnants:

Code:

irb(main):007:0> a = [1,5,2]
=> [1, 5, 2]
irb(main):008:0> b = a.sort!()
=> [1, 2, 5]
irb(main):009:0> b
=> [1, 2, 5]
irb(main):010:0> a
=> [1, 2, 5]

>>> a = [1,5,2]
>>> b = a.sort()
>>> a
[1, 2, 5]
>>> print b
None


N'empêche tout cela me donne envie de me repencher sur Ruby... Aller, je finis mon année et je m'en occupe.
Back to top
View user's profile Send private message
boozo
Advocate
Advocate


Joined: 01 Jul 2004
Posts: 3141

PostPosted: Fri Apr 28, 2006 8:35 am    Post subject: Reply with quote

'alute

je ne pite pas tout au débat mais c'est 'achement intéressant votre échange là :wink:

on sent déjà se profiler un DOW Python vs Ruby :lol: comment ?! on y est déjà ?

gardez-en sous le pied qd m^ :wink:
_________________
" Un psychotique, c'est quelqu'un qui croit dur comme fer que 2 et 2 font 5, et qui en est pleinement satisfait.
Un névrosé, c'est quelqu'un qui sait pertinemment que 2 et 2 font 4, et ça le rend malade ! "
Back to top
View user's profile Send private message
geekounet
Bodhisattva
Bodhisattva


Joined: 11 Oct 2004
Posts: 3756
Location: Lyon, France

PostPosted: Fri Apr 28, 2006 8:48 am    Post subject: Reply with quote

Effectivement, je trouve ce petit débat Ruby vs Python intéressant parce que j'hésite encore entre l'un ou l'autre. J'ai commencé à apprendre un peu des 2, mais je ne saurai pas encore faire mon choix sur le meilleur. En tout cas, la connaissance des 2 semble importante puisqu'ils semblent très bien adaptés pour faire des scripts courts et efficaces ;)
_________________
Google+ | Twitter
Back to top
View user's profile Send private message
GuillaumeB
n00b
n00b


Joined: 24 Aug 2004
Posts: 71

PostPosted: Fri Apr 28, 2006 10:47 am    Post subject: Reply with quote

pierreg wrote:
Effectivement, je trouve ce petit débat Ruby vs Python intéressant parce que j'hésite encore entre l'un ou l'autre. J'ai commencé à apprendre un peu des 2, mais je ne saurai pas encore faire mon choix sur le meilleur. En tout cas, la connaissance des 2 semble importante puisqu'ils semblent très bien adaptés pour faire des scripts courts et efficaces ;)


Un avis qui essaye d'être le plus objectif possible (ce qui n'est pas possible vu que je connais très bien python et très mal Ruby).

L'un suit une philosophie très particulière (ouvre une console python et tape "import this") qui des fois est vexante mais est agréable quand l'on doit bosser sur un gros projet (Python est explicite, indentation importante, clareté...)

Maitenant Ruby est plus "fun" et permet de faire des choses des fois en moins de ligne avec des méthodes plus artistiques.

C'est sur cela qu'il faut faire son choix car en matière de possibilitées et librairies externe, c'est kif kif, avec des fois certains avantages pour l'un ou l'autre.
Back to top
View user's profile Send private message
kwenspc
Advocate
Advocate


Joined: 21 Sep 2003
Posts: 4915

PostPosted: Fri Apr 28, 2006 12:07 pm    Post subject: Reply with quote

Intéressant ce petit débat.
Enfin cela me conforte dans l'idée que peu de langages peuvent se permettre, à l'instar de python donc, de pouvoir être massivement utilisé dans le monde professionel et ce justement parce que python oblige à être clair un minimum, qu'il est trés facile de faire des choses propres etc...
Le côté "fun" est à des années lumières des préoccupation de ce monde là :wink:
( sauf si vous êtes votre propre patron :mrgreen: )
_________________
membre officieux du SAV Ati GEntoo
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Fri Apr 28, 2006 12:33 pm    Post subject: Reply with quote

pierreg wrote:
Effectivement, je trouve ce petit débat Ruby vs Python intéressant parce que j'hésite encore entre l'un ou l'autre. J'ai commencé à apprendre un peu des 2, mais je ne saurai pas encore faire mon choix sur le meilleur. En tout cas, la connaissance des 2 semble importante puisqu'ils semblent très bien adaptés pour faire des scripts courts et efficaces ;)


Disons que Python est un très bon language. Mais je n'aime pas Python: c'est de l'ordre des gouts et des couleurs ...

J'ai essayé d'apprendre Python fin 98, mais le coup des indentations ne me plaisait pas ... J'ai voulu ré-éssayer y'a 4 ans ..mais la c'est le coup du self comme premier argument de chaque fonction (avec une explication boiseuse), et le coup d"il n'y a qu'une seule bonne façon de le faire" qui ne m'ont vraiment pas plu .... mais je pense quand même que c'est un bon language ... même si Ruby est meilleur (je plaisante, on, pas les dents !!)
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Fri Apr 28, 2006 12:35 pm    Post subject: Reply with quote

kwenspc wrote:
Intéressant ce petit débat.
Enfin cela me conforte dans l'idée que peu de langages peuvent se permettre, à l'instar de python donc, de pouvoir être massivement utilisé dans le monde professionel et ce justement parce que python oblige à être clair un minimum, qu'il est trés facile de faire des choses propres etc...
Le côté "fun" est à des années lumières des préoccupation de ce monde là :wink:
( sauf si vous êtes votre propre patron :mrgreen: )


Pas d'accord ... Quelque soit le language tu peux écrire des trucs pourris, et illisibles ... Disons que Ruby est moins bavard que Python, ce qui ne veut pas dire moins lisible ....
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Fri Apr 28, 2006 9:58 pm    Post subject: Reply with quote

GuillaumeB wrote:
Un autre exemple qui fait la force et la faiblesse de Ruby, il fait tout à la fois avec des effets de bords étonnants:

Code:

irb(main):007:0> a = [1,5,2]
=> [1, 5, 2]
irb(main):008:0> b = a.sort!()
=> [1, 2, 5]
irb(main):009:0> b
=> [1, 2, 5]
irb(main):010:0> a
=> [1, 2, 5]

>>> a = [1,5,2]
>>> b = a.sort()
>>> a
[1, 2, 5]
>>> print b
None



Euh je vois pas trop ou est l'effet de bord là ... Certaines méthodes existent en 2 versions: sans effect de bord (exemple: sort) et avec effet de bord (exemple: sort!) :

Code:

irb(main):001:0> a = [1,5,2]
=> [1, 5, 2]
irb(main):002:0> b = a.sort
=> [1, 2, 5]
irb(main):003:0> b
=> [1, 2, 5]
irb(main):004:0> a
=> [1, 5, 2]
irb(main):005:0> a.sort!
=> [1, 2, 5]
irb(main):006:0> a
=> [1, 2, 5]
Back to top
View user's profile Send private message
GuillaumeB
n00b
n00b


Joined: 24 Aug 2004
Posts: 71

PostPosted: Fri Apr 28, 2006 10:40 pm    Post subject: Reply with quote

Sleeper wrote:

Euh je vois pas trop ou est l'effet de bord là ... Certaines méthodes existent en 2 versions: sans effect de bord (exemple: sort) et avec effet de bord (exemple: sort!) :


Ce qui me choque c'est que cela fasse deux choses, trier la liste et renvoyer une/la liste (la même ou un autre...) J'en sait trop rien.
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Sat Apr 29, 2006 6:26 am    Post subject: Reply with quote

GuillaumeB wrote:

Ce qui me choque c'est que cela fasse deux choses, trier la liste et renvoyer une/la liste (la même ou un autre...) J'en sait trop rien.


Ben justement ... Ca te renvoie un tableau ... qui te permet d'enchainer les méthodes:

Code:

[5,2,1].sort.compact.join(", ")


sort renvoie un tablea, on peut donc lui appliquer compact, qui renvoie un tableau à qui on peut appliquer join ... etc ...
Back to top
View user's profile Send private message
TGL
Bodhisattva
Bodhisattva


Joined: 02 Jun 2002
Posts: 1978
Location: Rennes, France

PostPosted: Sat Apr 29, 2006 10:49 am    Post subject: Reply with quote

Sleeper wrote:
sort renvoie un tablea, on peut donc lui appliquer compact

Heu, c'est plutôt avant le sort() qu'on appellera compact(), puisque les éléments nil n'ont pas de méthode de comparaison et ne sont donc ordonnables avec rien. Enfin bon, on s'en fout, c'était juste un exemple comme ça je suppose.

Mais quoi qu'il en soit, de ce que j'ai compris de la remarque de GuillaumeB, ce qui le dérange n'est de toute façon pas que sort() renvoie un tableau trié (je vois pas trop ce qu'il pourrait faire d'autre), mais que sort!() le fasse lui aussi, en plus de modifier l'objet. Perso, dans un sens, je le comprends, et pour trier définitivement a et en faire une chaine b, j'écrirais plus volontier ça :
Code:
a.sort!
b=a.join(",")
que ça :
Code:
b=a.sort!.join(",")
Ceci parceque le second peut facilement être relu de travers (on peut ne pas se rendre compte que a est modifié).

Mais d'un autre côté, c'est très pratique que ces méthodes machin! renvoient une ref à l'objet qu'elles ont affecté, parceque ça permet de les enchainer (et c'est peut être ça que tu voulais dire Sleeper ?). Genre dans cet exemple, ça fait sens, et c'est parfaitement lisible, de profiter de la ref renvoyée par compact!() :
Code:
a = [1,nil,5,2,nil]
a.compact!.sort!

C'est aussi, de manière générale, cohérent avec les autres affectations : après tout, un simple a=qlqchose a lui aussi une valeur de retour... (bien pratique elle aussi, ne serait-ce que pour les "a = b = qqch")

Bref, c'est un truc à utiliser à bon essien, et puis voilà. Un peu comme les machin++ ou ++truc du C (ou autre), qui isolément sont bien pratiques et lisibles, genre pour boucler sur des accès à tableau[++i], mais qui, multipliés au sein d'une expression arithmétique (genre d = ++a*(b + c++);), rendent le code pénible à déchiffrer (comparé à un ++a; d=a*(b+c); ++c;).

Après, évidemment, il y a une part de subjectivité là dedans. Genre perso, entre ces deux codes, j'hésite :
Code:
a.compact!
print a.join(",") if a

Code:
print a.join(",") if a.compact!

Dans le second, la modification de a est un peu cachée, mais pas trop quand même, donc bon, moi je relis aussi bien les deux. Mais certains préfèreront sûrement l'une ou l'autre version.

Et pour répondre à la question «(la même ou un autre...) J'en sait trop rien.» de GuillaumeB : c'est bien de la même liste qu'il s'agit. Ce sont, de manière générale, des méthodes de modification des objets, et elles ne font pas de copie. Logique d'ailleurs, puisque sinon un a.compact!.sort! ferait le compact! sur a mais le sort! sur une copie, ce qui serait vachement moins utile.
Back to top
View user's profile Send private message
GuillaumeB
n00b
n00b


Joined: 24 Aug 2004
Posts: 71

PostPosted: Sat Apr 29, 2006 11:08 am    Post subject: Reply with quote

TGL wrote:

Mais quoi qu'il en soit, de ce que j'ai compris de la remarque de GuillaumeB, ce qui le dérange n'est de toute façon pas que sort() renvoie un tableau trié (je vois pas trop ce qu'il pourrait faire d'autre), mais que sort!() le fasse lui aussi, en plus de modifier l'objet. Perso, dans un sens, je le comprends, et pour trier définitivement a et en faire une chaine b, j'écrirais plus volontier ça :
Code:
a.sort!
b=a.join(",")
que ça :
Code:
b=a.sort!.join(",")
Ceci parceque le second peut facilement être relu de travers (on peut ne pas se rendre compte que a est modifié).


Voila, c'est ça mon problème.

Quote:

Mais d'un autre côté, c'est très pratique que ces méthodes machin! renvoient une ref à l'objet qu'elles ont affecté, parceque ça permet de les enchainer (et c'est peut être ça que tu voulais dire Sleeper ?). Genre dans cet exemple, ça fait sens, et c'est parfaitement lisible, de profiter de la ref renvoyée par compact!() :
Code:
a = [1,nil,5,2,nil]
a.compact!.sort!



J'avais pas vu cela comme ça, en effet.

Quote:

Et pour répondre à la question «(la même ou un autre...) J'en sait trop rien.» de GuillaumeB : c'est bien de la même liste qu'il s'agit. Ce sont, de manière générale, des méthodes de modification des objets, et elles ne font pas de copie. Logique d'ailleurs, puisque sinon un a.compact!.sort! ferait le compact! sur a mais le sort! sur une copie, ce qui serait vachement moins utile.


Remarque que
Code:
a.sort()
fait une copie lui ;o) Bon, je suis de mauvaise foi, mais je comprend mieux le mécanisme. C'est puissant, mais cela peu être troublant.
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Sat Apr 29, 2006 11:56 am    Post subject: Reply with quote

TGL wrote:

Mais quoi qu'il en soit, de ce que j'ai compris de la remarque de GuillaumeB, ce qui le dérange n'est de toute façon pas que sort() renvoie un tableau trié (je vois pas trop ce qu'il pourrait faire d'autre), mais que sort!() le fasse lui aussi, en plus de modifier l'objet. Perso, dans un sens, je le comprends, et pour trier définitivement a et en faire une chaine b, j'écrirais plus volontier ça :
Code:
a.sort!
b=a.join(",")
que ça :
Code:
b=a.sort!.join(",")
Ceci parceque le second peut facilement être relu de travers (on peut ne pas se rendre compte que a est modifié).


C'est pour celà que justement, on n'enchaine pas souvent les méthodes qui modifient l'objet de "départ" ...

L'avantage (combiné au fait que l'on puisse ré-ouvrir les classes) c'est de pouvoir écrire des choses du genre:

Code:

>> 10.minutes.ago
=> Sat Apr 29 13:39:17 CEST 2006


quand on a les helpers fournis avec Rails ... C'est quand même plus parlant que ago(minutes(10)) ...

Quote:

Bref, c'est un truc à utiliser à bon essien, et puis voilà. Un peu comme les machin++ ou ++truc du C (ou autre), qui isolément sont bien pratiques et lisibles, genre pour boucler sur des accès à tableau[++i], mais qui, multipliés au sein d'une expression arithmétique (genre d = ++a*(b + c++);), rendent le code pénible à déchiffrer (comparé à un ++a; d=a*(b+c); ++c;).


Oui et non ... ce n'est pas seulement une facilité d'écriture mais plutôt IMHO de lecture ainsi que de "localité de code" (on groupe ce qui va fonctionnellement ou logiquement ensemble)

Quote:

Après, évidemment, il y a une part de subjectivité là dedans. Genre perso, entre ces deux codes, j'hésite :
Code:
a.compact!
print a.join(",") if a

Code:
print a.join(",") if a.compact!



Hummm ... je préfère
Code:

puts a.join(",") unless a.compact!.nil?


ou alors
Code:

puts (a.compact! || a).join(", ")


qui affichera a dans tous les cas ...
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Sat Apr 29, 2006 11:57 am    Post subject: Reply with quote

GuillaumeB wrote:

Remarque que
Code:
a.sort()
fait une copie lui ;o) Bon, je suis de mauvaise foi, mais je comprend mieux le mécanisme. C'est puissant, mais cela peu être troublant.


Oui, c'est justement la différence entre sort() et sort!() ;)
Back to top
View user's profile Send private message
TGL
Bodhisattva
Bodhisattva


Joined: 02 Jun 2002
Posts: 1978
Location: Rennes, France

PostPosted: Sat Apr 29, 2006 12:11 pm    Post subject: Reply with quote

GuillaumeB wrote:
Remarque que
Code:
a.sort()
fait une copie lui ;o)

Remarque que en Python y'a deux méthodes aussi, avec la même distinction : machin.sort() pour modifier trier la liste machin, et sorted(machin) pour en obtenir une copie triée. La seule différence, c'est que machin.sort() ne renvoie rien. Ça correspond bien à la philosophie Python (une seule bonne façon de faire qqch : ici, une décomposition en plusieurs lignes si on veut filtrer puis trier puis etc.), mais je comprends tout à fait que ça ne plaise pas à tout le monde (et perso ça me gonfle aussi parfois).
Quote:
C'est puissant, mais cela peu être troublant.

Oui, c'est Ruby quoi... Globalement, je dirais que c'est un langage qui s'improvise moins que le Python. Il y a plus de subtilités, il est plus difficile de comprendre du code quand on ne connait pas le langage, et il faut en passer par un peu de lecture de la doc. Mais d'un autre côté, le gros point fort de Ruby c'est à mon sens sa cohérence : le langage a vraiment été penser avec des concepts clairs et les plus largement applicables possibles, donc quand tu piges un truc (comme ici le coup des method vs. method!), bah il est valable partout, et t'as vraiment aucune chance d'avoir des surprises avec par la suite. C'est à mon avis beaucoup moins vrai en Python, où tout le monde sait par exemple, pour l'avoir vu utilisé 36 fois, que len est un builtin, et qu'il n'y a pas de méthode liste.len(), mais où personne ne pourrait vraiment expliquer pourquoi.

Bon, bref, je peux l'avouer, point de vu langage je préfère Ruby à Python. Ceci dit, c'est Python que j'utilise le plus, de loin, parceque je le connais depuis plus longtemps et donc mieux, et parceque lui seul autorise les "import portage". En gros, Python et moi on est un vieux couple, on se côtoie au quotidien, alors que Ruby c'est la petite jeunette que je vais voir un weekend de temps en temps...
Back to top
View user's profile Send private message
TGL
Bodhisattva
Bodhisattva


Joined: 02 Jun 2002
Posts: 1978
Location: Rennes, France

PostPosted: Sat Apr 29, 2006 1:41 pm    Post subject: Reply with quote

Sleeper wrote:
C'est pour celà que justement, on n'enchaine pas souvent les méthodes qui modifient l'objet de "départ" ...

On est bien d'accord, et c'est pour ça que GuillaumeB posait la question de l'utilité de leur valeur de retour.
Quote:
Code:
>> 10.minutes.ago
=> Sat Apr 29 13:39:17 CEST 2006
C'est quand même plus parlant que ago(minutes(10)) ...

Certes, mais ça personne n'a dit le contraire. Il n'y a pas d'effet de bord dans ton exemple (minutes retourne un nouvel entier, etc.), donc là y'a pas à tortillier : appliquer des méthodes directement sur le retour d'autres méthodes, c'est normal et c'est très bien (et on le fait souvent en Python aussi, quand même...). Ça n'est que si il y a des modifications d'objets de planquées au milieu que c'est discutable (et qu'on en discutait).

Quote:
Oui et non ... ce n'est pas seulement une facilité d'écriture mais plutôt IMHO de lecture ainsi que de "localité de code" (on groupe ce qui va fonctionnellement ou logiquement ensemble)
Oui, je suis d'accord.

Quote:
Hummm ... je préfère
Code:
puts a.join(",") unless a.compact!.nil?

Mouais, on n'a pas visé le même cas en fait :
- moi je supposais que le tableau a n'était pas vide, mais pouvait contenir des nil, et je voulais ne l'afficher que si il contenait au moins un vrai élément (et donc si le compact renvoyait un truc de longueur non nulle).
- toi tu supposes que a peut être vide, et que donc le compact peut renvoyer nil, et c'est seulement dans ce cas que tu zappes l'affichage. Mais par contre tu vas afficher une string vide si a est, par exemple, [nil,nil,nil].

Mais bref, quoi qu'il en soit, la question posée par mon exemple était plutôt de savoir si il est bon ou non d'utiliser le retour d'une méthode modifiante comme un cas de test. Toi là tu le fais, et moi j'hésite... Enfin en fait, en ce qui me concerne, ça dépend de ce qui se passe ensuite : si on se ressert du a compacté, je préfère isoler le a.compact! sur une ligne avant, histoire qu'il soit bien explicite. Si par contre c'est une modification qui n'a servi que pour le test et l'affichage, et qu'ensuite on ne se ressert plus de a, alors je fais plutôt du tout en un (ma 2nd solution ou une des tiennes, selon ce qu'on veut faire exactement) parceque ça va effectivement ensemble (ça rejoint ta notion de regroupement fonctionnel ou logique).
Back to top
View user's profile Send private message
Sleeper
l33t
l33t


Joined: 12 Nov 2002
Posts: 667

PostPosted: Sat Apr 29, 2006 2:53 pm    Post subject: Reply with quote

TGL wrote:

Mais bref, quoi qu'il en soit, la question posée par mon exemple était plutôt de savoir si il est bon ou non d'utiliser le retour d'une méthode modifiante comme un cas de test. Toi là tu le fais, et moi j'hésite... Enfin en fait, en ce qui me concerne, ça dépend de ce qui se passe ensuite : si on se ressert du a compacté, je préfère isoler le a.compact! sur une ligne avant, histoire qu'il soit bien explicite. Si par contre c'est une modification qui n'a servi que pour le test et l'affichage, et qu'ensuite on ne se ressert plus de a, alors je fais plutôt du tout en un (ma 2nd solution ou une des tiennes, selon ce qu'on veut faire exactement) parceque ça va effectivement ensemble (ça rejoint ta notion de regroupement fonctionnel ou logique).


Je le fais pour l'exemple ... dans mon code je ne le fais pas :) Je te rejoins totalement su rl afaçon de l'utiliser ;)
Back to top
View user's profile Send private message
kopp
Advocate
Advocate


Joined: 09 Apr 2004
Posts: 2869
Location: Grenoble, France

PostPosted: Mon May 01, 2006 9:28 pm    Post subject: Reply with quote

Pour ma part, c'est du script BASH, ou des fois FISH (ça diffère légèrement du coup je m'embrouille à chaque fois)
J'ai jamais eu besoin d'autre chose, donc je ne m'y suis pas plongé...
Le script, ça fait parti des choses que je dois faire... mais la liste est longue, et se remplit plus qu'elle ne diminue.
Back to top
View user's profile Send private message
penguin_totof
Apprentice
Apprentice


Joined: 04 Aug 2004
Posts: 227
Location: Lyon, France

PostPosted: Fri May 05, 2006 10:04 am    Post subject: Reply with quote

salut a tous!
interessant ce thread, voila deux bout de scripts plus ou moins utile:

pour obtenir un Eterm avec de la transparence et une couleur aleatoire. (et ne me demandez pas pourquoi j'ai fait ca en perl, j en sais rien :) )
ca ne sert a rien, c est juste un peut plus joli qu'un terminal tout blanc ou noir ;)
Code:

#!/usr/bin/perl -w

use strict;

my $greentint = rand(300);
$greentint = int($greentint);

my $redtint = rand(300);
$redtint = int($redtint);

my $bluetint = rand(300);
$bluetint = int($bluetint);

system "Eterm --trans --cmod-green $greentint --cmod-red $redtint --cmod-blue $b
luetint -x --buttonbar 0 --scrollbar 0";




ou encore quelques lignes dans le .bashrc pour faciliter le montage/demontage des peripheriques amovibles (pour ceux qui ne veulent pas s'emm***** avec le montage automatique, hal/dbus ou je ne sais quoi qui n'as jamais fonctionne a 100% chez moi ;) . Simple mais efficace )

Code:

#alias de montage de peripheriques amovibles

alias mountfloppy="mount /dev/fd0 && cd /mnt/floppy/ && echo \"Floppy disk mounted successfully on /mnt/floppy...\" && echo \"floppy disk contains:\" && ls -l /mnt/floppy/"
alias umountfloppy="sync && cd ~/ && umount /dev/fd0 && echo \"Floppy disk unmounted successfully...\""

alias mountusb="mount /dev/sda1 && cd /mnt/usbkey/ && echo \"USB Key mounted successfully on /mnt/usbkey...\" && echo \"USB Key contains:\" && ls -l /mnt/usbkey/"
alias umountusb="sync && cd ~/ && umount /dev/sda1 && echo \"USB Key unmounted successfully...\""

alias mf="mountfloppy"
alias umf="umountfloppy"
alias mu="mountusb"
alias umu="umountusb"
alias mcd="mountcd"
alias umcd="umountcd"

_________________
1001111100100001110010011100100111111001
1001111100100100110010011100111001100111
1001111100100110010010011100111110011111
1001111100100111000010011100111001100111
1000000100100111100011000001100111111001
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index French All times are GMT
Goto page Previous  1, 2, 3, 4  Next
Page 2 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum