Well commented python code
\nclass MedianFinder:\n    \n    def __init__(self):\n        """\n        Initialize your data structure here.\n        """\n        self.lowerhalf = [] # stor
```\nclass MedianFinder:\n    \n    def __init__(self):\n        """\n        Initialize your data structure here.\n        """\n        self.lowerhalf = [] # store the small half, top is the largest in the small part\n        self.upperhalf = [] # store the large half, top is the smallest in the large part\n\n    def addNum(self, num):\n        """\n        Adds a num into the data structure.\n        :type num: int\n        :rtype: void\n        """\n        # The case for the first element, just add to the minheap\n        if len(self.lowerhalf) == 0:\n            heapq.heappush(self.lowerhalf, -num)\n            return\n        \n        # Now choose where to add the new element \n        # If it is less than or equal the top of min heap, it can be accomodated under it else go to max heap\n        if num <= -self.lowerhalf[0]:\n            heapq.heappush(self.lowerhalf, -num) # Go to the max Heap \n            #(-ve sign because to implement max heap using the default heapq in python, we need to negate the values)\n        else:\n            heapq.heappush(self.upperhalf, num) # Go to the min Heap\n            \n        # Adjusting the balance\n        \n        # If the lowerhalf heap has more elements\n        if len(self.lowerhalf) - len(self.upperhalf) == 2:\n            heapq.heappush(self.upperhalf, - heapq.heappop(self.lowerhalf))\n        \n        # If the upperhalf heap has more elements\n        elif len(self.upperhalf) - len(self.lowerhalf) == 2:\n            heapq.heappush(self.lowerhalf, - heapq.heappop(self.upperhalf))\n        \n\n    def findMedian(self):\n        """\n        Returns the median of current data stream\n        :rtype: float\n        """\n        # If both heaps have same number of elements return the avg\n        # If not, then the root of the one with more elements, is the answer\n        \n        if len(self.lowerhalf) == len(self.upperhalf):\n            return (- self.lowerhalf[0] + self.upperhalf[0] )/2.0 \n            # - sign because lowerhalf has negative value\n        elif len(self.lowerhalf) > len(self.upperhalf):\n            return -float(self.lowerhalf[0])\n        else:\n            return float(self.upperhalf[0])\n\n# Your MedianFinder object will be instantiated and called as such:\n# obj = MedianFinder()\n# obj.addNum(num)\n# param_2 = obj.findMedian()\n```\nBased on video solution from: youtube.com/watch?v=1CxyVdA_654
['Heap (Priority Queue)', 'Python']