Как вызвать функцию внутри другой функции в vPython

ОБНОВЛЕНИЕ: игнорируйте главный вопрос. Я понял это (спасибо gilch). Единственное, что мне нужно знать сейчас, это второй вопрос ниже... Как вызвать отдельную функцию внутри другой функции.

Когда оператор while завершен и я сброшен, я больше не могу перемещать мяч, потому что цикл while не будет повторно инициирован, поэтому я не могу повторно поднять мяч, чтобы снова упасть. Я должен полностью перезапустить код. Я новичок в vpython (делаю это для урока физики), и я не могу найти способ повторно инициировать цикл while (или, как-то еще, чтобы исправить это).

Я почти уверен, что это потому, что цикл while заканчивается, а затем, когда положение и скорость мяча сбрасываются, цикл while не будет повторно инициироваться, поэтому я не могу переместить мяч, но я не уверен как это сделать. Спасибо всем, кто может помочь.

Код:

GlowScript 2.7 VPython
#Start without running
running = False
#when "Run" is initiated
def Run(b):
    #Bring in running variable from outside
    global running
    #When Run/Pause Button is pressed, switch between running and pausing the program
    running = not running
    #When run button is pressed, change text to "Pause"
    if running: bbutton.text = "Pause"
    #When pause button is pressed, change text to "Run"
    else: bbutton.text = "Run"

#Create Run Button above program
bbutton = button(text="Run", pos=scene.title_anchor, bind=Run)

#When "Reset" is initiated
def Reset(c):
    #Bring in t and ball variables from outside
    global t, ball
    #Set back to time = 0 (when reset)
    t = 0
    #Reset ball's position to initial position (when reset)
    ball.pos = vec(0,2,0)
    #resets ball's velocity to initial velocity (when reset)
    ball.vel = vec(0,0,0)

#Create reset button above program
cbutton = button(text="Reset", pos=scene.title_anchor, bind=Reset)

#Create ground
ground = box(pos=vec(0,0,0), size=vec(10,0.2,10))
#Create ball
ball = sphere(pos=vec(0,2,0), radius=0.4, color=color.yellow)
#Initial Velocity
ball.vel = vec(0,0,0)
#Acceleration (free-falling)
g = -9.8
#Initial Time
t = 0
#Time increase per frame
deltat = 0.01

#Turns "drag" condition to false to begin
drag = False
#Initial mouse position
R = vec(0,0,0)
#When you click
scene.bind("mousedown", def():
    #Bring in drag variable from outside
    global drag
    #Set drag to true on mouseclick
    drag = True

    #When you release click
    scene.bind("mouseup", def():
        #Bring in drag variable from outside
        global drag
        #Set drag to false when you release click
        drag = False
    )
)

#While True (the program is running) and the ball is higher than slightly under the ground
#If the second condition is not there, the ball will continually go down through the ground forever
#The second condition stops the ball once it begins going underneath the platform, so it looks normal

while True and ball.pos.y > ground.pos.y + 0.48:
    #Slow down program
    rate(100)
    #When the drag condition is true (When mouse is clicked on ball)...
    if drag:
        #Set R to position of mouse
        R = scene.mouse.pos
        #Set ball position to R (position of mouse) -- allows the ball to be     dragged (changes ball position)
        ball.pos = R
    #When the program is running (run button is pressed)...
    if running:
        #Update ball velocity
        #   v      =     v0     + a (change in time)
        ball.vel.y = ball.vel.y + g*deltat
        #Update position velocity
        #   x    =    x0    +    v    *(change in time)
        ball.pos = ball.pos + ball.vel*deltat
        #When the ball hits the surface of the ground...
        if (ball.pos.y <= ground.pos.y + 0.5):
            #Change the sign of the velocity (to go back up)
            ball.vel.y = -ball.vel.y
        if (ball.pos.y < ground.pos.y +0.48):
            break
        #Update time
        t = t + deltat

ОБНОВЛЕНИЕ: я поместил цикл while в функцию Initiate, но не знаю, как добавить функцию Initiate в функцию Reset...

Новый код (включая связанный код): #OTHER CODE

def Reset(c):
    #Bring in t and ball variables from outside
    global t, ball
    #Set back to time = 0 (when reset)
    t = 0
    #Reset ball's position to initial position (when reset)
    ball.pos = vec(0,2,0)
    #resets ball's velocity to initial velocity (when reset)
    ball.vel = vec(0,0,0)

    #Initiate() -- HOW DO I RUN INITIATE INSIDE THE RESET FUNCTION**

#OTHER CODE

Initiate()    

def Initiate():
    global ground, ball, g, t, deltat, drag, R

    while True and ball.pos.y > ground.pos.y + 0.48:
        #Slow down program
        rate(100)
        #When the drag condition is true (When mouse is clicked on ball)...
        if drag:
            #Set R to position of mouse
            R = scene.mouse.pos
            #Set ball position to R (position of mouse) -- allows the ball to be dragged (changes ball position)
            ball.pos = R
        #When the program is running (run button is pressed)...
        if running:
            #Update ball velocity
            #   v      =     v0     + a (change in time)
            ball.vel.y = ball.vel.y + g*deltat
            #Update position velocity
            #   x    =    x0    +    v    *(change in time)
            ball.pos = ball.pos + ball.vel*deltat
            #When the ball hits the surface of the ground...
            if (ball.pos.y <= ground.pos.y + 0.5):
                #Change the sign of the velocity (to go back up)
                ball.vel.y = -ball.vel.y
            if (ball.pos.y < ground.pos.y +0.48):
                break
            #Update time
            t = t + deltat

person Jonah    schedule 18.05.2018    source источник
comment
Попробуйте создать mvce stackoverflow.com/help/mcve, и вы получите лучшие ответы.   -  person gilch    schedule 18.05.2018
comment
Спасибо, что сообщили мне об этом. Я помнил это для второй части моего вопроса.   -  person Jonah    schedule 18.05.2018
comment
Я обычно советую новичкам в Python прочитать A Byte of Python, бесплатную онлайн-книгу для начинающих. python.swaroopch.com   -  person gilch    schedule 18.05.2018


Ответы (2)


Попробуйте поместить цикл while внутри определения функции и запустить его, вызвав функцию. Затем вы можете снова вызвать функцию, чтобы перезапустить цикл.

person gilch    schedule 18.05.2018
comment
Я сделал это, Гилч. Однако я не знаю, как взять функцию инициации и поместить ее внутрь функции сброса. Я новичок в питоне. Какие-либо предложения? - person Jonah; 18.05.2018
comment
Initiate() должно работать. Если вы пробовали это, в чем была ошибка? - person gilch; 18.05.2018
comment
Выдает ошибку: Ошибка: источник оптимизации ошибки:: Функция содержит асинхронные вызовы, но не имеет параметра _: undefined в строке 89. - person Jonah; 18.05.2018
comment
И затем он дает кучу URL-адресов: (sandbox.glowscript. org/package/RScompiler.2.7.min.js:1:1223258) в _propogate — один из них — в конце каждого URL есть разные числа. Мне нужно вводить это вручную, поэтому я не хочу вводить другие, если в этом нет крайней необходимости. - person Jonah; 18.05.2018
comment
Эта ошибка не имеет смысла. Попробуйте поставить Initiate() после функции def Initiate. - person gilch; 18.05.2018
comment
Я не думаю, что первоначальный запуск при первом запуске программы является проблемой. Это тот, который я помещаю внутрь def Reset(c)... он работает и без него, но как только я добавляю его, я получаю эту странную ошибку. --- Должен ли я вводить функцию Initiate в функцию Reset, как я сделал с переменной t и ball? Это возможно? Я не совсем уверен. - person Jonah; 18.05.2018
comment
Python на самом деле позволяет вам помещать функцию определения внутри функции определения. Вы также можете сначала объявить имя функции глобальным. Я не очень хорошо знаком с GlowScript, но ваш код не должен делать эту ошибку сам по себе. - person gilch; 18.05.2018

Перейдите на vpython.org и нажмите на ссылку на форум vpython или на форум GlowScript и задайте свой вопрос там.

person John    schedule 18.05.2018