سؤال

أحاول استخدام وحدة Turtle في Python لرسم العلم الأمريكي باستخدام وظائف منفصلة، ​​أولاً لدي draw_flag الذي يحسب جميع الأبعاد، ثم draw_rectangle الذي يرسم شكل العلم بالفعل، ثم سأرسم نجومًا، وما إلى ذلك، لرسم العلم الأمريكي. النجوم والخطوط.

ولكن، أواجه بعض المشاكل في فهم كيفية عمل الوظائف.. وإليك الكود الخاص بي حتى الآن:

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)

كنت أتمنى أن يعود عن طريق رسم مستطيل، لكنه يظل يقول إن الطول غير محدد، ولست متأكدًا من مكان وضع "الطول" حيث سيتعرف على المتغير.

أنا أستخدم بايثون 3، شكرًا.

هل كانت مفيدة؟

المحلول

إليك طريقة جيدة للتفكير في الأمر.الدالة عبارة عن "صندوق أسود" يأخذ عددًا معينًا من القيم، تسمى الحجج, بترتيب معين ويفعل شيئًا معهم لإنتاج قيمة أخرى.عندما أقول "الصندوق الأسود"، أعني أنه عند استخدام الوظيفة، لا يتعين عليك الاهتمام كيف إنها تفعل ما تفعله، ما عليك سوى إعطائها بعض القيم وستحصل على القيمة مرة أخرى.

لنفكر في دالة بسيطة جدًا تقوم فقط بطرح الرقمين المعطاين لها:الأول ناقص الثاني.بمعنى آخر ، سنقوم بعمل وظيفة تنفذ القاعدة "الوسيطة رقم 1 - الوسيطة رقم 2." الآن ، عندما تكتب الرمز لهذه الوظيفة ، تحتاج إلى طريقة ما لإخبار الكمبيوتر عندما تريد استخدام الوسيطة رقم 1 وعندما تريد استخدام الوسيطة رقم 2.في بعض لغات البرمجة الأخرى، يتعين عليك القيام بذلك عن طريق تحديد رقم الوسيطة التي تريد استخدامها بشكل صريح (#1 أو #2)، ولكن من الأسهل كثيرًا كتابة التعليمات البرمجية إذا كان بإمكانك تسمية هذه القيم بأسماء.لذا، فإن بايثون، مثل معظم اللغات الأخرى، تتيح لك الإشارة إلى وسائط دالة باستخدام أسماء من اختيارك.على سبيل المثال، لنفترض أنك تريد وضع الوسيطة رقم 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).تعرف بايثون أنك لا تستطيع الإشارة إلى وسيطة دالة لست فيها، لذا تتوقع منك أن تكون قد حددتها بالفعل 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 الخاص بالنطاقات المتغيرة.سيساعدك ذلك لاحقًا عندما تتوقع طباعة بعض المتغيرات ولكنك تحصل على أخطاء غريبة - خاصة إذا كنت تستخدم وظائف.

جرب ما يلي

giveacodicetagpre.

حسنًا، للإجابة على سؤالك الأكثر عمومية، تقبل الوظائف في بايثون الوسائط عند استدعائها، ويتم تمريرها حسب المرجع، مما يعني أنه سينتهي بك الأمر بنفس البيانات داخل الوظيفة كما في مساحة الاتصال.هذا مهم للأنواع القابلة للتغيير، لأنه إذا تم تغييرها داخل الوظيفة، فسيتم تغييرها خارج الوظيفة أيضًا.(str وint وfloat وtuple غير قابلة للتغيير، أما dict وlist فهي قابلة للتغيير).عندما تعود دالة، يتم تمرير القيمة بعد رمز الإرجاع مرة أخرى إلى المتصل، لذلك إذا قلت ذلك a=input('input? '), ، يأخذ إدخال الوظيفة وسيطة للموجه ليتم عرضها للمستخدم، لاحظ أنه يتم تمريرها حسب المرجع، وهي ليست نسخة من السلسلة.تقوم بإرجاع المدخلات التي أنشأها المستخدم، والتي يتم تخزينها في ملف.يمكنك إرجاع قيم متعددة من دالة، ويتم تحويلها تلقائيًا إلى صف؛اذا كنت تمتلك

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

سوف تحصل على = 1 و ب = 2.يجب تعريف الأسماء المستخدمة داخل الدالة.يتم البحث عنها أولاً داخل الوظيفة، ثم في أي مساحات أسماء متضمنة، وأخيرًا في الإضافات.لا يمكن استخدام المتغيرات المعرفة في وظائف أخرى، لأنها ليست في مساحة الاسم المحلية ولا في أي من أصولها.للوصول إلى قيم هذه الأسماء، عليك تمريرها إلى الدالة، لاحظ أن الأسماء المستخدمة داخل الدالة لا يجب أن تتطابق مع الأسماء الموجودة خارج الدالة.يعتبر:

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

يتم تخزين القيمة 5 في الذاكرة تحت الاسم b، ثم يتم تمريرها بالرجوع إلى fun1، هذه المرة تحت الاسم a، ويتم مضاعفتها وإعادتها (يتم الإرجاع أيضًا بالرجوع إليها)، ثم يتم تخزين القيمة المرجعة تحت الاسم ج، ثم تتم طباعته.

return إرجاع كل ما تعيده إلى المتصل.نعم هو كذلك لا جعل المتغيرات المحلية داخل الوظيفة متاحة بالخارج تلقائيًا (هذه هي محلي لسبب ما!).لاحظ ذلك أيضًا return بدون أي وسائط سوف يعود القيمة الخاصة None (لذلك فهو يعادل return None).

لذلك، إذا كنت تريد إرجاع بعض القيم، استخدم return height, length داخل الوظيفة، و height, length = draw_flag(A) الخارج.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top