to do: debug existing JSON file feature

This commit is contained in:
Mikayla Dobson
2023-01-07 19:53:23 -06:00
parent c4e7e1301c
commit b1ba613468
3 changed files with 91 additions and 52 deletions

View File

@@ -3,10 +3,16 @@ import psycopg2
class Config: class Config:
# store all user input # store all user input
def __init__(self): def __init__(self, format=None):
self.data_path = None if format:
self.pg_config = None self = format
self.sort_by_match_strength = False else:
self.data_path: str = ""
self.pg_config = None
self.sort_by_match_strength: bool = False
def __repr__(self):
return f"data path: {self.data_path}, pg_config: {self.pg_config}, sorted: {str(self.sort_by_match_strength)}"
def run(self): def run(self):
"""Completes new config process or uses an existing one. Dumps new data into a JSON file if it is generated, and returns either an old instance of `Config` or the new one as `self`""" """Completes new config process or uses an existing one. Dumps new data into a JSON file if it is generated, and returns either an old instance of `Config` or the new one as `self`"""
@@ -15,14 +21,14 @@ class Config:
if prev_config is not None: if prev_config is not None:
return prev_config return prev_config
else: else:
self.get_data_path() self.receive_data_path()
self.set_pg_config() self.set_pg_config()
self.output_formatting() self.output_formatting()
with open("./config.json", "w") as outfile: with open("./config.json", "w") as outfile:
json.dump(self.__encode(), outfile) json.dump(self.__encode(), outfile)
return self return self
else: else:
self.get_data_path() self.receive_data_path()
self.set_pg_config() self.set_pg_config()
self.output_formatting() self.output_formatting()
with open("./config.json", "w") as outfile: with open("./config.json", "w") as outfile:
@@ -35,26 +41,33 @@ class Config:
response_for_prev_config = input("Use existing configuration file? y/n " ).lower() response_for_prev_config = input("Use existing configuration file? y/n " ).lower()
if response_for_prev_config == "y": if response_for_prev_config == "y":
prev_data: Config = open("./config.json") with open("./config.json", "r") as infile:
prev_data = json.load(prev_data) config_data = json.load(infile)
return prev_data
return Config(config_data)
elif response_for_prev_config == "n": elif response_for_prev_config == "n":
return None return None
else: else:
print("Invalid response.") print("Invalid response.")
self.handle_prev_config() self.handle_prev_config()
def get_data_path(self): def receive_data_path(self):
"""Locates a valid directory from user input and stores it in Config state as `self.data_path`.""" """Locates a valid directory from user input and stores it in Config state as `self.data_path`."""
data_path = input("Provide the location of the directory where we can find your photos: ") data_path = input("Provide the location of the directory where we can find your photos: ")
if not os.path.exists(data_path): if not os.path.exists(data_path):
print("We didn't find a directory by this name.") print("We didn't find a directory by this name.")
self.data_path = self.get_data_path() self.receive_data_path()
else: else:
print("Got it!") print("Got it!")
self.data_path = data_path self.data_path = data_path
def get_data_path(self):
return self.data_path
def set_data_path(self, value):
self.data_path = value
def set_pg_config(self): def set_pg_config(self):
"""Determine if data should be associated with a PostgreSQL instance, and, if so, record the required connection info""" """Determine if data should be associated with a PostgreSQL instance, and, if so, record the required connection info"""
elect_for_pg = input("Connect this program to a PostgreSQL instance? y/n ").lower() elect_for_pg = input("Connect this program to a PostgreSQL instance? y/n ").lower()
@@ -107,7 +120,4 @@ class Config:
self.output_formatting() self.output_formatting()
def __encode(self): def __encode(self):
return json.dumps(self, default=lambda x: x.__dict__) return json.dumps(self, default=lambda x: x.__dict__)
new_config = Config()
new_config.run()

View File

@@ -1,47 +1,74 @@
import json, os, shutil import json, os, shutil
from config import Config
def format_result(src_path, json_path): def format_result(app_config: Config, json_path):
# dictionary to hold and later display our results
insertions_by_label = {} insertions_by_label = {}
data_path = app_config.data_path
# if pg_config is not None, run the postgres prediction[0] of this code
pg_config = app_config.pg_config
# if this is True, run the prediction[0] "for line in contents:" below
sort_by_match_strength = app_config.sort_by_match_strength
weak_results = 0 weak_results = 0
total_count = 0 total_count = 0
# store analysis results in contents
with open(json_path) as results: with open(json_path) as results:
contents = json.load(results) contents = json.load(results)
for qualifier in ['strong', 'moderate', 'fair', 'weak']: # prepare individual locations for match strengths if sort is enabled
if not os.path.exists("./predictions/" + qualifier): if sort_by_match_strength:
os.makedirs('./predictions/' + qualifier) for qualifier in ['strong', 'moderate', 'fair', 'weak']:
if not os.path.exists("./predictions/" + qualifier):
os.makedirs('./predictions/' + qualifier)
# handles data for each photo
for line in contents: for line in contents:
img_path = src_path + line['path'] img_path = data_path + line['path']
prediction = line['prediction'] prediction = line['prediction']
for section in prediction:
total_count += 1
guess_label = section[0][1]
match_strength = 'weak/'
if float(section[0][2]) > 0.9: # handles data for first prediction for a given photo
match_strength = 'strong/' total_count += 1
elif float(section[0][2]) > 0.75: guess_label = prediction[0][0][1]
match_strength = 'moderate/' match_strength = 'weak'
elif float(section[0][2]) > 0.5:
match_strength = 'fair/'
elif match_strength == 'weak/':
weak_results += 1
if not guess_label in insertions_by_label: # assign value for match strength
insertions_by_label[guess_label] = 0 if float(prediction[0][0][2]) > 0.9:
match_strength = 'strong'
elif float(prediction[0][0][2]) > 0.7:
match_strength = 'moderate'
elif float(prediction[0][0][2]) > 0.4:
match_strength = 'fair'
elif match_strength == 'weak':
weak_results += 1
# modify variable for path
match_strength = match_strength + "/"
if not guess_label in insertions_by_label:
insertions_by_label[guess_label] = 0
# copy file to appropriate location, depending on if sorting
if sort_by_match_strength:
if (not os.path.exists("./predictions/" + match_strength + guess_label)): if (not os.path.exists("./predictions/" + match_strength + guess_label)):
os.makedirs("./predictions/" + match_strength + guess_label) os.makedirs("./predictions/" + match_strength + guess_label)
if (not os.path.exists('./predictions/' + match_strength + guess_label + '/' + img_path)): if (not os.path.exists('./predictions/' + match_strength + guess_label + '/' + img_path)):
shutil.copy(img_path, "./predictions/" + match_strength + guess_label) shutil.copy(img_path, "./predictions/" + match_strength + guess_label)
insertions_by_label[guess_label] = insertions_by_label[guess_label] + 1 insertions_by_label[guess_label] = insertions_by_label[guess_label] + 1
else:
if (not os.path.exists("./predictions/" + guess_label)):
os.makedirs("./predictions/" + guess_label)
if (not os.path.exists('./predictions/' + guess_label + '/' + img_path)):
shutil.copy(img_path, "./predictions/" + guess_label)
insertions_by_label[guess_label] = insertions_by_label[guess_label] + 1
print(str(weak_results) + " weak result(s) of a total " + str(total_count) + " input(s)\n") print(str(weak_results) + " weak result(s) of a total " + str(total_count) + " input(s)\n")
print("By subject:\n\n") print("By subject:\n")
for k, v in insertions_by_label.items(): for k, v in insertions_by_label.items():
print(k + ": " + str(v) + " file(s) found") print(k + ": " + str(v) + " file(s) found")

34
main.py
View File

@@ -6,36 +6,30 @@
import os, json import os, json
from config import Config from config import Config
from time import time from time import time
from predict import predict
from formatresult import format_result
from keras.applications.vgg16 import VGG16
print("\n\nImage Sorting Utility\n") print("\nImage Sorting Utility\n")
print("Script by Mikayla Dobson\n") print("Script by Mikayla Dobson\n")
print("\n\n") print("\n\n")
############################## CONFIG ############################## CONFIG
print("Running app config...") print("Running app config...")
appconfig = Config() appconfig: Config = Config()
config_file = appconfig.run() config_file = appconfig.run()
############################## SETUP if (config_file.get_data_path()[-1] != "/"):
############################## SETUP config_file.set_data_path(config_file.get_data_path() + "/")
############################## SETUP
# create the target directory if it doesn't exist # create the target directory if it doesn't exist
if (not os.path.exists("./predictions")): if (not os.path.exists("./predictions")):
print("Did not find predictions directory, creating...\n\n") print("Did not find predictions directory, creating...\n\n")
os.makedirs("./predictions") os.makedirs("./predictions")
# receive directory path as CLI argument and get a list of all files in path ############################## SETUP
src_path = config_file.data_path ############################## SETUP
############################## SETUP
if (src_path[-1] != "/"): files = os.listdir(config_file.data_path)
src_path += "/"
files = os.listdir(src_path)
# generate current time for use in identifying outfiles # generate current time for use in identifying outfiles
cur_time = str(int(time())) cur_time = str(int(time()))
@@ -47,6 +41,14 @@ all_results = []
############################## ANALYSIS ############################## ANALYSIS
############################## ANALYSIS ############################## ANALYSIS
print("Attempting TF imports...\n\n")
from predict import predict
from formatresult import format_result
from keras.applications.vgg16 import VGG16
print("Success!")
# declare model to be used for each prediction # declare model to be used for each prediction
model = VGG16(weights='imagenet') model = VGG16(weights='imagenet')
@@ -54,7 +56,7 @@ print("Running image analysis. This may take some time...\n\n")
# for each file in directory, append its prediction result to main list # for each file in directory, append its prediction result to main list
for file in files: for file in files:
result = predict(model, src_path + file) result = predict(model, config_file.data_path + file)
if result is not None: if result is not None:
all_results.append({ "path": file, "prediction": result }) all_results.append({ "path": file, "prediction": result })
@@ -72,6 +74,6 @@ print("Analysis complete! Beginning sort process...\n\n")
############################## SORTING ############################## SORTING
############################## SORTING ############################## SORTING
format_result(src_path, json_path) format_result(appconfig, json_path)
print("File sort successful! Process complete.") print("File sort successful! Process complete.")