Find next perfect square -- Not working in python

  • Context: Python 
  • Thread starter Thread starter shivajikobardan
  • Start date Start date
  • Tags Tags
    Python Square
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
18 replies · 2K views
shivajikobardan
Messages
637
Reaction score
54
Code:
def find_next_square(sq):

    # Return the next square if sq is a square, -1 otherwise

    sq2=(sq**1/2)

    xyz=isinstance(sq2, int)

    if (xyz==True):

        print("Is perfect square")

        nextsq=sq+1

        print("Next perfect square=",nextsq**2)

    else:

        print("Not perfect square")

        return -1
n=int(input("Enter an integer"))

find_next_square(n)

Output-:

Enter an integer25

Not perfect square
Expected output-:

Enter an integer25

Next perfect square=36
 
Physics news on Phys.org
My logic is that xyz checks if $(sq)^0.5$ is integer or not. If it is integer we find next perfect square, else we return -1
 
In general, you should be putting debugging lines into check for yourself what is going wring.

First, you could print ##sq## to check you have the right input.

Then, you can print ##sq2## to see what that is.

Then you can print ##xyz## etc.

Once the program is working, you can comment them out or delete them.
 
  • Like
Likes   Reactions: shivajikobardan
I think I found the problem
Code:
sq=25
sq2=(sq**(1/2))
print(sq2)
xyz=isinstance(sq2, int)
print(xyz)

This generates output as 5.0 and false. I need a way to get integer as sq2.
 
shivajikobardan said:
I think I found the problem
Code:
sq=25
sq2=(sq**(1/2))
print(sq2)
xyz=isinstance(sq2, int)
print(xyz)

This generates output as 5.0 and false. I need a way to get integer as sq2.
Here's an idea:

Take the integer part of ##\sqrt n##, square that and compare with ##n##. If they are equal, then ##n## is a perfect square and you avoid any problems with a small error in the square root function.
 
  • Like
Likes   Reactions: shivajikobardan
shivajikobardan said:
My logic is that xyz checks if $(sq)^0.5$ is integer or not.
No, that's not what your code does.
Here's line 5:
Python:
sq2=(sq**1/2)
When sq == 25, the expression in parentheses evaluates to (sq ** 1)/2, or $$\frac{25^1} 2 = 12.5$$
Add a print statement right after the above line of code to verify this.

Since you want the square root, use the sqrt() function of the math module.
Python:
from math import sqrt
.
.
.
sq2 = sqrt(sq)
shivajikobardan said:
I think I found the problem

shivajikobardan said:
This generates output as 5.0 and false. I need a way to get integer as sq2.
See if sq2 = int(sq2) equals zero. If so, then sq2 is an integer.
 
Mark44 said:
See if sq2 = int(sq2) equals zero. If so, then sq2 is an integer.
I had a problem with doing something like this on big numbers. For example, if ##n## is a very large perfect square plus 1, then the square root might turn out to look like an integer to however many decimal places.

Squaring the integerised number then reveals that ##n## was not a perfect square.
 
I need a way to do this-: If I input 25, answer should be 5 as integer. If I input 24 answer should be 4.898989486 float. Is this possible to do in python?
 
PeroK said:
Squaring the integerised number then reveals that n was not a perfect square.
For reasonably small numbers, my solution would probably be OK, but I like your suggestion more.
 
Mark44 said:
For reasonably small numbers, my solution would probably be OK, but I like your suggestion more.
It was a program I wrote to get the prime factorisation of large numbers. Initially, large factors were being found that were not right. So, I found I had to double-check the apparent integer factorisation.
 
I made it-:

Code:
import math

def find_next_square(sq):
    # Return the next square if sq is a square, -1 otherwise
    sq2=math.sqrt(sq)
    sq2=(int(sq2) if sq2.is_integer() else sq2)  # convert answer to int if we can do it
    xyz=isinstance(sq2, int)
    if (xyz==True):
        print("Is perfect square")
        nextsq=sq+1
        print("Next perfect square=",nextsq**2)
    else:
        print("Not perfect square")
        return -1

n=int(input("Enter an integer"))
find_next_square(n)
 
shivajikobardan said:
I need a way to do this-: If I input 25, answer should be 5 as integer. If I input 24 answer should be 4.898989486 float. Is this possible to do in python?
@Mark44 and @PeroK have provided two ways to check if a value is an integer, another one is the function is_integer.

Why do you think think these methods work but isinstance doesn't?
 
  • Like
Likes   Reactions: PeroK
Python integer datatype has limits on the "size" of very large numbers. Squaring is a great way to get gigantic numbers, really fast. Without going into any great detail on this concern, consider using the "long" datatype. I do not know if the very current version of Python automatically promotes huge numbers to long. Version:Python 2.5 does not do "dynamic typing" - (auto-magically finding the correct datatype to use in calculation), specifically convert integer datatypes to the bignum datatype "long".

Instead of waiting to test this and getting garbage errors , just use the long datatype as it applies to your code.

If this not correct please help out here.
 
PeroK said:
Here's an idea:

Take the integer part of ##\sqrt n##, square that and compare with ##n##. If they are equal, then ##n## is a perfect square and you avoid any problems with a small error in the square root function.
Code:
n=int(input("enter a number"))

if(int(n**0.5)**2==n):
    print("Perfect square")
    nnext=n**0.5+1
    print("Next perfect square=",nnext**2)
else:
    print("Not perfect square")

I made it this way as well.
 
  • Like
Likes   Reactions: Tom.G and PeroK
jim mcnamara said:
Python integer datatype has limits on the "size" of very large numbers. Squaring is a great way to get gigantic numbers, really fast. Without going into any great detail on this concern, consider using the "long" datatype. I do not know if the very current version of Python automatically promotes huge numbers to long. Version:Python 2.5 does not do "dynamic typing" - (auto-magically finding the correct datatype to use in calculation), specifically convert integer datatypes to the bignum datatype "long".

Instead of waiting to test this and getting garbage errors , just use the long datatype as it applies to your code.

If this not correct please help out here.
Unlike C, C++, and some other languages, I don't believe there is a "long" data type in Python as of versions 3.0 and later. The V 2.x limits on the size of integers are effectively gone in the newer versions.
Python:
n = 999999999999999999999999999999999999999999
n_sqr = n * n
print("n: ", n)
print("n * n: ", n_sqr)
print("Type of n_sqr: ", type(n_sqr))

Output:
Code:
n:  999999999999999999999999999999999999999999
n * n:  999999999999999999999999999999999999999998000000000000000000000000000000000000000001
Type of n_sqr:  <class 'int'>
 
  • Like
Likes   Reactions: jim mcnamara
jim mcnamara said:
If this not correct please help out here.
It's not correct I'm afraid. Python now has only one type for integers, int. Conversion between 32 bit/64 bit/arbitrary length internal representations is handled automagically.
 
  • Like
Likes   Reactions: jim mcnamara
How about taking the least integer greater than the square root of x , the input? Example. For x=37, its square root is approx 6.085. Least integer greater than 6.085 is 7, so use ##7^2=49##.
 
WWGD said:
How about taking the least integer greater than the square root of x , the input? Example. For x=37, its square root is approx 6.085. Least integer greater than 6.085 is 7, so use ##7^2=49##.
Or using the isqrt() function from the math module
Python:
# isqrt() is available from Python 3.8 on
from math import isqrt
x = 37
y = isqrt(x)
print(f"Integer square root: {y}")
The value displayed is 6. x will be a perfect square if y*y == x.
 
  • Like
Likes   Reactions: WWGD