简体   繁体   中英

The only numbers allowed are those divisible by either 2 or 3

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.

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