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

Bastard007

Гуру форума
Регистрация
17 Авг 2009
Сообщения
179
Реакции
52
Доброго времени суток. Сильно не пинайте, Питон изучаю первый день.

Собственно, вопрос такой - как обновлять (ну например, раз в 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)
 
Последнее редактирование:

Sorcus

Sorcus. A New Beginning.
Регистрация
10 Июл 2011
Сообщения
513
Реакции
1.002
Не силён в питоне, но почему у тебя в последнем коде в цикле while определяются функции write_to_lcd и loop_string?
url тоже можно вынести за пределы цикла while, т.к. он у тебя не меняется.
И я в коде не вижу, чтобы у тебя где-то вызывалась функция loop_string.
 

s10n

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

Xardas4522

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

wmic

Писатель
Регистрация
30 Янв 2020
Сообщения
1
Реакции
0
from multiprocessing.dummy import Pool

Можно поиграться с потоками, поставить таймауты каждый поток
 

sai_NT

Постоялец
Регистрация
10 Фев 2007
Сообщения
70
Реакции
84
Доброго времени суток. Сильно не пинайте, Питон изучаю первый день.

Собственно, вопрос такой - как обновлять (ну например, раз в 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)

Вот несколько приёмов на выбор: Для просмотра ссылки Войди или Зарегистрируйся
 
Сверху