Partage
  • Partager sur Facebook
  • Partager sur Twitter

[exercice][intermédiaire] range amélioré

    3 août 2011 à 22:01:11

    hello,

    sans doute cette fonction existe déjà dans une lib, si vous la connaissez ...

    écrire une fonction mrange(start,stop,length,type=None):
    retourne une liste de step length valeurs comprises entre start et stop (inclus)
    type(falcutatif) force le type des valeurs retournées et indique si ceux sont des int ou des float
    exemple:
    # ici le type n'est pas précisé, float l'emporte sur int pour le 2ième élément de chaque tuple.
    >>> mrange((-3,5.),(1,20),4)
    [(-3, 5.0), (-2, 10.0), (0, 15.0), (1, 20.0)]
    
    >>> mrange(1,10,10)
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    >>> mrange((1,5),(9,27),5,float)
    [(1.0, 5.0), (3.0, 10.5), (5.0, 16.0), (7.0, 21.5), (9.0, 27.0)]
    
    >>> mrange(1,5,10)
    [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
    
    >>> mrange(10,-25,5)
    [10, 1, -8, -16, -25]
    
    >>> mrange((10.3,-21.0),(-25.1,2.325),20,int)
    [(10, -21), (8, -20), (7, -19), (5, -17), (3, -16), (1, -15), (-1, -14), (-3, -12), (-5, -11), (-6, -10), (-8, -9), (-10, -7), (-12, -6), (-14, -5), (-16, -4), (-18, -3), (-20, -1), (-21, 0), (-23, 1), (-25, 2)]


    cette fonction me sert à déplacer des sprites en lignes droites, à faire des dégradés de couleurs, etc ...
    par exemple du noir au blanc en 10 niveaux de gris:
    >>> mrange((0,0,0),(255,255,255),10)
    [(0, 0, 0), (28, 28, 28), (57, 57, 57), (85, 85, 85), (113, 113, 113), (142, 142, 142), (170, 170, 170), (198, 198, 198), (227, 227, 227), (255, 255, 255)]



    mon code:
    def mrange(start,stop,step,type_=None):
        if hasattr(start,'__iter__'): return list(zip(*[mrange(x,y,step,type_) for x,y in zip(start,stop)]))
        v = (stop-start)/(step-1.)
        if (not type_ and type(stop-start) is int) or (type_ is int): return [int(round(v*i+start)) for i in range(step)]
        return [v*i+start for i in range(step-1)]+[float(stop)]
    


    bon code ;)
    • Partager sur Facebook
    • Partager sur Twitter

    Python c'est bon, mangez-en. 

      3 août 2011 à 22:56:07

      Bonsoir, j'ai réussi la partie facile, mais évidemment quand ça se complique il y a plus personne ^^

      Voici ma solution pour les cas 1 et 3:
      >>> mrange(1,10,10)
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      
      >>> mrange(1,5,10)
      [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]


      def mrange(start=1,stop=2,step=10):
          l = []
          for _ in range(stop):
              for _ in range(int(step/stop)):
                  l.append(start)
              start += 1
          return l
      
      print(mrange())
      


      Pour le deuxième cas, il va me falloir plus de temps. J'éditerais mon message demain si je trouves.
      Bonne soirée et merci pour l'exercice.
      • Partager sur Facebook
      • Partager sur Twitter
        3 août 2011 à 22:59:18

        Je sais pas si c'est voulu, mais normalement, step, c'est le pas. Genre range(1,10,2) retourne 1,3,5,7,9 et range(1,5,10), uniquement 1.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          4 août 2011 à 10:53:08

          Citation : Fayden

          Je sais pas si c'est voulu, mais normalement, step, c'est le pas. Genre range(1,10,2) retourne 1,3,5,7,9 et range(1,5,10), uniquement 1.



          Citation : josmiley

          retourne une liste de step valeurs comprises entre start et stop (inclus)

          • Partager sur Facebook
          • Partager sur Twitter
            4 août 2011 à 15:51:51

            Citation : fred1599

            Citation : Fayden

            Je sais pas si c'est voulu, mais normalement, step, c'est le pas. Genre range(1,10,2) retourne 1,3,5,7,9 et range(1,5,10), uniquement 1.



            Citation : josmiley

            retourne une liste de step valeurs comprises entre start et stop (inclus)


            Ce que veut dire Fayden, c'est que comme son nom l'indique, step représente en général le pas, donc le nom de la variable est inapproprié ici.

            D'ailleurs, j'ai été choqué aussi.
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              4 août 2011 à 16:11:54

              Citation

              Ce que veut dire Fayden, c'est que comme son nom l'indique, step représente en général le pas, donc le nom de la variable est inapproprié ici.



              J'ai compris ce que voulais dire Fayden, mais c'est pas comme si ce n'était pas expliqué ;)

              Il est vrai que c'est un mal dit de l'auteur.
              • Partager sur Facebook
              • Partager sur Twitter
                4 août 2011 à 18:17:33

                oué, oué, ici step c'est le nombre de pas et non la longueur du pas ...
                • Partager sur Facebook
                • Partager sur Twitter

                Python c'est bon, mangez-en. 

                  5 août 2011 à 3:37:59

                  J'ai très bien lu le message fred1599 (et accessoirement josmiley), tu n'as visiblement pas compris mon interrogation. Je trouve simplement plutôt étrange de vouloir reproduire une fonction en utilisant les mêmes paramètres avec les mêmes noms, mais de changer le fonctionnement de l'un d'eux en utilisant un nom qui ne reflète pas du tout son but.

                  Après, si c'est voulu pour je-ne-sais quelle raison, il suffit de le dire. Je trouve simplement que c'est complètement contre-intuitif et ça peut porter à confusion.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    5 août 2011 à 22:55:20

                    et si je remplace step par lenght, vous allez coder un truc ou pas ? ... :colere:



                    :p
                    • Partager sur Facebook
                    • Partager sur Twitter

                    Python c'est bon, mangez-en. 

                      5 août 2011 à 22:59:45

                      Seulement si tu écris length... ;-)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        5 août 2011 à 23:02:34

                        effectivement ... >_<
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Python c'est bon, mangez-en. 

                          6 août 2011 à 4:34:16

                          Je propose une solution un peu moche mais qui a l'air de marcher. Par contre je ne fais aucun test sur les paramètres, donc si on passe n'importe quoi ça va donner n'importe quoi :lol:
                          Je mets le code et la petite explication en secret.

                          def mrange(start,stop,length,t=int):
                          	def _mrange(start,stop,length,t=int):
                          		if t == int:
                          			t = round
                          		L,step,dif = [],(stop-start)/(length-1),0
                          		while len(L) < length:
                          			L.append(t(start + dif))
                          			dif += step
                          		return L
                          	if type(start) == int:
                          		return _mrange(start,stop,length,t)
                          	return list(zip(*(_mrange(b,e,length,t) for b,e in zip(start,stop))))
                          

                          En gros je me sers de la fonction du type passé en argument, et dans le cas d'un int je remplace par round. Je détermine le pas avec <math>\(\frac{\text{stop}-\text{start}}{\text{length}-1}\)</math> et je mets la différence entre la valeur de départ et la valeur actuelle dans dif, bien que ça serait aussi simple de changer la valeur start. Dans le cas où start et stop sont des entiers, je renvoie simplement le résultat de la sous-fonction, sinon, je considère que ce sont des tuples. Dans ce cas je me sers de zip pour d'abord transformer par exemple (0,0,0),(255,255,255) en (0,255),(0,255),(0,255), que je passe ensuite à ma sous-fonction, et pour finir, je me ressers de zip pour transformer le résultat du type [[0,28,...,255],[0,28,...,255],[0,28,...255]] en [(0,0,0),(28,28,28),...,(255,255,255)]
                          • Partager sur Facebook
                          • Partager sur Twitter
                            6 août 2011 à 11:03:42

                            Shaddan, c'est à quelques choses près ce que j'ai fait, ça fonctionne comme il faut(sauf sous python2).
                            Par contre et c'est ma faute car mal expliqué dans l'énoncé, l'argument type sert à forcer la type retourné ... j'édite l'énoncé.
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Python c'est bon, mangez-en. 

                            Anonyme
                              6 août 2011 à 14:07:34

                              Je n'ai pas tout à fait respecté l'énoncé. :honte:
                              J'ai remplacé l'argument type par le nombre de décimal (ndigit). Ça m'a semblé plus pratique.

                              Ainsi, si ndigit est nul ou négatif, les résultats seront des entiers, sinon des décimaux arrondis à ndigit après la virgule.


                              Code rectifié. ;)

                              def mrange(start, stop, length, typ_=None):
                                  gen = lambda a, b, c: ( a + b * i for i in range(c) )
                                  if hasattr(start, '__iter__'):
                                      for t in zip(*[ mrange(a, b, length, typ_)
                                                      for a, b in zip(start, stop) ]):
                                          yield t
                                  else:
                                      step = (stop - start) / (length - 1)
                                      if (typ_ is None and type(start) is int and type(stop) is int) \
                                         or typ_ is int:
                                          for n in gen(start, step, length):
                                              yield round(n)
                                      else:
                                          for n in gen(start, step, length):
                                              yield n
                              

                              • Partager sur Facebook
                              • Partager sur Twitter
                                6 août 2011 à 23:15:33

                                merci de participer PsycoPy,
                                le code de Shaddan est pour le moment était le plus rapide ... (j'ai éditer le mien :p )
                                désolé PsycoPy, ton code est 2x moins rapide que celui de Shaddan.
                                • Partager sur Facebook
                                • Partager sur Twitter

                                Python c'est bon, mangez-en. 

                                  7 août 2011 à 1:45:35

                                  Juste un truc, le [débutant] dans la titre de l'exercice, me semble un peu sous estimé, non?
                                  Il faut déjà une certaine maitrise en Python, je crois. :-°
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Zeste de Savoir, le site qui en a dans le citron !
                                  Anonyme
                                    7 août 2011 à 2:49:29

                                    Citation : josmiley

                                    (j'ai éditer le mien :p )


                                    Moizossi... :-°
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      7 août 2011 à 6:58:37

                                      Citation : josmiley

                                      Shaddan, c'est à quelques choses près ce que j'ai fait, ça fonctionne comme il faut(sauf sous python2).
                                      Par contre et c'est ma faute car mal expliqué dans l'énoncé, l'argument type sert à forcer la type retourné ... j'édite l'énoncé.


                                      En effet, j'ai complètement oublié de préciser que c'était du Python 3.x, désolé.
                                      Pour ce qui est du type retourné, round sans 2ème argument retourne un int donc je ne pense pas qu'il y ait de problème avec mon code à ce niveau là, si ?
                                      Par contre j'avoue que j'avais pas pensé à faire un appel récursif plutôt que de créer une sous-fonction. L'appel récursif me parait quand même plus malin.

                                      Citation : GurneyH

                                      Juste un truc, le [débutant] dans la titre de l'exercice, me semble un peu sous estimé, non?
                                      Il faut déjà une certaine maitrise en Python, je crois. :-°


                                      Je suis d'accord que ça serait peut-être mieux de mettre au moins débutant/intermédiaire. Il faut au moins connaître à peu près les listes et les tuples, et savoir se servir un minimum de la librairie standard (si on veut ne pas trop galérer) donc pour un vrai débutant ça me parait compliqué.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        7 août 2011 à 11:31:53

                                        Citation : PsycoPy

                                        Citation : josmiley

                                        (j'ai éditer le mien :p )


                                        Moizossi... :-°



                                        joli!
                                        j'avais essayé de mettre un générateur mais perdu en temps d'exécution ... je ne dois pas bien les utiliser.

                                        en tous cas bravo, ton code est 20% plus rapide que le mien :(

                                        par contre en testant qu'avec le type int, je me fait démonter allègrement et le code de Shaddan devient le plus rapide.
                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        Python c'est bon, mangez-en. 

                                          7 août 2011 à 16:39:16

                                          Citation : josmiley

                                          Citation : PsycoPy

                                          Citation : josmiley

                                          (j'ai éditer le mien :p )


                                          Moizossi... :-°



                                          joli!
                                          j'avais essayé de mettre un générateur mais perdu en temps d'exécution ... je ne dois pas bien les utiliser.

                                          en tous cas bravo, ton code est 20% plus rapide que le mien :(

                                          par contre en testant qu'avec le type int, je me fait démonter allègrement et le code de Shaddan devient le plus rapide.


                                          Personnellement je comprends jamais rien aux benchmarks de Python :lol:
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Anonyme
                                            7 août 2011 à 16:55:16

                                            Citation

                                            Personnellement je comprends jamais rien aux benchmarks de Python.


                                            Leur intérêt ou leur fonctionnement ?

                                            Pour ce qui est de l'intérêt... bah il n'y en a pas vraiment, mais c'est sympa de voir les différence de perfs d'un algo à l'autre. :p



                                            Puisqu'on en parle :
                                            # -*- coding:utf-8 -*-
                                            from __future__ import print_function
                                            
                                            
                                            # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
                                            # josmiley :
                                            
                                            def josmiley_mrange(start, stop, step, type_=None):
                                                if hasattr(start,'__iter__'):
                                                    return list(zip(*[ josmiley_mrange(x, y, step, type_) for x, y in zip(start, stop) ]))
                                                elif type_ is None and type(start) is int and type(stop) is int:
                                                    type_ = int
                                                v = (stop-start) / (step-1.)
                                                return ([ int(round(v * i + start)) for i in range(step) ]) if type_ is int else ([ v * i + start for i in range(step) ][:-1] + [float(stop)])
                                            
                                            
                                            # -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
                                            # PsycoPy :
                                            
                                            def PsycoPy_mrange(start, stop, length, type_=None):
                                                if hasattr(start, "__iter__"):
                                                    return zip(*( PsycoPy_mrange(a, b, length, type_)
                                                                    for a, b in zip(start, stop) ))
                                                else:
                                                    step = (stop - start) / (length - 1)
                                                    if type_ is int or (type_ is None and type(start) is int and type(stop) is int):
                                                        return ( round(start + step * i) for i in range(length) )
                                                    else:
                                                        return ( start + step * i for i in range(length) )
                                            
                                            
                                            
                                            
                                            ###############################################################################
                                            ################################# Benchmark ###################################
                                            ###############################################################################
                                            
                                            if __name__ == "__main__":
                                                
                                                from timeit import Timer
                                                
                                                print("\n[mrange] Benchmark")
                                            
                                                players = (
                                                    "josmiley",
                                                    "PsycoPy"
                                                )
                                                
                                                arguments = (
                                                    "(0, 39657, 7)",
                                                    "(0, 39657, 70000)",
                                                    "(1453, 10, 100, float)",
                                                    "(10.6, 9000.9, 42)",
                                                    "(10.6, -9000.9, 50450, int)",
                                                    "((32.2, 5), (32.5, -247), 54321)",
                                                    "((123, 456), (-1234, -4567), 123, float)"
                                                )
                                                
                                                def test(funct, args):
                                                    for _ in funct(*args):
                                                        pass
                                            
                                                repeat = 50
                                            
                                                stmt = "test({}_mrange, {})"
                                                setup = "from __main__ import test, {}_mrange"
                                            
                                                mrange = josmiley_mrange # fonction désignée comme étant valide
                                                
                                                scores = []
                                                for name in players:
                                                    
                                                    print()
                                                    
                                                    ls = []
                                                    for args in arguments:
                                                        
                                                        print(name, "_mrange", args, sep='')
                                                        
                                                        # Tester si la fonction retourne bien le resultat attendu
                                                        # (par rapport à la fonction mrange désignée comme valide) :
                                                        s = "list(mrange" +args+ ") == list(" +name+ "_mrange" +args+ ')'
                                                        if eval(s):
                                                            
                                                            t = Timer(stmt.format(name, args),
                                                                      setup.format(name)).timeit(repeat)
                                                            print('\t', t, " seconde", 's' if t > 1 else '', sep='')
                                                            ls.append(t)
                                                        
                                                        else:
                                                            print("\tERROR : resultat incorrect !")
                                                            break
                                                    
                                                    else:
                                                        t = sum(ls)
                                                        print("Total : ", t, " seconde", 's' if t > 1 else '', sep='')
                                                        scores.append((t, name))
                                                
                                                print("\nPodium")
                                                
                                                scores.sort()
                                                for i, t in enumerate(scores):
                                                    
                                                    print(i + 1, '> ', t[1].rjust(25), ' : ', t[0],
                                                          " seconde", 's' if t[0] > 1 else '', sep='')
                                            

                                            À noter que les deux algos présenté ici sont totalement identique.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              7 août 2011 à 17:02:45

                                              Nan, ce que je voulais dire c'est que autant en C ou dans d'autres langages, en général on a un benchmark plus ou moins proche de ce à quoi on pourrait s'attendre, autant en Python ça dépend vraiment des fois :lol:
                                              Un code censé faire, théoriquement, deux fois plus de calculs qu'un autre pourrait être plus rapide, ça ne m'étonnerait pas plus que ça.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                7 août 2011 à 23:12:14

                                                je viens de faire des testes et ...
                                                vos codes ne donnent pas les résultats attendus:

                                                avec mrange((-30,50),(1,201),40)) on doit obtenir:

                                                [(-30, 50), (-29, 54), (-28, 58), (-28, 62), (-27, 65), (-26, 69), (-25, 73), (-24, 77), (-24, 81), (-23, 85), (-22, 89), (-21, 93), (-20, 96), (-20, 100), (-19, 104), (-18, 108), (-17, 112), (-16, 116), (-16, 120), (-15, 124), (-14, 127), (-13, 131), (-13, 135), (-12, 139), (-11, 143), (-10, 147), (-9, 151), (-9, 155), (-8, 158), (-7, 162), (-6, 166), (-5, 170), (-5, 174), (-4, 178), (-3, 182), (-2, 186), (-1, 189), (-1, 193), (0, 197), (1, 201)]


                                                et vos codes ne retournent pas ça ... :o
                                                • Partager sur Facebook
                                                • Partager sur Twitter

                                                Python c'est bon, mangez-en. 

                                                  7 août 2011 à 23:43:40

                                                  C'est ça, qui m'a arrêté.
                                                  Pas si simple de spécifier les valeurs attendues.
                                                  Lorsque tu dis

                                                  Citation : Josmiley


                                                  on doit obtenir:


                                                  Tu te bases sur quoi?
                                                  Les résultats de ton code? ;)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  Zeste de Savoir, le site qui en a dans le citron !
                                                  Anonyme
                                                    7 août 2011 à 23:51:33

                                                    Dans mon code, le problème venait de la dernière valeur renvoyée : au lieu de renvoyer stop, je renvoyais une valeur calculée qui, théoriquement devait être égale à stop, mais les float ne sont pas assez précis, la valeur retournée était légèrement différente.

                                                    Correction :

                                                    J'ai juste modifié une valeur dans ma lambda gen et ajouté un yield à la fin. ;)
                                                    Du coup, je dois même gagner en perf...
                                                    def mrange(start, stop, length, typ_=None):
                                                        gen = lambda a, b, c: ( a + b * i for i in range(c - 1) )
                                                        if hasattr(start, '__iter__'):
                                                            for t in zip(*[ mrange(a, b, length, typ_)
                                                                            for a, b in zip(start, stop) ]):
                                                                yield t
                                                        else:
                                                            step = (stop - start) / (length - 1)
                                                            if (typ_ is None and type(start) is int and type(stop) is int) \
                                                               or typ_ is int:
                                                                for n in gen(start, step, length):
                                                                    yield round(n)
                                                            else:
                                                                for n in gen(start, step, length):
                                                                    yield n
                                                            yield stop
                                                    
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      8 août 2011 à 0:30:41

                                                      Citation : GurneyH

                                                      C'est ça, qui m'a arrêté.
                                                      Pas si simple de spécifier les valeurs attendues.
                                                      Lorsque tu dis

                                                      Citation : Josmiley


                                                      on doit obtenir:


                                                      Tu te bases sur quoi?
                                                      Les résultats de ton code? ;)



                                                      retourne une liste de length valeurs comprises entre start et stop (inclus)
                                                      ce n'était pas précisée mais les valeurs doivent être équidistantes les unes des autres (hormis les aléas des float)

                                                      ben, si ça répond pas à l'énoncé, c'est pas bon ...
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Python c'est bon, mangez-en. 

                                                        8 août 2011 à 0:35:16

                                                        Citation : Josmiley


                                                        ce n'était pas précisée mais les valeurs doivent être équidistantes les unes des autres (hormis les aléas des float)


                                                        Ok merci, j'ai eu un doute. :-°

                                                        Je vais réessayer alors..
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Zeste de Savoir, le site qui en a dans le citron !
                                                          8 août 2011 à 6:43:08

                                                          Citation : josmiley

                                                          je viens de faire des testes et ...
                                                          vos codes ne donnent pas les résultats attendus:

                                                          avec mrange((-30,50),(1,201),40)) on doit obtenir:

                                                          [(-30, 50), (-29, 54), (-28, 58), (-28, 62), (-27, 65), (-26, 69), (-25, 73), (-24, 77), (-24, 81), (-23, 85), (-22, 89), (-21, 93), (-20, 96), (-20, 100), (-19, 104), (-18, 108), (-17, 112), (-16, 116), (-16, 120), (-15, 124), (-14, 127), (-13, 131), (-13, 135), (-12, 139), (-11, 143), (-10, 147), (-9, 151), (-9, 155), (-8, 158), (-7, 162), (-6, 166), (-5, 170), (-5, 174), (-4, 178), (-3, 182), (-2, 186), (-1, 189), (-1, 193), (0, 197), (1, 201)]



                                                          avec mrange((-30.,50.),(1.,201.),40)) on doit obtenir:

                                                          [(-30.0, 50.0), (-29.205128205128204, 53.87179487179487), (-28.41025641025641, 57.743589743589745), (-27.615384615384617, 61.61538461538461), (-26.82051282051282, 65.48717948717949), (-26.025641025641026, 69.35897435897436), (-25.23076923076923, 73.23076923076923), (-24.435897435897438, 77.1025641025641), (-23.641025641025642, 80.97435897435898), (-22.846153846153847, 84.84615384615384), (-22.05128205128205, 88.71794871794872), (-21.256410256410255, 92.58974358974359), (-20.46153846153846, 96.46153846153845), (-19.666666666666668, 100.33333333333334), (-18.871794871794872, 104.2051282051282), (-18.07692307692308, 108.07692307692308), (-17.282051282051285, 111.94871794871796), (-16.48717948717949, 115.82051282051282), (-15.692307692307693, 119.6923076923077), (-14.897435897435898, 123.56410256410257), (-14.102564102564104, 127.43589743589743), (-13.30769230769231, 131.30769230769232), (-12.512820512820515, 135.17948717948718), (-11.717948717948719, 139.05128205128204), (-10.923076923076923, 142.9230769230769), (-10.128205128205128, 146.7948717948718), (-9.333333333333336, 150.66666666666669), (-8.53846153846154, 154.53846153846155), (-7.7435897435897445, 158.4102564102564), (-6.948717948717949, 162.28205128205127), (-6.153846153846157, 166.15384615384616), (-5.358974358974361, 170.02564102564102), (-4.564102564102566, 173.8974358974359), (-3.76923076923077, 177.76923076923077), (-2.9743589743589745, 181.64102564102564), (-2.1794871794871824, 185.51282051282053), (-1.3846153846153868, 189.3846153846154), (-0.5897435897435912, 193.25641025641025), (0.2051282051282044, 197.12820512820514), (1.0, 201.0)]



                                                          et vos codes ne retournent pas ça ... :o


                                                          Hum, en effet étant donné que dans mon code le type par défaut est int, il faut rajouter une condition pour vérifier le type des variables passés en paramètres.
                                                          J'ai pas testé mais à mon avis avec ça ça devrait passer.

                                                          def mrange(start,stop,length,t=int):
                                                          	def _mrange(start,stop,length,t=int):
                                                          		t = float if float in {t,type(start)} else round
                                                          		L,step,dif = [],(stop-start)/(length-1),0
                                                          		while len(L) < length:
                                                          			L.append(t(start + dif))
                                                          			dif += step
                                                          		return L
                                                          	if type(start) == int:
                                                          		return _mrange(start,stop,length,t)
                                                          	return list(zip(*(_mrange(b,e,length,t) for b,e in zip(start,stop))))
                                                          

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            8 août 2011 à 6:57:04

                                                            mon code est faux aussi, en effet pour le type float, mathématiquement a/b*c et (a*c)/b renvoient le même résultat ... ben non.

                                                            mon new code:

                                                            def mrange(start,stop,step,type_=None):
                                                                if hasattr(start,'__iter__'): return list(zip(*[mrange(x,y,step,type_) for x,y in zip(start,stop)]))
                                                                s,v = stop-start,step-1.
                                                                if (not type_ and type(s) is int) or (type_ is int): return [int(round((s*i)/v+start)) for i in range(step)]
                                                                return [(s*i)/v+start for i in range(step)]
                                                            


                                                            on gagne en précision de calcul mais on perd en performance.

                                                            mrange(0.,201,40)

                                                            # ancien code
                                                            [0.0, 5.153846153846154, 10.307692307692308, 15.461538461538463, 20.615384615384617, 25.76923076923077, 30.923076923076927, 36.07692307692308, 41.23076923076923, 46.38461538461539, 51.53846153846154, 56.69230769230769, 61.846153846153854, 67.0, 72.15384615384616, 77.3076923076923, 82.46153846153847, 87.61538461538463, 92.76923076923077, 97.92307692307693, 103.07692307692308, 108.23076923076924, 113.38461538461539, 118.53846153846155, 123.69230769230771, 128.84615384615387, 134.0, 139.15384615384616, 144.30769230769232, 149.46153846153848, 154.6153846153846, 159.76923076923077, 164.92307692307693, 170.0769230769231, 175.23076923076925, 180.3846153846154, 185.53846153846155, 190.6923076923077, 195.84615384615387, 201.0]

                                                            # new code

                                                            [0.0, 5.153846153846154, 10.307692307692308, 15.461538461538462, 20.615384615384617, 25.76923076923077, 30.923076923076923, 36.07692307692308, 41.23076923076923, 46.38461538461539, 51.53846153846154, 56.69230769230769, 61.84615384615385, 67.0, 72.15384615384616, 77.3076923076923, 82.46153846153847, 87.61538461538461, 92.76923076923077, 97.92307692307692, 103.07692307692308, 108.23076923076923, 113.38461538461539, 118.53846153846153, 123.6923076923077, 128.84615384615384, 134.0, 139.15384615384616, 144.30769230769232, 149.46153846153845, 154.6153846153846, 159.76923076923077, 164.92307692307693, 170.07692307692307, 175.23076923076923, 180.3846153846154, 185.53846153846155, 190.69230769230768, 195.84615384615384, 201.0]

                                                            après se pose la question de l'utilité d'une telle précision, faut-il donner la choix à l'user ... ?
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter

                                                            Python c'est bon, mangez-en. 

                                                              8 août 2011 à 13:06:47

                                                              Non sans mal. :-°
                                                              Je n'ai pas insisté plus que ça sur la précision, et je n'ai pas comparer la sortie avec les code précédents.
                                                              def mrange(start, end, length, type_ = None):
                                                                  if hasattr(start, '__iter__'):
                                                                      return zip(*[mrange(a, b, length, type_)for a, b in zip(start, end)])
                                                                  
                                                                  if start > end:
                                                                      start_, end_ = end, start
                                                                  else:
                                                                      start_, end_ = start, end
                                                                      
                                                                  ret, step = [], float(end_ - start_) / (length - 1)
                                                                  if type(start) is int and type(end) is int and type_ is None:
                                                                      type_ = int
                                                              
                                                                  while start_ < end_:
                                                                      if type_ is int:
                                                                          ret.append(int(round(start_)))
                                                                      else:
                                                                          ret.append(float(start_))
                                                                      start_ += step
                                                                  ret.append(end_)
                                                              
                                                                  if start < end:
                                                                      return ret
                                                                  else:
                                                                      return list(reversed(ret))
                                                              


                                                              J'ai une question!
                                                              Cette ligne
                                                              return list(reversed(ret))
                                                              

                                                              Je l'ai bricolé car
                                                              return ret.reverse()
                                                              

                                                              me retourne None.

                                                              C'est surement stupide, mais je ne vois pas le problème. :honte:
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter
                                                              Zeste de Savoir, le site qui en a dans le citron !

                                                              [exercice][intermédiaire] range amélioré

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown