'How to check if user was available in a particular interval? I have to check users busy time and available online in a particular interval?

This is my sample dataframe: Here U1 was online from 9:45 to 15:00 PM and then from 22:00 PM to 23:45, and same is with U2.

user Status Flag Timestamp
U1 0 Offline 09:30
U1 1 Online 09:45
U1 0 Offline 15:00
U1 0 Offline 16:00
U1 0 Offline 00:00
U1 1 Online 22:00
U1 0 Offline 23:45
U2 0 Offline 09:30
U2 1 Online 09:45
U2 0 Offline 15:00
U2 0 Offline 16:00
U2 0 Offline 00:00
U2 1 Online 22:00
U2 0 Offline 23:45

Expected output for each user:

User TimeInterval Online/Offline
U1 00:00-00:30 offline
U1 00:31-01:00 offline
U1 01:00-01:30 offline
U1 01:31-02:00 offline
U1 02:00-02:30 offline
U1 02:31-03:00 offline
U1 03:00-03:30 offline
U1 03:31-04:00 offline
U1 04:00-04:30 offline
U1 04:31-05:00 offline
U1 05:00-05:30 offline
U1 05:31-06:00 offline
U1 06:00-06:30 offline
U1 06:31-07:00 offline
U1 07:00-07:30 offline
U1 07:31-08:00 offline
U1 08:00-08:30 offline
U1 08:31-09:00 offline
U1 09:00-09:30 offline
U1 09:31-10:00 Online
U1 10:00-10:30 Online
U1 10:31-11:00 Online
U1 11:00-11:30 Online
U1 11:31-12:00 online
U1 12:00-12:30 Online
U1 12:31-13:00 Online
U1 13:00-13:30 Online
U1 13:31-14:00 Online
U1 14:00-14:30 Online
U1 14:31-15:00 Online
U1 15:00-15:30 Offline
U1 15:31-16:00 offline
U1 16:00-16:30 offline
U1 16:31-17:00 offline
U1 17:00-17:30 offline
U1 17:31-18:00 offline
U1 18:00-18:30 offline
U1 18:31-19:00 offline
U1 19:00-19:30 offline
U1 19:31-20:00 offline
U1 20:00-20:30 offline
U1 20:31-21:00 offline
U1 21:00-21:30 offline
U1 21:31-22:00 offline
U1 22:00-22:30 Online
U1 22:31-23:00 Online
U1 23:00-23:30 Online
U1 23:31-00:00 Online


Solution 1:[1]

Here I first create online periods and then check if a half-hour intersects one of those:

dataframe = [
    ['U1',     'Offline',   '09:30'],
    ['U1',     'Online',    '09:45'],
    ['U1',     'Offline',   '15:00'],
    ['U1',     'Offline',   '16:00'],
    ['U1',     'Offline',   '00:00'],
    ['U1',     'Online',    '22:00'],
    ['U1',     'Offline',   '23:45'],
    ['U2',     'Offline',   '09:30'],
    ['U2',     'Online',    '09:45'],
    ['U2',     'Offline',   '15:00'],
    ['U2',     'Offline',   '16:00'],
    ['U2',     'Offline',   '00:00'],
    ['U2',     'Online',    '22:00'],
    ['U2',     'Offline',   '23:45'],
]


def get_online_periods(dataframe):
    online_periods = {}
    for row in dataframe:
        user, status, time = row
        user_info = online_periods.setdefault(
            user, {
                'status': 'Offline',
                'online_time': None,
                'periods': []
            }
        )
        if status != user_info['status']:
            user_info['status'] = status
            if status == 'Online':
                user_info['online_time'] = time
            else:
                user_info['periods'].append((user_info['online_time'], time))
    return {
        user: info['periods']
            for user, info in online_periods.items()
    }


def overlap(period1, period2):
    """Checks if two intervals overlap"""
    start1, stop1 = period1
    start2, stop2 = period2
    return start1 < stop2 and start2 < stop1


def print_halfhour_status(user, online_periods):
    for i in range(48):
        hour = i//2
        start_minute = 30*(i%2)
        stop_minute  = start_minute + 29
        half_hour = ("{:02d}:{:02d}".format(hour, start_minute), "{:02d}:{:02d}".format(hour, stop_minute))
        print(
            user,
            f"{half_hour[0]} -- {half_hour[1]}",
            'Online' if any(map(lambda p: overlap(p, half_hour), online_periods)) else 'Offline'
        )


def main():
    for user, online_periods in get_online_periods(dataframe).items():
        print_halfhour_status(user, online_periods)


if __name__ == '__main__':
    main()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 md2perpe