циклы — Python как остановить цикл по клику пункта меню?
Одна опечатка и одна принципиальная ошибка.
Опечатка в присваивании:
if work:
work==False # должно быть просто =
А ошибка в том, что вы снова вызываете move_clockwise() в конце функции def move_counterclockwise(). В результате функции уходят в рекурсию и никогда не возвращаются в цикл проверки условия на останов:
while work:
move_clockwise()
Ну и work = True надо бы добавить в начало def start(event):. Чтобы можно было снова запустить движение овала.
Ну а вообще, код можно подсократить. И останавливаться мгновенно.
from tkinter import *
import random
import time
#from PIL import ImageTk, Image
root = Tk()
root.title("Лабораторная работа №4")
root.geometry('360x360')
width=360
height=360
sleep=0.02
step=15
work=False
c = Canvas(root, width=width, height=height, bg="white")
c.place(x = 0, y = 0)
oval = c.
create_oval(0, 0, 30, 30, fill='green')
def move(figure):
while True:
for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
(True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
for i in range(((height if vertical else width) - 30) // step):
if not work:
c.coords(figure, 0, 0, 30, 30)
return
c.move(figure, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment)
root.update()
time.sleep(sleep)
def start(event):
global work
if not work:
work = True
move(oval)
def stop():
global work
work = False
#Заполнение матрицы
for x in range(6):
for y in range(6):
text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99)))
c.bind('<Double-Button-1>', start)
menu=Menu(root)
root.config(menu=menu)
menu.
add_command(label="Stop", command=stop)
root.mainloop()
К тому же задание довольно невнятное. С учётом того, что движение должно происходить с дискретом 0.8 секунды (а это довольно большая пауза), возможно имелось ввиду, что овал должен прыгать по элементам матрицы. И в таком случае time.sleep() вообще применять нельзя, т.к. он будет фризить интерфейс на это время. Нужно использовать функцию after() для отложенного запуска следующего перемещения. Например, с использованием генератора, код может выглядеть так:
from tkinter import *
import random
import time
#from PIL import ImageTk, Image
root = Tk()
root.title("Лабораторная работа №4")
sleep = 0.8
step = 60
oval_size = 40
matrix_size = {"W":6, "H":6} # width, height
offset = (step - oval_size) // 2
work = False
root.geometry(f'{matrix_size["W"] * step}x{matrix_size["H"] * step}')
c = Canvas(root, width=matrix_size["W"] * step, height=matrix_size["H"] * step, bg="white")
c.place(x = 0, y = 0)
oval = c.
create_oval(offset, offset, offset + oval_size, offset + oval_size)
def move(gen=None):
if work:
next(gen)
root.after(int(sleep*1000), lambda: move(gen))
def move_generator():
while True:
for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
(True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
for i in range(matrix_size["H" if vertical else "W"] - 1):
c.move(oval, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment)
yield
def start(event):
global work
if not work:
work = True
move(move_generator())
def stop():
global work
work = False
c.coords(oval, offset, offset, offset + oval_size, offset + oval_size)
#Заполнение матрицы
for x in range(6):
for y in range(6):
text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99)))
c.bind('<Double-Button-1>', start)
menu=Menu(root)
root.
config(menu=menu)
menu.add_command(label="Stop", command=stop)
root.mainloop()
Оно же без использования генератора.
from tkinter import *
import random
import time
root = Tk()
root.title("Лабораторная работа №4")
sleep = 0.8
step = 60
oval_size = 40
matrix_size = {"W":6, "H":6} # width, height
offset = (step - oval_size) // 2
work = False
root.geometry(f'{matrix_size["W"] * step}x{matrix_size["H"] * step}')
c = Canvas(root, width=matrix_size["W"] * step, height=matrix_size["H"] * step, bg="white")
c.place(x = 0, y = 0)
oval = c.create_oval(offset, offset, offset + oval_size, offset + oval_size)
movements = []
for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
(True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
for i in range(matrix_size["H" if vertical else "W"] - 1):
movements.append(((0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment))
def move(pos=0):
if work:
c.
move(oval, *movements[pos])
root.after(int(sleep*1000), lambda: move( (pos+1) % len(movements) ))
def start(event):
global work
if not work:
work = True
move()
def stop():
global work
work = False
c.coords(oval, offset, offset, offset + oval_size, offset + oval_size)
#Заполнение матрицы
for x in range(6):
for y in range(6):
text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99)))
c.bind('<Double-Button-1>', start)
menu=Menu(root)
root.config(menu=menu)
menu.add_command(label="Stop", command=stop)
root.mainloop()
python — Как правильно выйти из бесконечного цикла
Столкнулся с проблемой в цикле.
Его нужно прервать по команде "done:", но при этом, чтобы вызывалась ошибка «Invalid input» в блоке try / except.
В моем же случае исключение ошибки ввода не позволяет прервать такой цикл строчкой.
largest = 0
smallest = 0
while True:
try:
num = int(input("Enter a number: "))
except:
print("Invalid input")
continue
if num == "done":
break
elif largest < num:
largest = num
elif smallest < num:
smallest = num
print("Maximum is ", largest)
print("Minimum is ", smallest)```
- python
- python-3.

x - циклы
- while
- break
Попробуйте так
largest = 0
smallest = 0
fl = False
while True:
try:
_input = input("Enter a number: ")
num = int(_input)
except Exception as e:
print(f"Invalid input: {e}")
num = _input
fl = True
#print(f'num = {num}') #
# continue
if num == "done":
break
elif fl:
fl = False
elif largest < num:
largest = num
elif smallest < num:
smallest = num
print("Maximum is ", largest)
print("Minimum is ", smallest)
Предлагаю Вам так:
largest = 0
smallest = 0
while True:
try:
answer = input("Enter a number: ")
number = int(answer)
except (TypeError, ValueError):
if answer == "done":
break
else:
print("Invalid input")
else:
if largest < number:
largest = number
elif number < smallest:
smallest = number
print("Maximum is ", largest)
print("Minimum is ", smallest)
values = {0}
while True:
if (reply := input("Enter a number: ")) == 'done':
break
sign = ''
if reply.
startswith(('+', '-')):
sign, *val = reply
reply = ''.join(val)
if not reply.isnumeric():
print('Wrong value. Try once more.')
continue
values.add(
int(sign + reply)
)
print("Maximum is ", max(values))
print("Minimum is ", min(values))
Если чем-то не устраивает использование max и min
можно так:
smallest = 0
largest = 0
while True:
if (reply := input("Enter a number: ")) == 'done':
break
sign = ''
if reply.startswith(('+', '-')):
sign, *val = reply
reply = ''.join(val)
if not reply.isnumeric():
print('Wrong value. Try once more.')
continue
smallest, _, largest = sorted([smallest, int(sign + reply), largest])
print("Maximum is ", smallest)
print("Minimum is ", largest)
Зарегистрируйтесь или войдите
Регистрация через Google Регистрация через Facebook Регистрация через почтуОтправить без регистрации
ПочтаНеобходима, но никому не показывается
Отправить без регистрации
ПочтаНеобходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
Как выйти из цикла в Python
Извините, я все еще новичок в Python и не знаю, как выйти из цикла.
Во-первых, у меня проблемы с вводом «q to quit». Я возился с этим и не могу заставить программу выйти, используя q или Q.
full_name = input ('Введите имя клиента (или q, чтобы выйти): ')
address = input ("Введите адрес клиента:")
location = input("Введите город, штат и почтовый индекс клиента: " )
отмена = 'к'
в то время как отмена == 'q' или отмена == 'Q':
Распечатать ()
thin_M = 'Тонкие мятные конфеты'
thin_M = int(input('Введите количество тонких монетных дворов: '))
в то время как thin_M > 10:
print («К сожалению, мы принимаем не более 10 коробок каждого типа».)
Во-вторых, как только я дошел до части while, я обнаружил, что если введенное число больше 10, мой оператор печати будет продолжать повторяться снова и снова. Что мне делать, чтобы последний оператор печати не зацикливался? Программа должна повторно запросить и выдать сообщение с извинениями. Я не уверен, что вершина также считается циклом, но как мне заставить q или Q работать с этим кодом?
- питон
Вы можете использовать break , чтобы выйти из цикла.
В вашем коде также есть некоторые другие ошибки, которые я исправил. Попробуйте это:
full_name = input («Введите имя клиента (или q, чтобы выйти): ')
если полное_имя == 'q':
Выход()
address = input ("Введите адрес клиента:")
location = input("Введите город, штат и почтовый индекс клиента: " )
текст = ''
в то время как text.lower() != 'q':
thin_M = int(input('Введите количество тонких монетных дворов: '))
если thin_M > 10:
print («К сожалению, мы принимаем не более 10 коробок каждого типа».)
еще:
перерыв
Во-первых, вы никогда не изменяете отменяете переменную, так что условие всегда True и затем оно зацикливается навсегда. Я предполагаю, что вы скорее хотели сравнить full_name с q в соответствии с вашей подсказкой ввода.
Также thin_M = 'Thin Mints' Назначение бессмысленно, так как оно перезаписывается перед любым чтением, поэтому просто удалите его.
И, наконец, 2-й , а скорее должен быть простым , если .
full_name = input («Введите имя клиента (или q, чтобы выйти): ')
address = input ("Введите адрес клиента:")
location = input("Введите город, штат и почтовый индекс клиента: " )
отмена = полное_имя.lower() == 'q'
в то время как отменить == Ложь:
Распечатать ()
thin_M = int(input('Введите количество тонких монетных дворов: '))
если thin_M > 10:
print («К сожалению, мы принимаем не более 10 коробок каждого типа».)
еще:
отмена = Истина
3Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google Зарегистрироваться через Facebook Зарегистрируйтесь, используя электронную почту и парольОпубликовать как гость
Электронная почтаТребуется, но никогда не отображается
Опубликовать как гость
Электронная почтаТребуется, но не отображается
python — остановка цикла или цикла while при выполнении условия
Задавать вопрос
спросил
Изменено 1 год, 6 месяцев назад
Просмотрено 2к раз
Я новичок в программировании.
Цель состоит в том, чтобы считать числа в списке по порядку, но цикл должен останавливаться, когда условие выполняется или близко к нему, но не должно превышать его.
Например: список = [4,4,4,3,3], состояние = 11 Ожидаемый результат будет 4 + 4 = 8, потому что еще 4 превысят условие (4 + 4 + 4 = 12).
список = [4,4,4,3,3]
состояние = 11
def for_fun (список, условие):
сумма_размеров = 0
для я в списке:
сумма_размеров += я
если sum_of_sizes <= условие:
перерыв
вернуть sum_of_sizes
Мне проще работать с циклами for, хотя цикл while может быть лучше для этой задачи.
- питон
Чтобы добавить решение, используя и , к решению @matle:
список = [4,4,4,3,3]
состояние = 11
def for_fun (список, условие):
сумма_размеров = 0
индекс = 0
пока верно:
если sum_of_sizes + list[index] > условие:
перерыв
sum_of_sizes += список[индекс]
индекс += 1
вернуть sum_of_sizes
печать (for_fun (список, условие))
И, пожалуйста, старайтесь не перезаписывать ключевые слова Python, такие как list !
Я предлагаю вам проверить, является ли ваша следующая сумма sum_of_sizes больше или равной вашему условию, и прервать, если это так.

create_oval(0, 0, 30, 30, fill='green')
def move(figure):
while True:
for vertical, increment in ((False, +1), (True , +1), (False, -1), (True , -1), # по часовой
(True , +1), (False, +1), (True , -1), (False, -1)): # против часовой
for i in range(((height if vertical else width) - 30) // step):
if not work:
c.coords(figure, 0, 0, 30, 30)
return
c.move(figure, (0 if vertical else 1) * step * increment, (1 if vertical else 0) * step * increment)
root.update()
time.sleep(sleep)
def start(event):
global work
if not work:
work = True
move(oval)
def stop():
global work
work = False
#Заполнение матрицы
for x in range(6):
for y in range(6):
text=c.create_text(30+60*x, 30+60*y, text=str(random.randint(0,99)))
c.bind('<Double-Button-1>', start)
menu=Menu(root)
root.config(menu=menu)
menu.

config(menu=menu)
menu.add_command(label="Stop", command=stop)
root.mainloop()


startswith(('+', '-')):
sign, *val = reply
reply = ''.join(val)
if not reply.isnumeric():
print('Wrong value. Try once more.')
continue
values.add(
int(sign + reply)
)
print("Maximum is ", max(values))
print("Minimum is ", min(values))