Given an input text array
input_array = [
'JUNK', 'Mon', 'JUNK', '10am', 'JUNK', '-', ' 5pm',
'6pm', '-', '9pm', 'JUNK', 'Tue', '10am', '-', 'JUNK', '5pm'
]
should be converted to a JSON
[
{
"weekday_name": "monday",
"starting_time": "10am",
"ending_time": "5pm"
},
{
"weekday_name": "monday",
"starting_time": "6pm",
"ending_time": "10pm"
},
...
]
Although this is a simple algorithm, I'm forced to create temporary variables which is usually considered non-pythonic.
The code with ugly temporary variables
import pprint
input_array = ['JUNK','Mon','JUNK','10am','JUNK','-','5pm','6pm','-','9pm','JUNK','Tue','10am','-','JUNK','5pm']
business_hours = []
start_hours = None
end_hours = None
current_day = None
dash_found = False
days_of_the_week = {}
days_of_the_week['Mon'] = 'monday'
days_of_the_week['Tue'] = 'tuesday'
days_of_the_week['Wed'] = 'wednesday'
days_of_the_week['Thu'] = 'thursday'
days_of_the_week['Fri'] = 'friday'
days_of_the_week['Sat'] = 'saturday'
days_of_the_week['Sun'] = 'sunday'
for x in input_array:
if x in days_of_the_week:
current_day = days_of_the_week[x]
elif x[0].isdigit() and dash_found == False:
starting_time = x
elif x == '-':
dash_found = True
elif x[0].isdigit() and dash_found == True:
ending_time = x
business_hours.append({"weekday_name":current_day,"starting_time":starting_time,"ending_time":ending_time})
dash_found = False
pprint.pprint(business_hours)
Can i make my code less ugly and accomplish the same without having to create many temporary variables in python?
Since your data are always in the same order:
# Here you remove all the cells in your array which are not a day of the week
# or a time (not the call to "list" before filter object are not indexable in Python 3+)
data = list(filter(lambda x: x in days_of_the_week or x[0].isdigit(), input_array))
while data:
# Get the first item available and remove it
curday = days_of_the_week[data.pop(0)]
# For each couple (start, end), add an item to business_hours
while data and data[0][0].isdigit():
business_hours.append({
'weekday_name': curday,
'starting_time': data[0],
'ending_time': data[1]
})
data = data[2:]
There are certainly plenty of way of doing this, you will probably be stuck with the curday variable since you have to memorize it (you could use the latest entry in business_hours but it would be uglier, IMO).
Edit: Someone suggested an edit saying list is not necessary. Since I don't know which version of python you are using, I assume python 3.0, in which case list is mandatory (filter are kind of generator in python 3.0, so they cannot be indexed). If you are using python 2.0, list may not be mandatory.
For the fun of it, here is a one liner using reduce (do I have to tell you not to do that?):
from functools import reduce # Okay, okay, 2 lines!
reduce (lambda r, x: r + [{'weekday_name': days_of_the_week[x]}] if x in days_of_the_week
else r + [{'weekday_name': r[-1]['weekday_name'], 'starting_time': x}] if len(r[-1]) == 3
else (r[-1].update({'starting_time': x}), r)[1] if len(r[-1]) == 1
else (r[-1].update({'ending_time': x}), r)[1],
filter(lambda x: x in days_of_the_week or x[0].isdigit(), input_array), [])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With