циклы — 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 больше или равной вашему условию, и прервать, если это так.