как обновить python программу из редактируемого CSV, не останавливая программу? - PullRequest
0 голосов
/ 23 марта 2020

Я сделал каталог говорящих торговых автоматов для слепых, он работает внутри малинового пи, вставленного в торговый автомат с динамиком.

Программа будет работать все время, без головы и csv где хранится информация о закусках торгового автомата и номера, он будет размещен в сети (хотя пока он временно находится в Pi). Его структура такова: 66, миссис фрешли кексы 14, Flamin Hot Cheetos и др c. Неважно, какие элементы заказа добавляются в CSV, поскольку я сортирую список в своем коде. Парень из компании Vending Machine сказал, что они с радостью обновят CSV новым содержимым, если они изменят вещи внутри торгового автомата; и поэтому, когда они сохраняют этот CSV, я хочу, чтобы моя программа, которая будет работать постоянно, извлекала эти данные fre sh и обновляла мою переменную VL (VendyList). Таким образом, если добавлен элемент «70, липкие медведи» или изменен номер 66, он автоматически обновит его. Есть ли способ обновить sh импорт CSV? Или обновлять sh всю программу всякий раз, когда кто-то нажимает «00» для функции «справки»?

Вот код

from gtts import gTTS
import pygame
from io import BytesIO
import os
import sys
import time

pygame.init()
if sys.version_info[0] == 3:
    # for Python3
    from tkinter import *   ## notice lowercase 't' in tkinter here
else:
    # for Python2
    from Tkinter import *

def say(text):
    tts = gTTS(text=text, slow=False, lang='en-us', lang_check=False)
    fp = BytesIO()
    tts.write_to_fp(fp)
    fp.seek(0)
    pygame.mixer.init()
    pygame.mixer.music.load(fp)
    pygame.mixer.music.play()



from csv import reader
infile = open(r'/home/pi/VendyLogProject/vendylist.csv',mode='r')

vl = sorted(list(reader(infile)))
vl2 = [item[0] for item in vl]


baseposition = vl[0] # 0 is the first entry index in the vl list




def current(event=None):
        global baseposition # baseposition was defined outside of the function, therefore we call global
        say(baseposition[1]+baseposition[0])



def back(event=None):
        global baseposition
        currentposition = vl.index(baseposition)
        if currentposition == 0: 
                say(baseposition[1]+baseposition[0])

        else:
                previousposition = int(currentposition) - 1 # previousposition is previous position
                baseposition = vl[previousposition]
                say(baseposition[1]+baseposition[0])



def forward(event=None):
        global baseposition
        currentposition = vl.index(baseposition)
        if currentposition == (len(vl) - 1):
                say(baseposition[1]+baseposition[0])

        else:
                nextposition = int(currentposition) + 1 # nextposition is next position
                baseposition = vl[nextposition]
                say(baseposition[1]+baseposition[0])


def readnumber(int):
           for item in vl:
            global baseposition
            currentposition = vl.index(baseposition)
            if int == item[0]:
                      baseposition = vl[vl.index(item)]
                      say(baseposition[1]+baseposition[0])


def help():
           say("Welcome to Vendy log! Use the plus and minus keys to go through the list of snacks or push a number to hear its contents!")







root = Tk()
prompt = '      VendyLog      '
label1 = Label(root, text=prompt, width=len(prompt))
label1.pack()

#keys buffer
keybuf = []

def test_after():
           if keybuf:
                      num = ''.join(keybuf)
                      keybuf.clear()




def get_key(event):
           keybuf.append(event.char)
           event.char = ''.join(keybuf)
           root.after(500,test_after)
           if event.char == '-':
                      back()
           elif event.char == '+':
                      forward()
           elif event.char == '.':
                      current()
           elif event.char in vl2:
                      readnumber(event.char)
           elif event.char == '00':
                      help()




root.bind_all('<Key>', get_key)

root.mainloop()

Ответы [ 2 ]

1 голос
/ 23 марта 2020

Вот рефакторинг вашего кода с добавлением refre sh каждые 60 секунд, через load_list, refresh_list и refresh_list_and_enqueue_next_refresh.

Я позволил себе исправить и некоторые другие вещи, а именно ...

  • Поскольку я не на Raspberry Pi, у меня нет доступных Pygame и gTTS. Теперь они являются необязательными, но если они недоступны, они будут предупреждать пользователя.
  • Поддерживается только импорт Python 3 tkinter. Python 2 устарела.
  • Сейчас мы используем только индексную переменную списка для просмотра items, а не копируем элементы в и из списка.
  • Ошибка повторного входа исправление буфера ключа, когда пользователь все еще входил в тест, было исправлено путем отслеживания последнего момента времени, когда пользователь нажимал кнопку.
import time
from io import BytesIO
import csv
import tkinter

try:
    import pygame
    from gtts import gTTS
except ImportError:
    pygame = None
    print("Warning: no sound output.")


if pygame:
    pygame.init()
    pygame.mixer.init()


def say(text):
    print("Speaking:", text)
    if pygame:
        tts = gTTS(text=text, slow=False, lang="en-us", lang_check=False)
        fp = BytesIO()
        tts.write_to_fp(fp)
        fp.seek(0)
        pygame.mixer.music.load(fp)
        pygame.mixer.music.play()


def load_list():
    with open(r"./vendylist.csv", mode="r") as infile:
        return sorted(list(csv.reader(infile)))


items = []
list_index = 0


def refresh_list():
    global items, list_index
    new_items = load_list()
    if items != new_items:
        print("Loaded new items (count: %d)." % len(new_items))
        # TODO: here's hoping resetting the list isn't interrupting an user!
        items = new_items
        list_index = 0
    else:
        print("No new items loaded...")


def speak_current():
    speak_index(list_index)


def speak_index(index):
    item = items[index]
    say("%s %s" % (item[1], item[0]))


def clamp_list_index(new_index):
    return min(len(items) - 1, max(new_index, 0))


def back():
    global list_index
    list_index = clamp_list_index(list_index - 1)
    speak_current()


def forward():
    global list_index
    list_index = clamp_list_index(list_index + 1)
    speak_current()


def readnumber(entered_number):
    global list_index
    for index, (number, text) in enumerate(items):
        if str(entered_number) == str(number):
            speak_index(index)
            # EDIT: Update the global list index
            #       so +/- start from the item just spoken.
            list_index = index
            break


def help():
    say("Welcome to Vendy log!")


root = tkinter.Tk()
prompt = "      VendyLog      "
label1 = tkinter.Label(root, text=prompt)
label1.pack()

last_key_time = time.time()
keybuf = []


def maybe_clear_buffer():
    if keybuf and time.time() - last_key_time > 1:
        print("Clearing key buffer (%s)." % keybuf)
        keybuf.clear()


def get_key(event):
    global keybuf, last_key_time
    last_key_time = time.time()
    keybuf.append(event.char)
    keybuf_str = "".join(keybuf)
    root.after(1000, maybe_clear_buffer)

    if event.char == "-":
        back()
    elif event.char == "+":
        forward()
    elif event.char == ".":
        speak_current()
    elif keybuf_str == "00":
        help()
    elif keybuf_str.isnumeric():
        readnumber(keybuf_str)


def refresh_list_and_enqueue_next_refresh():
    refresh_list()
    root.after(60000, refresh_list_and_enqueue_next_refresh)


refresh_list_and_enqueue_next_refresh()
root.bind_all("<Key>", get_key)
root.mainloop()
0 голосов
/ 23 марта 2020

В настоящее время файл никогда не закрывается, но вы можете перечитать его для любого события, которое хотите реализовать, с помощью следующего (open следует csv, модуль делает c рекомендации для Python 2 и 3):

if sys.version_info[0] == 3:
    with open(r'/home/pi/VendyLogProject/vendylist.csv',newline='') as infile:
        vl = sorted(list(reader(infile)))
else:
    with open(r'/home/pi/VendyLogProject/vendylist.csv','rb') as infile:
        vl = sorted(list(reader(infile)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...