-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.py
161 lines (127 loc) · 4.65 KB
/
api.py
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import traceback
import pickle
from pandas import DataFrame as df
import pandas as pd
import classes.BMICalculator as bmic
import classes.Encoders as enc
from config import CONFIG
# get child bme ref table
child_bmi_data = CONFIG["CHILD_BMI"]
child_bmi_df = pd.read_csv(child_bmi_data)
# import model
with open ("model.txt", "rb") as file:
model = pickle.load(file)
file.close()
def calc_bmi(data):
height = data["h_text"]
height_unit = data["h_unit"]
weight = data["w_text"]
weight_unit = data["w_unit"]
if height_unit == "m":
imp_obj = bmic.MetricBMICalculator(weight_kg = weight, height_m = height)
bmi = imp_obj.calculate()
else:
imp_obj = bmic.ImperialBMICalculator(weight_lb = weight, height_in = height)
bmi = imp_obj.calculate()
return bmi
def isfloat(num):
try:
float(num)
return True
except ValueError:
return False
def request_bmi(*args):
"""Validate input, request bmi"""
data = {
"h_text": args[0],
"h_unit": args[1],
"w_text": args[2],
"w_unit": args[3]
}
try:
run_status = "Successful run!"
valid_input = validate_input(data)
if not valid_input:
raise Exception(run_status)
bmi = calc_bmi(data)
return bmi , run_status
except Exception as error:
traceback.print_exc()
print (str(error))
return 0, str(error)
def validate_input(data):
"""
Validate that one unit type was selected and that each is a number.
"""
height = data["h_text"]
weight = data["w_text"]
height_unit = data["h_unit"]
weight_unit = data["w_unit"]
is_zero = any([i == 0 for i in [height, weight]])
missing_data = any([i is None for i in [height, weight, height_unit, weight_unit]])
if missing_data or is_zero:
run_status = "Please enter information and try again."
raise Exception(run_status)
# check if units are consistent
imperial = ["in", "lb"]
metric = ["m", "kg"]
is_imperial = set(imperial) == set([height_unit, weight_unit])
is_metric = set(metric) == set([height_unit, weight_unit])
consistent = any([is_imperial, is_metric])
if not consistent:
run_status = "BMI input units need to be consitently metric (kg and m) or imperial (in and lb). Please try again"
raise Exception(run_status)
# check that each only contains numbers
valid_input = all(isfloat(i) for i in [height,weight])
if not valid_input:
run_status = "All inputs must be numeric"
raise Exception(run_status)
return valid_input
def encode_pred(df, final_cols):
if all(df["age"] > 19):
bmi = enc.AdultBMIEncoder(df).encode()
else:
bmi = enc.ChildBMIEncoder(bmi_table= child_bmi_df, data_table= df).encode()
enc.one_hot_enc_bmi(df,"bmi_buckets")
enc.GenderEncoder(df,"gender").encode()
enc.AgeEncoder(df,"age").encode()
enc.MarriageEncoder(df,"ever_married").encode()
enc.ResidenceEncoder(df,"Residence_type").encode()
enc.SmokingStatusEncoder(df, "smoking_status").encode()
enc.HypertensionEncoder(df,"hypertension").encode()
enc.HeartDiseaseEncoder(df,"heart_disease").encode()
df = df[final_cols]
return df
def prep_pred_data(*args):
"""
Create dataframe to make a prediction on.
"""
data = args
new_df_dict = {}
new_df_dict["age"] = data[0][0]
new_df_dict["gender"] = data[0][1]
new_df_dict["Residence_type"] = data[0][2]
new_df_dict["hypertension"] = data[0][3]
new_df_dict["heart_disease"] = data[0][4]
new_df_dict["smoking_status"] = data[0][5]
new_df_dict["ever_married"] = data[0][6]
new_df_dict["bmi"] = data[0][7]
col_order = ["age", "hypertension", "heart_disease", "bmi_under", "bmi_healthy", "bmi_over", "bmi_obese", "is_male", "c_ever_married", "live_urban", "ss_1", "ss_2", "ss_3", "ss_4"]
pred_df = df.from_dict([new_df_dict])
encoded_pred_df = encode_pred(pred_df, col_order)
return encoded_pred_df
def request_prediction(*args):
"""
Request user input and predict data
"""
data = args
try:
pred_df = prep_pred_data(data)
stroke_pred = model.predict(pred_df)
stroke = "Stroke predicted"
no_stroke = "No stroke predicted"
pred_val = stroke if stroke_pred == 1 else no_stroke
return pred_val
except Exception as error:
traceback.print_exc()
print (str(error))