How to make the number of executions of an algorithm a function of processing capacity and not of time?

Asked

Viewed 58 times

0

I wrote a little program to send a message on my father’s Whatsapp to remind him to take his meds. Below I present the code that can be replicated by anyone with a mobile number and a record in the twilio API. in addition to the spreadsheet medications.csv (see below)

My problem is: I want my Father to receive a single message for every remedy in the database medications.csv, but I don’t know how to specify it. A hackish Solution What I found was to specify the exact second the message should be sent. However, I believe that there should be a better solution since if the program runs on a PC faster than mine it is likely that the logical test and the loop run at a speed of more than half a second, in which case my Father would receive n identical messages (where n is the number of complete operations per second).

How do I run this algorithm only once independent of hardware capability?

from twilio.rest import Client
import pandas as pd 
from datetime import datetime
import re
from time import sleep

account_sid = '' #insira seu sid aqui
auth_token = '' #insira seu token aqui
client = Client(account_sid, auth_token)

def to_list_integer(dt_time):
    return [dt_time.year,dt_time.month,dt_time.day, dt_time.hour,dt_time.minute]



df=pd.read_csv('medications.csv')

while True:
    data_lista =  to_list_integer(datetime.now())
    x=datetime(*data_lista)
    hora = x.strftime("%Hh%M")
    for i in range(len(df)):
        if (datetime.now().hour==df['hour'][i]) & (datetime.now().minute==5) & (datetime.now().second==1):
            text = '''*Lembrete: {0}*\n
Olá sr(a). Fulano, agora são {1}, 
\nestá na hora de tomar {2} comprimido(s) de {0}
\n\n*recomendação médica: {3}*'''.format(df['name'][i],hora,re.search(r'\d+',df['recomendation'][i]).group(),
                                                df['recomendation'][i])
            for person in ['whatsapp:+55XXXXXXXXXXX','whatsapp:+XXXXXXXXXXX']:#insira o seu número e do familiar aqui. Oseu é apenas pra controlar
                message = client.messages.create(
                                            body=text,
                                            from_='whatsapp:+XXXXXXXXXXX',#insira seu número twilio aqui
                                            to=person
                                        )
            print(message.sid)

medications.csv:

name,dosage,recomendation,hour,minute
remédio 1,100mg,Tomar 1 comprimido pela manhã,6,9
remédio 1 Plus,20/12.5 mg,Tomar 1 comprimido pela manhã,6,10
remédio 1 XR,500mg,Tomar 2 comprimidos após o café e após a última refeição da noite,7,10
remédio 2,75mg,Tomar 1 comprimido após o almoço,16,5
remédio 3,100mg,Tomar 1 comprimido após o almoço,16,6
remédio 1,10mg,Tomar 2 comprimidos à noite,20,10
remédio 1 XR,500mg,Tomar 2 comprimidos após o café e após a última refeição da noite,20,11
Rosuvastatina,20mg,Tomar 1 comprimido após a última refeição da noite,20,12

P.S: It was hard to summarize my doubt in the question’s title. I accept suggestions to make it clearer and more objective

1 answer

1

Hello, you asked for ideas and suggestions. But your code is not very clear at least for me. But from what I understand you want a routine that calls a function at predetermined times on a single correct day? The routine I could imagine for that was this.

import pandas as pd
import time

T = pd.Timestamp.today()
print(T)
hora1 = pd.Timestamp(T.year, T.month,T.day, T.hour,T.minute,20)
hora2 = pd.Timestamp(T.year, T.month,T.day, T.hour,T.minute,30)
hora3 = pd.Timestamp(T.year, T.month,T.day, T.hour,T.minute,40)

hora_reset = pd.Timestamp(T.year, T.month,T.day, 23,59,55)

d = {'Horário': [hora1,hora2,hora3], 'Controle':[False,False,False],'Lembretes': ['Remedio1', 'Remedio2', 'Remedio1']}

while True:
    t = pd.Timestamp.now()
    for x in range(len(d['Horário'])):
        if (t > d['Horário'][x] ) and (d['Controle'][x] == False):
            print(d['Lembretes'][x])
            d['Controle'][x] = True
        if (t > hora_reset):
            d['Horário'][0] = pd.Timestamp(t.year, t.month,(t.day+1), 8,0,0)
            d['Horário'][1] = pd.Timestamp(t.year, t.month,(t.day+1), 12,0,0)
            d['Horário'][2] = pd.Timestamp(t.year, t.month,(t.day+1), 16,0,0)
            hora_reset = pd.Timestamp(t.year, t.month,(t.day+1), 23,59,55)
            d['Lembretes'][0] = False
            d['Lembretes'][1] = False
            d['Lembretes'][2] = False
    time.sleep(1)

In case the program prints the message in the next 20, 30 and 40 seconds to test, but if you change the time setting lines to 8h00, 12h00, 16h00, etc. It looks like this:

hora1 = pd.Timestamp(T.year, T.month,T.day, 8,0,0)
hora2 = pd.Timestamp(T.year, T.month,T.day, 12,0,0)
hora3 = pd.Timestamp(T.year, T.month,T.day, 16,0,0)

How do I make this algorithm run only once independent of hardware capacity?

I believe the answer to that is function time.sleep() which is in the code. In case it causes a delay of 'x' seconds in each while loop and you can adjust to how to get better for your application and save computer processing. In the case of medicines you can have a delay of 60 until some 300 seconds that is well acceptable.

  • Interesting. Soon more I will look calmly your solution. On your last point, I initially used the time.sleep(), but it comes into the same problem: fix the time, delay or run, does not guarantee that different computers do the same number of operations within the for loop

  • The number of operations within a loop is determined by the code within the loop. The runtime that is set by the hardware. Any computer runs that loop in milliseconds or less. Also I don’t see why you think that running time is something critical to your program. If you look at the code you will see that the shot happens when 'now()' is longer than the time of the shot, if you use without delay, the shot occurs only milliseconds dps that passed the time when I think it solves your problem well. And you can guarantee that the shot is unique by the control variable.

  • In the case of my for loop the number of operations depends on how many operations the PC does while the conditional remains true. To better understand what I mean, run my code without specifying the seconds. As the condition of if (datetime.now().hour==df['hour'][i]) & (datetime.now().minute==5) will be true for an entire minute, the PC will perform the operation within the for loop a number n sometimes, but this n will depend on the computer’s processing capacity. Note that specify the segundos does not solve the problem, only decreases the average of n.

  • thank you so much for your help. Unfortunately, I was not clear enough. I think the best thing to do is to delete this question and ask another one with a minimal replicable example and present what I am thinking abstractly with some simple equations. Soon I will

  • 1

    Now I understand what you mean. Precisely because of this problem of fixing an equal hour. That I suggested a control structure with inequality > and a boolean control variable to ensure single firing.

  • 1

    If you are interested, see the discussion of the question I asked in the American stack: https://stackoverflow.com/questions/60555797/how-can-i-make-the-number-of-runs-of-an-infinite-algorithm-fixed-regardless-of-m. I tried to do here, but they closed

Show 1 more comment

Browser other questions tagged

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