Infinite loop in Python

2

I am currently working on a project where I need to loop an infinite loop to a python code so that the data I'm asking for from a .json database is updated every so often. p>

The code is as follows:

from RPLCD import CharLCD
import json
import requests
import time

lcd = CharLCD(cols=16, rows=2, pin_rs=37, pin_e=35, pins_data=[33, 31, 29, 23]) #definimos los pines
lcd2 = CharLCD(cols=16, rows=2, pin_rs=37, pin_e=35, pins_data=[33, 31, 29, 23]) #definimos los pines



url = 'https://api.coindesk.com/v1/bpi/currentprice.json' #url
response = requests.get(url)

if response.status_code == 200: #si status = 200 se ejecuta esto

    lcd.write_string(u'Bitcoin Tracker\n\rBy ElTallerDeTD')
    time.sleep(4)
    lcd.clear()
    lcd2.cursor_pos = (0, 0)
    lcd2.write_string(time.strftime("Hora: "+"%H:%M"))
    time.sleep(1)
    lcd.cursor_pos = (1, 0) #pos seteada segunda fila primera columna
    data = json.loads(response.text)
    val_dol = data['bpi']['USD']['rate']+"  " #busca el valor en la ubicacion en USD
    val_eur = data['bpi']['EUR']['rate']+"  " #busca el valor en la ubicacion en EUR
    val_gbp = data['bpi']['GBP']['rate']+"" #busca el valor en la ubicacion en GBP

#########################################################################################

    framebuffer = [
        '',
        '',
    ]

    def write_to_lcd(lcd, framebuffer, num_cols):
        lcd.home()
        for row in framebuffer:
            lcd.write_string(row.ljust(num_cols)[:num_cols])
            lcd.write_string('\r\n')

    write_to_lcd(lcd, framebuffer, 16)


    long_string = 'BTC/USD: '+val_dol+'BTC/EUR: '+val_eur+'BTC/GBP: '+val_gbp

    def loop_string(string, lcd, framebuffer, row, num_cols, delay=0.8): #DELAY= CONTROLS THE SPEED OF SCROLL
        padding = ' ' * num_cols
        s = padding + string + padding
        for i in range(len(s) - num_cols + 1):
            framebuffer[row] = s[i:i+num_cols]
            write_to_lcd(lcd, framebuffer, num_cols)
            time.sleep(delay)

    while True:
        loop_string(long_string, lcd, framebuffer, 1, 16)

Any ideas on how to do? Thanks in advance!

    
asked by TaD 21.03.2018 в 00:27
source

1 answer

1

If I have not understood correctly, your problem would be summarized as follows:

  • I want to find out what time it is, and what change bitcoin has in that hour
  • I want to show both data on an LCD (although you have not specified exactly what should be seen on the two lines you have)
  • I want to go back to step 1 every N seconds
  • The code you've presented looks like a mix built by short & paste from different places. There is a function called write_to_lcd() , without documentation of what it does, which apparently dumps as many lines as elements have the framebuffer list that it receives as a parameter, "truncating" the displayed to only the first numcol letters.

    Another function called loop_string() , also undocumented, apparently deals with repeatedly calling write_to_lcd() , passing a slightly modified framebuffer in each iteration, so that the effect is that the text shown on the lcd "scroll "horizontal.

    Assuming that we want to use these functions already given, the first thing would be to define them at the beginning of the program, and not within a if as they are now. The second thing would be to give your program this structure:

    repetir infinitas veces:
        tomar qué hora es
        tomar la cotización del bitcoin
        mostrar esa información en el display
        dormir un tiempo (por ejemplo 1s)
    

    The simple part is to repeat infinity, because it is simply while True . The rest is not so complicated either, since you already have it written in your program. Everything consists in organizing it better. We will write a function to get what time it is. Another to get the bitcoin change, and two others (which were already in your code) to show data. I do not understand the reason why you install two displays with exactly the same parameters, so I have reduced it to one.

    Read the code and its comments to understand how it works to see if it's what you asked for.

    from RPLCD import CharLCD
    import json
    import requests
    import time
    
    def get_time():
        """Esta función retorna la hora actual en el formato a mostrar en el display"""
        return time.strftime("Hora: "+"%H:%M")
    
    def get_bpi():
        """Esta función retorna el 'long_string' con las cotizaciones del bitcoin
        tal como queremos que aparezca en el display"""
        url = 'https://api.coindesk.com/v1/bpi/currentprice.json' #url
        response = requests.get(url)
        if response.status_code == 200: #si status = 200 se ejecuta esto
            data = json.loads(response.text)
            val_dol = data['bpi']['USD']['rate']+"  " #busca el valor en la ubicacion en USD
            val_eur = data['bpi']['EUR']['rate']+"  " #busca el valor en la ubicacion en EUR
            val_gbp = data['bpi']['GBP']['rate']+"" #busca el valor en la ubicacion en GBP
            return "BTC/USD: {} BTC/EUR: {} BTC/GBP: {}".format(val_dol, val_eur, val_gbp)
        else:
            return "Cotizaciones no disponibles"
    
    def write_to_lcd(lcd, framebuffer, num_cols):
        """Esta funcion vuelca un framebuffer a un display, truncándolo a los num_clos
        primeros caracteres"""
        lcd.home()
        for row in framebuffer:
            lcd.write_string(row.ljust(num_cols)[:num_cols])
            lcd.write_string('\r\n')
    
    def loop_string(string, lcd, framebuffer, row, num_cols, delay=0.8):
        """Esta función prepara una fila del framebuffer recibido de modo que
        muestre la cadena recibida como primer parámetro desplazándose hacia
        la izquierda hasta haberla mostrado completa y luego retorna.
        El parámetro 'delay' controla la velocidad del desplazamiento"""
        padding = ' ' * num_cols
        s = padding + string + padding
        for i in range(len(s) - num_cols + 1):
            framebuffer[row] = s[i:i+num_cols]
            write_to_lcd(lcd, framebuffer, num_cols)
            time.sleep(delay)
    
    
    # Programa principal
    
    # Inicizar el LCD
    lcd = CharLCD(cols=16, rows=2, pin_rs=37, pin_e=35, pins_data=[33, 31, 29, 23]) #definimos los pines
    
    # Mostrar mensaje inicial 4 segundos
    lcd.write_string(u'Bitcoin Tracker\n\rBy ElTallerDeTD')
    time.sleep(4)
    lcd.clear()
    
    framebuffer = ['', ''] # Información a mostrar en cada fila del LCD
    
    while True:
        framebuffer[0] = get_time()  # Actualizar la hora en cada iteración del bucle
        long_string = get_bpi()
    
        # Mostrar hora y texto deslizante con la cotización
        loop_string(long_string, lcd, framebuffer, 1, 16, 0.3)
        # Esperar 1 seg y repetir bucle
        time.sleep(1)
    

    Look at a detail. The function loop_string() will take a while to return since until it has not finished moving the chain and has shown it whole, it does not return. Depending on the length of that string and the delay parameter, it will take more or less to finish. Once finished, time.sleep(1) sleeps a second, which adds to the time spent per loop_string() . If for example loop_string() takes 4 seconds to finish, then the infinto loop would repeat every 4 + 1 = 5 seconds. The time (and the bitcoin quote) are therefore not updated "in real time", but only every time.

        
    answered by 23.03.2018 / 17:49
    source