简体   繁体   中英

Additional while loops not waiting after first loop condition is met?

Here's my code:

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!")

The program does exactly what I want it to core-functionality wise, but after pressing enter the first time to randomize the first mastery, it doesn't break and wait for the next two enter inputs, it just runs and completes after pressing enter once. Example:

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!

Any idea on how to fix this or better implement what I am trying to accomplish?

I believe the problem is happening because keyboard.is_pressed('enter') returns True . I recommend you to read again the documentation of keyboard library, it'll raise your self-learning skill. But I think you're doing it wrong, you can search here some questions on the forum that interests you how to implement X at the best way? (it'll raise your programming skill and I believe the understanding of programming at all), so I searched for you what's the best way to caught enter keypress ( The question ), and as I see the best option is input() , there's getch() too but it'll accept all the keys in the keyboard, you can create a loop of getch() and check if the key is Enter (and break the loop on caught as well).

Example code:

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

You may actually find that your blazingly fast computer has finished executing that entire piece of code while your humanly slow finger is still on the enter key:-)

If that's the case, you simply have to wait for the release of the key before the next check, such as with:

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

It's also very inefficient to open and read those text files every time through the loop (unless they could be changing quite a lot on disk, which would be unusual). You would be better off reading a file once before the loop starts, and just using the randomness to select an element.

Also keep in mind that, unless current running time for the program or current time of day, has an effect on random.choice() (and I don't believe this is the case), what you're doing is not relevant - you will get the same values whether or not you wait for the enter key to be pressed.

Assuming you want to use the user as an entropy source, you can use a function like:

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)

Then call that with the much more succinct:

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: ")

This sort of refactoring (moving common stuff into functions) has several advantages, among them:

  • reducing duplicate code, so that it's easier to fix or enhance things; and
  • making your main-line code more readable, by removing unnecessary details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM