Вопрос

Я пытаюсь использовать модуль Turtle в Python, чтобы нарисовать американский флаг, используя отдельные функции: сначала у меня есть draw_flag, который вычисляет все размеры, а затем draw_rectangle, который фактически рисует форму флага, затем я сделаю draw_stars и т. д., чтобы нарисовать звезды и линии.

Но у меня возникли некоторые проблемы с пониманием того, как работают функции... вот мой код:

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)

Я надеялся, что он вернется, нарисовав прямоугольник, но он продолжает говорить, что длина не определена, и не уверен, где разместить «длину», где он распознает переменную.

Я использую Python 3, спасибо.

Это было полезно?

Решение

Вот хороший способ подумать об этом.Функция — это «черный ящик», который принимает некоторое количество значений, называемое аргументы, в определенном порядке и что-то делает с ними, чтобы получить какое-то другое значение.Когда я говорю «черный ящик», я имею в виду, что когда вы используете эту функцию, вам не о чем беспокоиться. как он делает то, что делает, вы просто даете ему некоторые значения и получаете их обратно.

Давайте рассмотрим очень простую функцию, которая просто вычитает два заданных числа:первое минус второе.Другими словами, мы сделаем функцию, которая реализует правило «Аргумент № 1 - аргумент № 2». Теперь, когда вы пишете код для этой функции, вам нужен какой -нибудь способ рассказать компьютеру, когда вы хотите использовать аргумент № 1 и когда вы хотите использовать аргумент № 2.В некоторых других языках программирования вам придется сделать это, явно указав номер аргумента, который вы хотите использовать (#1 или #2), но гораздо проще писать код, если вы можете дать этим значениям имена.Таким образом, Python, как и большинство других языков, позволяет вам ссылаться на аргументы функции, используя имена по вашему выбору.Например, предположим, вы хотите, чтобы аргумент №1 имел имя x, и аргумент №2 под именем y.Вы можете указать это, написав следующее:

def subtract(x, y):

За этим будет следовать код, составляющий функцию.Для примера вычитания это будет

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

Когда компилятор Python встречается с этим, он переводит код в свое внутреннее представление «Рассчитайте значение № 1 - значение № 2 и отправляет его обратно моему абоненту». Затем он собирает этот блок кода и сохраняет его под именем subtract (потому что вы сказали, что хотите назвать функцию именно так).

Надеюсь, имеет смысл, что как только этот блок кода завершит выполнение, больше не будет смысла ссылаться на «аргумент № 1» или «аргумент № 2», потому что без функции не может быть аргументов!Аналогично, как только функция выполнила свою задачу, метки, которые вы присвоили аргументам, x и y, уже не имеют никакого значения.Метки существуют только на протяжении всего кода функции.Это называется обзор:ограничение меток той частью кода, где они что-то означают.

Потому что этикетки x и y являются локально, можно сказать, в каком-то смысле даже не важно, какие они.Например, если бы у вас было такое определение subtract в своем коде вы можете произвольно решить изменить их на first и second, и все, что вам нужно будет изменить, — это код внутри этой функции.Вы бы просто изменили определение на

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

и все — ваш код функционально точно такой же.В любом другом месте программы, где x и y случаются, они относятся к чему-то другому, а не к аргументам этой функции, поэтому вам не нужно менять их при переименовании аргументов.

В вашем случае происходит то, что вы пытались использовать ярлык length где-то за пределами функции, для которой он был определен (а именно, функции, которую вы сохранили как draw_rectangle).Python знает, что вы не можете ссылаться на аргумент функции, в которой вы не участвуете, поэтому он ожидает, что вы уже определили length означать что-то другое.Но ты этого не сделал.Вот почему вы получаете ошибку.(Ну, во всяком случае, эта одна ошибка)

Другие советы

У вас есть две проблемы.Сначала вы определяете функцию draw_flag но ты никогда не называешь это.

Однако если бы вы ее вызвали, это не сработало бы, потому что ваша функция draw_flag действительно ничего не делает.Он просто определяет некоторые переменные внутри себя, а затем выбрасывает их, когда завершается.Вы должны вернуть длину и высоту с помощью return length, height, тогда делай length, height = draw_flag(A) и позвони draw_rectangle с этими ценностями.(Или вы могли бы сделать draw_rectangle(*draw_flag(A)).)

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

Функции не взаимодействуют друг с другом волшебным образом.Функция принимает входные данные и возвращает возвращаемое значение.Если вы хотите использовать возвращаемое значение где-то еще, вам нужно вызвать функцию в том месте, где вы хотите использовать это значение.

Вы вызываете функцию draw_rectangle, который принимает два аргумента — длину и высоту.Длина рассчитывается по draw_flag функция;но вы не возвращаете значение.

У вас есть несколько способов решить эту проблему.Один из них — просто позвонить draw_flag функцию с заданной пользователем высотой, сохраните возвращаемое значение, а затем вызовите 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))

Другой — переместить input к draw_flag функцию, а затем вызвать draw_rectangle функционировать изнутри draw_flag функция.Если вы это сделаете, то draw_flag функция вообще не нуждается в аргументах:

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()

Я думаю, вам также следует просмотреть раздел вашей книги по Python, посвященный областям действия переменных.Это поможет позже, когда вы ожидаете вывода некоторых переменных, но получаете странные ошибки, особенно если вы используете функции.

Попробуйте следующее

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)
.

Хорошо, чтобы ответить на ваш более общий вопрос: функции в Python принимают аргументы, когда вы их вызываете, они передаются по ссылке, а это означает, что вы получаете те же данные внутри функции, что и в пространстве вызова.Это важно для изменяемых типов, поскольку если они изменяются внутри функции, они изменяются и вне функции.(str, int, float и tuple не изменяемы, а dict и list — изменяемы).Когда функция возвращает значение, значение после токена возврата передается обратно вызывающей стороне, поэтому, если вы скажете a=input('input? '), входная функция принимает аргумент для подсказки, отображаемой пользователю. Обратите внимание, что он передается по ссылке, а не является копией строки.Он возвращает сгенерированный пользователем ввод, который сохраняется в файле.Вы можете вернуть несколько значений из функции, они автоматически преобразуются в кортеж;если у вас есть

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

Вы получите a=1 и b=2.Имена, используемые внутри функции, должны быть определены.Сначала они ищутся внутри функции, затем во всех окружающих пространствах имен и, наконец, во встроенных функциях.Переменные, определенные в других функциях, использовать нельзя, поскольку они не находятся ни в локальном пространстве имен, ни в каком-либо из его родительских элементов.Чтобы получить доступ к значениям этих имен, вам необходимо передать их в функцию. Обратите внимание, что имена, используемые внутри функции, не обязательно должны совпадать с именами вне функции.Учитывать:

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

Значение 5 сохраняется в памяти под именем b, затем передается по ссылке в fun1, на этот раз под именем a, оно удваивается и возвращается (возврат также осуществляется по ссылке), затем возвращаемое значение сохраняется под именем c, который затем распечатывается.

return возвращает все, что вы возвращаете вызывающему абоненту.Оно делает нет автоматически делает локальные переменные внутри функции доступными снаружи (это местный по причине!).Обратите внимание также, что return без каких-либо аргументов вернет специальное значение None (так что это эквивалентно return None).

Итак, если вы хотите вернуть некоторые значения, используйте return height, length внутри функции и height, length = draw_flag(A) снаружи.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top