title: Python backtracking maze really slow
body: <p><em>check the edit</em>,
  I wrote some code while watching The Coding Train on youtube.. the maze backtracking generator. The youtuber wrote the code in javascript and I tried to understand the code while writing in python. It seems he had to change the framerate because his program was so fast just to see the generating part. While mine after some 10ish squares it was already so slow.
  It cant be an hardware problem, I've got an i5-4690K CPU and a good matching GPU, it must be something in the code! But I can't find what it is.</p>
  
  <p>I rewatched the episodes so I could see what was wrong, but it seems I wrote everything just fine.</p>
  
  <pre class="lang-py prettyprint-override"><code>from tkinter import *
  import math
  import random
  import time
  
  # initialization canvas
  root = Tk()
  canvas = Canvas(root, width=400, height=400, bg="#333333")
  canvas.pack()
  
  # some global variables
  w = 40;
  cols = math.floor(int(canvas["width"])/w)
  rows = math.floor(int(canvas["height"])/w)
  grid = []
  current = None
  
  class Cell():
      line_color = "#AAAAAA"
      visited_color = "green"
      visited = False
      rectangle = None
  
      def __init__(self, i, j):
          self.i = i
          self.j = j
          self.wall = [True, True, True, True] # top , right, bottom, left
  
      def __repr__(self):
          return "({}, {})".format(self.i, self.j)
  
      def draw_lines(self):
          x = self.i*w
          y = self.j*w
  
          if self.visited :
              self.rectangle = canvas.create_rectangle(x, y, x+w, y+w, fill="purple", outline="")
              canvas.update()
  
          if self.wall[0]:
              canvas.create_line(x, y, x+w, y, fill=self.line_color)
          else:
              canvas.create_line(x, y, x+w, y, fill="purple")
          if self.wall[1]:
              canvas.create_line(x+w, y, x+w, y+w, fill=self.line_color)
          else:
              canvas.create_line(x+w, y, x+w, y+w, fill="purple")
          if self.wall[2]:
              canvas.create_line(x, y+w, x+w, y+w, fill=self.line_color)
          else:
              canvas.create_line(x, y+w, x+w, y+w, fill="purple")
          if self.wall[3]:
              canvas.create_line(x, y, x, y+w, fill=self.line_color)
          else:
              canvas.create_line(x, y, x, y+w, fill="purple")
  
      def checkNeighbors(self):
          neighbors = []
          top = None
          bottom = None
          left = None
          right = None
          if index(self.i, self.j-1) != -1:
              top = grid[index(self.i, self.j-1)]
  
          if index(self.i, self.j+1) != -1:
              bottom = grid[index(self.i, self.j+1)]
  
          if index(self.i-1, self.j) != -1:
              left = grid[index(self.i-1, self.j)]
  
          if index(self.i+1, self.j) != -1:
              right = grid[index(self.i+1, self.j)]
  
          if top is not None and top.visited is False:
              neighbors.append(top)
          if right is not None and right.visited is False:
              neighbors.append(right)
          if bottom is not None and bottom.visited is False:
              neighbors.append(bottom)
          if left is not None and left.visited is False:
              neighbors.append(left)
  
          if len(neighbors) &gt; 0:
              r = random.randint(0, len(neighbors)-1)
              return neighbors[r]
          else:
              return None
  
  def removeWalls(a, b):
      x = a.i - b.i
      y = a.j - b.j
  
      if x != 0:
          if x == 1:
              a.wall[3] = False
              b.wall[1] = False
          else:
              a.wall[1] = False
              b.wall[3] = False
  
      if y != 0:
          if y == 1:
              a.wall[0] = False
              b.wall[2] = False
          else:
              a.wall[2] = False
              b.wall[0] = False
  
  def index(i, j):
      if j &lt; 0 or j &gt; rows - 1 or i &lt; 0 or i &gt; cols - 1:
          return -1
      return j + i * cols
  
  def setup():
      global current
      for i in range(rows):
          for j in range(cols):
              cell = Cell(i, j)
              grid.append(cell)
      current = grid[0]
  
  next_one = None
  def draw():
      global current
      global next_one
      stack = []
      almost = False
      while True:
          current.visited = True
          for cell in grid:
              cell.draw_lines()
          next_one = current.checkNeighbors()
          if next_one:
              stack.append(current)
              removeWalls(current, next_one)
              current = next_one
          elif len(stack) &gt; 0:
              cell = stack.pop()
              current = cell
  
  for cell in grid:
      print(cell.visited)
  
  setup()
  draw()
  
  
  root.mainloop()
  </code></pre>
  
  <p>I'm sorry to put all the code, but I think all of it is relevant for what comes to performance, haven't put any useful comments, sorry I'm trying to become a better programmer and change that bad habit</p>
  
  <p><strong>BIG EDIT:</strong>
  I tested to just draw my maze once I finished calculating it, and it takes less than a second, so I figure it has to be with the amount of widgets (lines) I'm creating..? How could I minimize the widgets so I could see the maze being created like I wanted to?</p>