В поисках идеальной площади

У меня есть этот код Python:

def sqrt(x):
    ans = 0
    if x >= 0:
        while ans*ans < x:
            ans = ans + 1
            if ans*ans != x:
                print x, 'is not a perfect square.'
                return None
            else:
                print x, ' is a perfect square.'
                return ans
    else:
        print x, ' is not a positive number.'
        return None

y = 16      
sqrt(y)

выход:

16 is not a perfect square.

Тогда как это работает отлично:

x = 16
ans = 0
if x >= 0:
    while ans*ans < x:
        ans = ans + 1
        #print 'ans =', ans
    if ans*ans != x:
        print x, 'is not a perfect square'  
    else: print ans, 'is a perfect square'
else: print x, 'is not a positive number'

Что я делаю неправильно?

9 ответов

Решение

Сделайте отступ в своем коде правильно, чтобы while оператор выполняется до ans*ans < x:

def sqrt(x):
    ans = 0
    if x >= 0:
        while ans*ans < x:
            ans = ans + 1

        if ans*ans != x:  # this if statement was nested inside the while
            print x, 'is not a perfect square.'
            return None
        else:
            print x, ' is a perfect square.'
            return ans
    else:
        print x, ' is not a positive number.'
        return None

y = 16          
print sqrt(y)

Попробуйте это здесь.

Просто подумал, что могу предложить более простое решение:

def is_square(n):
    return sqrt(n).is_integer()

Это действительно для n < 2**52 + 2**27 = 4503599761588224 ,

Примеры:

>>> is_square(4)
True
>>> is_square(123)
False
>>> is_square(123123123432**2)
True

Ваш while цикл выполняется только один раз. Независимо от того, какая ветвь if Оператор внутри этого занимает, вся функция вернется немедленно.

РЕДАКТИРОВАТЬ Я изменил его, опробовал, и он работает. Вам просто нужен этот кусок кода

Как только ans = 4, ans * ans уже не меньше x. Попробуйте пока ans*ans <= x: вместо просто <

def sqrt(x):
ans = 0
if x >= 0:
        while ans*ans <= x:                     
                if ans*ans == x:
                            print x, ' is a perfect square.'
                            return ans
        else:
            ans = ans + 1

Измените код, чтобы он отображал значение ans так же как x, так что вы можете сказать, сколько раз цикл выполняется.

def isPerfectSquare(number):
    return len(str(math.sqrt(number)).split('.')[1]) == 1

Я думаю, что это, вероятно, короткий.

 def issquare():
      return (m**.5 - int(m**.5)==0)

Если ваш пример кода на самом деле правильно с отступом, первый раунд while вернется в первый раунд - всегда. Таким образом, любое положительное значение x>1 заполняет значение ans*ans=1*1=1!= X, давая "x не является идеальным квадратом".

По сути, вам нужно правильно настроить отступы, как в другом примере. Опять же - если ваш пример кода здесь на самом деле правильно с отступом. Попробуй это:

def sqrt(x):
    ans = 0
    if x >= 0:
        while ans*ans < x:
            ans = ans + 1

        if ans*ans != x:
            print x, 'is not a perfect square.'
            return None
        else:
            print x, ' is a perfect square.'
            return ans
    else:
        print x, ' is not a positive number.'
        return None

Если цель состоит в том, чтобы определить, является ли число идеальным квадратом, я думаю, что было бы проще (и, возможно, более эффективно) использовать встроенные математические функции, например:

def is_perfect_square(n):
  if not ( ( isinstance(n, int) or isinstance(n, long) ) and ( n >= 0 ) ):
    return False 
  else:
    return math.sqrt(n) == math.trunc(math.sqrt(n))
Другие вопросы по тегам