[Python] Обновление переменной

Тема в разделе "Perl, Python, Ruby", создана пользователем Bastard007, 20 окт 2019.

  1. Bastard007

    Bastard007

    Регистр.:
    17 авг 2009
    Сообщения:
    174
    Симпатии:
    51
    Доброго времени суток. Сильно не пинайте, Питон изучаю первый день.

    Собственно, вопрос такой - как обновлять (ну например, раз в 30 секунд) переменную в коде?

    Суть такая - парсим JSON, берем оттуда переменную (в моем случае nowplay ) - используем эту переменную для вывода на LCD дисплей. Сейчас все работает. Но данные в JSON меняются. Хотелось бы каждые 30 секунд получать эту переменную nowplay и обновлять вывод на экране

    Код сейчас такой:

    Код:
    import urllib, json, time
    url = "ТУТ URL"
    response = urllib.urlopen(url)
    data = json.loads(response.read())
    nowplay = data['current']['name']
    framebuffer = ['STATUS: OK!','',]
    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')
      
    from RPLCD.i2c import CharLCD
    lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1,
                  cols=20, rows=4, dotsize=8,
                  charmap='A00',
                  auto_linebreaks=True
                 )
    write_to_lcd(lcd, framebuffer, 16)
    long_string = nowplay
    for i in range(len(long_string) - 16 + 1):
        framebuffer[1] = long_string[i:i+16]
        write_to_lcd(lcd, framebuffer, 16)
        time.sleep(0.2)
    #time.sleep(2)
    #lcd.close(clear=True)
    #lcd.backlight_enabled = False
    
    
    
    def loop_string(string, lcd, framebuffer, row, num_cols, delay=0.2):
        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)
    
    Загоняю цикл получения JSON в while с time.sleep (30) - данные берет каждые 30 секун, но текст перестает "бегать по экрану", т.е. перестает работать
    Код:
    while True:
        loop_string(long_string, lcd, framebuffer, 1, 16)
    
    P.S. Постарался объяснить как можно проще...не ругайте, если совсем нифика не понятно

    Код, при котором данные обновляются раз в 30 секунд, но при этом текст перестает "бегать"
    Код:
    # -*- coding: utf-8 -*-
    import urllib, json, time, sys
    from RPLCD.i2c import CharLCD
    lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1,cols=16, rows=2, dotsize=8,charmap='A00',auto_linebreaks=True)
    def my_except_hook(exctype, value, traceback):
        if exctype == KeyboardInterrupt:
            time.sleep(2) 
            lcd.close(clear=True)
            lcd.backlight_enabled = False 
        else:
            sys.__excepthook__(exctype, value, traceback)
    sys.excepthook = my_except_hook
    while True:
        url = "тут URL"
        response = urllib.urlopen(url)
        data = json.loads(response.read())
        nowplay = data['current']['name']
        print("Данные получены")
        framebuffer = ['STATUS: OK!','',]
        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)
        #import time
        long_string = nowplay
        for i in range(len(long_string) - 16 + 1):
            framebuffer[1] = long_string[i:i+16]
            write_to_lcd(lcd, framebuffer, 16)
            time.sleep(0.2)
        #time.sleep(2) 
        #lcd.close(clear=True)
        #lcd.backlight_enabled = False 
     
     
     
        def loop_string(string, lcd, framebuffer, row, num_cols, delay=0.2):
            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) 
     
        time.sleep(30)
    
    
     
    Последнее редактирование: 20 окт 2019
  2. Sorcus

    Sorcus Sorcus. A New Beginning.

    Moderator
    Регистр.:
    10 июл 2011
    Сообщения:
    470
    Симпатии:
    842
    Не силён в питоне, но почему у тебя в последнем коде в цикле while определяются функции write_to_lcd и loop_string?
    url тоже можно вынести за пределы цикла while, т.к. он у тебя не меняется.
    И я в коде не вижу, чтобы у тебя где-то вызывалась функция loop_string.
     
  3. s10n

    s10n Создатель

    Регистр.:
    6 авг 2015
    Сообщения:
    10
    Симпатии:
    1
    Зачем функции в цикле определять? Вынесите определение за него, а из цикла вызывайте. И у write_to_lcd пропущено def
     
    Bastard007 нравится это.
  4. Xardas4522

    Xardas4522 Создатель

    Регистр.:
    7 окт 2016
    Сообщения:
    10
    Симпатии:
    4
    Изучил код, я вижу что вторая часть кода, где цикл while ожидает паузу
    Как вариант решения проблемы - использование многопоточности. Извлекайте данные и обновляйте переменную в параллельном потоке с паузой, а основной код вывода пусть работает без паузы.
     
    Bastard007 нравится это.