blob: 9c7e0870c15dfe14713363aab664ac65721ba12d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# Section 1
# Convert csv file into line items and queries
# This code assumes a file format similar to the one on the
# Arduino BOM
import csv
csv_file = open("arduino_bom.csv", "r")
csv_reader = csv.DictReader(csv_file)
line_items = []
queries = []
for line_item in csv_reader:
# Skip line items without part numbers and manufacturers
if not line_item['Part Number'] or not line_item['Manufacturer']:
continue
line_items.append(line_item)
queries.append({'mpn': line_item['Part Number'],
'brand': line_item['Manufacturer'],
'reference': len(line_items) - 1})
# Section 2
# Send queries to REST API for part matching.
import json
import urllib
results = []
for i in range(0, len(queries), 20):
# Batch queries in groups of 20, query limit of
# parts match endpoint
batched_queries = queries[i: i + 20]
url = 'http://octopart.com/api/v3/parts/match?queries=%s' \
% urllib.quote(json.dumps(batched_queries))
url += '&apikey=e3d61a07'
data = urllib.urlopen(url).read()
response = json.loads(data)
print response
# Record results for analysis
results.extend(response['results'])
# Section 3
# Analyze results sent back by Octopart API
from decimal import Decimal
print "Found %s line items in BOM." % len(line_items)
# Price BOM
hits = 0
total_avg_price = 0
for result in results:
line_item = line_items[result['reference']]
if len(result['items']) == 0:
print "Did not find match on line item %s" % line_item
continue
# Get pricing from the first item for desired quantity
quantity = Decimal(line_items[result['reference']]['Qty'])
prices = []
for offer in result['items'][0]['offers']:
if 'USD' not in offer['prices'].keys():
continue
price = None
for price_tuple in offer['prices']['USD']:
# Find correct price break
if price_tuple[0] > quantity:
break
# Cast pricing string to Decimal for precision
# calculations
price = Decimal(price_tuple[1])
if price is not None:
prices.append(price)
if len(prices) == 0:
print "Did not find pricing on line item %s" % line_item
continue
avg_price = quantity * sum(prices) / len(prices)
total_avg_price += avg_price
hits += 1
print "Matched on %.2f of BOM, total average price is USD %.2f" % ( \
hits / float(len(line_items)), total_avg_price)
|