2

I'm "newish" to python programming. I'm trying my best to make my code look nice and function well. I'm using Pycharm as my IDE. I'm doing something for myself. I play tabletop RPG's and I'm attempting to create a character creator for a game I play. I have everything working well, but Pycharm is telling me that "Expression can be simplified" and "PEP 8: E712 comparison to True should be 'if cond is not True:' or 'if not cond:'"

Here is the code in question:

fname = False
while fname != True:
    new_character.firstName = input('What would you like your first name to be?\n').capitalize()
    if 1 >= len(new_character.firstName) or len(new_character.firstName) > 20:
        print('Name does not meet length requirements. Please try again.')
    if new_character.firstName.isalpha() != True:
        print('Please do not use numbers or special characters in your name. Please try again.')
    if (1 < len(new_character.firstName) < 20) and (new_character.firstName.isalpha() == True):
        fname = True

Pycharm is telling me that my "while fname != True:" is the part that can be simplified as well as the "if new_character.firstName.isalpha() != True:".

I've tried googling a solution for what I'm doing, but most of them are for something kinda like what I'm asking, but never with the != True portion. I've even reached out to one of my friends that's a python programmer, but I haven't heard back yet.

Again, I want to state that as it is now, the code works correctly the way it is written, I'm just wanting to understand if there is a way to make the code look cleaner/neater or do the same function and be simplified somehow.

Any pointers on how to potentially simplify those lines of code and maintain the functionality would be greatly appreciated.

  • 1
    Explicitly comparing a boolean result to `True` or `False` is almost never the right thing to do. The result of that comparison is itself a boolean; why is *that* boolean somehow acceptable for use, but not the original value? – jasonharper Nov 14 '22 at 04:15
  • @ddejohn I did understand that it was telling me something, but my lack of understanding wasn't putting 2 and 2 together. I really appreciate how you broke things down below. I'm going to plug that structure into my code and see if everything works the same as it did before. I'm certain that it will, since I'm sure you've been doing this longer than I have :) – Billy Blanks Nov 14 '22 at 04:41
  • The first snippet I posted is not 100% identical. It restarts the loop as soon as the first constraint is violated, whereas yours continues checking the name with the second constraint. The second snippet I posted is a much more simple logical flow -- check that both requirements are met and assign the name if so, otherwise print an error message and start the loop over. – ddejohn Nov 14 '22 at 04:43

1 Answers1

1

Here's one way you could rewrite this code to make it easier to read, and more efficient:

# Loop until the user provides a good input
while True:
    # Set a temp variable, don't constantly reassign to the new_character.firstName attribute
    name = input('What would you like your first name to be?\n').capitalize()

    # If the name isn't between 2 and 20 characters, start the loop over at the beginning
    if not (1 < len(name) <= 20):
        print('Name does not meet length requirements. Please try again.')
        continue

    # If the name contains anything other than letters, start the loop over at the beginning
    if not name.isalpha():
        print('Please do not use numbers or special characters in your name. Please try again.')
        continue

    # You can only reach this break if the name "passed" the two checks above
    break

# Finally, assign the character name
new_character.firstName = name

One thing you could do to simplify further is to check both conditions at the same time, and print a more helpful error message that re-states the requirements explicitly:

NAME_ERROR_MESSAGE = """
Invalid name '{name}'. Your character's name
must be between 2 and 20 characters long, and
contain only letters. Please try again.
"""

while True:
    name = input('What would you like your first name to be?\n').capitalize()

    if (1 < len(name) <= 20) and name.isalpha():
        new_character.firstName = name
        break

    print(NAME_ERROR_MESSAGE.format(name=name)
ddejohn
  • 8,775
  • 3
  • 17
  • 30
  • is there a difference in using "pass" opposed to "continue" for those if statements? I was under the impression that pass would continue the loop whereas continue would push forward or fail? I'm not certain. I'm going to google that as I type this. – Billy Blanks Nov 14 '22 at 04:52
  • Yes, there's a difference: https://stackoverflow.com/questions/9483979/is-there-a-difference-between-continue-and-pass-in-a-for-loop-in-python – ddejohn Nov 14 '22 at 04:54
  • in the second one that you have posted there, is the NAME_ERROR_MESSAGE a global variable that you declare somewhere? – Billy Blanks Nov 14 '22 at 05:28
  • It's just declared at the same scope as your `while` loop. You could declare it globally, maybe make it more generic (different length constraints for first and last names?). – ddejohn Nov 14 '22 at 05:29
  • 1
    thank you for all the help with this. after I went through and changed things up using your suggestions, all of the "warnings" went away in Pycharm – Billy Blanks Nov 14 '22 at 05:31