input: Write a function to implement a knapsack algorithm that maximizes the value within a given weight limit. 
  assert knapsack([Item('a', 10, 2), Item('b', 5, 3), Item('c', 15, 5), Item('d', 7, 7)], 10) == 25
  assert knapsack([Item('a', 20, 4), Item('b', 10, 2), Item('c', 15, 3)], 5) == 25
  assert knapsack([Item('a', 50, 10), Item('b', 60, 20), Item('c', 140, 30)], 50) == 200
output: class Item:
      def __init__(self, name, value, weight):
          self.name = name
          self.value = value
          self.weight = weight
  
  def knapsack(items, max_weight):
      n = len(items)
      dp = [[0 for x in range(max_weight + 1)] for x in range(n + 1)]
      
      for i in range(n + 1):
          for w in range(max_weight + 1):
              if i == 0 or w == 0:
                  dp[i][w] = 0
              elif items[i-1].weight <= w:
                  dp[i][w] = max(items[i-1].value + dp[i-1][w-items[i-1].weight], dp[i-1][w])
              else:
                  dp[i][w] = dp[i-1][w]
      
      return dp[n][max_weight]