0

I am writing a script to find meeting time for three people. I manage to get their Free/Busy status encoding in a binary format with 0 being free and 1 being busy in increment of 30 minutes for the next three days. I grouped their status by day into a dictionary format as below.

print(date_schedule)
{'Monday, 2020-02-03': ['000000000000000000101101001110110000000000000000',
  '000000000000000000001111011100001100000000000000',
  '000000000000000011110100011000110000000000000000'],
 'Tuesday, 2020-02-04': ['000000000000000000100010000000000000000000000000',
  '000000000000000000001111001000110000000000000000',
  '000000000000000011111000111100101000000000000000'],
 'Wednesday, 2020-02-05': ['000000000000000000111000000000000000000000000000',
  '000000000000000001001100110000000000000000000000',
  '000000000000000000111100000001001000000000000000']}

Goal: Translate those 0 into a block of thirty minutes intervals.

For Example: 00:00----00:30
             00:30----01:00
                   ...
             23:30----24:00

Attempted:

#Separate the code into a two dimensional list
schedule = date_free.values()

#Append the block to a new list.
free = []
for value in schedule:
   for v in value:
       for idx, time in enumerate(v):
           if time == '0':
                idx = idx/2
                end = idx + 0.5
                #5 slots, and two decimals
                idx = '{:05.2f}'.format(idx).replace('.50','.30').replace('.',':')
                end =  '{:05.2f}'.format(end).replace('.50','.30').replace('.',':')
                free.append((idx + '----' + end))

Problem: free has 372 elements and I don't know how to make it become a two-dimensional-list structure as it was before in schedule (because the number of 0 is different for each v). Is there a way to not creating a new list but directly apply the above logic element-wise to schedule?

Bonus question: I have not gotten there yet, but my next goal is to find the intersection of those 30 time block for each day as demonstrated in the random example below. If you have any suggestions, please let me know

print(date_time_final)
{'Monday, 2020-02-03': ['08:00----08:30','09:30----10:00','12:00----12:30'],
'Tuesday, 2020-02-04' : ['09:00----09:30','10:30----11:00','13:00----13:30','14:00----14:30']
'Wednesday, 2020-02-05' : ['07:00----07:30','14:30----15:00','15:00----15:30','19:00----19:30']}

Thank you in advance for your help!

BoBoMann
  • 101
  • 1
  • 7
  • When I execute the above code, I dont get 372 values, but just 12: A list with the string element `'00:00----00:30'` 12x. A few assumptions I have to confirm: 1) I assume the 3 binary sequences for each day are the 3 different people's busy/free statuses? Secondly, I assume you want the list to show only those free times, where all 3 persons are free, and right now you just append the free time slots to a list, but I assume your problem is, that if the first person being parsed is free and the next is not, you also need to remove the item retroactively? – tst Feb 05 '20 at 06:31
  • @tst: Yes, all your assumptions are correct. I ended up figure this out by writing a function to translate only the '0' into time block for each binary string and using the 'reduce' function from 'functools' module to find the intersection of those zero-time-blocks. – BoBoMann Feb 06 '20 at 12:39

1 Answers1

1

Is something like this what you were looking for?

schedule = {'Monday, 2020-02-03': ['000000000000000000101101001110110000000000000000',
  '000000000000000000001111011100001100000000000000',
  '000000000000000011110100011000110000000000000000'],
 'Tuesday, 2020-02-04': ['000000000000000000100010000000000000000000000000',
  '000000000000000000001111001000110000000000000000',
  '000000000000000011111000111100101000000000000000'],
 'Wednesday, 2020-02-05': ['000000000000000000111000000000000000000000000000',
  '000000000000000001001100110000000000000000000000',
  '000000000000000000111100000001001000000000000000']}

combined = {}
for value in schedule:
    day = {}
    for v in schedule[value]:
        for idx, time in enumerate(v):
            idx = idx/2
            end = idx + 0.5
            #5 slots, and two decimals
            idx = '{:05.2f}'.format(idx).replace('.50','.30').replace('.',':')
            end =  '{:05.2f}'.format(end).replace('.50','.30').replace('.',':')

            if time == '0':
                try: #Only assigns "True" if value does not yet exist and is not already False
                    if day[idx + '----' + end] == False:
                        pass
                    else:
                        day[idx + '----' + end] = True
                except:
                    day[idx + '----' + end] = True
            elif time == '1':
                day[idx + '----' + end] = False
    combined[value] = day

for day in combined:
    print(day)
    for time_slot in combined[day]:
        print("Time slot %s is free = %s" % (time_slot, str(combined[day][time_slot])))

Instead of lists, I used dictionary format to sort by day and by time slot, maintaining every time slot on record, but giving them a boolean value to determine if its free or not. (True == free, False == busy) That way you can do whatever you like with the output.

tst
  • 371
  • 1
  • 11
  • This is exactly what I am looking for except it is solved in a different way. The thought of nested dictionary never crossed my mind. Thank you for showing me this. I do have a few questions, what exception are you catching? Can you explain how do you check if time == '0' not yet exist. Thank you! – BoBoMann Feb 06 '20 at 12:45
  • Also, why do you need the try and except block inside the if statement? why can't you just directly set day[idx + '----' + end] = True if time == '0' and day[idx + '----' + end] = False if time == '1' – BoBoMann Feb 06 '20 at 13:16
  • The exception I am trying to catch is KeyError. If the time == 0 and its the first time you enter the loop, the if statement checking for the value of the key will throw an exception, because the Key doesnt exist yet. – tst Feb 07 '20 at 07:05