Дополнительные циклы while, не ожидающие после выполнения первого условия l oop? - PullRequest
0 голосов
/ 11 июля 2020

Вот мой код:

import random
import keyboard

print("First, press enter to randomize your first mastery:")
while True:
    if keyboard.is_pressed("enter"):
        with open("masteries.txt", "r") as f:
            masteries = f.read().splitlines()
            random_mastery1 = random.choice(masteries)
            break

file_name = random_mastery1.lower() + "_skills.txt"

print(f"Next, press enter to randomize your primary active skill for your first randomized mastery:")
while True:
    if keyboard.is_pressed("enter"):
        with open(file_name, "r") as skill_file:
            skills = skill_file.read().splitlines()
            random_skill = random.choice(skills)
            break

print(f"Finally, press enter to randomize your second mastery:")
while True:
    if keyboard.is_pressed("enter"):
        with open("masteries.txt", "r") as f:
            masteries = f.read().splitlines()
            random_mastery2 = random.choice(masteries)
            break

print(f"You'll be starting as {random_mastery1} with a primary active skill of {random_skill}." + 
f" Your second mastery will be {random_mastery2}. Have fun!")

Программа делает именно то, что я хочу, с точки зрения основных функций, но после первого нажатия клавиши ввода для рандомизации первого мастерства она не прерывается и не ждет для следующих двух вводов он просто запускается и завершается после однократного нажатия Enter. Пример:

First, press enter to randomize your first mastery:
**I press enter here**

Next, press enter to randomize your primary active skill for your first randomized mastery:
Finally, press enter to randomize your second mastery:
You'll be starting as Shaman with a primary active skill of Grasping Vines. Your second mastery will be Nightblade. Have fun!

Есть идеи, как исправить это или лучше реализовать то, что я пытаюсь выполнить sh?

Ответы [ 2 ]

0 голосов
/ 11 июля 2020

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

Если это В этом случае вам просто нужно дождаться освобождения ключа перед следующей проверкой, например, с:

import time
:
while keyboard.is_pressed("enter"):
    time.sleep(0.01)

Также очень неэффективно открывать и читать эти текстовые файлы каждый раз время через l oop (если только они не могут сильно меняться на диске, что было бы необычно). Вам было бы лучше прочитать файл один раз до начала l oop и просто использовать случайность для выбора элемента.

Также имейте в виду, что, если текущее время работы для программа или текущее время дня влияет на random.choice() (и я не верю, что это так), то, что вы делаете, не имеет значения - вы получите те же значения независимо от того, ждете вы или нет enter клавиша, которую нужно нажать.

Предполагая, что вы хотите использовать пользователя в качестве источника энтропии, вы можете использовать такую ​​функцию, как:

import keyboard, time, random

def userRand(seq, prompt = None):
    # Wait until ENTER key up then prompt if desired.

    while keyboard.is_pressed("enter"):
        time.sleep(0.01)
    if prompt is not None:
        print(prompt, end = "")

    # Get random choice from sequence, until ENTER key down.

    retVal = random.choice(seq)
    while not keyboard.is_pressed("enter"):
        time.sleep(0.01)
        retVal = random.choice(seq)

Затем вызовите что с гораздо более кратким:

with open("masteries.txt", "r") as f:
    masteries = f.read().splitlines()
random_mastery1 = userRand(masteries, "Press ENTER for first mastery: ")

with open(f"{random_mastery1.lower()}_skills.txt", "r") as f:
    skills = f.read().splitlines()
random_skill = userRand(skills, "Press ENTER for primary skill: ")

random_mastery2 = userRand(masteries, "Press ENTER for second mastery: ")

Такой вид рефакторинга (перенос обычных вещей в функции) имеет несколько преимуществ, среди которых:

  • сокращение дублирования кода, так что он легче исправить или улучшить вещи; и
  • делая ваш основной код более читаемым, удаляя ненужные детали.
0 голосов
/ 11 июля 2020

Я считаю, что проблема возникает из-за того, что keyboard.is_pressed('enter') возвращает True. Я рекомендую вам еще раз прочитать документацию библиотеки keyboard, это повысит ваши навыки самообучения. Но я думаю, что вы делаете это неправильно, вы можете поискать здесь несколько вопросов на форуме, которые вас интересуют, как наилучшим образом реализовать X? (это повысит ваши навыки программирования, и я верю, что понимание программирования вообще), поэтому я искал вас, как лучше всего поймать нажатие клавиши ввода ( вопрос ), и, как я вижу, лучший вариант это input(), есть и getch(), но он будет принимать все клавиши на клавиатуре, вы можете создать al oop из getch() и проверить, является ли клавиша Enter (и сломать l oop на пойманном также).

Пример кода:

import msvcrt as m # I don't recommend to use one-letter import, just copied from the question.

def wait_for_enter():
    key = m.getch()

    if key == b'\r': # Enter pressed.
        print('enter pressed')
        break
...