Shrinking and expanding square I'm a computer science student who's just starting out with algorithms and their implementation. I wrote this code for a dynamically morphing square. I was wondering if I could get a review on it.  I apologize if the comments are excessive, this is how I submitted on it at school.

import time  #imported the time module to make the loop stop for a .5 sec before the next iteration

user_input = int(input("Input a number greater than 3: ")) #gets the user input in the form of an integer

def pattern(count): #created a function here called pattern, and gave it a parameter called count
    while user_input &gt; 3: #This loop works as long as the integer entered is &gt; 3
        min = 0 #initialize the variable min as the starting corner of the square i.e zero point.
        max = count - 1 #initialize the variable max as "count -1". This is because this variable will be updated by the loops through each iteration.
        for run in range(0,count): #first loop to control the iterations of the square
            print(run) #This will print the number of the iteration we are in at the time. This is put here as a check to see if the loop works as intended.
            for i in range(0,count): #this loop goes from row 0 to row N, where N is the value entered by the user.
                for j in range(0,count): #this loop goes from column 0 to column N, where N is the value entered by the user. This will be responsible for printing the stars in the square, from column to column.
                    if (min &lt;= max and min &lt;= i and i &lt;= max and min &lt;= j and j &lt;= max) and (i == min or i == max or j == min or j == max): #this branch checks if ceertain cinditions are met. then prints * if they are. The conditions are explained below.
                        print("*",end="") #prints * without a line break after every iteration of its loop
                    else:
                        print(".",end="") #prints . without a line break after every iteration of its loop
                print("") #prints a new line
            print("") #prints a new line
            if run &lt; count / 2: #in this branch, if the iterations of the boxes &lt; half of the user input, the variable min will be incremented by 1
                min += 1        #and the variable max will be reduced by 1
                max -= 1
            if run &gt;= count / 2: #if the iterations of the boxes &gt; half of the user input, min will be reduced by 1 and  max will increase by 1.
                min -= 1
                max += 1
            time.sleep(.5) #pauses for .5 secs between iterations of the square.


if user_input &gt;= 3: #if the user input &gt; 3, the function called pattern will be called 
    pattern(user_input)
else: #if the user input &lt; 3, there will be an error message printed
    print("Enter a number greater than 3 ")




# The first branch in this function checks if the variable min&lt;max, if min &lt; i &lt;= max, if min &lt; j &lt;= max, if i = min, if j = min, if i = max and if j = max.
# These conditions confine the points that are printed to the space between min and max, in both the rows and columns of the square.
# The four final conditions are there to allow the square to dissappear creating a set of dots and display the first square where both rows and columns are equal to the number entered by the user.


The results are as follows:
A few things stand out:


The many levels of indentation. Consider putting the contents of one of the loops into a function, and calling that instead. For example, all the printing work could be done in a separate function. I'd suggest a maximum number of four levels of indentation
The amount of comments. Comments are to explain how something works (an algorithm), not what you're doing. The latter should be obvious from the code. And definitely not a comment per line.

For example:


def pattern(count): #created a function here called pattern, and gave it a parameter called count



is an unnecessary comment: Python programmers know def means to create a function, and the parameter (I think Pythoneers tend to use the term argument instead) is obvious as well.
The lengthy lines. The suggested maximum line length is 79 characters, though preferences and local standards may differ. A situation like here provides a good example about a limited line length: you have put code in a code block on a web site, which has set a limited viewing width. And you can immediately see why long lines can be bad, in particular: hard to read. (Hint: other than removing all those comments, consider putting comment lines on the line preceding the code).
If a user enters something that can't be converted to an int, they'll get presented with a traceback. That is not very user friendly. Consider testing this appropriately (error checking is, for some code at least, > 50% of the actual code).
You have if run &lt; count / 2:, and below that if run &gt;= count / 2:. Since run and count don't change in between, an else instead of the second if-statement is probably clearer.