• # Python

    Posté par . En réponse au journal Un article de "Pour la science" m'ayant amené à coder pour une petite vérification perso.... Évalué à 6.

    Sans aucune animosité, je me permet simplement quelques remarques sur le style du code:

    # -*- coding: utf8 -*-

    C’est un vieux truc qui n’a plus aucun intérêt.

    from random import *

    C’est en général pas conseillé d’importer *, il vaut mieux soit importer le module et utiliser module.fonction soit importer les fonctions dont tu as besoin.

    people=[]
    # first setting NB_PEOPLE people with the same amount of money (AMOUNT_START)
    while i<NB_PEOPLE :
     people.append(AMOUNT_START)
     i+=1

    L’initialisation de la variable people peut être réduite à people = [AMOUNT_START] * NB_PEOPLE

    i=0
    a=0
    b=0
    base=0

    Tu n’as pas besoin d’initialiser toutes tes variables globalement en Python.

    while i<NB_LOOP :

    En général en Python on utilise des boucles for plutôt que while : for _ in range(0, NB_LOOP + 1): (tu n’utilise pas la variable i, autant ne pas lui donner de nom)

    if c>0.5 : # a pays b

    Il me semble que les deux blocks font la même chose, avec les signes inversés, du coup une fonction pays(a, b, base) où tu inverse a et b et qui renvoie la nouvelle valeur de a et b devrait faire l’affaire non ?

    Genre people[a], people[b] = pays(a, b, base) ou people[b], people[a] = pays(b, a, base).

    while i<NB_PEOPLE :

    Idem que précédemment, mais en plus tu peux directement itérer sur people for person in people:, mais le mieux c’est surtout d’utiliser str.join() : final = ", ".join(str(p) for p in people).

    final="Last tranfert base : " + str(base) +". "

    On utilise plutôt les f-string, str.format() ou les %-string plutôt que la concaténation pour faire ça en général : print(f"Last tranfert base : {base}. {', '.join(str(p) for p in people)}")


    Après avoir appliquer ça (et utilisé black pour le formatage), ça donne quelque chose comme ça :

    #!/usr/bin/python3
    from random import random, randint
    NB_PEOPLE = 500
    AMOUNT_START = 2000
    NB_LOOP = 5000000
    RATE = 0.2
    DRATE = 0.05
    def pays(a, b, base):
     # no advantage for the poorest as no poorest
     if a == b:
     a = a - base * RATE
     b = b + base * RATE
     # poorest receive the money so add DRATE in the transfer
     elif a > b:
     a = a - base * (RATE + DRATE)
     b = b + base * (RATE + DRATE)
     # poorest pay the money so deduct DRATE in the transfer
     else:
     a = a - base * (RATE - DRATE)
     b = b + base * (RATE - DRATE)
     return a, b
    people = [AMOUNT_START] * NB_PEOPLE
    for _ in range(0, NB_LOOP + 1):
     # select two random people
     a = randint(0, NB_PEOPLE - 1)
     b = randint(0, NB_PEOPLE - 1)
     # compare the capital of both and select the base for the calculation for the next
     # step (capital of the poorest)
     if people[a] < people[b]:
     base = people[a]
     else:
     base = people[b]
     # a pays b
     if random() > 0.5:
     people[a], people[b] = pays(a, b, base)
     # b pays a
     else:
     people[b], people[a] = pays(b, a, base)
    # final, show the resluts
    print(f"Last tranfert base : {base}. {', '.join(str(p) for p in people)}")

    Cela dit, ma fonction pays() doit pas être bonne, j’obtiens des résultats qui m’ont l’air bien différent de ton code.