I'm trying to write a code to check that the only numbers allowed are those divisible by either 2 or 3 using while loop, here is the code I write:
def has_divisible_numbers(x):
countdigit = 0
while countdigit < len(x):
if x[countdigit].isdigit == True:
y = x[countdigit]
if y%2 == 0 or y%3 == 0:
return True
else:
return False
countdigit += 1
else:
countdigit += 1
return True
But I realized that this code can only test the first digit in a string not all of them, therefore when I test string like 'asdf@25', it return True. So I was wondering how to fix it and is there any other problem in my code? THANKS!
There are a number of things wrong with your code.
if x[countdigit].isdigit == True:
You are not calling the isdigit
method. call it like this: isdigit()
y = x[countdigit]
and then if y%2 == 0 or y%3 == 0:
Here you are checking if a string is divisible by 3 or 2. Convert the string into an integer first: y = int(x[countdigit])
if y%2 == 0 or y%3 == 0: return True
Here you are returning from the function when you see a digit that is divisible by 3 or 2. You are returning without checking the remaining digits. Instead of returning immediately, do nothing. if y%2 == 0 or y%3 == 0: pass
Here is the full code:
def has_divisible_numbers(x):
countdigit = 0
while countdigit < len(x):
if x[countdigit].isdigit() == True:
y = int(x[countdigit])
if y%2 == 0 or y%3 == 0:
pass
else:
return False
countdigit += 1
else:
countdigit += 1
return True
s = 'asdf@25'
r = has_divisible_numbers(s)
print(r)
It is because when you hit the first instance you return True
- This basically breaks the while loop at that point ie 2
in the line of 25
.
You basically should be doing the following
is_allowed &= (y%2 == 0 or y%3 == 0)
with is_allowed = True
at the start.
This will stay true if every digit is divisible by 2
or 3
.
Sidenote, you can create more test cases to build your model from scratch. Try simple cases ie "2"
, "3"
, "5"
, "23"
etc. before trying the harder stuff.
Your main issue is that you're return
ing True
too early. Your current code returns as soon as the first valid number is seen, but since there might be invalid numbers later, that's premature. Instead, you should only keep the return False
part of that if
/ else
combination. While the most direct translation of your code would be to replace return True
with pass
(which does nothing), a better approach would be to invert the condition and only an if
, with no else
:
if not (y%2 == 0 or y%3 == 0): # or distribute the negation: if y%2 != 0 or y%3 != 0
return False
# no else for this if!
There are some other issues I think you'll be having with your current code though. The largest issue is that it's not clear whether you're iterating over a list of numbers or over the characters of a string. I think your intention is to iterate over a string and ignore the non-numeric characters, but you have some issues. The first thing you need to fix then is that use of isdigit
. That is a method, but you're not calling it at all. You're instead comparing the method itself to True
(which will never succeed).
I think you want if x[countdigit].isdigit():
instead of what you currently have. This calls the method, and doesn't do an unnecessary boolean comparison (the if
already checks for a "truthy" value).
The next issue is that you're never turning your numeric one-character string into an actual number before you go on to the mathematical parts of the code. I think a natural place to do that is when you assign to y
. You could use something like y = int(x[countdigit])
to do the conversion just before the assignment.
Something else that's not an issue is the whole structure of your code in a while
loop. In Python, you can use for
loops to iterate over various container types directly, rather than needing to index them with successive integers manually. Your while
along with all the countdigit
code could be replaced by for character in x:
(and using character
instead of x[countdigit]
in the rest of the code).
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.