Using datetime to obtain the time of the next lecture Often before the lecture starts, and occasionally in the break I like to display a timer with a countdown until the lectures starts/ resumes while playing some lofi-hip hop in the background. While the university students seems to enjoy this, I am ashamed of the code running the timer.
So my lecture schedules is as follows
Monday:    10:15 -- 12:00
Wednesday: 12:15 -- 14:00
Thursday:  08:15 -- 10:00

I am interested in finding when my next lecture is in iso format. I did this using the code below and it works fine. E.g if the current time is 16:00 on a Thursday, the output should be Monday and 10:15. I commented out the actual timer, as it is not important.

Is there a better way / cleaner python code to obtain the date and time for my next lecture?

My attempt (which works, albeit a bit ugly) is as follows:
from datetime import datetime, timedelta
from subprocess import call

# Format (day, hour, minute)
Lectures = [(0, 10, 15), (), (2, 12, 15), (3, 8, 15)]


def get_next_lecture(now=datetime.now()):

    next_lecture = now.replace(minute=15, second=0, microsecond=0)

    # monday = 0, tuesday = 1, ...
    current_day = datetime.today().weekday()
    current_hour = now.hour
    lecture_day = current_day

    correct_day = False
    while not correct_day:
        # If the day is tuesday, increment to wednesday
        if current_day == 1:
            lecture_day = current_day + 1
            lecture_hour = Lectures[lecture_day][1]
            lecture_minute = Lectures[lecture_day][2]
            now += timedelta(days=1)
            correct_day = True
            # if the day is friday, increment to monday
        elif current_day == 4:
            lecture_day = 0
            lecture_hour = Lectures[lecture_day][1]
            lecture_minute = Lectures[lecture_day][2]
            now += datetime.today() + timedelta(days=3)
            correct_day = True
        else:
            # If it is not monday or friday, I have a lecture
            # checks if the lecture is in the future, if else increment day and try again
            if now.hour &lt; Lectures[lecture_day][1]:
                if now.minute &lt; Lectures[lecture_day][2]:
                    lecture_hour = Lectures[lecture_day][1]
                    lecture_minute = Lectures[lecture_day][2]
                    correct_day = True
                else:
                    current_day += 1
                    now += timedelta(days=1)
            else:
                current_day += 1
                now += timedelta(days=1)

    next_lecture = now.replace(
        hour=lecture_hour, minute=lecture_minute, second=0, microsecond=0
    )

    return next_lecture


def launch_timer(time):
    call([&quot;termdown&quot;, time.isoformat()])


if __name__ == &quot;__main__&quot;:

    next_lecture = get_next_lecture()
    print(lecture)
    # launch_timer(next_lecture)
Your algorithm seems good, but the while loop, and lecture_hour and lecture_minute variables make your code a lot more complicated.
If we KISS then a simple algorithm is to just remove () from Lectures and iterate through it, since it is sorted.
The first lecture that is after the current time is the lecture we want.
This is nice and simple:
import datetime


LECTURES = [(0, 10, 15), (2, 12, 15), (3, 8, 15)]


def _get_next_lecture(now):
    today = (now.weekday(), now.hour, now.minute)
    for lecture in LECTURES:
        if today &lt; lecture:
            return lecture


def get_next_lecture(now=None):
    if now is None:
        now = datetime.datetime.now()
    day, hour, minute = _get_next_lecture(now)
    return (
        now.replace(hour=hour, minute=minute, second=0, microsecond=0)
        + datetime.timedelta(day - now.weekday())
    )

From here we can see if the weekday is 4-6 then _get_next_lecture will return nothing and so will error.
This is easy to solve, we just return the first lecture with +7 days.
def _get_next_lecture(now):
    today = (now.weekday(), now.hour, now.minute)
    for lecture in LECTURES:
        if today &lt; lecture:
            return lecture
    day, hour, minute = LECTURES[0]
    return day + 7, hour, minute

With only 3 lectures there's not much point in optimizing further. However if you have more, here is some food for thought:

You can use bisect to find where to insert into in \$O(\log n)\$ time.

You can change LECTURES into a 7 item list with the weekday as the index and the lectures as the value (always as a list). From here you just find the date using either of the above algorithms.
This would look like your Lectures. But with a list for each day.
This has either \$O(d)\$ or \$O(\log d)\$ time where \$d\$ is the maximum amount of lectures in a day.


Test code
def replace(date, changes):
    day, hour, minute = changes
    return date.replace(hour=hour, minute=minute) + datetime.timedelta(days=day)


def test(tests, bases, fn):
    for base in bases:
        date = base.replace(second=0, microsecond=0) - datetime.timedelta(days=base.weekday())
        for test, exp in tests:
            try:
                output = fn(replace(date, test))
            except Exception as e:
                print(f'❌ {test=}, {exp=}')
                print('  ', e)
                continue
            expected = replace(date, exp)
            try:
                assert output == expected
            except AssertionError:
                print(f'❌ {test=}, {exp=}')
                print('  ', date, output, expected)
            else:
                print(f'✔️ {test=}, {exp=}')

TESTS = [
    [(0, 0, 0), (0, 10, 15)],
    [(0, 10, 10), (0, 10, 15)],
    [(0, 10, 15), (2, 12, 15)],
    [(0, 10, 20), (2, 12, 15)],
    [(1, 12, 20), (2, 12, 15)],
    [(1, 13, 20), (2, 12, 15)],
    [(2, 10,  0), (2, 12, 15)],
    [(2, 10,  14), (2, 12, 15)],
    [(2, 12,  15), (3, 8, 15)],
    [(3, 8,  15), (7, 10, 15)],
]
BASES = [
    datetime.datetime.now(),
    datetime.datetime(2020, 9, 1),
    datetime.datetime(2020, 10, 1) - datetime.timedelta(days=1),
    datetime.datetime(2020, 12, 1),
    datetime.datetime(2021, 1, 1) - datetime.timedelta(days=1),
]

test(TESTS, BASES, get_next_lecture)