text: import random
  import pandas as pd
  import numpy as np
  import datetime
  
  # Read in marketing tables
  print('reading campaigns, channels...')
  campaigns = pd.read_csv('../source/campaigns.csv')
  campaigns['start_dt'] = pd.to_datetime(campaigns['start_date'])
  campaigns['end_dt'] = pd.to_datetime(campaigns['end_date'])
  channels = pd.read_csv('../source/campaign_channels.csv')
  
  # Given a date, find a campaign running on that date, and return the tracking
  # code for one of that campaign's channels at random
  def find_tracking_code(order_date):
      # campaigns that are effective around our order_date
      potential_campaigns = campaigns[(order_date >= campaigns['start_dt']) \
                                  & (order_date <= campaigns['end_dt'])]
      pcl = len(potential_campaigns) # potential_campaigns length (could be zero)
  
      # select one of found campaigns at random, or none
      # This part is a little tricky
      #   if pcl is 0, then rn will be 0 and we return blank
      #   if pcl is 2, and rn is 2 then we return blank
      #     otherwise rn is an index into potential_campaigns
      rn = random.randint(0,pcl) #
      if rn < pcl :
          cid = potential_campaigns.iloc[rn]['campaign_id'] # Chosen Campaign ID
      else:
          return ''
      # Find a channel
      pch = channels[channels['campaign_id'] == cid] # potential channels
      pchl = len(pch) # pot channels len
      sch = pd.Series() # selected channel
      if pchl == 0:
          return ''
      # retrive the selected channel
      return pch.iloc[random.randint(0,pchl-1)]['tracking_code']
  
  # Read in the orders as generated by Mockaroo
  # curl "https://api.mockaroo.com/api/d29b2110?count=1000&key=66099da0" > "orders_unmatched.csv"
  orders = pd.read_csv('../temp/orders_unmatched.csv')
  print('order_rows: ' + str(len(orders)))
  orders.insert(loc=5, column='tracking_code', value="")
  
  order_lines = pd.read_csv('../temp/order_lines.csv')
  print('order lines: ' + str(len(order_lines)))
  
  
  # Loop through each order, construct a combined master/detail row, one or more order-lines per order
  
  new_orders = pd.DataFrame(columns=['order_id', 'customer_id', 'order_date', 'order_type', 'order_status', 'tracking_code', \
                                     'shipping_amount', 'order_line_id', 'product_id', 'price', 'quantity'])
  n_order_lines = len(order_lines)
  new_orders_idx = 0
  order_lines_idx = 0
  order_line = 1
  
  for i, row in orders.iterrows():
      # Print dots while processing
      if (i % 1000) == 0:
          print('.', end='', flush=True)
  
      # Get a tracking code for this order if we are lucky
      tc = find_tracking_code(row['order_date'])
      order_line = 1
  
      while True:
          new_orders.loc[new_orders_idx] = row
          new_orders.loc[new_orders_idx, 'order_line_id'] = row['order_id']+'-'+str(order_line)
          new_orders.loc[new_orders_idx, 'tracking_code'] = tc
          new_orders.loc[new_orders_idx, "product_id"] = str(order_lines.loc[order_lines_idx, "product_id"])
          new_orders.loc[new_orders_idx, "quantity"] = str(order_lines.loc[order_lines_idx, "quantity"])
  
          # add a bit of inflation to the prices
          price = float(order_lines.loc[order_lines_idx, "price"])
          year = pd.to_datetime(row['order_date']).year
          new_price = round(price * (1.05**(year-2014)),2)
          new_orders.loc[new_orders_idx, "price"] = new_price
  
          new_orders_idx = new_orders_idx + 1
          order_line = order_line + 1
          # Don't exceed the index into the order_lines dataframe
          order_lines_idx = order_lines_idx + 1 if order_lines_idx + 1 < n_order_lines else 0
  
          # Decide whether to add another order line (geometric progression)
          if random.randint(0,1) == 0:
              break;
  
  # Output the new orders file
  print ('\ntotal order lines: ', new_orders_idx)
  newfilename='../source/orders_1_' + str(int(datetime.datetime.now().timestamp())) + '.csv'
  new_orders.to_csv(newfilename, encoding='utf-8', index=False)
  
  quit()
  