Created
September 21, 2020 05:45
-
-
Save mentix02/2384a0dcabf335d1529914d7265fb336 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import re | |
import csv | |
import datetime as dt | |
from prettytable import PrettyTable | |
# intialize table | |
rows = [] | |
table = PrettyTable() | |
table.field_names = ['id', 'name', 'price', 'expires'] | |
def load(): | |
global rows | |
# load data into a list of list | |
with open('products.csv', 'r') as f: | |
# read file into a csv format | |
reader = csv.reader(f) | |
# iterate to 1st element and | |
# remove the field's name row | |
header = next(reader) | |
# load data into rows with | |
# proper data type format | |
rows = [[int(row[0]), row[1], float(row[2]), dt.datetime.strptime(row[3], '%m/%d/%Y')] for row in reader] | |
def display_results(results): | |
""" | |
Displays product information in a row. | |
The results will be a list of lists. Each | |
list will contain the required parameters that | |
are id, name, price and expiration date. | |
Example of the structure should be - | |
table.add_row([1, 'First sample item', 1.23, 'JAN-01-2019']) | |
""" | |
for result in results: | |
table.add_row(result) | |
print(table) | |
table.clear_rows() | |
def query(tokens): | |
filter_by_min_max = list(filter(lambda row: tokens[0] <= row[2] <= tokens[1], rows)) | |
filter_by_dates = list(filter(lambda row: tokens[2] <= row[3] <= tokens[3], filter_by_min_max)) | |
return sorted(filter_by_dates, key=lambda row: row[3]) | |
def query_to_result_formatter(results): | |
""" | |
converts query into proper string | |
type format so it can be loaded into | |
table.add_row() function; line 26 | |
""" | |
for i, result in enumerate(results): | |
result[3] = result[3].strftime('%b-%d-%Y').upper() | |
results[i] = result | |
return results | |
def parse_command(command): | |
""" | |
Parses and returns tokens of | |
command in proper data type. | |
Returns 'False' if command was | |
misconfigured of wrongly typed. | |
misconfigured example - | |
"aicnadjnaifv" => False | |
"2.40 2.60 JAN-01-2019" => False | |
correct example - | |
"2.40 2.60 JAN-01-2019 JAN-31-2019" => [2.4, 2.6, datetime.datetime(2019, 1, 1, 0, 0), datetime.datetime(2019, 1, 31, 0, 0)] | |
""" | |
tokens = command.split(' ') | |
# since a proper command has 4 | |
# components to it, if the token | |
# split returned less or greater | |
# than 4 then we don't need to | |
# check for validity of the command | |
if len(tokens) != 4: | |
return ('command should be in "PRICE_MIN PRICE_MAX EXPIRES_START EXPIRES_STOP" format',), False | |
# try to convert strings into | |
# proper formats and catch any | |
# exceptions that are raised | |
# to return the False for error | |
try: | |
price_min = float(tokens[0]) | |
price_max = float(tokens[1]) | |
expires_start = dt.datetime.strptime(tokens[2].capitalize(), '%b-%d-%Y') | |
expires_stop = dt.datetime.strptime(tokens[3].capitalize(), '%b-%d-%Y') | |
except Exception as e: | |
return (e,), False | |
# on successful execution, load | |
# data in proper times into a list | |
# and return | |
return (price_min, price_max, expires_start, expires_stop), True | |
def start(): | |
""" | |
Start accepting user input | |
Quit program when user types 'exit' | |
""" | |
load() | |
while True: | |
command = input('> ') | |
if command == 'exit': | |
break | |
tokens, success = parse_command(command) | |
if success: | |
q = query(tokens) | |
results = query_to_result_formatter(q) | |
display_results(results) | |
load() | |
continue | |
else: | |
print('error :', tokens[0]) | |
# display_results(rows) | |
if __name__ == '__main__': | |
start() | |
# tokens, e = parse_command('2.40 2.60 JAN-01-2019 JAN-31-2019') | |
# q = query(tokens) | |
# results = query_to_result_formatter(q) | |
# display_results(results) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment