-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommodity.py
More file actions
129 lines (94 loc) · 3.96 KB
/
commodity.py
File metadata and controls
129 lines (94 loc) · 3.96 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import requests
from bs4 import BeautifulSoup
import math
from route import Route, Port
class Commodity:
def __init__(self, t_name, t_cateogry, t_url):
self.name = t_name
self.category = t_cateogry
self.ports_of_purchase = list()
self.ports_of_sale = list()
self.routes = list()
page = requests.get(t_url)
soup = BeautifulSoup(page.content, "html.parser")
price_unit_tables = soup.find_all("table")
if len(price_unit_tables) != 2:
return
purchase_table = price_unit_tables[0]
sale_table = price_unit_tables[1]
self.ports_of_purchase = self.build_port_list(purchase_table)
self.ports_of_sale = self.build_port_list(sale_table)
def build_port_list(self, t_port_table):
port_list = list()
rows = t_port_table.find_all("tr")
for row in rows:
table_data = row.find_all("td")
port = Port()
port.planetary_body = table_data[0].text.strip()
port.planetary_body = " ".join(port.planetary_body.split()[:-1])
if table_data[1].string == None:
port_name = "???"
else:
port.name = table_data[1].string.strip()
try:
port.price = int(float(table_data[2].string.strip()) * 100)
except AttributeError:
port.price = 0
try:
port.refresh_per_minute = \
math.floor(float(table_data[3].string.strip()))
except AttributeError:
port.refresh_per_minute = 0
try:
port.max_inventory = int(table_data[4].string.strip())
except AttributeError:
port.max_inventory = 0
port_list.append(port)
return port_list
def build_routes(self, t_investment, t_units, t_profit_per_unit,
t_buy_time, t_sell_time):
self.routes.clear()
units = t_units
for purchase_port in self.ports_of_purchase:
best_case_buy = self.best_case(purchase_port, t_units)
worst_case_buy = self.worst_case(purchase_port, t_units)
if best_case_buy == -1 or worst_case_buy == -1 or\
worst_case_buy > t_buy_time:
continue
if t_units * purchase_port.price > t_investment:
units = int(t_investment / purchase_port.price)
if units <= 0:
continue
for sale_port in self.ports_of_sale:
profit_per_unit = sale_port.price - purchase_port.price
if profit_per_unit < t_profit_per_unit:
continue
best_case_sell = self.best_case(sale_port, t_units)
worst_case_sell = self.worst_case(sale_port, t_units)
if best_case_sell == -1 or worst_case_sell == -1 or\
worst_case_sell > t_buy_time:
continue
route = Route(purchase_port, sale_port, units,
purchase_port.price, sale_port.price,
best_case_buy, best_case_sell,
worst_case_buy, worst_case_sell, self.name)
self.routes.append(route)
self.routes.sort(key=lambda route: route.total_profit(),
reverse=True)
def worst_case(self, t_port, t_units):
try:
worst_case = \
int(t_units / t_port.refresh_per_minute)
except ZeroDivisionError:
worst_case = -1
return worst_case
def best_case(self, t_port, t_units):
if t_port.max_inventory > t_units:
best_case = 0
else:
t_units -= t_port.max_inventory
try:
best_case = math.ceil(t_units / t_port.refresh_per_minute)
except ZeroDivisionError:
best_case = -1
return best_case