Question

J'essaie d'utiliser le module Turtle en Python pour dessiner le drapeau américain en utilisant des fonctions distinctes. J'ai d'abord draw_flag qui calcule toutes les dimensions, puis draw_rectangle qui dessine réellement la forme du drapeau, puis je ferai draw_stars, etc., pour dessiner le étoiles et lignes.

Mais j'ai un peu de mal à comprendre le fonctionnement des fonctions. Voici mon code jusqu'à présent :

import turtle
import time
import random

def draw_rectangle(length, height):
    turtle.up()
    x = length
    y = height

    turtle.begin_fill()
    turtle.setpos(x,y)
    turtle.down()
    turtle.forward(418)
    turtle.right(90)
    turtle.forward(220)
    turtle.right(90)
    turtle.forward(418)
    turtle.right(90)
    turtle.forward(220)
    turtle.end_fill()

    turtle.sleep(2)
    turtle.bye

def draw_flag(A):
    height = int(A)
##    length = height*1.9
##    union_height = height*(7/13)
##    union_length = length*(2/5)
##    E = F = union_height/10
##    G = H = union_length/12
##    stripe_width = height/13
##    diameter_star = stripe_width*(4/5)
    length = height*1.9
    return

A = input("Please enter the height of the flag: ")

draw_rectangle(length, height)

J'espérais qu'il reviendrait en dessinant un rectangle, mais il n'arrête pas de dire que la longueur n'est pas définie, je ne sais pas où placer « longueur » là où il reconnaîtra la variable.

J'utilise Python 3, merci.

Était-ce utile?

La solution

Voici une bonne façon d’y penser.Une fonction est une « boîte noire » qui contient un certain nombre de valeurs, appelées arguments, dans un ordre spécifique et fait quelque chose avec eux pour produire une autre valeur.Quand je dis « boîte noire », je veux dire que lorsque vous utilisez la fonction, vous n'avez pas à vous en soucier comment il fait ce qu'il fait, vous lui donnez simplement quelques valeurs et vous récupérez une valeur.

Considérons une fonction très simple qui soustrait simplement les deux nombres qui lui sont donnés :le premier moins le second.En d'autres termes, nous allons faire une fonction qui implémente la règle "Argument # 1 - Argument # 2". Maintenant, lorsque vous écrivez le code pour cette fonction, vous avez besoin d'un moyen de dire à l'ordinateur lorsque vous souhaitez utiliser l'argument # 1 et lorsque vous souhaitez utiliser l'argument # 2.Dans certains autres langages de programmation, vous devez le faire en spécifiant explicitement le numéro de l'argument que vous souhaitez utiliser (#1 ou #2), mais il est beaucoup plus facile d'écrire du code si vous pouvez donner des noms à ces valeurs.Ainsi Python, comme la plupart des autres langages, vous permet de faire référence aux arguments d'une fonction en utilisant les noms de votre choix.Par exemple, supposons que vous souhaitiez que l'argument n°1 soit placé sous le nom x, et l'argument n°2 à placer sous le nom y.Vous pourriez l'indiquer en écrivant ceci :

def subtract(x, y):

Ceci serait suivi du code qui constitue la fonction.Pour l’exemple de soustraction, ce serait

def subtract(x, y):
    return x - y

Lorsque le compilateur Python le rencontre, il traduit le code en sa représentation interne de "Calculer la valeur # 1 - valeur # 2 et renvoyer cela à mon appelant". Il emballe ensuite ce bloc de code et l'enregistre sous le nom subtract (parce que c'est ce que vous lui avez dit que vous vouliez nommer la fonction).

Espérons qu'il soit logique qu'une fois l'exécution de ce bloc de code terminée, cela n'ait plus de sens de faire référence à « l'argument n°1 » ou à « l'argument n°2 », car vous ne pouvez pas avoir d'arguments sans fonction !De la même manière, une fois que la fonction a fait son travail, les étiquettes que vous avez données aux arguments, x et y, n'ont plus aucun sens.Les étiquettes n'existent que pendant la durée du code de la fonction.C'est appelé portée:limiter les étiquettes à la partie du code où elles signifient quelque chose.

Parce que les étiquettes x et y sont portée locale, comme on pourrait le dire, d'une certaine manière, peu importe ce qu'ils sont.Par exemple, si vous aviez cette définition de subtract dans votre code, vous pourriez arbitrairement décider de les changer en first et second, et tout ce que vous auriez à changer serait le code de cette fonction.Vous changeriez simplement la définition en

def subtract(first, second):
    return first - second

et c'est tout - votre code est fonctionnellement exactement le même.N'importe où ailleurs dans le programme x et y se produisent, ils font référence à autre chose que les arguments de cette fonction, vous n'avez donc pas besoin de les modifier lorsque vous renommez les arguments.

Ce qui se passe dans votre cas, c'est que vous avez essayé d'utiliser le label length quelque part en dehors de la fonction pour laquelle il a été défini (à savoir, la fonction que vous avez stockée sous draw_rectangle).Python sait que vous ne pouvez pas faire référence à l'argument d'une fonction dans laquelle vous n'êtes pas, il s'attend donc à ce que vous l'ayez déjà défini length pour signifier autre chose.Mais tu ne l'as pas fait.C'est pourquoi vous obtenez une erreur.(Eh bien, cette erreur, en tout cas)

Autres conseils

Vous avez deux problèmes.Tout d'abord, vous définissez la fonction draw_flag mais tu ne l'appelles jamais.

Cependant, si vous l'appeliez, cela ne fonctionnerait pas, car votre fonction draw_flag ne fait vraiment rien.Il définit simplement certaines variables en lui-même, puis les jette à la fin.Vous devez renvoyer la longueur et la hauteur avec return length, height, alors fais length, height = draw_flag(A) et appelle draw_rectangle avec ces valeurs.(Ou tu pourrais faire draw_rectangle(*draw_flag(A)).)

length, height = draw_flag(A)
draw_rectangle(length, height)

Les fonctions ne communiquent pas comme par magie entre elles.Une fonction prend des entrées et produit une valeur de retour.Si vous souhaitez utiliser cette valeur de retour ailleurs, vous devez appeler la fonction à l'endroit où vous souhaitez utiliser la valeur.

Vous appelez la fonction draw_rectangle, qui attend deux arguments : une longueur et une hauteur.La longueur est calculée par le draw_flag fonction;mais vous ne renvoyez pas la valeur.

Vous avez plusieurs façons de résoudre ce problème.La première consiste simplement à appeler le draw_flag fonction avec la hauteur fournie par l'utilisateur, enregistrez la valeur de retour, puis appelez draw_rectangle:

def draw_flag(A):
    height = int(A)
##    length = height*1.9
##    union_height = height*(7/13)
##    union_length = length*(2/5)
##    E = F = union_height/10
##    G = H = union_length/12
##    stripe_width = height/13
##    diameter_star = stripe_width*(4/5)
    return height*1.9

A = input("Please enter the height of the flag: ")
length = draw_flag(A)
draw_rectangle(length, int(A))

L'autre consiste à déplacer votre input au draw_flag fonction, puis appelez la draw_rectangle fonctionner de l’intérieur du draw_flag fonction.Si vous faites cela, alors le draw_flag la fonction n'a besoin d'aucun argument :

def draw_flag():
    A = input("Please enter the height of the flag: ")
    height = int(A)
##    length = height*1.9
##    union_height = height*(7/13)
##    union_length = length*(2/5)
##    E = F = union_height/10
##    G = H = union_length/12
##    stripe_width = height/13
##    diameter_star = stripe_width*(4/5)
    draw_rectangle(height*1.9, height)

draw_flag()

Je pense que vous devriez également consulter la section de votre livre Python sur les portées variables.Cela vous aidera plus tard lorsque vous vous attendez à ce que certaines variables s'impriment mais que vous obtenez des erreurs étranges - surtout si vous utilisez des fonctions.

Essayez ce qui suit

import turtle
import time
import random

def draw_rectangle(length, height):
   turtle.up()
   x = length
   y = height

   turtle.begin_fill()
   turtle.setpos(x,y)
   turtle.down()
   turtle.forward(418)
   turtle.right(90)
   turtle.forward(220)
   turtle.right(90)
   turtle.forward(418)
   turtle.right(90)
   turtle.forward(220)
   turtle.end_fill()

   turtle.sleep(2)
   turtle.bye

 def draw_flag(A):
   height = int(A)
   length = height*1.9
   draw_rectangle(length,height)
   return

A = input("Please enter the height of the flag: ")

draw_flag(A)

D'accord, donc pour répondre à votre question plus générale, les fonctions en python acceptent les arguments lorsque vous les appelez, ceux-ci sont passés par référence, ce qui signifie que vous vous retrouvez avec les mêmes données à l'intérieur de la fonction que dans l'espace appelant.Ceci est important pour les types mutables, car s’ils sont modifiés à l’intérieur de la fonction, ils le sont également à l’extérieur de la fonction.(str, int, float et tuple ne sont pas mutables, dict et list le sont).Lorsqu'une fonction revient, la valeur après le jeton de retour est renvoyée à l'appelant, donc si vous dites a=input('input? '), l'entrée de la fonction prend un argument pour que l'invite s'affiche à l'utilisateur, notez que celui-ci est transmis par référence, ce n'est pas une copie de la chaîne.Il renvoie l'entrée générée par l'utilisateur, qui est stockée dans un fichier a.Vous pouvez renvoyer plusieurs valeurs à partir d'une fonction, elles sont automatiquement converties en tuple ;si tu as

def test():
    return 1,2
a,b = test()

Vous obtiendrez a=1 et b=2.Les noms utilisés dans une fonction doivent être définis.Ils sont d'abord recherchés à l'intérieur de la fonction, puis dans tous les espaces de noms englobants, enfin dans les éléments intégrés.Les variables définies dans d'autres fonctions ne peuvent pas être utilisées, car elles ne se trouvent pas dans l'espace de noms local ni dans aucun de ses parents.Pour accéder aux valeurs de ces noms, vous devez les transmettre à la fonction, notez que les noms utilisés à l'intérieur de la fonction ne doivent pas nécessairement correspondre aux noms en dehors de la fonction.Considérer:

def fun1(a):
    return a * 2
def fun2():
    b = 5
    c = fun1(b)
    print c
fun2()

La valeur 5 est stockée en mémoire sous le nom b, puis passée par référence dans fun1, cette fois sous le nom a, elle est doublée et renvoyée, (le retour se fait aussi par référence), la valeur de retour est ensuite stockée sous le nom c, qui est ensuite imprimé.

return renvoie ce que vous redonnez à l'appelant.Cela fait pas rend automatiquement les variables locales à l'intérieur de la fonction disponibles à l'extérieur (ce sont locale pour une raison!).Notez également que return sans aucun argument, la valeur spéciale sera renvoyée None (donc c'est équivalent à return None).

Donc, si vous souhaitez renvoyer des valeurs, utilisez return height, length à l'intérieur de la fonction, et height, length = draw_flag(A) dehors.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top