Page 1 sur 2

Script qui refuse de s’exécuter sur la Numworks N0100 (bis)

Message non luPosté: 13 Oct 2019, 15:25
de cent20
Bonjour,

Cette fois ci mon script est tout petit, à peine 800 octets et mon problème n'est donc pas un problème de mémoire.

Le script est ici : https://workshop.numworks.com/python/cent20/longueurcourbe et par sécurité je le colle ci-dessous, juste au cas où je renomme un jour celui du workshop ce qui brise le lien ...

Code: Tout sélectionner
from math import sqrt


def fonc():
    global f
    print("Saisir une fonction :")
    f = str(input("f(x) = "))


def interval():
    global a, b
    print("Saisir un intervalle [a,b] :")
    a = float(input("a = "))
    b = float(input("b = "))


def coupe():
    global n
    print("Combien de segment :")
    n = int(input("n = "))


def long():
    fonc()
    interval()
    coupe()
    lc, p = 0, (b-a)/n
    for i in range(n):
        x1, x2 = a + i*p, a + (i+1)*p
        x = x1
        y1 = eval(f)
        x = x2
        y2 = eval(f)
        d = sqrt((x1-x2)**2+(y1-y2)**2)
        lc = lcn + d
    print("La longueur de la courbe de f")
    print("définie par f(x) =",f)
    print("sur [{},{}]".format(a, b))
    print("est :",lc)


Il tourne sans problème sur Spyder, sur Thonny mais sur la numworks rien à faire elle ne veut pas le faire tourner...

Bon je vais me rabattre sur celui de sesamath (ci-dessous), mais c'est fatiguant ces implémentations non standard !

Code: Tout sélectionner
from math import sqrt
def f(x):
    return x**2 #Modifier la fonction ici
def distance(x1,y1,x2,y2):
    return sqrt((x1-x2)**2 + (y1-y2)**2)
def longueurCourbe(f,a,b,n):
    longueur = 0
    x1,y1 = a,f(a)
    h = (b-a)/n
    for i in range(n):
        x2 = x1 + h
        y2 = f(x2)
        longueur = longueur + distance(x1,y1,x2,y2)
        x1,y1 = x2,y2
    return longueur

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 13 Oct 2019, 15:29
de cent20
spyderOK.JPG


thonnyOK.JPG
thonnyOK.JPG (30.49 Kio) Vu 2900 fois


numworksKO.JPG

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 13 Oct 2019, 18:22
de critor
Bonjour.

Apparemment la fonction eval() évalue dans l'environnement global, et non pas dans l'environnement local associé à l'exécution de la fonction long().
La variable x étant définie dans la fonction long(), elle n'existe pas dans l'environnement global, d'où l'erreur.

Pour contourner ce problème, il te suffit de rajouter une simple ligne au début de la fonction long() :
Code: Tout sélectionner
def long():
  global x
  ...

Et ça marche : :)
Image

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 13 Oct 2019, 18:30
de critor
Comme compléments, eval() utilise apparemment :
  • l'environnement global dans ma ligne de commande
  • l'environnement local sur NumWorks
  • l'environnement local sur Casio Graph 90/35+E II
  • l'environnement local sur TI-83 Premium CE
C'est sûrement une des différences entre le Python complet et les implémentations légères MicroPython/CircuitPython.

Merci à toi, tu me fais apprendre des choses, j'ignorais cette différence-ci. :)

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 13 Oct 2019, 19:29
de cent20
Merci beaucoup pour ces explications très claires. J’avais oublié que c’était micro python et pas Python. En plus je pense que ça va résoudre mon problème d’origine car le script proposé ici était une version dégradée d’un autre script...

Script qui refuse de s’exécuter sur la Numworks N0100 (bis)

Message non luPosté: 13 Oct 2019, 20:57
de cent20
Mon problème d'origine persiste, il n'était pas l'objet du post d'origine...

Code: Tout sélectionner
def fonction(f,a):
    global x
    x = a
    return eval(f)


L'utilisateur saisie alors f(x**2,3) dans la console et il doit obtenir en retour 9 mais cela plante car

Code: Tout sélectionner
NameError: name 'x' is not defined


J'ai essayé de bricolé, sans succès :

Code: Tout sélectionner
def fon(str(f), a):
    global x
    x = a
    return eval(f)


ne marche bien sur pas, tout comme les tentative pour rajouter une déclaration de type

Code: Tout sélectionner
def fonction(fonc,a):
    global x
    x = a
    f = str(fonc)
    return eval(f)


N'y a t'il vraiment aucun moyen de faire saisir l'utilisateur la "fonction mathématiques" directement dans les paramètres de la "fonction python" sans passer par une saisie manuelle préalable ?

Code: Tout sélectionner
    print("Saisir une fonction :")
    f = str(input("f(x) = "))


J'aurais voulu faire ceci :

Code: Tout sélectionner
def long(fonction, a=1, b=2, n=2):


directement, récupérer une chaîne de caractère dans fonction et l'évaluer en f° d'un x défini à l'aide de a,b et n

Alors oui, on peut toujours faire

long("x**2",1, 2, 10) mais se souvenir qu'il faut saisir des " " est peu probable ..

Bon sinon merci pour le "global", il n'y a plus qu'à tester ça demain.

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 13 Oct 2019, 21:19
de critor
Lors d'un appel de fonction, les paramètres sont d'abord évalués avant même l'exécution de sa première ligne de code, d'où l'erreur.

Si l'on souhaite passer une expression à la fonction, il faut donc la mettre entre "..." pour en bloquer l'évaluation.
Ou sinon il faut passer par un input(...).

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 14 Oct 2019, 16:07
de cent20
Mon script marche est il est terminé.

longueurcourbe.JPG


Sur numworks : https://workshop.numworks.com/python/cent20/longueurcourbe

Ici en copié collé codé au format PEP8 :

Code: Tout sélectionner
from math import sqrt


def fonc():
    global f
    print("Saisir une fonction :")
    f = str(input("f(x) = "))


def interval():
    global a, b
    print("Saisir un intervalle [a,b] :")
    a = float(input("a = "))
    b = float(input("b = "))


def coupe():
    global n
    print("Combien de segment :")
    n = int(input("n = "))


def long(h=""):
    global x
    if (h == 15) or (h == 112):
        print('long() calcule la longueur')
        print("de la courbe de la f° f")
        print("sur l'intervalle [a,b]")
        print("en la découpant en n segments")
    else:
        fonc()
        interval()
        coupe()
        lc, p = 0, (b-a)/n
        for i in range(n):
            x1, x2 = a + i*p, a + (i+1)*p
            x = x1
            y1 = eval(f)
            x = x2
            y2 = eval(f)
            d = sqrt((x1-x2)**2+(y1-y2)**2)
            lc = lc + d
        print("La longueur de la courbe de f")
        print("définie par f(x) =",f)
        print("sur [{},{}]".format(a, b))
        print("est :",lc)


Il calcule la longueur d'une courbe en la découpant en n segment.

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 14 Oct 2019, 16:10
de cent20
Mon code n'est pas reconnu en python, c'est quoi cette diablerie ? Il y a des agents lexibook infiltrés ici ou quoi ?

Ohhh il vient de changer de couleur ...

Re: Script qui refuse de s’exécuter sur la Numworks N0100 (b

Message non luPosté: 14 Oct 2019, 18:08
de coco33920
Pourquoi passer par des eval() et ne pas utiliser les lambda ?.
Par exemple passer un argument f dans ta fonction qui est juste lambda x: x**2 et comme ça tu fais f(1), f(2) etc. ?