File size: 7,843 Bytes
4529978
 
 
 
707d248
d7a157d
7a1892c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d7a157d
7a1892c
4529978
 
abf5145
4529978
37ccb21
d12540a
abf5145
d631e11
603074c
d631e11
4522da4
abf5145
4529978
f70fecd
5d07cf3
b22223b
 
 
 
 
 
 
f70fecd
6a4b31a
 
3bf3b1e
 
 
 
 
 
f7f3d55
5d07cf3
3bf3b1e
4529978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b14a168
093db42
 
 
 
 
 
 
 
9236d36
 
 
f71ba4a
9236d36
603074c
6da80fe
 
 
4529978
 
 
 
 
 
 
 
 
4dd48d8
 
 
454ee33
aa649e8
60250ba
115e24e
779d92d
 
3c44956
4529978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a1892c
 
952d497
d6a899e
7a1892c
35a6b1a
6a4b31a
e25c598
35a6b1a
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import pandas as pd
import numpy as np
import tensorflow as tf
import streamlit as st
import time
#-------------------------------------------------------------
# For outputting the final type but in color
type_to_color = {
    'GRASS': "#33FF3F",
    'FIRE': "#FF4533",
    'WATER':"#339DFF",
    'BUG': "#AFFF33",
    'NORMAL': "#000000",
    'DARK':  "#10081A",
    'POISON': "#E36DED",
    'ELECTRIC': "#FCFF2A",
    'GROUND': "#7F5131",
    'ICE': "#B3FEFF",
    'FAIRY': "#FFB3FE",
    'STEEL': "#6E6E6E",
    'FIGHTING': "#AB7148",
    'PSYCHIC': "#A33EBF",
    'ROCK': "#4A3727",
    'GHOST': "#DDD2F4",
    'DRAGON': "#DB8645",
    'FLYING': "#98E6FF"
}
#---------------------------------------------------------------------

# Input your X values for prediction (a NumPy array)--------------------
options = ['Type', 'BST', 'HP', 'Attack', 'Defense', 'Sp. Attack', 'Sp. Defense', 'Speed']

# Create the multiselect
selected_options = st.multiselect('Select which stats you already have (Pick 2-7):', options)
input_feature_length = len(selected_options)
while input_feature_length not in range(2,8):
    time.sleep(0.5)
loaded_model = tf.keras.models.load_model(f'Pokemon_Trained_Models/{input_feature_length}feature_model.HDF5')
# Initializing a numpy array to house input values
X_values = np.zeros((1,int(input_feature_length)+8))

options_to_positions = {
    'Type': 0,
    'BST': 1,
    'HP': 2,
    'Attack': 3,
    'Defense': 4,
    'Sp. Attack': 5,
    'Sp. Defense': 6,
    'Speed': 7,
}
# Reversing the options_to_positions dictionary so I can use it to label output stats
reversed_options_to_positions = {v: k for k, v in options_to_positions.items()}
# Ordering selected_options numerically based on options_to_positions dictionary
selected_options = sorted(selected_options, key=lambda x: options_to_positions[x])

# Adding the indicator vector based on selected stats
indicator_positions = [options_to_positions[i] for i in selected_options]
for i in indicator_positions:
    X_values[0, i+input_feature_length] = 1


types_to_numbers = {
    'GRASS': 0.056,
    'FIRE': 0.112,
    'WATER':0.168,
    'BUG': 0.224,
    'NORMAL': 0.28,
    'DARK':  0.336,
    'POISON': 0.392,
    'ELECTRIC': 0.448,
    'GROUND': 0.504,
    'ICE': 0.56,
    'FAIRY': 0.616,
    'STEEL': 0.672,
    'FIGHTING': 0.728,
    'PSYCHIC': 0.784,
    'ROCK': 0.84,
    'GHOST': 0.896,
    'DRAGON': 0.952,
    'FLYING': 1.008
}

option_stat_ranges = {'BST': 'BST (175-1125)', 'HP': 'HP (1-255)', 'Attack': 'Attack (5-190)', 'Defense': 'Defense (5-250)', 'Sp. Attack': 'Sp. Attack (10-194)', 'Sp. Defense': 'Sp. Defense (20-250)', 'Speed': 'Speed (5-200)'}
pokemon_types = ['GRASS', 'FIRE', 'WATER', 'BUG', 'NORMAL', 'DARK', 'POISON', 'ELECTRIC', 'GROUND', 'ICE', 'FAIRY', 'STEEL', 'FIGHTING', 'PSYCHIC', 'ROCK', 'GHOST', 'DRAGON', 'FLYING']
counter = 0
for i in selected_options:
    counter += 1
    if 'Type' == i:
        selected_type = st.selectbox('What type is the Pokemon:', pokemon_types)
        X_values[0, counter-1] = types_to_numbers[selected_type]
    else:
        while True:
            try:
                X_values[0, counter-1] = st.text_input(f'What is the value for {option_stat_ranges[i]}?')
                break
            except Exception:
                time.sleep(0.5)
# Changing 'Type' to 'Type 1' so it fits the name in the .csv file
selected_options = ['Type 1' if item == 'Type' else item for item in selected_options]

# Define the file path
file_path = "pokemon.csv"

df = pd.read_csv(file_path)
columns_to_delete = ['Dex No', 'Name', 'Base Name', 'Type 2']
df = df.drop(columns=columns_to_delete)
#Copy dataframe for future refernce:
old_df = df.copy()

#Selecting columns that will be scaled
values_to_scale = X_values[0, 0:input_feature_length]
#Scaling the columns with Min-Max Scaling
counter_2 = 0
for stat in selected_options:
    counter_2 +=1
    if stat != 'Type 1':
        min_value = df[stat].min()
        max_value = df[stat].max()
        X_values[0, counter_2-1] = (X_values[0, counter_2-1] - min_value) / (max_value - min_value)
#-====================================================================================================================================

# Extract indices of '1' values-----------------------------------------
indices_of_ones = [index for index, value in enumerate(X_values[0]) if value == 1]
# Changing values so they fit their appropriate column
for i in range(len(indices_of_ones)):
    indices_of_ones[i] -= input_feature_length-1
print("Indices of '1' values:", indices_of_ones)
# Use the '1' values to find what the export columns will be---
full_range = list(range(1, 9))
# Find the missing indices by taking the set difference
missing_indices = list(set(full_range) - set(indices_of_ones))
missing_indices.sort()
print(missing_indices)

# Use the model to make predictions-------------------------------------
Y_values = loaded_model.predict(X_values)
List_Y_values = Y_values[0].tolist()
print(f"Raw Output Values: {List_Y_values}")
# Initializing 'converted_Y_values' to be same length as 'Y_values'
converted_Y_values = [None] * (len(missing_indices))
#_------------ Making values readable (undoing min-max and other scaling)
if 1 in indices_of_ones:
  converted_Y_values = [None] * (len(missing_indices))
  #'len(missing_indices)' is the length of the 'missing_indices'
  for i in range(len(missing_indices)):
    # Defining Min-Max Values, using the indicies value to match elements
    min_max_values = {
    2: [old_df['BST'].min(), old_df['BST'].max()],
    3: [old_df['HP'].min(), old_df['HP'].max()],
    4: [old_df['Attack'].min(), old_df['Attack'].max()],
    5: [old_df['Defense'].min(), old_df['Defense'].max()],
    6: [old_df['Sp. Attack'].min(), old_df['Sp. Attack'].max()],
    7: [old_df['Sp. Defense'].min(), old_df['Sp. Defense'].max()],
    8: [old_df['Speed'].min(), old_df['Speed'].max()]
    }
    temp_min_max = min_max_values[missing_indices[i]]
    # Undo the min-max scaling
    converted_Y_values[i] = List_Y_values[i] * (temp_min_max[1] - temp_min_max[0]) + temp_min_max[0]
else:
    converted_Y_values = [None] * (len(missing_indices) - 1)
   # Converting 'Type 1' back to readable type
    type_output_indicator = True
    closest_type = None
    min_difference = float('inf')
  # Finding closest type for the value
    for pokemon_type, value in types_to_numbers.items():
        difference = abs(Y_values[0,0] - value)
        if difference < min_difference:
            min_difference = difference
            closest_type = pokemon_type
    # Delete the '1' from missing indices because it's dealt with above
    del missing_indices[0]
    del List_Y_values[0]
    for i in range(len(missing_indices)):
    # Defining Min-Max Values, using the indicies value to match elements
      min_max_values = {
      2: [old_df['BST'].min(), old_df['BST'].max()],
      3: [old_df['HP'].min(), old_df['HP'].max()],
      4: [old_df['Attack'].min(), old_df['Attack'].max()],
      5: [old_df['Defense'].min(), old_df['Defense'].max()],
      6: [old_df['Sp. Attack'].min(), old_df['Sp. Attack'].max()],
      7: [old_df['Sp. Defense'].min(), old_df['Sp. Defense'].max()],
      8: [old_df['Speed'].min(), old_df['Speed'].max()]
      }
      temp_min_max = min_max_values[missing_indices[i]]
      # Undo the min-max scaling
      converted_Y_values[i] = List_Y_values[i] * (temp_min_max[1] - temp_min_max[0]) + temp_min_max[0]
# For making the 'closest_type' text the color of the type 
color = type_to_color[closest_type]
st.write("Output Stats:")
if 'closest_type' in vars():
    st.write(f"<p style='color: {color};'>Type - {closest_type}</p>", unsafe_allow_html=True)
counter_3 = 0
for i in missing_indices:
    st.write(f"{reversed_options_to_positions[i-1]} - {round(converted_Y_values[counter_3])}")
    counter_3 +=1