Usvainfinity svg

Où s'arrête l'infini?

miamondo Par Le 19/08/2020 à 02:58 comment 6

Bonjour,

En Python, pour créer une boucle infinie, il suffit d'écrire ces quelques lignes:

i = 0
while 1 < 2 :
    print(i)
    i += 1

while 1 < 2 signifie tant que 1 est inférieur à 2. Or, dans notre espace-temps, 1 < 2 est une vérité mathématique immuable. Cela signifie que si vous êtes à l'intérieur de la boucle, vous êtes perdu(e)s, vous n'avez aucune chance de vous en sortir. Si vous êtes à l'extérieur de la boucle et que c'est vous qui avez lancé ce programme, vous n'avez plus le contrôle. La variable i va gonfler. Vous aurez beau lui affecter une autre valeur, même négative, la boucle va continuer à incrémenter cette dernière, et votre ordinateur finira par planter, faute de place dans ses espaces de stockage. On peut donc en déduire que l'infini conduit non pas à l'éternité mais à la mort.

Cette boucle est proscrite car elle est incontrôlable. C'est l'homme qui se prend pour Dieu et qui déclenche un processus qui lui échappe! Mais le problème, c'est qu'on a parfois besoin de laisser le temps s'écouler en direction de l'infini. C'est la cas si vous décidez par exemple de coder une horloge. Il faudra bien que cette dernière laisse défiler les secondes!

Essayons donc avec le code ci-dessous:

import datetime
import time

ts = 1
for i in range(0, int(datetime.datetime.now().timestamp())):

    print(i, int(datetime.datetime.now().timestamp()))

    time.sleep(ts)

  • 0 est le point de départ de la boucle.
  • Le but à atteindre pour interrompre la boucle est int(datetime.datetime.now().timestamp()). Il s'agit d'un nombre entier qu'on appelle Epoch et qui correspond au nombre de secondes écoulées depuis le 1er janvier 1970 (temps de référence Unix). C'est l'instant présent, insaisissable frontière entre le passé et le futur. Évidemment, s'il n'est pas emprisonné dans une variable, ce nombre s'incrémente d'une seconde toutes les secondes.
  • La variable ts est le time.sleep. Le programme se met en pause une seconde à chaque tour de boucle. Je lance cette dernière et je traduis sa condition en langage humain: Rajoute 1 à la variable i et mets le programme en pause une seconde à chaque tour de boucle, dans l'intervalle de temps compris entre 0 et l'instant présent.

Vous l'aurez compris, i et epoch sont incrémentés d'une seconde à chaque tour de boucle, si bien que la variable i court derrière l'objectif sans jamais pouvoir l'atteindre! Nous sommes donc bien en présence d'une boucle infinie, allez-vous en conclure. 


Petite précision:

Le commentateur Chris m'a fait la remarque que le deuxième code n'est pas une boucle infinie puisque les bornes de départ et d'arrivée sont définies une bonne fois pour toute et ne peuvent pas être modifiées en cours d'itération. Il a raison. La bonne d'arrivée ne s'incrémente pas. Je vous invite à lire son commentaire qui apporte des précisions à l'article. Et je prends acte de cette erreur.

Il doit être possible cependant de faire une sorte de boucle infinie avec for in range(), en utilisant un générateur comme par exemple dans ce code inspiré d'un script trouvé sur stackoverflow:

def adjustable_range(i, stop=None, step=None):

    if stop is None:

        i, stop = 0, i

    if step is None:

        step = 1

    while i < stop:

        change_bound = (yield i)

        if change_bound is None:

            i += step

        else:

            stop = change_bound

myrange = adjustable_range(2)

for i in myrange:

    print(i)

    myrange.send(2+i)

    time.sleep(1)


Oui et non, tout dépend de l'endroit où se trouve l'observateur et tout dépend de ce que l'on entend par infini. Si vous êtes à l'intérieur de la boucle, alors je suis désolé de vous annoncer que vous allez passer le reste de votre éternité à tenter d'atteindre Epoch. Vers la fin, ça risque d'être un peu long. Par contre, si vous êtes à l'extérieur de la boucle, vous pouvez agir sur la variable ts en lui affectant la valeur 0. Le programme ne se met plus en pause. Avec ces nouvelles conditions, la variable i effectue 4255 tours de boucle en une seconde (du moins sur mon ordinateur). À ce rythme, elle finira par rattraper Epoch, et en retrouvant notre espace-temps, la boucle infinie va s'interrompre.

Pourtant, même avec les conditions de depart (ts = 1), il me semble qu'à plus ou moins long terme, cette boucle finira par s'écrouler sur elle-même. Pourquoi? Parce que la variable i gonfle sans qu'il soit possible de réduire sa valeur. Par exemple, si elle atteint 1000000 et que vous décidez de la repasser à 0, ce changement ne sera pas pris en compte. C'est sans doute dû au fait que la variable i est en charge de l'itération de la boucle. On ne peut donc pas modifier sa valeur en cours de route. Enfin, c'est ce que j'en déduis, mais n'hésitez pas à me corriger si je fais fausse route.

Personnellement, pour coder mom horloge, j'ai opté pour cette formule hybride qui permet de garder le contrôle du time.sleep et de réduire régulièrement.

import datetime
import time

i = 0
ts = 1
while i < int(datetime.datetime.now().timestamp()):
    print(i, int(datetime.datetime.now().timestamp()))
    time.sleep(ts)
    if i==10000:
        i = 0
    i += 1

Dans ce troisième code, vous pouvez agir sur la variable ts, en lui affectant 0. Ainsi, vous annulez son action. Vous pouvez également shunter la variable i en lui affectant 10001, ce qui fait qu'elle ne repassera plus à la valeur 0. Dans ces conditions, i finira par rattraper epoch et par interrompre la boucle.

J'ignore s'il existe d'autres alternatives qui permettent d'avoir une boucle infinie sous contrôle. Si c'est le cas, je vous saurais gré de me le dire.

Quelle conclusion peut-on tirer de cette petite excursion temporelle? On dit que notre univers est en expansion. Il gonfle, parait-il. Du coup, je me demande si notre espace-temps n'est pas prisonnier d'une boucle infinie. Est-ce que la mort est la variable qui permet à chacun d'entre nous de s'en extraire? Difficile de répondre à cette question vu que nous sommes encore en vie... Et quelle est la nature de cette boucle qui enveloppe notre univers? Si Dieu a choisi while 1 < 2, alors il a fait une sacrée connerie! Et nous sommes perdu(e)s. Même Greta Thunberg ne peut rien pour nous. Notre univers va gonfler avant de planter comme un ordinateur.

Si par contre, Dieu s'est donné les moyens de pouvoir modifier les conditions qui gouvernent la boucle, alors l'univers pourra entamer une phase de contraction qui lui évitera d'exploser. Observez bien le symbole de l'infini qui illustre l'article. Il s'agit d'une boucle qui symbolise l'expansion et la contraction d'un volume fini. C'est peut-être aussi la meilleure définition de la récursivité.

 

boucles infinies programmation Philosophie

  • 1 vote. Moyenne 4.00 sur 5.

Commentaires

  • Kody

    1 Kody Le 19/08/2020

    Article intéressant !
    Personnellement, j'aurais pris une autre route

    https://s.kdy.ch/Code_aaGDDtcJp2.png
    miamondo

    miamondo Le 19/08/2020

    Ah oui! C'est vrai, c'est encore plus simple.
    miamondo

    miamondo Le 19/08/2020

    Oui mais non...

    Je viens de réfléchir. Comment fais-tu pour interrompre la boucle? Quelle variable modifies-tu?

  • sodimel

    2 sodimel Le 19/08/2020

    J'aurais fait pareil que Kody, mais en remplaçant True par 1 (puisque c'est plus court à écrire et que tout int != 0 vaut vrai)
  • Chris

    3 Chris Le 19/08/2020

    Bonjour

    Pour le second code, le range construit est par définition fini, et sa taille est figée à la ligne exacte ou il est appelé. La boucle n'est donc pas du tout infinie.

    for i in range(0, int(datetime.datetime.now().timestamp())): << cela devient "for i in range(0, X)" avec X = int(datetime.datetime.now().timestamp()) au moment (unique) ou le code est passé par l'évaluation du range. Peu importe que le temps s'écoule après, les bornes du générateur ont été résolues et sont connues, elles n'ont aucune raison de chercher à être recalculées à itération de boucle.

    L'explication est assez confuse par la suite : soit on est en train d'exécuter la boucle, soit on ne l'est pas. Il n'y pas de notion "d'observateur" abstraite, le code est executé de manière déterministe et reproductible : la variable "ts" ne peut pas être modifiée par magie, ou alors on fait intervenir des threads par exemple, mais ça ne semble pas être le cas ici, le code n'étant pas du tout adapté à cela ?

    Pour le troisieme code c'est différent car l'expression du while est évaluée à chaque début de boucle, donc la borne testé augmente d'1 à chaque seconde qui passe en effet.

    Tout cela semble très étrange, compliqué et adhoc pour rien : pourquoi spécialement choisir datetime.datetime.now().timestamp() plutôt que juste valeur attendue + 1 dans ce cas, quite à faire des boucles dont les bornes changent sans arrêt à chaque itération... ?

    Cela n'a pas vraiment de sens, et je pense qu'il vous manque l'utilisation du mot clé "break", qui permet d'arrêter l'exécution d'une boucle for ou while:

    stop = False
    while True:
    if stop:
    break;
    time.sleep(1)

    avec cet exemple un peu naïf, il est possible de "contrôler" (plutôt "interrompre", donc) la boucle depuis un thread extérieur, en changeant la valeur de la variable "stop".
    miamondo

    miamondo Le 19/08/2020

    Bonjour, Merci pour votre long commentaire. L'article est sans doute étrange et manque de rigueur, mais il s'agit d'une variation assez libre sur le boucles et l'espace-temps. Concernant le deuxième code, vous avez raison. J'ai remplacé la borne 0 par int(datetime.datetime.now().timestamp()) - 10, et la boucle s'est interrompu au bout de dix tours, ce qui prouve que les bornes du range sont définies une bonne fois pour toutes. Je vais le préciser dans le corps de l'article mais sans modifier l'article en lui-même. je vais faire un lien vers votre commentaire. Tant pis pour moi, je n'avais qu'a vérifier. Merci en tout cas pour vos précisions.

Ajouter un commentaire

Anti-spam
 
expand_less