Perfect Square function that doesn't return
<p>I'm a beginner working with Python and I was given this task: <em>write a function which returns the highest perfect square which is less or equal to its parameter (a positive integer).</em></p>

<pre><code>def perfsq(n):

    x = 0
    xy = x * x
    if n &gt;= 0:
        while xy &lt; n:
            x += 1

        if xy != n:
            print (("%s is not a perfect square.") % (n))
            x -= 1
            print (("%s is the next highest perfect square.") % (xy))
        else:
            return(print(("%s is a perfect square of %s.") % (n, x)))
</code></pre>

<p>When I run the code to execute the function it doesn't output anything. I'll admit, I'm struggling and if you could give me some advice on how to fix this, I would be grateful.</p>

<p>A simpler way of doing what you desire is below:</p>

<pre><code>def perfsq(n):
    x = n
    while True:
        if x**2 &lt;= n:
            # display the result on the console using print function
            print ("The highest perfect square of %s or less is %s" %(n,x**2))

            return x**2 # return the value so that it can be used outside of the function
        else:
            x -= 1

highest_sqr = perfsq(37000)
</code></pre>

<p>This prints the highest perfect square as well as returning the value to be used later in your code:</p>

<blockquote>
  <p>The highest perfect square of 37000 or less is 36864</p>
</blockquote>

<p><strong>UPDATE</strong></p>

<p>As said in the comments by @JohnColeman, the code above is very inefficient as it calculates a lot more squares than it needs to before coming to the actual answer. A much better answer to the question was found <a href="https://www.quora.com/Is-there-an-algorithm-to-find-the-nearest-square-of-a-given-number" rel="nofollow">here</a>. I have modified the code from that answer to be applicable to this question:</p>

<pre><code>def find_perfsqr(n):
    root_of_n = math.sqrt(n) # square root the inital number

    # Find the closest integer smaller than the root of n
    floor_int = int(root_of_n)  # closest below

    floor_int_sqaure = floor_int * floor_int  # square integer calculated above

    return floor_int_sqaure

test_number = 123456
perfect_square = find_perfsqr(test_number)
print ("The highest perfect square of %s or less is %s" %(test_number, perfect_square))
</code></pre>

<p>This produces the output </p>

<blockquote>
  <p>The highest perfect square of 123456 or less is 123201</p>
</blockquote>

<p>If you wanted to print out the results with print statements inside the function you can add the following line just before the <code>return</code> statement.</p>

<pre><code>("The highest perfect square of %s or less is %s" %(n, floor_int_square))
</code></pre>

<p>To compare the speed of this code compared to my original answer I have used the timeit module. This calls the function for a user defined number of repetitions and records the time it takes:</p>

<pre><code>import timeit
print(timeit.timeit("find_perfsqr(123456)", "from __main__ import find_perfsqr",number= 1000))
print(timeit.timeit("perfsq(123456)", "from __main__ import perfsq",number= 1000))
</code></pre>

<p>Which gives the following results for 1000 repetitions:</p>

<pre><code>0.000784402654164445  # The new function, find_perfsqr (result is in seconds)
67.38138927728903     # Original function, perfsq (result is in seconds)
</code></pre>

<p>This shows that for large numbers the <code>find_perfsqr</code> function is considerably faster.</p>

python loops if-statement