Find next perfect square -- Not working in python

  • Context: Python 
  • Thread starter Thread starter shivajikobardan
  • Start date Start date
  • Tags Tags
    Python Square
Click For Summary

Discussion Overview

The discussion revolves around a Python function intended to find the next perfect square given an integer input. Participants explore issues related to the implementation of the function, debugging strategies, and alternative approaches to determine if a number is a perfect square.

Discussion Character

  • Technical explanation
  • Debugging
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant presents a function that attempts to determine if a number is a perfect square by checking if the square root is an integer, but the implementation has a flaw in the calculation of the square root.
  • Another participant suggests using the `sqrt()` function from the math module to obtain the square root correctly.
  • Some participants propose alternative methods to check if a number is a perfect square, such as comparing the square of the integer part of the square root with the original number.
  • Concerns are raised about the handling of large integers in Python, with discussions on the integer data type and its limits in different Python versions.
  • One participant mentions the potential for errors when dealing with large numbers and suggests using the `long` data type, although this is later corrected by another participant who clarifies that Python 3 uses a single `int` type that can handle large values.
  • There are suggestions to use the `isqrt()` function from the math module for integer square roots, which is available in Python 3.8 and later.

Areas of Agreement / Disagreement

Participants express differing views on the best approach to determine if a number is a perfect square and how to handle large integers in Python. There is no consensus on a single solution, and multiple methods are proposed and debated.

Contextual Notes

Some participants note that the original implementation does not correctly check if the square root is an integer due to operator precedence issues. There are also discussions about the implications of using different data types for large numbers, which may affect the results.

Who May Find This Useful

Readers interested in Python programming, particularly in mathematical functions and debugging techniques, may find this discussion relevant.

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
 
Technology 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.
 
  • #10
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.
 
  • #11
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?
Do what?
 
  • #12
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)
 
  • #13
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
  • #14
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.
 
  • #15
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
  • #16
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
  • #17
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
  • #18
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##.
 
  • #19
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

Similar threads

  • · Replies 10 ·
Replies
10
Views
1K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 9 ·
Replies
9
Views
3K
Replies
5
Views
2K
  • · Replies 29 ·
Replies
29
Views
3K
  • · Replies 34 ·
2
Replies
34
Views
5K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 18 ·
Replies
18
Views
2K
  • · Replies 15 ·
Replies
15
Views
2K