title: How I get the best combination of offers that gonna limit the vendors(shipping) and I get best possible price using python or machine learning or not
body: <ul>
  <li>The user selects from 1 product to {N} products in bucket</li>
  <li>For every product, there are {N} offers from vendors</li>
  <li>And I want to give the user the opportunity to tell him</li>
  </ul>
  
  <h2>My output I want to be:</h2>
  
  <ul>
  <li>IF you take from vendor (A) your total cost for 5 products is 87$</li>
  <li>IF you take from vendor (A) and (B) your total cost for 5 products is 80$ + 
  (x2 shipping cost)</li>
  <li>IF you take from vendor (A)(B) and (C) your total cost for 5 products is 72$ + 
  (x3 shipping cost)</li>
  </ul>
  
  <h3>python pandas</h3>
  
  <pre><code>x = pd.DataFrame.from_dict(OFFERS)
  print(x)
  
  
      offer_price  product_id ventor
  0           5.0           1      A
  1           6.0           1      B
  2           7.0           1      C
  3           8.0           1      D
  4           9.0           1      E
  5           5.1           2      A
  6           6.1           2      B
  7           7.1           2      C
  8           8.1           2      D
  9           9.1           2      E
  10          5.2           3      A
  11          6.2           3      B
  12          7.2           3      C
  13          8.2           3      D
  14          9.2           3      E
  15         77.2           3      F
  16         66.2           3      G
  </code></pre>
  
  <blockquote>
    <p>I get a list with JSON format from server</p>
  </blockquote>
  
  <pre><code>OFFERS = [
      {'offer_id': 100, 'product_id': 1, 'vendor':'A', 'offer_price':5.00},
      {'offer_id': 101, 'product_id': 1, 'vendor':'B', 'offer_price':6.00},
      {'offer_id': 102, 'product_id': 1, 'vendor':'C', 'offer_price':7.00},
      {'offer_id': 103, 'product_id': 1, 'vendor':'D', 'offer_price':8.00},
      {'offer_id': 104, 'product_id': 1, 'vendor':'E', 'offer_price':9.00},
  
      {'offer_id': 105, 'product_id': 2, 'vendor':'A', 'offer_price':5.10},
      {'offer_id': 106, 'product_id': 2, 'vendor':'B', 'offer_price':6.10},
      {'offer_id': 107, 'product_id': 2, 'vendor':'C', 'offer_price':7.10},
      {'offer_id': 108, 'product_id': 2, 'vendor':'D', 'offer_price':8.10},
      {'offer_id': 109, 'product_id': 2, 'vendor':'E', 'offer_price':9.10},
  
      {'offer_id': 110, 'product_id': 3, 'vendor':'A', 'offer_price':5.20},
      {'offer_id': 111, 'product_id': 3, 'vendor':'B', 'offer_price':6.20},
      {'offer_id': 112, 'product_id': 3, 'vendor':'C', 'offer_price':7.20},
      {'offer_id': 113, 'product_id': 3, 'vendor':'D', 'offer_price':8.20},
      {'offer_id': 114, 'product_id': 3, 'vendor':'E', 'offer_price':9.20}
  ]
  </code></pre>
  
  <h2>PROBLEM No1</h2>
  
  <blockquote>
    <p>How I get the best combination of offers that gonna limit the vendors(shipping) and I get best possible price</p>
  </blockquote>
  
  <h2>My output I want to be:</h2>
  
  <ul>
  <li>IF you take from vendor (A) your total cost for 5 products is 87$</li>
  <li>IF you take from vendor (A) and (B) your total cost for 5 products is 80$ + 
  (x2 shipping cost)</li>
  <li>IF you take from vendor (A)(B) and (C) your total cost for 5 products is 72$ + (x3 shipping cost)</li>
  </ul>
  
  <h3>My questions are:</h3>
  
  <ul>
  <li>And I think in what is the name of the problem I want to solve?</li>
  <li>Do I need to use machine learning to solve that problem?</li>
  </ul>
  
  <blockquote>
    <p>My code so far is with python 3.6</p>
    
    <p>=========================== TRY No1 ============================</p>
    
    <h3>After 3 hours of digging I come with this but I think this algorithm is very slow</h3>
    
    <p>My data have this format:</p>
  </blockquote>
  
  <pre><code>OFFERS = [
      {'offer_id':'oid_1','product_id': 'pid_1', 'vendor':'B', 'offer_price':5.00},
      {'offer_id':'oid_1','product_id': 'pid_1', 'vendor':'B', 'offer_price':6.00},
      {'offer_id':'oid_2','product_id': 'pid_1', 'vendor':'C', 'offer_price':7.00},
      {'offer_id':'oid_3','product_id': 'pid_1', 'vendor':'D', 'offer_price':2.00},
      {'offer_id':'oid_4','product_id': 'pid_1', 'vendor':'E', 'offer_price':9.00},
  
      {'offer_id':'oid_5','product_id': 'pid_2', 'vendor':'A', 'offer_price':5.10},
      {'offer_id':'oid_6','product_id': 'pid_2', 'vendor':'B', 'offer_price':6.10},
      {'offer_id':'oid_7','product_id': 'pid_2', 'vendor':'C', 'offer_price':7.10},
      {'offer_id':'oid_8','product_id': 'pid_2', 'vendor':'D', 'offer_price':18.10},
      {'offer_id':'oid_9','product_id': 'pid_2', 'vendor':'E', 'offer_price':9.10},
  
      {'offer_id':'oid_10','product_id': 'pid_3', 'vendor':'A', 'offer_price':5.20},
      {'offer_id':'oid_11','product_id': 'pid_3', 'vendor':'B', 'offer_price':6.20},
      {'offer_id':'oid_12','product_id': 'pid_3', 'vendor':'C', 'offer_price':37.20},
      {'offer_id':'oid_13','product_id': 'pid_3', 'vendor':'D', 'offer_price':8.20},
      {'offer_id':'oid_14','product_id': 'pid_3', 'vendor':'E', 'offer_price':9.20},
      {'offer_id':'oid_15','product_id': 'pid_3', 'vendor':'F', 'offer_price':77.20},
      {'offer_id':'oid_16','product_id': 'pid_3', 'vendor':'G', 'offer_price':66.20},
  ]
  </code></pre>
  
  <h3>app.py</h3>
  
  <pre><code>import pandas as pd
  import json
  from collections import defaultdict, Counter
  import itertools
  import random
  from timeit import default_timer as timer
  
  
  
  # START MY TIMER TO ESTIMATE HOW LONG TAKE TO CALCULATE
  start = timer()
  print('Timer Start')
  
  def generate_random_offers():
      ''' Generate random offers with this format:
          {'offer_id':'oid_1','product_id': 'pid_1', 'ventor':'B', 'offer_price':5.00}
      '''
  
      _offers = []
      _vendors = ['A','B','C','D','E']
      _pids_1 = ['pid_1']
      _pids_2 = ['pid_1','pid_2']
      _pids_3 = ['pid_1','pid_2','pid_3']
      _pids_4 = ['pid_1','pid_2','pid_3','pid_4']
      _pids_5 = ['pid_1','pid_2','pid_3','pid_4','pid_5']
      _pids_6 = ['pid_1','pid_2','pid_3','pid_4','pid_5','pid_6']
      _pids_7 = ['pid_1','pid_2','pid_3','pid_4','pid_5','pid_6','pid_7']
  
      _pids_5 = ['pid_1','pid_2','pid_3','pid_4','pid_5']
      for i in range(1, 100):
          random_price = round(random.uniform(1, 80), 2)
          random_vendor = random.choice(_vendors)
          random_pid = random.choice(_pids_4)
  
          print(i)
          schema = {}
          schema['offer_id'] = f'oid_{i}'
          schema['product_id'] = random_pid
          schema['ventor'] = random_vendor
          schema['offer_price'] = random_price
          _offers.append(schema)
      # print(_offers)
  
  
      # write_json_file(_offers)
      return _offers
  #end
  
  # initiate the variable that gona hold all the offers
  OFFERS = []
  OFFERS = generate_random_offers()
  
  
  def get_the_vendors():
      ''' Return array of all individuals vendors in offers array '''
  
      _vendors = []
  
      for offer in OFFERS:
  
          if offer['ventor'] not in _vendors:
              _vendors.append(offer['ventor'])
  
      # print(vendors)
      return _vendors
  #end
  
  
  def get_the_products():
      ''' Get the products that is inside the array '''
  
      _products = []
  
      for offer in OFFERS:
  
          if offer['product_id'] not in _products:
              _products.append(offer['product_id'])
  
      # print('products =&gt; ', _products)
      return _products
  #end
  
  
  def get_offers_base_on_product():
      ''' Get the offers base on products '''
  
      _offers_by_product = []
      PRODUCTS = get_the_products()
  
      for product in PRODUCTS:
  
          _prod = {}
  
          p = []
          for offer in OFFERS:
  
              if offer['product_id'] == product:
                  p.append(offer['offer_id'])
                  # _prod[offer['product_id']] = p
                  _prod = p
  
          _offers_by_product.append(_prod)
  
      # print('_offers_by_product', _offers_by_product)
      return _offers_by_product
  #end
  
  
  def get_the_vendors_total_product_price():
      ''' Return the sum of the vendors offers '''
  
      _v = []
      VENDORS = get_the_vendors()
  
      for vendor in VENDORS:
  
          v = []
          _sum = 0
  
          for offer in OFFERS:
  
              x = {}
              if offer['ventor'] == vendor:
                  _sum += offer['offer_price']
                  print('sum of ' + vendor + ' =&gt; ',  _sum)
  
              x['vendor'] = vendor
              x['sum'] = _sum
  
          _v.append(x)
      print(_v)
      return _v
  #end
  
  
  def compinations():
  
      list_of_offers_by_product = get_offers_base_on_product()
      a = []
      for _list in list_of_offers_by_product:
          a.append(_list)
  
      super_compinations = list(itertools.product(*a))
      # print('ALL POSSIBLE COMBINATIONS', super_compinations)
      print(super_compinations[0])
      print(super_compinations[1])
      print(super_compinations[2])
  
      return super_compinations
  #end
  
  
  def get_sums():
  
      super_compinations = compinations()
      _sums = []
      best_price = {}
      min_price = 1000
      min_set = ''
  
      # for i in range(30):
      for i in range(len(super_compinations)):
          price = 0
  
          for ii in range(len(super_compinations[i])):
              offer_id = super_compinations[i][ii]
  
              for _offer in OFFERS:
  
                  try:
                      if _offer['offer_id'] == offer_id:
                          price += _offer['offer_price']
                          # print(price)
                  except KeyboardInterrupt:
                      print('Interrupted')
  
          _sums.append(price)
          if price &lt; min_price:
              min_price = price
              min_set = super_compinations[i]
  
      print('========')
      print('OFFERS SUMS =&gt; ', _sums)
      print('========')
  
      print('Min Price: ', min_price)
      print('Min Set: ', min_set)
  
      # STOP MY TIMER
      elapsed_time = timer() - start # in seconds
      print('TOOK: ', elapsed_time)
  #end
  
  # Heare a start the program to calculate all the combinations and 
    after I get all the combinations I try to get the sum of every combination one by one
  get_sums() 
  
  
  
  
  
  
  
   _offers_by_product [['oid_1', 'oid_1', 'oid_2', 'oid_3', 'oid_4'], ['oid_5', 'oid_6', 'oid_7', 'oid_8', 'oid_9'], ['oid_10', 'oid_11', 'oid_12', 'oid_1
  3', 'oid_14', 'oid_15', 'oid_16']]
  
  
   ALL POSSIBLE COMBINATIONS [
      ('oid_1', 'oid_5', 'oid_10'), 
      ('oid_1', 'oid_5', 'oid_11'), 
      ('oid_1', 'oid_5', 'oid_12'), 
      ('oid_1', 'oid_5', 'oid_13'), 
      ('oid_1', 'oid_5', 'oid_14'), 
      ('oid_1', 'oid_5', 'oid_15'), 
      ('oid_1', 'oid_5', 'oid_16'), 
      ('oid_1', 'oid_6', 'oid_10'), 
      ('oid_1', 'oid_6', 'oid_11'), 
      ### N..... Possible combinations mabe 1.000.000 milion
  ]
  </code></pre>
  
  <h2>this is the output 1Trillion combinations took 20sec</h2>
  
  <pre><code>[4, 177.64, 206.63, 227.38, 152.29, 202.47, 211.85, 195.35, 171.37, 191.94, 
  187.51999999999998, 122.53999999999999, 139.34, 166.43, 135.62, 167.49, 182.12, 169.79
      , 193.42000000000002, 147.42, 176.41, 197.16, 122.07, 172.25, 181.63, 165.13, 141.15, 161.72, 157.3, 150.73999999999998, 167.54, 194.63, 163.82, 195.69, 210.32,
  193.54000000000002, 225.41000000000003, 240.04000000000002, 227.71, 251.34000000000003, 205.34,
      234.33, 255.08, 179.99, 230.17000000000002, 239.55, 223.05, 192.67000000000002, 213.24, 208.82]
  
  ========
  Min Price:  14.08
  Min Set:  ('oid_22', 'oid_16', 'oid_9', 'oid_71')
  TOOK:  19.05843851931529
  PS C:\Users\George35mk\Desktop\MACHINE LERNING EXAMPLES\Hello world&gt;
  </code></pre>
  
  <p>Can someone expert tell me if I am in the right way</p>