0

For my program i am asking the user for a zip code. I am trying to make the program ask the user for their zip code again if the one they typed in isn't only numbers and is exactly 5 characters. It does ask for the zip code again if it isn't 5 characters, but it doesn't ask again if the user typed in something that isn't a number. For example if you typed in "8789" it wouldn't work, but if you typed in "8jkf0" it would work.

I've tried switching my or to an and but that's about it. I couldn't think of anything else to try. I am very new to python. I use it in school and do it sometimes in my free time.

zipcode = input("What is your ZIP code? ")
ziplen = len(zipcode)
while not (char.isnumber() for char in zipcode) or not ziplen == 5:
    zipcode = input("What is your ZIP code? ")
    ziplen = len(zipcode)

I expected that the program would ask for the user's zipcode again if what they typed in wasn't only numbers and exactly 5 characters, but it only checks if it is exactly 5 characters.

Tony Neydon
  • 25
  • 1
  • 4
  • 1
    Also, it should be `not all(char.isnumber() for char in zipcode)` – Barmar Apr 26 '19 at 23:46
  • @Barmar thank you for your help, but now I have a different error – Tony Neydon Apr 26 '19 at 23:57
  • @barmar `Traceback (most recent call last): File "C:\Users\tonyj\Downloads\Hello.py", line 9, in while not all(char.isnumber() for char in zipcode) or not ziplen == 5: File "C:\Users\tonyj\Downloads\Hello.py", line 9, in while not all(char.isnumber() for char in zipcode) or not ziplen == 5: AttributeError: 'str' object has no attribute 'isnumber'` – Tony Neydon Apr 26 '19 at 23:59
  • The correct spelling is `isnumeric()` - or `isdigit()` --- there is no `isnumber()` method. – thebjorn Apr 27 '19 at 00:00
  • You want `isdigit`, not `isnumber` – donkopotamus Apr 27 '19 at 00:01
  • Why are you thanking me? I didn't find that error. – Barmar Apr 27 '19 at 00:02
  • @TonyNeydon If you have a comment related to a specific answer, you should post it below the answer, not below the question. – Barmar Apr 27 '19 at 00:04

2 Answers2

4

isnumeric checks the entire string, so it's just:

while not zipcode.isnumeric() or not len(zipcode) == 5:
    ...
thebjorn
  • 26,297
  • 11
  • 96
  • 138
  • It should be `or`, not `and` (I made this mistake earlier, too). – Barmar Apr 27 '19 at 00:02
  • @thebjorn thank you, this worked for me but but only if i changed your and to an or. for some reason if i used an and it checked neither of the conditions, but if i used an or it checked both, but anyways, it works now. – Tony Neydon Apr 27 '19 at 00:04
  • @TonyNeydon Refresh, he already correct the answer as I mentioned. – Barmar Apr 27 '19 at 00:05
  • @Barmar In this same program I had a different while function that was similar to this one that I had an and on and after a while I figured out that the problem was that it should have been or, so I made the same mistake. – Tony Neydon Apr 27 '19 at 00:06
  • @TonyNeydon See https://stackoverflow.com/questions/26337003/execute-block-if-a-variable-is-not-one-of-some-specific-values for the more common case where it needs to be `and`. – Barmar Apr 27 '19 at 00:09
  • How about combining them into `while not (zipcode.isnumeric() or len(zipcode) == 5):` – Sheldore Apr 27 '19 at 00:13
  • @Sheldore I decided to not add De Morgan's (https://en.wikipedia.org/wiki/De_Morgan%27s_laws) converstions to keep it as close to the OP's code as possible. It is probably how I would write it in my own code though. – thebjorn Apr 27 '19 at 00:15
1

You need to call the all() function to return the result of testing all the characters in zipcode. Your list comprehension produces a generator, which will always be truthy.

And the correct function is isdigit, not isnumber.

while ziplen != 5 or not all(map(str.isdigit, zipcode)):
Barmar
  • 741,623
  • 53
  • 500
  • 612