Skip to content

Instantly share code, notes, and snippets.

@mentix02
Created September 21, 2020 05:45
Show Gist options
  • Save mentix02/2384a0dcabf335d1529914d7265fb336 to your computer and use it in GitHub Desktop.
Save mentix02/2384a0dcabf335d1529914d7265fb336 to your computer and use it in GitHub Desktop.
#!/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