Select data according to a specific time

Asked

Viewed 149 times

1

I am doing a program in which, given the day of the week, the hours and the current minutes, he responds with all the "Doctors" available at that time.

Each doctor has a period of care. For example:

  • Carlos attends on Mondays from 10:00 to 12:00, and on Thursdays from 15:00 to 16:30.
  • Juliana attends on Mondays from 10:00 to 11:30, and on Fridays from 15:00 to 16:00.

If someone runs the program at 11:00 on Monday, the program must print that Carlos and Juliana are available. If it runs on Wednesday at 15:00, the program should warn that no one is available. And finally, in case it runs on Thursday at 15:00, must return that Carlos is available.

I am doing this using Python 3. My logic is a sequence of if and else with their schedules, but I’m pretty sure it’s a pretty dumb way to solve that problem.

   from datetime import datetime
   from datetime import date
   
 async def responder(ctx):
    hoje = date.today()
    now = datetime.now()
    
    diaDaSemana = date.today()
    hora = now.hour
    minuto = now.minute
    
    if(diaDaSemana == 0):
        resposta = segundaFeira(hora, minuto)
    
    
    response = random.choice(brooklyn_99_quotes)
    await ctx.send(response)

def segundaFeira(hora, minuto):
    str = "Disponiveis: "
    if hora => 10 and hora <= 12:
        str += "Carlos"
    return str

Surely there is a simpler way to do this. I would like to know what this way is, I can use any python library.

  • I suggest taking a look at the dictionary definition, could make up each day of the week with a list with each available professional and their respective schedules.

1 answer

1


An alternative is to store the available schedules and the respective doctors in a dictionary. A suggestion is to have this structure:

from datetime import datetime, time

# dias da semana: 0 - segunda, 1 - terça, etc
horarios = {
    'Carlos': {
        0: (time(10, 0), time(12, 0)), # segunda, das 10h às 12h
        3: (time(15, 0), time(16, 30)) # quinta, das 15h às 16:30
    },
    'Juliana': {
        0: (time(10, 0), time(11, 30)), # segunda, das 10h às 11:30
        5: (time(15, 0), time(16, 0)) # sexta, das 15h às 16h
    }
}

That is, for each name, I have another dictionary containing the days of the week (using the values 0 for Monday, 1 for Tuesday, and so on). I did so to be compatible with the values returned by datetime.weekday().

And for each day of the week, I create a tuple with the initial and final hours. With this, just go through the structure and see if the time fits in one of them:

from datetime import datetime, time

# dias da semana: 0 - segunda, 1 - terça, etc
horarios = {
    'Carlos': {
        0: (time(10, 0), time(12, 0)), # segunda, das 10h às 12h
        3: (time(15, 0), time(16, 30)) # quinta, das 15h às 16:30
    },
    'Juliana': {
        0: (time(10, 0), time(11, 30)), # segunda, das 10h às 11:30
        5: (time(15, 0), time(16, 0)) # sexta, das 15h às 16h
    }
}

# data e hora atual
hoje = datetime.now()
dia_da_semana = hoje.weekday() # obter o dia da semana
horario = hoje.time() # pegar somente o horário

# imprime a data atual
print(f'Hoje é {hoje:%A, %d/%m/%Y %H:%M:%S}')
encontrado = False
for nome, disponibilidade in horarios.items(): # para cada médico
    if dia_da_semana in disponibilidade: # se atende no dia da semana
        inicio, fim = disponibilidade[dia_da_semana]
        if inicio <= horario <= fim: # verifica se horário está entre o início e fim
            print(f'{nome} está disponível das {inicio:%H:%M} às {fim:%H:%M}')
            encontrado = True

if not encontrado:
    print('Não há médicos disponíveis')

The detail is that when printing the day of the week, by default the name is shown in English. To print in Portuguese, you need to use the module locale:

import locale
# setar locale para português
locale.setlocale(locale.LC_ALL, 'pt_BR.utf8')

# restante do programa é igual

Recalling that in this case the locale must be installed in the system, as explained in this reply.

And I used f-strings to print the date and times. But if you are using a Python version earlier than 3.6 an alternative is to use format along with strftime. Just change the print's for:

print('Hoje é {}'.format(hoje.strftime('%A, %d/%m/%Y %H:%M:%S')))

print('{} está disponível das {} às {}'.format(nome, inicio.strftime('%H:%M'), fim.strftime('%H:%M')))

I noticed that you are assembling a string with the available names. In this case, a solution is to go storing the names in a list, and at the end you join them in a string:

disponiveis = []
for nome, disponibilidade in horarios.items():
    if dia_da_semana in disponibilidade:
        inicio, fim = disponibilidade[dia_da_semana]
        if inicio <= horario <= fim:
            disponiveis.append(nome)

if disponiveis: # se encontrou alguém
    resposta = f'Disponíveis: {", ".join(disponiveis)}'
else: # não encontrou ninguém disponível
    resposta = 'Não há médicos disponíveis'

# usar a resposta aqui...

I created the list disponiveis containing the names of the doctors found. Then, if you have any, I put together the names using join (in the above example I used ", ", so names are separated by comma and space, but you can switch to whatever you want). The result is a string containing the names of all doctors found, which will be in the variable resposta.


More than one time on the same day

If you have more than one schedule in the same day, then it changes a little. In this case you need to have a list of tuples (each containing the start and end time). Something like this:

from datetime import datetime, time

horarios = {
    'Carlos': {
        0: [(time(10, 0), time(12, 0)), (time(15, 0), time(16, 0))], # segunda, das 10h às 12h e das 15h às 16h 
        3: [(time(15, 0), time(16, 30))] # quinta, das 15h às 16:30
    },
    'Juliana': {
        0: [(time(10, 0), time(11, 30)), (time(15, 30), time(17, 0))], # segunda, das 10h às 11:30 e das 15:30 às 17h
        5: [(time(15, 0), time(16, 0))] # sexta, das 15h às 16h
    }
}

hoje = datetime.now()
dia_da_semana = hoje.weekday() # obter o dia da semana
horario = hoje.time() # pegar somente o horário

disponiveis = []
for nome, disponibilidade in horarios.items():
    if dia_da_semana in disponibilidade:
        # procurar na lista de horários
        for inicio, fim in disponibilidade[dia_da_semana]:
            if inicio <= horario <= fim:
                disponiveis.append(nome)
                break # encontrei horário nesse dia, posso interromper o loop
  • I managed to implement it. My question is, if a doctor has 2 hours of care on the same day, this would work?

  • 1

    @Gabrielarruda In this case it changes a little. I updated the answer with this option. Another thing: If the answer solved your problem, you can accept it, see here how and why to do it. It is not mandatory, but it is a good practice of the site, to indicate to future visitors that it solved the problem. Don’t forget that you can also vote in response, if it has found it useful.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.