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