如何在不停止程序的情况下从正在编辑的CSV更新python程序?

2024-06-15 05:39:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我为盲人制作了一个会说话的自动售货机目录,里面放着一个树莓皮,里面放着一个扬声器

该程序将一直运行,无头,保存自动售货机零食信息和编号的csv将在线托管(但目前暂时在Pi中,如本问题所述)。其结构如下:
66,弗雷什利夫人的纸杯蛋糕
14、火红热奶酪
等等
在csv中添加什么顺序项并不重要,因为我在代码中对列表进行排序。 自动售货机公司的家伙说,如果他们改变了自动售货机内的东西,他们会很高兴地用新内容更新csv;因此,当他们保存csv时,我希望我的程序能够不断运行,将新数据拉入并更新我的VL(VendyList)变量。 这样,如果添加了项目“70,粘熊”,或者更改了编号66,它将自动更新该项目。是否有方法刷新导入csv?或者,每当有人按“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()


Tags: csvinfromimporteventifdefpygame
2条回答

下面是通过load_listrefresh_listrefresh_list_and_enqueue_next_refresh添加每60秒刷新一次的代码重构

我还擅自修理了一些其他东西,即

  • 因为我不是在一个树莓皮,我没有Pygame和GTT立即可用。这些现在是可选的,但如果不可用,将警告用户
  • 仅支持Python 3tkinter导入。Python2已被弃用
  • 我们现在只使用列表索引变量来查看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()

目前,该文件从未关闭过,但您可以在任何事件上重新读取它,您希望通过以下(open遵循csv针对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)))

相关问题 更多 >